- 断言测试
- 异步上下文跟踪
- 异步钩子
- 缓冲(Buffer)
- C++ 插件
- 使用 Node-API 的 C/C++ 插件
- C++ 嵌入 Node环境
- 子进程(Child processes)
- 集群(Cluster)
- 命令行选项
- 控制台(Console)
- 核心包(Corepack)
- 加密(Crypto)
- 调试器(Debugger)
- 已弃用的 API
- 诊断通道(Diagnostics Channel)
- 域名系统(DNS)
- 域(Domain)
- 错误(Errors)
- 事件(Events)
- 文件系统(File system)
- 全局变量(Globals)
- HTTP
- HTTP/2
- HTTPS
- 检查器(Inspector)
- 国际化
- 模块:CommonJS 模块
- 模块:ECMAScript 模块
- 模块:
node:module
API - 模块:packages 模块
- 网络(Net)
- 系统(OS)
- 路径(Path)
- 性能挂钩(Performance hooks)
- 性能挂钩(Permissions)
- 进程(Process)
- Punycode 国际化域名编码
- 查询字符串(Query strings)
- 命令行库(Readline)
- REPL 交互式编程环境
- 诊断报告
- 单个可执行应用程序
- Stream 流
- 字符串解码器
- 单元测试
- 定时器(Timers)
- 传输层安全/SSL
- 跟踪事件
- TTY
- UDP/数据报
- URL
- 实用程序
- V8
- 虚拟机
- WebAssembly
- Web加密 API(Web Crypto API)
- 网络流 API(Web Streams API)
- 工作线程(Worker threads)
- zlib
Node.js v18.18.2 文档
- Node.js v18.18.2
- ► 目录
-
►
索引
- 断言测试
- 异步上下文跟踪
- 异步钩子
- 缓冲(Buffer)
- C++ 插件
- 使用 Node-API 的 C/C++ 插件
- C++ 嵌入 Node环境
- 子进程(Child processes)
- 集群(Cluster)
- 命令行选项
- 控制台(Console)
- 核心包(Corepack)
- 加密(Crypto)
- 调试器(Debugger)
- 已弃用的 API
- 诊断通道(Diagnostics Channel)
- 域名系统(DNS)
- 域(Domain)
- 错误(Errors)
- 事件(Events)
- 文件系统(File system)
- 全局变量(Globals)
- HTTP
- HTTP/2
- HTTPS
- 检查器(Inspector)
- 国际化
- 模块:CommonJS 模块
- 模块:ECMAScript 模块
- 模块:
node:module
API - 模块:packages 模块
- 网络(Net)
- 系统(OS)
- 路径(Path)
- 性能挂钩(Performance hooks)
- 性能挂钩(Permissions)
- 进程(Process)
- Punycode 国际化域名编码
- 查询字符串(Query strings)
- 命令行库(Readline)
- REPL 交互式编程环境
- 诊断报告
- 单个可执行应用程序
- Stream 流
- 字符串解码器
- 单元测试
- 定时器(Timers)
- 传输层安全/SSL
- 跟踪事件
- TTY
- UDP/数据报
- URL
- 实用程序
- V8
- 虚拟机
- WebAssembly
- Web加密 API(Web Crypto API)
- 网络流 API(Web Streams API)
- 工作线程(Worker threads)
- zlib
- ► 其他版本
- ► 选项
目录
WebAssembly 系统接口 (WASI)#
源代码: lib/wasi.js
WASI API 提供了WebAssembly 系统接口规范的实现 。WASI 通过一系列类似 POSIX 的函数使沙盒 WebAssembly 应用程序能够访问底层操作系统。
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 文本格式文件:
(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
$ wat2wasm demo.wat
类:WASI
#
WASI
类提供 WASI 系统调用 API 以及用于使用基于 WASI 的应用程序的其他便捷方法。每个WASI
实例代表一个不同的沙箱环境。出于安全目的,每个WASI
实例必须显式配置其命令行参数、环境变量和沙箱目录结构。
new WASI([options])
#
options
<对象>args
<Array> WebAssembly 应用程序将其视为命令行参数的字符串数组。第一个参数是 WASI 命令本身的虚拟路径。默认值:[]
。env
<Object>类似于process.env
的对象,WebAssembly 应用程序将其视为其环境。默认值:{}
。preopens
<Object>该对象表示 WebAssembly 应用程序的沙箱目录结构。preopens
的字符串键被视为沙箱内的目录。preopens
中的相应值是主机上这些目录的真实路径。returnOnExit
<boolean>默认情况下,WASI 应用程序通过__wasi_proc_exit()
函数终止 Node.js 进程。将此选项设置为true
会导致wasi.start()
返回退出代码而不是终止进程。默认值:false
。stdin
<integer>在 WebAssembly 应用程序中用作标准输入的文件描述符。默认值:0
。stdout
<integer>在 WebAssembly 应用程序中用作标准输出的文件描述符。默认值:1
。stderr
<integer>在 WebAssembly 应用程序中用作标准错误的文件描述符。默认值:2
。
wasi.start(instance)
#
instance
<WebAssembly.Instance>
尝试通过调用_start()
导出来开始将instance
作为 WASI 命令
执行。如果instance
不包含_start()
导出,或者如果
instance
包含_initialize()
导出,则会引发异常。
start()
要求instance
导出名为
memory
的WebAssembly.Memory
。如果instance
没有memory
导出,则会引发异常。
如果多次调用start()
,则会引发异常。
wasi.initialize(instance)
#
instance
<WebAssembly.Instance>
尝试通过调用其_initialize()
导出(如果存在)将instance
初始化为 WASI 反应器
。如果instance
包含_start()
导出,则会引发异常。
initialize()
要求instance
导出名为
memory
的WebAssembly.Memory
。如果instance
没有memory
导出,则会引发异常。
如果多次调用initialize()
,则会引发异常。
wasi.wasiImport
#
wasiImport
是一个实现 WASI 系统调用 API 的对象。该对象应在WebAssembly.Instance
实例化期间作为wasi_snapshot_preview1
导入传递。