Preview1 state lives in the host, so Go modules (esbuild) work. esbuild bundles byte-identical to native; uutils and QuickJS-ng file tests pass. The failed guest-side adapter attempt (T7) moves to spikes/s7-preview1-adapter/.
Preview1 over the virtual filesystem
State owns a process's preview1 descriptors outside guest memory.
It uses the caller's Arc<dyn Layer> for every filesystem operation.
The caller can supply the same mount namespace that its components use.
The namespace has one preopen, /, at descriptor 3.
Relative paths through descriptor 3 resolve against the process cwd.
Paths through other directory descriptors resolve against that descriptor's virtual path.
The resolver normalizes .. before the mount namespace routes the operation.
Construct State::new(root, cwd, argv, env, stdin, stdout, stderr).
The stream types accept boxed Tokio AsyncRead and AsyncWrite implementations.
The state wraps them with Wasmtime's existing pollable streams.
These streams supply readiness without a guest-memory buffer for adapter state.
Register imports with add_to_linker(&mut linker, |store| &mut store.preview1).
Instantiate the core module asynchronously and call its _start export.
A wasmtime_wasi::I32Exit error carries the process exit status.
Wiggle generates the ABI from the copied preview1 WITX files.
Their source is Wasmtime v49.0.2, commit 3c8a3e79aa3188a1a12b3aebbaa097abccceac92.
Wiggle checks guest pointers before the implementation accesses their contents.
The implementation maps filesystem errors to preview1 errno values.
The Layer interface does not expose inode identity.
Metadata therefore hashes the virtual path, as the component adapter does.
Directory descriptors retain their original paths after a rename.
Hard links, symlink creation, file preallocation, signals, and sockets return NOTSUP.
Preview1 does not expose the platform's WASI 0.2 sockets.
The integration test uses the existing S6 and lab guests:
- esbuild v0.27.7:
/tmp/s6-esbuild/esbuild.wasmand/tmp/s6-esbuild/esbuild-native. - uutils 0.12.0:
/tmp/wasi-userland-lab/uu/coreutils-0.12.0-wasm32-wasip1/coreutils.wasm. - QuickJS-ng v0.18.0:
/tmp/wasi-userland-lab/qjs-wasi.wasm.
The QuickJS-ng input matches its recorded release SHA-256.
The S6 fixture also requires /tmp/s6-esbuild/app/node_modules.
It stores local Wasmtime compilation artifacts in a persistent test cache.
Run it from the repository root:
CARGO_TARGET_DIR=target/preview1 nix develop -c cargo test -p sausage-vfs --test preview1 -- --nocapture