Node.js v21.7.2 文件
- Node.js v21.7.2
- ► 目錄
-
► 索引
- 斷言測試
- 非同步內容追蹤
- 非同步掛鉤
- 緩衝區
- C++ 外掛程式
- 使用 Node-API 的 C/C++ 外掛程式
- C++ 嵌入式 API
- 子程序
- 叢集
- 命令列選項
- 主控台
- Corepack
- 加密
- 偵錯器
- 已棄用的 API
- 診斷頻道
- DNS
- 網域
- 錯誤
- 事件
- 檔案系統
- 全域變數
- HTTP
- HTTP/2
- HTTPS
- 檢查器
- 國際化
- 模組:CommonJS 模組
- 模組:ECMAScript 模組
- 模組:
node:module
API - 模組:套件
- 網路
- 作業系統
- 路徑
- 效能掛鉤
- 權限
- 程序
- Punycode
- 查詢字串
- 讀取命令列
- REPL
- 報告
- 單一可執行應用程式
- 串流
- 字串解碼器
- 測試執行器
- 計時器
- TLS/SSL
- 追蹤事件
- TTY
- UDP/資料報
- URL
- 工具程式
- V8
- VM
- 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 '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('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 提供一個基於功能的模型,透過此模型,應用程式會提供其自訂的 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>
嘗試透過呼叫其 _start()
輸出,開始執行 instance
作為 WASI 命令。如果 instance
不包含 _start()
輸出,或如果 instance
包含 _initialize()
輸出,則會擲回例外狀況。
start()
要求 instance
匯出名為 memory
的 WebAssembly.Memory
。如果 instance
沒有 memory
匯出,則會擲回例外。
如果 start()
被呼叫超過一次,則會擲回例外。
wasi.initialize(instance)
#
instance
<WebAssembly.Instance>
嘗試初始化 instance
作為 WASI 反應器,方法是呼叫其 _initialize()
匯出(如果存在)。如果 instance
包含 _start()
匯出,則會擲回例外。
initialize()
要求 instance
匯出名為 memory
的 WebAssembly.Memory
。如果 instance
沒有 memory
匯出,則會擲回例外。
如果 initialize()
被呼叫超過一次,則會擲回例外。
wasi.wasiImport
#
wasiImport
是實作 WASI 系統呼叫 API 的物件。這個物件應該在 WebAssembly.Instance
的實例化期間傳遞為 wasi_snapshot_preview1
匯入。