Интерфейс системы WebAssembly (WASI)
Исходный код: lib/wasi.js
API WASI предоставляет реализацию спецификации интерфейса системы WebAssembly. WASI предоставляет защищенным приложениям WebAssembly доступ к ОС через набор функций, похожих на POSIX.
'use strict';
const fs = require('fs');
const { WASI } = require('wasi');
const wasi = new WASI({
args: process.argv,
env: process.env,
preopens: {
'/sandbox': '/some/real/path/that/wasm/can/access'
}
});
const importObject = { wasi_snapshot_preview1: wasi.wasiImport };
(async () => {
const wasm = await WebAssembly.compile(fs.readFileSync('./demo.wasm'));
const instance = await WebAssembly.instantiate(wasm, importObject);
wasi.start(instance);
})(); Чтобы запустить приведенный выше пример, создайте новый файл формата текста WebAssembly с именем 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
$ wat2wasm demo.wat
Для выполнения этого примера необходимы аргументы командной строки --experimental-wasi-unstable-preview1 и --experimental-wasm-bigint.
Класс: WASI
Класс WASI предоставляет API системных вызовов WASI и дополнительные удобные методы для работы с приложениями на основе WASI. Каждый экземпляр WASI представляет отдельную защищенную среду. В целях безопасности каждый экземпляр WASI должен иметь явно настроенные аргументы командной строки, переменные среды и структуру каталогов виртуальной среды.
new WASI([options])
-
options<Объект>-
args<Массив> Массив строк, которые приложение WebAssembly увидит как аргументы командной строки. Первый аргумент — виртуальный путь к команде WASI. По умолчанию:[]. -
env<Объект> Объект, аналогичныйprocess.env, который приложение WebAssembly увидит как свою среду. По умолчанию:{}. -
preopens<Объект> Этот объект представляет структуру каталогов виртуальной среды приложения WebAssembly. Строковые ключиpreopensобрабатываются как каталоги в виртуальной среде. Соответствующие значения вpreopens— это реальные пути к этим каталогам на хост-машине. -
returnOnExit<логическое значение> По умолчанию приложения WASI завершают процесс Node.js с помощью функции__wasi_proc_exit(). Установка этого параметра вtrueзаставляетwasi.start()возвращать код завершения вместо завершения процесса. По умолчанию:false. -
stdin<целое число> Дескриптор файла, используемый в качестве стандартного ввода в приложении WebAssembly. По умолчанию:0. -
stdout<целое число> Дескриптор файла, используемый в качестве стандартного вывода в приложении WebAssembly. По умолчанию:1. -
stderr<целое число> Дескриптор файла, используемый в качестве стандартной ошибки в приложении WebAssembly. По умолчанию:2.
-
wasi.start(instance)
-
instance<WebAssembly.Instance>
Попытка начать выполнение instance как команды WASI, вызвав ее экспорт _start(). Если instance не содержит экспорт _start(), или если instance содержит экспорт _initialize(), происходит исключение.
Для start() необходимо, чтобы instance экспортировал WebAssembly.Memory с именем memory. Если instance не имеет экспорта memory, происходит исключение.
Если start() вызывается более одного раза, происходит исключение.
wasi.initialize(instance)
-
instance<WebAssembly.Instance>
Попытка инициализации instance как реактора WASI путем вызова его экспорта _initialize(), если он присутствует. Если instance содержит экспорт _start(), происходит исключение.
Для initialize() необходимо, чтобы instance экспортировал WebAssembly.Memory с именем memory. Если instance не имеет экспорта memory, происходит исключение.
Если initialize() вызывается более одного раза, происходит исключение.
wasi.wasiImport
wasiImport — это объект, реализующий API системных вызовов WASI. Этот объект должен быть передан как импорт wasi_snapshot_preview1 при создании WebAssembly.Instance.
© Joyent, Inc. and other Node contributors
Licensed under the MIT License.
Node.js is a trademark of Joyent, Inc. and is used with its permission.
We are not endorsed by or affiliated with Joyent.
https://nodejs.org/dist/latest-v12.x/docs/api/wasi.html