WebAssembly 系统接口 (WASI)
\WebAssembly System Interface (WASI)
稳定性: 1 - 实验性的
\Stability: 1 - Experimental
源代码: lib/wasi.js
WASI API 提供了 WebAssembly 系统接口 规范的实现。WASI 让沙盒化的 WebAssembly 应用通过一系列类似 POSIX 的函数访问底层操作系统。
\The WASI API provides an implementation of the WebAssembly System Interface specification. WASI gives sandboxed WebAssembly applications access to the underlying operating system via a collection of POSIX-like functions.
import { readFile } from 'node:fs/promises'; import { WASI } from 'wasi'; import { argv, env } from 'node:process'; const wasi = new WASI({ args: argv, env, preopens: { '/sandbox': '/some/real/path/that/wasm/can/access', }, }); // Some WASI binaries require: // const importObject = { wasi_unstable: wasi.wasiImport }; const importObject = { wasi_snapshot_preview1: wasi.wasiImport }; const wasm = await WebAssembly.compile( await readFile(new URL('./demo.wasm', import.meta.url)), ); const instance = await WebAssembly.instantiate(wasm, importObject); wasi.start(instance);'use strict'; const { readFile } = require('node:fs/promises'); const { WASI } = require('wasi'); const { argv, env } = require('node:process'); const { join } = require('node:path'); const wasi = new WASI({ args: argv, env, preopens: { '/sandbox': '/some/real/path/that/wasm/can/access', }, }); // Some WASI binaries require: // const importObject = { wasi_unstable: wasi.wasiImport }; const importObject = { wasi_snapshot_preview1: wasi.wasiImport }; (async () => { const wasm = await WebAssembly.compile( await readFile(join(__dirname, 'demo.wasm')), ); const instance = await WebAssembly.instantiate(wasm, importObject); 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