NURLNURL registrynurl-lang.org →

← wasmtime

wasmtime 0.3.0 API

interp.nu

packages/wasmtime/src/interp.nu — a small WebAssembly interpreter (pure NURL).

Executes wasm: i32/i64/f32/f64 const, locals, globals, the integer and float arithmetic/comparison/bitwise ops, all int↔float conversions, structured control flow (block / loop / if / else / br / br_if / return), drop / select, direct and indirect calls, and linear memory load/store. Each value occupies one 64-bit cell; i32 wraps + sign-extends to 32 bits, and floats are held as their IEEE-754 bit pattern (reinterpreted via std/floatbits for arithmetic). Imports (the WASI surface) are the remaining milestone — so this runs self-contained compute modules today.

Control flow uses an explicit control stack. Entering a block/if computes its matching end by a one-pass immediate-skipping scan; br to a loop re-enters at the loop start, to a block jumps past its end.

API

& m @ rint f x → f

round-to-nearest-even (wasm f*.nearest) — libm rint honours the default mode.

: Arg { ( Vec u ) bytes }

: Ctrl { i is_loop i start_pc i end_pc i height i arity }

: WFd { i kind ( Vec u ) data i pos ( Vec u ) host ( Vec u ) name b writable b dirty }

A WASI file descriptor. kind: 0 closed, 1 stdio, 2 preopened dir, 3 file. For a file, data holds the contents (read) or the bytes written so far, pos the read/write offset, host the on-disk path (for open/flush), and name (a dir) the guest-visible preopen name reported by fd_prestat_*.

: Interp

: Interp {
    s mod  // *Module
    ( Vec i ) vs  // value stack
    ( Vec u ) mem  // linear memory (bytes)
    i mem_pages  // current size in 64 KiB pages
    ( Vec i ) globals  // mutable global values
    ( Vec s ) argv  // *( Vec u ) — WASI program arguments (argv[0] = program)
    ( Vec s ) fds  // *WFd — file-descriptor table (0/1/2 stdio, 3 preopen, …)
    b exited  // set after proc_exit
    i exit_code
    b trap
    ( Vec u ) trapmsg
}

@ interp_new * Module m → *Interp

@ interp_free * Interp it → v

@ interp_push_arg * Interp it s str → v

Append a program argument (copied from a NUL-terminated host string).

@ interp_set_preopen * Interp it s host_path s guest_name → v

Grant the module one preopened host directory, visible to it as guest_name (the path it resolves opens against). Installed as fd 3.

@ exec_func * Interp it i fidx → v


module.nu

packages/wasmtime/src/module.nu — WebAssembly binary decoder (pure NURL).

Decodes a wasm32 module's structure: the magic/version header and the sections this runtime understands (type, function, table, memory, global, export, element, code, data). Imports and the custom/start sections are skipped. The byte cursor + LEB128 readers here are reused by the interpreter (interp.nu) to walk instruction streams.

API

: Wc { ( Vec u ) buf i pos i len }

@ wc_new ( Vec u ) buf → *Wc

@ wc_free * Wc c → v

Wc does not own buf (the module bytes outlive it); free only the struct.

@ wc_eof * Wc c → b

@ wc_u8 * Wc c → i

@ wc_peek * Wc c → i

@ wc_uleb * Wc c → i

Unsigned LEB128 → i (NURL i is 64-bit, covers u32/u64).

@ wc_sleb * Wc c → i

Signed LEB128 → i (sign-extended).

@ wc_skip * Wc c i n → v

Skip n bytes.

: FuncType { ( Vec i ) params ( Vec i ) results }

: WFunc { i typeidx ( Vec i ) locals i code_start i code_end }

A defined function: its type index, its declared (non-param) local valtypes expanded flat, and the [start,end) byte range of its instruction stream.

: WExport { ( Vec u ) name i kind i index }

: DataSeg { i offset ( Vec u ) bytes }

An active data segment: raw bytes to copy into linear memory at offset.

: WImport { ( Vec u ) field i typeidx }

An imported function (the only import kind this runtime resolves): its field name selects the host (WASI) implementation; typeidx gives its signature.

: Module

: Module {
    ( Vec s ) types  // *FuncType
    ( Vec i ) functypes  // type index per defined function
    ( Vec s ) funcs  // *WFunc
    ( Vec s ) exports  // *WExport
    ( Vec u ) code  // the whole module byte image (functions index into it)
    i has_mem
    i mem_min  // initial pages (64 KiB each)
    i mem_max  // 0 if unbounded
    ( Vec s ) datas  // *DataSeg
    ( Vec i ) global_init  // initial value per global
    ( Vec i ) global_mut  // 1 if mutable
    i has_table
    ( Vec i ) table  // function indices (−1 = empty slot)
    ( Vec s ) imports  // *WImport (imported functions, in index order)
    i num_import_funcs  // imported funcs occupy func indices 0..n-1
    b ok
    ( Vec u ) err
}

@ module_free * Module m → v

@ module_decode ( Vec u ) bytes → *Module

Decode a whole module. On error, .ok is F and .err carries a message.

@ module_export_func * Module m s name → i

Find an exported function index by name (-1 if absent).


main.nu

packages/wasmtime/src/main.nu — wasmtime: a WebAssembly runtime in pure NURL.

wasmtime run --invoke <export> <module.wasm> [int args…]

Loads a wasm module, invokes an exported function with integer arguments, and prints the integer result. This is the foundation — the integer interpreter core (module.nu + interp.nu). Linear memory, floats, and the WASI surface (incl. --dir) build on top in later milestones.

API

@ usage → v

@ run_invoke s export s path i first_arg i argc → i

@ run_command s path i prog_start i argc s dir → i

WASI command: run the module's _start with argv = [module, prog args…].

@ main → i