Как экспортировать функцию WebAssembly? - PullRequest
0 голосов
/ 09 марта 2020

То, что я пытаюсь сделать, это загрузчик 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 действительно плохой подход.

РЕДАКТИРОВАТЬ: привет. 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

1 Ответ

0 голосов
/ 09 марта 2020

Кажется, это работает нормально:

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);
  }
};

Но по какой-то причине она работает примерно на 0,1 с медленнее, чем обычная JS функция. Weird ...

...