WebAssembly入门笔记[2]:利用Memory传递数据-二、导出Memory

时间:2024-01-26 09:12:06

上面演示了如何将Memory对象从宿主应用中导入到WebAssembly模块,现在我们反其道而行,将WebAssembly模块中创建的Memory导出到宿主程序,为此我们将app.wat文件修改为如下的内容。如代码片段所示,我们利用(memory (export "memory") 1)节点定义了一个初始大小为1Page的Memory,并以名称“memory”进行导出。随后定义的导出函数initialize会将作为参数指定的两个整数写入前8个字节。针对Memory的写入通过{i32|i64|f32|f64}.store指令完成,该指令接受两个参数,第一个代表写入的位置,第二个代表写入的值。由于我们具体调用的是i32.store指令,所以在第二次调用的时候指定的写入位置是4,而不是2。

(module
    (memory (export "memory") 1)
    (func (export "initialize") (param $first i32) (param $second i32)
         i32.const 0
         local.get $first
         i32.store

         i32.const 4
         local.get $second
         i32.store
    )
)

在如下所示的index.html中,我们在加载WebAssembly模块“app.wasm”并得到模块实例后,调用导出的initialize函数在Memory中写入两个整数123。然后我们导出Memory对象,并将它的缓冲区映射为四种类型的数组(Uint32Array、BigUint64Array、Float32Array和Float64Array),并将第一个元素的值读取出来,这一操作与上面定义针对四个类型定义的读取函数可谓“异曲同工”。

<html>
    <head></head>
    <body>
        <div id="container"></div>
        <script>
            WebAssembly
                .instantiateStreaming(fetch("app.wasm"))
                .then(results => {
                    var exports = results.instance.exports;
                    exports.initialize(123,123);
                    var buffer = exports.memory.buffer;
                    document.getElementById("container").innerHTML =
                        `<p>Int32: ${new Uint32Array(buffer)[0]}</p>`+
                        `<p>Int32: ${new BigUint64Array(buffer)[0]}</p>` +
                        `<p>Int32: ${new Float32Array(buffer)[0]}</p>`+
                        `<p>Int32: ${new Float64Array(buffer)[0]}</p>`;
                });
        </script>
    </body>
</html>

我们按照相同的方式将读取出来的四个值转换成HTML进行输出,所以我们在浏览器上看到相同的结果。