WebAssembly 系统接口 (WASI)
【WebAssembly System Interface (WASI)】
稳定性: 1 - 实验性
node:wasi 模块目前尚未提供某些 WASI 运行时所具备的全面文件系统安全属性。未来可能会实现对安全文件系统沙箱的完全支持,也可能不会。在此期间,不要依赖它来运行不受信任的代码。
源代码: lib/wasi.js
WASI API 提供了 WebAssembly 系统接口 规范的实现。WASI 通过一系列类似 POSIX 的函数,使 WebAssembly 应用能够访问底层操作系统。
【The WASI API provides an implementation of the WebAssembly System Interface specification. WASI gives WebAssembly applications access to the underlying operating system via a collection of POSIX-like functions.】
import { readFile } from 'node:fs/promises';
import { WASI } from 'node:wasi';
import { argv, env } from 'node:process';
const wasi = new WASI({
version: 'preview1',
args: argv,
env,
preopens: {
'/local': '/some/real/path/that/wasm/can/access',
},
});
const wasm = await WebAssembly.compile(
await readFile(new URL('./demo.wasm', import.meta.url)),
);
const instance = await WebAssembly.instantiate(wasm, wasi.getImportObject());
wasi.start(instance);'use strict';
const { readFile } = require('node:fs/promises');
const { WASI } = require('node:wasi');
const { argv, env } = require('node:process');
const { join } = require('node:path');
const wasi = new WASI({
version: 'preview1',
args: argv,
env,
preopens: {
'/local': '/some/real/path/that/wasm/can/access',
},
});
(async () => {
const wasm = await WebAssembly.compile(
await readFile(join(__dirname, 'demo.wasm')),
);
const instance = await WebAssembly.instantiate(wasm, wasi.getImportObject());
wasi.start(instance);
})();要运行上述示例,请创建一个名为 demo.wat 的新 WebAssembly 文本格式文件:
【To run the above example, create a new WebAssembly text format file named
demo.wat:】
(module
;; Import the required fd_write WASI function which will write the given io vectors to stdout
;; The function signature for fd_write is:
;; (File Descriptor, *iovs, iovs_len, nwritten) -> Returns number of bytes written
(import "wasi_snapshot_preview1" "fd_write" (func $fd_write (param i32 i32 i32 i32) (result i32)))
(memory 1)
(export "memory" (memory 0))
;; Write 'hello world\n' to memory at an offset of 8 bytes
;; Note the trailing newline which is required for the text to appear
(data (i32.const 8) "hello world\n")
(func $main (export "_start")
;; Creating a new io vector within linear memory
(i32.store (i32.const 0) (i32.const 8)) ;; iov.iov_base - This is a pointer to the start of the 'hello world\n' string
(i32.store (i32.const 4) (i32.const 12)) ;; iov.iov_len - The length of the 'hello world\n' string
(call $fd_write
(i32.const 1) ;; file_descriptor - 1 for stdout
(i32.const 0) ;; *iovs - The pointer to the iov array, which is stored at memory location 0
(i32.const 1) ;; iovs_len - We're printing 1 string stored in an iov - so one.
(i32.const 20) ;; nwritten - A place in memory to store the number of bytes written
)
drop ;; Discard the number of bytes written from the top of the stack
)
) 使用 wabt 将 .wat 编译为 .wasm
【Use wabt to compile .wat to .wasm】
wat2wasm demo.wat