WebAssembly System Interface (WASI) | Node.js v17.9.1 Documentation (original) (raw)

Source Code: lib/wasi.js

The WASI API provides an implementation of the WebAssembly System Interfacespecification. WASI gives sandboxed WebAssembly applications access to the underlying operating system via a collection of POSIX-like functions.

`import { readFile } from 'fs/promises'; import { WASI } from 'wasi'; import { argv, env } from '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('fs/promises'); const { WASI } = require('wasi'); const { argv, env } = require('process'); const { join } = require('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); })();`

To run the above example, create a new WebAssembly text format file nameddemo.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
    )
)

Use wabt to compile .wat to .wasm

$ wat2wasm demo.wat

The --experimental-wasi-unstable-preview1 CLI argument is needed for this example to run.

Class: WASI#

Added in: v13.3.0, v12.16.0

The WASI class provides the WASI system call API and additional convenience methods for working with WASI-based applications. Each WASI instance represents a distinct sandbox environment. For security purposes, each WASIinstance must have its command-line arguments, environment variables, and sandbox directory structure configured explicitly.

new WASI([options])#

Added in: v13.3.0, v12.16.0

wasi.start(instance)#

Added in: v13.3.0, v12.16.0

Attempt to begin execution of instance as a WASI command by invoking its_start() export. If instance does not contain a _start() export, or ifinstance contains an _initialize() export, then an exception is thrown.

start() requires that instance exports a WebAssembly.Memory namedmemory. If instance does not have a memory export an exception is thrown.

If start() is called more than once, an exception is thrown.

wasi.initialize(instance)#

Added in: v14.6.0, v12.19.0

Attempt to initialize instance as a WASI reactor by invoking its_initialize() export, if it is present. If instance contains a _start()export, then an exception is thrown.

initialize() requires that instance exports a WebAssembly.Memory namedmemory. If instance does not have a memory export an exception is thrown.

If initialize() is called more than once, an exception is thrown.

wasi.wasiImport#

Added in: v13.3.0, v12.16.0

wasiImport is an object that implements the WASI system call API. This object should be passed as the wasi_snapshot_preview1 import during the instantiation of a WebAssembly.Instance.