如何导出 WebAssembly 函数?

How to export WebAssembly function?

我正在尝试做的是具有给定要求的 WASM 加载程序:

  1. 在运行时仅导入一次 WASM 函数。
  2. 在其他IIFE函数中直接调用WASM函数。如果不存在,请等待它加载。
  3. 导出它 (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 秒。奇怪...