11cb0ef41Sopenharmony_ci# WebAssembly System Interface (WASI) 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ci<!--introduced_in=v12.16.0--> 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci> Stability: 1 - Experimental 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ci<!-- source_link=lib/wasi.js --> 81cb0ef41Sopenharmony_ci 91cb0ef41Sopenharmony_ciThe WASI API provides an implementation of the [WebAssembly System Interface][] 101cb0ef41Sopenharmony_cispecification. WASI gives sandboxed WebAssembly applications access to the 111cb0ef41Sopenharmony_ciunderlying operating system via a collection of POSIX-like functions. 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_ci```mjs 141cb0ef41Sopenharmony_ciimport { readFile } from 'node:fs/promises'; 151cb0ef41Sopenharmony_ciimport { WASI } from 'wasi'; 161cb0ef41Sopenharmony_ciimport { argv, env } from 'node:process'; 171cb0ef41Sopenharmony_ci 181cb0ef41Sopenharmony_ciconst wasi = new WASI({ 191cb0ef41Sopenharmony_ci args: argv, 201cb0ef41Sopenharmony_ci env, 211cb0ef41Sopenharmony_ci preopens: { 221cb0ef41Sopenharmony_ci '/sandbox': '/some/real/path/that/wasm/can/access', 231cb0ef41Sopenharmony_ci }, 241cb0ef41Sopenharmony_ci}); 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_ci// Some WASI binaries require: 271cb0ef41Sopenharmony_ci// const importObject = { wasi_unstable: wasi.wasiImport }; 281cb0ef41Sopenharmony_ciconst importObject = { wasi_snapshot_preview1: wasi.wasiImport }; 291cb0ef41Sopenharmony_ci 301cb0ef41Sopenharmony_ciconst wasm = await WebAssembly.compile( 311cb0ef41Sopenharmony_ci await readFile(new URL('./demo.wasm', import.meta.url)), 321cb0ef41Sopenharmony_ci); 331cb0ef41Sopenharmony_ciconst instance = await WebAssembly.instantiate(wasm, importObject); 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_ciwasi.start(instance); 361cb0ef41Sopenharmony_ci``` 371cb0ef41Sopenharmony_ci 381cb0ef41Sopenharmony_ci```cjs 391cb0ef41Sopenharmony_ci'use strict'; 401cb0ef41Sopenharmony_ciconst { readFile } = require('node:fs/promises'); 411cb0ef41Sopenharmony_ciconst { WASI } = require('wasi'); 421cb0ef41Sopenharmony_ciconst { argv, env } = require('node:process'); 431cb0ef41Sopenharmony_ciconst { join } = require('node:path'); 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_ciconst wasi = new WASI({ 461cb0ef41Sopenharmony_ci args: argv, 471cb0ef41Sopenharmony_ci env, 481cb0ef41Sopenharmony_ci preopens: { 491cb0ef41Sopenharmony_ci '/sandbox': '/some/real/path/that/wasm/can/access', 501cb0ef41Sopenharmony_ci }, 511cb0ef41Sopenharmony_ci}); 521cb0ef41Sopenharmony_ci 531cb0ef41Sopenharmony_ci// Some WASI binaries require: 541cb0ef41Sopenharmony_ci// const importObject = { wasi_unstable: wasi.wasiImport }; 551cb0ef41Sopenharmony_ciconst importObject = { wasi_snapshot_preview1: wasi.wasiImport }; 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_ci(async () => { 581cb0ef41Sopenharmony_ci const wasm = await WebAssembly.compile( 591cb0ef41Sopenharmony_ci await readFile(join(__dirname, 'demo.wasm')), 601cb0ef41Sopenharmony_ci ); 611cb0ef41Sopenharmony_ci const instance = await WebAssembly.instantiate(wasm, importObject); 621cb0ef41Sopenharmony_ci 631cb0ef41Sopenharmony_ci wasi.start(instance); 641cb0ef41Sopenharmony_ci})(); 651cb0ef41Sopenharmony_ci``` 661cb0ef41Sopenharmony_ci 671cb0ef41Sopenharmony_ciTo run the above example, create a new WebAssembly text format file named 681cb0ef41Sopenharmony_ci`demo.wat`: 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_ci```text 711cb0ef41Sopenharmony_ci(module 721cb0ef41Sopenharmony_ci ;; Import the required fd_write WASI function which will write the given io vectors to stdout 731cb0ef41Sopenharmony_ci ;; The function signature for fd_write is: 741cb0ef41Sopenharmony_ci ;; (File Descriptor, *iovs, iovs_len, nwritten) -> Returns number of bytes written 751cb0ef41Sopenharmony_ci (import "wasi_snapshot_preview1" "fd_write" (func $fd_write (param i32 i32 i32 i32) (result i32))) 761cb0ef41Sopenharmony_ci 771cb0ef41Sopenharmony_ci (memory 1) 781cb0ef41Sopenharmony_ci (export "memory" (memory 0)) 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_ci ;; Write 'hello world\n' to memory at an offset of 8 bytes 811cb0ef41Sopenharmony_ci ;; Note the trailing newline which is required for the text to appear 821cb0ef41Sopenharmony_ci (data (i32.const 8) "hello world\n") 831cb0ef41Sopenharmony_ci 841cb0ef41Sopenharmony_ci (func $main (export "_start") 851cb0ef41Sopenharmony_ci ;; Creating a new io vector within linear memory 861cb0ef41Sopenharmony_ci (i32.store (i32.const 0) (i32.const 8)) ;; iov.iov_base - This is a pointer to the start of the 'hello world\n' string 871cb0ef41Sopenharmony_ci (i32.store (i32.const 4) (i32.const 12)) ;; iov.iov_len - The length of the 'hello world\n' string 881cb0ef41Sopenharmony_ci 891cb0ef41Sopenharmony_ci (call $fd_write 901cb0ef41Sopenharmony_ci (i32.const 1) ;; file_descriptor - 1 for stdout 911cb0ef41Sopenharmony_ci (i32.const 0) ;; *iovs - The pointer to the iov array, which is stored at memory location 0 921cb0ef41Sopenharmony_ci (i32.const 1) ;; iovs_len - We're printing 1 string stored in an iov - so one. 931cb0ef41Sopenharmony_ci (i32.const 20) ;; nwritten - A place in memory to store the number of bytes written 941cb0ef41Sopenharmony_ci ) 951cb0ef41Sopenharmony_ci drop ;; Discard the number of bytes written from the top of the stack 961cb0ef41Sopenharmony_ci ) 971cb0ef41Sopenharmony_ci) 981cb0ef41Sopenharmony_ci``` 991cb0ef41Sopenharmony_ci 1001cb0ef41Sopenharmony_ciUse [wabt](https://github.com/WebAssembly/wabt) to compile `.wat` to `.wasm` 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_ci```console 1031cb0ef41Sopenharmony_ci$ wat2wasm demo.wat 1041cb0ef41Sopenharmony_ci``` 1051cb0ef41Sopenharmony_ci 1061cb0ef41Sopenharmony_ci## Class: `WASI` 1071cb0ef41Sopenharmony_ci 1081cb0ef41Sopenharmony_ci<!-- YAML 1091cb0ef41Sopenharmony_ciadded: 1101cb0ef41Sopenharmony_ci - v13.3.0 1111cb0ef41Sopenharmony_ci - v12.16.0 1121cb0ef41Sopenharmony_ci--> 1131cb0ef41Sopenharmony_ci 1141cb0ef41Sopenharmony_ciThe `WASI` class provides the WASI system call API and additional convenience 1151cb0ef41Sopenharmony_cimethods for working with WASI-based applications. Each `WASI` instance 1161cb0ef41Sopenharmony_cirepresents a distinct sandbox environment. For security purposes, each `WASI` 1171cb0ef41Sopenharmony_ciinstance must have its command-line arguments, environment variables, and 1181cb0ef41Sopenharmony_cisandbox directory structure configured explicitly. 1191cb0ef41Sopenharmony_ci 1201cb0ef41Sopenharmony_ci### `new WASI([options])` 1211cb0ef41Sopenharmony_ci 1221cb0ef41Sopenharmony_ci<!-- YAML 1231cb0ef41Sopenharmony_ciadded: 1241cb0ef41Sopenharmony_ci - v13.3.0 1251cb0ef41Sopenharmony_ci - v12.16.0 1261cb0ef41Sopenharmony_ci--> 1271cb0ef41Sopenharmony_ci 1281cb0ef41Sopenharmony_ci* `options` {Object} 1291cb0ef41Sopenharmony_ci * `args` {Array} An array of strings that the WebAssembly application will 1301cb0ef41Sopenharmony_ci see as command-line arguments. The first argument is the virtual path to the 1311cb0ef41Sopenharmony_ci WASI command itself. **Default:** `[]`. 1321cb0ef41Sopenharmony_ci * `env` {Object} An object similar to `process.env` that the WebAssembly 1331cb0ef41Sopenharmony_ci application will see as its environment. **Default:** `{}`. 1341cb0ef41Sopenharmony_ci * `preopens` {Object} This object represents the WebAssembly application's 1351cb0ef41Sopenharmony_ci sandbox directory structure. The string keys of `preopens` are treated as 1361cb0ef41Sopenharmony_ci directories within the sandbox. The corresponding values in `preopens` are 1371cb0ef41Sopenharmony_ci the real paths to those directories on the host machine. 1381cb0ef41Sopenharmony_ci * `returnOnExit` {boolean} By default, WASI applications terminate the Node.js 1391cb0ef41Sopenharmony_ci process via the `__wasi_proc_exit()` function. Setting this option to `true` 1401cb0ef41Sopenharmony_ci causes `wasi.start()` to return the exit code rather than terminate the 1411cb0ef41Sopenharmony_ci process. **Default:** `false`. 1421cb0ef41Sopenharmony_ci * `stdin` {integer} The file descriptor used as standard input in the 1431cb0ef41Sopenharmony_ci WebAssembly application. **Default:** `0`. 1441cb0ef41Sopenharmony_ci * `stdout` {integer} The file descriptor used as standard output in the 1451cb0ef41Sopenharmony_ci WebAssembly application. **Default:** `1`. 1461cb0ef41Sopenharmony_ci * `stderr` {integer} The file descriptor used as standard error in the 1471cb0ef41Sopenharmony_ci WebAssembly application. **Default:** `2`. 1481cb0ef41Sopenharmony_ci 1491cb0ef41Sopenharmony_ci### `wasi.start(instance)` 1501cb0ef41Sopenharmony_ci 1511cb0ef41Sopenharmony_ci<!-- YAML 1521cb0ef41Sopenharmony_ciadded: 1531cb0ef41Sopenharmony_ci - v13.3.0 1541cb0ef41Sopenharmony_ci - v12.16.0 1551cb0ef41Sopenharmony_ci--> 1561cb0ef41Sopenharmony_ci 1571cb0ef41Sopenharmony_ci* `instance` {WebAssembly.Instance} 1581cb0ef41Sopenharmony_ci 1591cb0ef41Sopenharmony_ciAttempt to begin execution of `instance` as a WASI command by invoking its 1601cb0ef41Sopenharmony_ci`_start()` export. If `instance` does not contain a `_start()` export, or if 1611cb0ef41Sopenharmony_ci`instance` contains an `_initialize()` export, then an exception is thrown. 1621cb0ef41Sopenharmony_ci 1631cb0ef41Sopenharmony_ci`start()` requires that `instance` exports a [`WebAssembly.Memory`][] named 1641cb0ef41Sopenharmony_ci`memory`. If `instance` does not have a `memory` export an exception is thrown. 1651cb0ef41Sopenharmony_ci 1661cb0ef41Sopenharmony_ciIf `start()` is called more than once, an exception is thrown. 1671cb0ef41Sopenharmony_ci 1681cb0ef41Sopenharmony_ci### `wasi.initialize(instance)` 1691cb0ef41Sopenharmony_ci 1701cb0ef41Sopenharmony_ci<!-- YAML 1711cb0ef41Sopenharmony_ciadded: 1721cb0ef41Sopenharmony_ci - v14.6.0 1731cb0ef41Sopenharmony_ci - v12.19.0 1741cb0ef41Sopenharmony_ci--> 1751cb0ef41Sopenharmony_ci 1761cb0ef41Sopenharmony_ci* `instance` {WebAssembly.Instance} 1771cb0ef41Sopenharmony_ci 1781cb0ef41Sopenharmony_ciAttempt to initialize `instance` as a WASI reactor by invoking its 1791cb0ef41Sopenharmony_ci`_initialize()` export, if it is present. If `instance` contains a `_start()` 1801cb0ef41Sopenharmony_ciexport, then an exception is thrown. 1811cb0ef41Sopenharmony_ci 1821cb0ef41Sopenharmony_ci`initialize()` requires that `instance` exports a [`WebAssembly.Memory`][] named 1831cb0ef41Sopenharmony_ci`memory`. If `instance` does not have a `memory` export an exception is thrown. 1841cb0ef41Sopenharmony_ci 1851cb0ef41Sopenharmony_ciIf `initialize()` is called more than once, an exception is thrown. 1861cb0ef41Sopenharmony_ci 1871cb0ef41Sopenharmony_ci### `wasi.wasiImport` 1881cb0ef41Sopenharmony_ci 1891cb0ef41Sopenharmony_ci<!-- YAML 1901cb0ef41Sopenharmony_ciadded: 1911cb0ef41Sopenharmony_ci - v13.3.0 1921cb0ef41Sopenharmony_ci - v12.16.0 1931cb0ef41Sopenharmony_ci--> 1941cb0ef41Sopenharmony_ci 1951cb0ef41Sopenharmony_ci* {Object} 1961cb0ef41Sopenharmony_ci 1971cb0ef41Sopenharmony_ci`wasiImport` is an object that implements the WASI system call API. This object 1981cb0ef41Sopenharmony_cishould be passed as the `wasi_snapshot_preview1` import during the instantiation 1991cb0ef41Sopenharmony_ciof a [`WebAssembly.Instance`][]. 2001cb0ef41Sopenharmony_ci 2011cb0ef41Sopenharmony_ci[WebAssembly System Interface]: https://wasi.dev/ 2021cb0ef41Sopenharmony_ci[`WebAssembly.Instance`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Instance 2031cb0ef41Sopenharmony_ci[`WebAssembly.Memory`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Memory 204