Node.js v25.0.0 文件
- Node.js v25.0.0
- 目錄
-
索引
- 斷言測試
- 非同步上下文跟蹤
- 非同步鉤子
- 緩衝區
- C++ 外掛
- 使用 Node-API 的 C/C++ 外掛
- C++ 嵌入器 API
- 子程序
- 叢集
- 命令列選項
- 控制檯
- 加密
- 偵錯程式
- 已棄用的 API
- 診斷通道
- DNS
- 域
- 環境變數
- 錯誤
- 事件
- 檔案系統
- 全域性物件
- HTTP
- HTTP/2
- HTTPS
- 檢查器
- 國際化
- 模組:CommonJS 模組
- 模組:ECMAScript 模組
- 模組:
node:moduleAPI - 模組:包
- 模組:TypeScript
- 網路
- 作業系統
- 路徑
- 效能鉤子
- 許可權
- 程序
- Punycode
- 查詢字串
- 逐行讀取
- REPL
- 報告
- 單一可執行檔案應用
- SQLite
- 流
- 字串解碼器
- 測試執行器
- 定時器
- TLS/SSL
- 跟蹤事件
- TTY
- UDP/資料報
- URL
- 實用工具
- V8
- 虛擬機器
- WASI
- Web Crypto API
- Web Streams API
- 工作執行緒
- Zlib
- 其他版本
- 選項
WebAssembly 系統介面 (WASI)#
node:wasi 模組目前不提供某些 WASI 執行時所提供的全面檔案系統安全屬性。未來可能會也可能不會實現對安全檔案系統沙箱的完全支援。在此期間,請勿依賴它來執行不受信任的程式碼。
原始碼: lib/wasi.js
WASI API 提供了 WebAssembly 系統介面規範的實現。WASI 透過一組類 POSIX 函式,讓 WebAssembly 應用程式能夠訪問底層作業系統。
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 文字格式檔案。
(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 提供了一個基於能力(capabilities-based)的模型,透過該模型為應用程式提供其自定義的 env、preopens、stdin、stdout、stderr 和 exit 能力。
Node.js 當前的威脅模型不像某些 WASI 執行時那樣提供安全的沙箱環境。
雖然支援這些能力特性,但它們在 Node.js 中並不構成一個安全模型。例如,檔案系統沙箱可以透過各種技術被繞過。該專案正在探索未來是否可以新增這些安全保證。
類: WASI#
WASI 類提供了 WASI 系統呼叫 API 以及用於處理基於 WASI 的應用程式的附加便利方法。每個 WASI 例項代表一個獨立的環境。
new WASI([options])#
options<Object>args<Array> 一個字串陣列,WebAssembly 應用程式會將其視為命令列引數。第一個引數是 WASI 命令本身的虛擬路徑。預設值:[]。env<Object> 一個類似於process.env的物件,WebAssembly 應用程式會將其視為其環境。預設值:{}。preopens<Object> 此物件表示 WebAssembly 應用程式的本地目錄結構。preopens的字串鍵被視為檔案系統內的目錄。preopens中相應的值是這些目錄在主機上的真實路徑。returnOnExit<boolean> 預設情況下,當 WASI 應用程式呼叫__wasi_proc_exit()時,wasi.start()會返回指定的退出碼,而不是終止程序。將此選項設定為false將導致 Node.js 程序以指定的退出碼退出。預設值:true。stdin<integer> 在 WebAssembly 應用程式中用作標準輸入的檔案描述符。預設值:0。stdout<integer> 在 WebAssembly 應用程式中用作標準輸出的檔案描述符。預設值:1。stderr<integer> 在 WebAssembly 應用程式中用作標準錯誤的檔案描述符。預設值:2。version<string> 請求的 WASI 版本。目前唯一支援的版本是unstable和preview1。此選項是必需的。
wasi.getImportObject()#
返回一個匯入物件,如果除了 WASI 提供的匯入之外不需要其他 WASM 匯入,則可以將其傳遞給 WebAssembly.instantiate()。
如果版本 unstable 被傳入建構函式,它將返回
{ wasi_unstable: wasi.wasiImport }
如果版本 preview1 被傳入建構函式,或者沒有指定版本,它將返回
{ wasi_snapshot_preview1: wasi.wasiImport }
wasi.start(instance)#
instance<WebAssembly.Instance>
嘗試透過呼叫 instance 的 _start() 匯出來開始執行該例項作為 WASI 命令。如果 instance 不包含 _start() 匯出,或者如果 instance 包含 _initialize() 匯出,則會丟擲異常。
start() 要求 instance 匯出一個名為 memory 的 WebAssembly.Memory。如果 instance 沒有 memory 匯出,則會丟擲異常。
如果 start() 被呼叫多次,則會丟擲異常。
wasi.initialize(instance)#
instance<WebAssembly.Instance>
嘗試透過呼叫 instance 的 _initialize() 匯出來將其初始化為 WASI 反應器(reactor),如果該匯出存在的話。如果 instance 包含 _start() 匯出,則會丟擲異常。
initialize() 要求 instance 匯出一個名為 memory 的 WebAssembly.Memory。如果 instance 沒有 memory 匯出,則會丟擲異常。
如果 initialize() 被呼叫多次,則會丟擲異常。
wasi.finalizeBindings(instance[, options])#
instance<WebAssembly.Instance>options<Object>memory<WebAssembly.Memory> 預設值:instance.exports.memory。
在不呼叫 initialize() 或 start() 的情況下,為 instance 設定 WASI 主機繫結。當 WASI 模組在子執行緒中例項化以線上程間共享記憶體時,此方法非常有用。
finalizeBindings() 要求 instance 匯出一個名為 memory 的 WebAssembly.Memory,或者使用者在 options.memory 中指定一個 WebAssembly.Memory 物件。如果 memory 無效,則會丟擲異常。
start() 和 initialize() 會在內部呼叫 finalizeBindings()。如果 finalizeBindings() 被呼叫多次,則會丟擲異常。
wasi.wasiImport#
- 型別:<Object>
wasiImport 是一個實現 WASI 系統呼叫 API 的物件。在例項化 WebAssembly.Instance 期間,應將此物件作為 wasi_snapshot_preview1 匯入來傳遞。