WebAssembly
创建webasm字符串模板
my-module.wat:
(module
(func $add (param $a i32) (param $b i32) (result i32)
(i32.add
(local.get $a)
(local.get $b)
)
)
(export "add" (func $add))
)
将wat转化为wasm二进制文件
$ wat2wasm.exe my-module.wat
上面的命令将使用my-module.wat
文件生成my-module.wasm
文件
js调用
const resp = await fetch("my-module.wasm");
const buf = await resp.arrayBuffer();
const { instance } = await WebAssembly.instantiate(buf);
const r = instance.exports.add(1, 2);
console.assert(r === 3);
wasm 使用导入的模块
(module
(import "JsModule" "alert" (func $alert (param i32)))
(func $add (param $a i32) (param $b i32)
(call $alert (i32.add
(local.get $a)
(local.get $b)
))
)
(export "add" (func $add))
)
const resp = await fetch("./my-module.wasm");
const buf = await resp.arrayBuffer();
const { instance } = await WebAssembly.instantiate(buf, {
JsModule: { alert },
});
const r = instance.exports.add(1, 2);
console.assert(r === undefined);
wasm 使用导入的内存
(module
(import "env" "memory" (memory 1))
(func $add (result i32)
(i32.add
(i32.load (i32.const 0))
(i32.load (i32.const 4))
)
)
(export "add" (func $add))
)
const mem = new WebAssembly.Memory({ initial: 1 });
const view = new DataView(mem.buffer);
// 你需要使用小端法来存数据
// view默认使用大端,但是在wasm中读取时使用小端
view.setInt32(0, 1, true);
view.setInt32(4, 2, true);
console.assert(view.getInt32(0, true) === 1);
console.assert(view.getInt32(4, true) === 2);
const resp = await fetch("./my-module.wasm");
const buf = await resp.arrayBuffer();
const { instance } = await WebAssembly.instantiate(buf, {
env: { memory: mem },
});
const r = instance.exports.add(1, 2);
console.assert(r === 3);
在线程中共享内存,及挂起线程
main.js
const sab = new SharedArrayBuffer(4);
const view = new Int32Array(sab);
const worker = new Worker("w.js");
worker.postMessage(sab);
setTimeout(() => {
view[0] = 100;
Atomics.notify(view, 0); // 唤醒等待的线程
}, 3000);
w.js
onmessage = (e) => {
const view = new Int32Array(e.data);
// 如果数组中给定位置的值等于提供的值,则将当前代理置于睡眠状态,导致执行挂起,
// 直到超时到期(返回“超时”)或直到代理被唤醒(返回“ ok”)为止。 “); 否则,返回“不等于”。
Atomics.wait(view, 0, 0); // view[0] === 0 挂起线程
console.log(view[0]);
console.assert(view[0] === 100);
};
See also: