То, что я пытаюсь сделать, это загрузчик 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 действительно плохой подход.
РЕДАКТИРОВАТЬ: привет. 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