首页 > 解决方案 > 将 Zig 编译为 wasm32-freestanding 时出错

问题描述

我正在尝试使用wasm32-freestanding目标将 Zig 函数编译为独立的 WebAssembly 模块。官方文档中有一个部分解释了如何执行此操作,但在最新版本的 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即使不使用它,我是否应该只向模块提供导出?

标签: javascriptwebassemblyzig

解决方案


您应该尝试使用build-lib而不是build-obj.


推荐阅读