feat(wasm-host): W2 minimal WASI preview1 subset for scoot-wasm - #148
Merged
Conversation
Add a deliberately small, capability-safe WASI preview1 layer to the
standalone scoot-wasm host so a wasm32-wasi command module can read
stdin, write stdout/stderr, and exit. Run with:
scoot-wasm wasi <module.wasm> [args...]
The host instantiates the module, runs its start section and _start
export, pipes this process's stdin to fd 0, forwards the module's
stdout/stderr, and exits with the module's proc_exit status (a normal
_start return exits 0). This is the intended subprocess host for the
external compression plugins of #98.
Exposed WASI surface (everything else traps; capability-safe by
construction):
- args_sizes_get / args_get, environ_sizes_get / environ_get
- fd_read (fd 0), fd_write (fd 1/2), fd_close
- fd_seek (stdio -> ESPIPE), fd_fdstat_get (stdio character device)
- clock_time_get (realtime/monotonic), random_get (seeded/deterministic)
- proc_exit
No filesystem or network functions are implemented; environ is empty by
default (the host environment is never leaked); out-of-bounds guest
pointers return EFAULT instead of corrupting host memory; bad fds return
EBADF. The engine performs no real IO: the host supplies clock nanos and
a random seed, and splitmix64 generates random bytes deterministically.
The WASI layer is compiled only into the standalone scoot-wasm binary
(-Dwasm-host=true); the zero-dependency core never links it.
Adds 11 hand-built wasm fixtures covering echo, args/env round-trip,
proc_exit codes, fd_write nwritten, random_get determinism, bad-fd
errno, OOB pointer -> EFAULT, and unknown-import traps. Updates
docs/WASM_TOOLS.md(.zh) and both changelogs.
Refs #100
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This was referenced Jun 26, 2026
Merged
jamiesun
added a commit
that referenced
this pull request
Jun 27, 2026
- wasm host W0-W4: integer, WASI preview1, type validation, float execution (#145, #147, #148, #149, #162) - feat: wasm_tool action for compute-only packages (#154) - wasm: narrow plugin sandbox to stdin/stdout/stderr/argv as a new hard rule (#164) - feat: committed playground test environment with full action coverage (#161) - release: single ReleaseSafe flavor, ship scoot-wasm artifacts, Homebrew tap (#166) - fix(release): reference SCOOT_DOCKERHUB_* secrets so Docker Hub login is attempted - docs: README rewrite + infographic, English comment translation (#160, #165, #146, #153) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Implements W2 of the
scoot-wasmplan (#100): a deliberately small,capability-safe WASI preview1 subset so a
wasm32-wasicommand module canread stdin, write stdout/stderr, and exit. Run with:
The host instantiates the module, runs its start section and
_startexport,pipes this process's stdin to fd 0, forwards the module's stdout/stderr, and
exits with the module's
proc_exitstatus (a normal_startreturn exits 0).This is the intended subprocess host for the external compression plugins of #98
(
host = "scoot-wasm wasi <component>", JSON-in/JSON-out over stdio).W0 (#145) and W1 (#147) are merged; this is the next independent phase PR.
Exposed WASI surface
Everything else traps — capability-safe by construction:
args_sizes_get/args_get,environ_sizes_get/environ_getfd_read(fd 0),fd_write(fd 1/2),fd_closefd_seek(stdio ->ESPIPE),fd_fdstat_get(stdio character device)clock_time_get(realtime/monotonic),random_get(seeded/deterministic)proc_exitNo filesystem or network functions are implemented.
environis empty bydefault (the host environment is never leaked). Out-of-bounds guest pointers
return
EFAULTinstead of corrupting host memory; bad fds returnEBADF. Theengine performs no real IO: the host supplies clock nanos and a random seed,
and splitmix64 generates random bytes deterministically.
Boundary
The WASI layer is compiled only into the standalone
scoot-wasmbinary(
-Dwasm-host=true); the zero-dependency core never links it. Defaultzig buildstill builds onlyscoot.Tests
Adds 11 hand-built wasm fixtures (no toolchain dependency) covering: echo
stdin->stdout, args/env round-trip,
proc_exitcodes,fd_writenwritten,random_getdeterminism, bad-fd errno, OOB pointer ->EFAULT, andunknown-import traps.
zig build testis green (all engine tests rununconditionally).
Verification
zig build -Dwasm-host=truezig build test(incl. 11 new WASI tests)echo.wasmround-tripsHello, WASI world!and exits 0;an
exit42.wasmexits 42; a missing module printsFAILto stderr and exits 1.Docs
Updates
docs/WASM_TOOLS.md(+.zh) andCHANGELOG.md(+docs/CHANGELOG.zh.md).Refs #100