如何导出 WebAssembly 函数?
How to export WebAssembly function?
我正在尝试做的是具有给定要求的 WASM 加载程序:
- 在运行时仅导入一次 WASM 函数。
- 在其他IIFE函数中直接调用WASM函数。如果不存在,请等待它加载。
- 导出它 (testWASM) 以便它可以从其他模块异步调用。
这个有效:
let testWASM;
(async() => {
const config = {
env: {
__memory_base: 0,
__table_base: 0,
memory: new WebAssembly.Memory({
initial: 256,
}),
table: new WebAssembly.Table({
initial: 0,
element: 'anyfunc',
}),
}
}
const fetchPromise = fetch(process.env.PUBLIC_URL + '/hello.wasm');
const {instance} = await WebAssembly.instantiateStreaming(fetchPromise, config);
testWASM = instance.exports.fib;
console.log(testWASM());
})();
setTimeout(() => {
console.log(testWASM());
}, 2000)
显然 setTimeout 是非常糟糕的方法。
编辑:hello.c:
#include <emscripten.h>
EMSCRIPTEN_KEEPALIVE
int fib() {
return 42;
}
构建命令:
emcc hello.c -Os -s WASM=1 -s SIDE_MODULE=1 -o hello.wasm
编辑:
这在导出方面效果很好,但我认为它不符合第一个要求。它非常慢,我认为这是由于每次调用函数时都在获取:
wasm.js
module.exports = async () => {
const config = {
env: {
__memory_base: 0,
__table_base: 0,
memory: new WebAssembly.Memory({
initial: 256
}),
table: new WebAssembly.Table({
initial: 0,
element: "anyfunc"
})
}
};
const fetchPromise = fetch(process.env.PUBLIC_URL + "/hello.wasm");
const { instance } = await WebAssembly.instantiateStreaming(
fetchPromise,
config
);
return instance.exports.fib();
};
然后我们可以这样使用它:
import * as foo from './wasm.js'
const bar = async () => {
console.log(await foo())
}
bar(); //42
这似乎工作正常:
let cache;
module.exports = async (x, y, z) => {
if (cache) {
return cache(x, y, z);
} else {
const config = {
env: {
__memory_base: 0,
__table_base: 0,
memory: new WebAssembly.Memory({
initial: 256
}),
table: new WebAssembly.Table({
initial: 0,
element: "anyfunc"
})
}
};
const fetchPromise = fetch(process.env.PUBLIC_URL + "/hello.wasm");
const { instance } = await WebAssembly.instantiateStreaming(
fetchPromise,
config
);
cache = instance.exports.mandelIter;
return instance.exports.mandelIter(x, y, z);
}
};
但由于某些原因,它比普通的 JS 函数慢了大约 0.1 秒。奇怪...
我正在尝试做的是具有给定要求的 WASM 加载程序:
- 在运行时仅导入一次 WASM 函数。
- 在其他IIFE函数中直接调用WASM函数。如果不存在,请等待它加载。
- 导出它 (testWASM) 以便它可以从其他模块异步调用。
这个有效:
let testWASM;
(async() => {
const config = {
env: {
__memory_base: 0,
__table_base: 0,
memory: new WebAssembly.Memory({
initial: 256,
}),
table: new WebAssembly.Table({
initial: 0,
element: 'anyfunc',
}),
}
}
const fetchPromise = fetch(process.env.PUBLIC_URL + '/hello.wasm');
const {instance} = await WebAssembly.instantiateStreaming(fetchPromise, config);
testWASM = instance.exports.fib;
console.log(testWASM());
})();
setTimeout(() => {
console.log(testWASM());
}, 2000)
显然 setTimeout 是非常糟糕的方法。
编辑:hello.c:
#include <emscripten.h>
EMSCRIPTEN_KEEPALIVE
int fib() {
return 42;
}
构建命令:
emcc hello.c -Os -s WASM=1 -s SIDE_MODULE=1 -o hello.wasm
编辑:
这在导出方面效果很好,但我认为它不符合第一个要求。它非常慢,我认为这是由于每次调用函数时都在获取:
wasm.js
module.exports = async () => {
const config = {
env: {
__memory_base: 0,
__table_base: 0,
memory: new WebAssembly.Memory({
initial: 256
}),
table: new WebAssembly.Table({
initial: 0,
element: "anyfunc"
})
}
};
const fetchPromise = fetch(process.env.PUBLIC_URL + "/hello.wasm");
const { instance } = await WebAssembly.instantiateStreaming(
fetchPromise,
config
);
return instance.exports.fib();
};
然后我们可以这样使用它:
import * as foo from './wasm.js'
const bar = async () => {
console.log(await foo())
}
bar(); //42
这似乎工作正常:
let cache;
module.exports = async (x, y, z) => {
if (cache) {
return cache(x, y, z);
} else {
const config = {
env: {
__memory_base: 0,
__table_base: 0,
memory: new WebAssembly.Memory({
initial: 256
}),
table: new WebAssembly.Table({
initial: 0,
element: "anyfunc"
})
}
};
const fetchPromise = fetch(process.env.PUBLIC_URL + "/hello.wasm");
const { instance } = await WebAssembly.instantiateStreaming(
fetchPromise,
config
);
cache = instance.exports.mandelIter;
return instance.exports.mandelIter(x, y, z);
}
};
但由于某些原因,它比普通的 JS 函数慢了大约 0.1 秒。奇怪...