WebAssembly System Interface (WASI) | Node.js v12.22.12 Documentation (original) (raw)

WebAssembly System Interface (WASI)#

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.

'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);
})();

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 and --experimental-wasm-bigintCLI arguments are needed for this example to run.

Class: WASI#

Added in: 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: v12.16.0

wasi.start(instance)#

Added in: 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: 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: 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.