ターゲットを使用して、Zig 関数を独立した WebAssembly モジュールにコンパイルしようとしていますwasm32-freestanding。公式ドキュメントには、これを行う方法を説明するセクションがありますが、最近のバージョンの Zig (0.8.0) では、生成されたモジュールを JavaScript でインスタンス化しようとするとエラーが発生します。
// file: main.zig
export fn add(a: i32, b: i32) i32 {
return a +% b;
}
// file: test.js
WebAssembly.instantiate((function() {
const source = require("fs").readFileSync("main.o");
return new Uint8Array(source);
})(), { env: {} }).then(wasm => {
const add = wasm.instance.exports.add;
console.log(add(1, 2));
});
$ zig version
0.8.0
$ node --version
14.17.3
$ zig build-obj main.zig -target wasm32-freestanding -dynamic -OReleaseFast
$ wc -c main.o # the generated code has extension `.o` instead of `.wasm`
135
$ node test.js
(node:2449) UnhandledPromiseRejectionWarning: LinkError: WebAssembly.instantiate(): Import #0 module="env" function="__linear_memory" error: memory import must be a WebAssembly.Memory object
(Use `node --trace-warnings ...` to show where the warning was created)
(node:2449) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:2449) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
生成された wasm モジュールを調べると__linear_memory、スコープから呼び出された値をインポートしようとしていることがわかりますenv。私はそのようなインポートを提供していないので、当然これは失敗します。ただし、サンプル プロジェクトzig-wasm-testには、これらのインポートを含まない WASM モジュール (Zig の古いバージョンでコンパイル) が含まれています。
ここで何が間違っていますか?__linear_memoryモジュールが使用されていない場合でも、モジュールへのエクスポートを提供する必要がありますか?