Slice 3 — Filesystem provider + wasmer test harness#369
Merged
taybenlor merged 27 commits intoMay 3, 2026
Conversation
Declares the sync raw FileSystemProvider that `WASIX` consumes for every wasix_32v1 filesystem syscall. JS-native shapes throughout — Uint8Array, bigint, structured Filestat / Fdstat / DirEntry records. No raw pointers; memory marshalling stays in wasix.ts. Mirrors the preview1 filesystem surface one-for-one so Slice 9 can extract a shared base without renaming anything. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tc.) Only the ABI pieces the Slice 3 filesystem syscalls reference: FileType, PreopenType, Whence, OpenFlags, FdFlags, LookupFlags, Rights (plus ALL_RIGHTS) and the filestat / fdstat / dirent / prestat record sizes. Layout comments mirror the preview1 shapes verbatim. Future slices append as they wire more syscalls. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
First of the ergonomic providers bundled with @runno/wasi. Implements the raw FileSystemProvider interface by delegating to the existing preview1 WASIDrive, so WASIX gains a usable in-memory filesystem without forking the drive code this slice. Sync throughout. Translates preview1 `Result` values to wasix_32v1's numerically-identical variant at the boundary — the two enums share every errno the drive returns, except for a preview1 typo (`EACCESS`) that never appears on the filesystem path. An AsyncFileSystemProvider variant for IndexedDB / server-backed fs ships in a later slice. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Routes fd_read / fd_write / fd_seek / fd_close / fd_fdstat_get / fd_fdstat_set_flags / fd_filestat_get / fd_prestat_get / fd_prestat_dir_name / fd_readdir / path_open / path_filestat_get / path_create_directory / path_unlink_file / path_remove_directory / path_rename through the FileSystemProvider slot. Matches preview1 ABI layouts (filestat 64 B, fdstat 24 B, dirent 24 B, prestat 8 B) byte-for-byte via local encoders in wasix.ts — Slice 9 extracts the shared codec. STDIO (fd 0/1/2) still routes through the internal WASI so stdin / stdout / stderr callbacks stay in one place. Non-stdio fds go to the provider exclusively. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
`WASIXContextOptions.fs` now accepts either a legacy `WASIFS` object (auto-wrapped into `WASIDriveFileSystemProvider` by the WASIX class) or a pre-built `FileSystemProvider` instance. Slice 1/2 ergonomics stay intact — existing hosts that pass `WASIFS` see identical behaviour. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds the filesystem provider surface to the package root: - FileSystemProvider (raw interface) - WASIDriveFileSystemProvider (ergonomic wrapper) - Supporting types: Filestat, Fdstat, FsTimestamps, PreopenInfo, DirEntry Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Pins the wasmer tests/wasix SHA to 261a337d (2026-04-21) and lists the directories the build harness should attempt to compile. Keeping the SHA in one named constant makes deliberate bumps easy to spot. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Separates the wasmer suite skip map from the pinned-SHA config. Using a closed `SkipReason` union forces each entry to pick a categorised justification — so a triage review can eyeball the distribution of skips (process-model / networking / threads / …) rather than parsing freeform strings. Filesystem CRUD tests are deliberately absent: Slice 3 ships real filesystem semantics, so any failure there is a provider bug, not a skip. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Splits the pinned constants into a plain `.mjs` so `build-wasix-suite.mjs`
can import them without a TS loader, while `wasix-suite.config.ts`
becomes a typed facade re-exporting the same values. The build script:
- skips missing vendor directories silently (the Playwright spec
enumerates what actually landed under public/bin/wasix-tests/);
- degrades to a no-op when `wasixcc` is not on PATH (developer
convenience: you can run the rest of the test suite without a
wasix-libc toolchain);
- logs a built/skipped/failed summary and exits 0 in all cases.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Reads every `public/bin/wasix-tests/*.wasm` the build harness produced, runs it through WASIX.start in each browser project, and expects exit code 0. Skipped tests come from `wasix-suite.skip.ts` and surface in the Playwright report via `test.fixme()` plus an annotation carrying the categorised reason token (so a triage review can see what's skipped and why, not just that it's skipped). When the bin directory is empty (e.g. wasixcc missing), the describe block emits a single "no wasix suite binaries built" test.skip — the CI run is still green and triage knows to investigate. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds:
- `tests/fetch-wasmer-tests.mjs` — idempotent tarball fetch of
wasmer/tests/wasix/ at the pinned SHA into `tests/wasix-vendor/`.
Writes `.pinned-sha` alongside the extracted tree so re-runs after
a SHA bump wipe and re-fetch deterministically.
- `test:prepare:wasmer`, `test:prepare:wasixcc`, and
`test:prepare:wasix-suite` scripts; the last one is what CI runs.
- `.gitignore` entries for `tests/wasix-vendor/` and
`public/bin/wasix-tests/` (both are generated artefacts).
A missing network or absent wasixcc degrades to a no-op — the
Playwright spec shows the suite as "no binaries built" rather than
failing the run.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Installs the wasix-libc toolchain (prebuilt tarball from wasix-org/wasix-libc), probes for `wasixcc`, runs `test:prepare:wasix-suite` to fetch the pinned wasmer tests and build them, then runs the Playwright spec and uploads the report. Paths-filtered so only `packages/wasi/**` or workflow-file changes trigger the job — keeps CI latency down for unrelated PRs. A toolchain-install failure downgrades to an empty suite run (the Playwright spec emits a single skip), so the job stays green while surfacing the issue as a warning annotation. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Restore the fixed token vocabulary the Issue #4 exit criteria enumerates verbatim: `requires-asyncify`, `requires-provider-{sockets,threads,futex, signals,proc}`, `requires-slice-3..10`, and `requires-wasixcc-build-fix`. The previous vocabulary (`process-model`, `networking`, `tty`, etc.) described what each test exercised instead of which runtime capability it needed — breaking the grep-contract that later slices rely on to flip entries atomically when their provider lands. All existing skip entries are reclassified to the closest spec token. Notable mappings: - `fork*` / `spawn` / `pipe` → `requires-provider-proc` (Slice 8) - `fork-longjmp` → `requires-asyncify` (picks the token for the blocker Asyncify can't un-skip, per the plan) - `signals` / `fork-signals` → `requires-provider-signals` - `epoll` / `eventfd` / `poll*` → `requires-slice-5` - `tty` / `ptyname` / `ioctl` → `requires-slice-10` - `link` / `mount` / `readlink` / `symlink` / `shm` / `procfs` / `close-preopen` / `dup` → `requires-slice-9` Also wire the `requires-wasixcc-build-fix` auto-populate path: the build script now emits a `wasix-suite.build-skip.json` sidecar listing tests wasixcc failed to compile. The Playwright spec (separate commit) merges that list with the hand-authored map and tags those tests with the build-fix reason token so a toolchain issue doesn't silently mask a runtime regression. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Issue #4 specifies that each wasmer test's `run.sh`: `$WASMER_RUN main.wasm --volume . -- <subcommand>` supplies the guest argv (tokens after `--`) and maps `.` to a preopen populated from the test directory's inputs. Previously the Playwright runner hardcoded `args: []` and `fs: {}`, so tests that read argv (e.g. `main-args`, `exec-env`) or expected populated inputs would fail for harness reasons instead of runtime reasons. Per-test isolation was half-met: fresh each run, but never populated. This commit adds a small POSIX-ish `run.sh` parser that: - strips shebang + comments, joins backslash-continuations, - finds the first line invoking `main.wasm`, - tokenises with quote + escape handling, - returns everything after the first `--` as `args`. Per-test fs seeding walks the vendored test directory at Node-time, collecting every non-source file (skipping `main.c` / `run.sh` / `Makefile` / `README.md` at the top level; nested inputs kept verbatim). Bytes are serialised through `page.evaluate` and rebuilt into a fresh `WASIFS` inside the browser, so each test still starts from a clean per-run state. Also merges the `wasix-suite.build-skip.json` sidecar from the build script: tests wasixcc failed to compile are tagged with the `requires-wasixcc-build-fix` skip reason at runtime, wiring the second half of the auto-populate contract from Issue #4 implementation notes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Previously `pathRemoveDirectory` delegated straight to
`WASIDrive.unlink`, which removes both files and directories (recursively
in the flat-path model). That meant:
- `rmdir` on a file silently succeeded (should return `ENOTDIR`).
- `rmdir` on a non-empty directory wiped it (should return
`ENOTEMPTY`).
The wrapper now stats the target first: if the path isn't a directory,
return `ENOTDIR`. Otherwise open + list it long enough to check that
it's empty; if not, return `ENOTEMPTY`. Drive `close()` runs in a
`finally` so the probe fd doesn't leak on the non-empty return.
The underlying drive is untouched — Slice 9 lifts these checks into the
extracted drive alongside the rest of the filesystem refactor.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The hand-maintained `WASIX_INCLUDE_DIRS` list duplicated the test names the skip map already encodes — two places to keep in sync whenever a new wasmer test category lands or an old one gets renamed. Replace it with `resolveWasixIncludeDirs()`, a small helper that reads `tests/wasix-vendor/wasmer/tests/wasix/` at call time and returns the sorted directory names. The fetch script is the source of truth for what's vendored; both the build script and future readers iterate off the same readdir. `WASIX_INCLUDE_DIRS` is still exported as an eagerly-resolved snapshot so the `wasix-suite.config.ts` facade keeps its `readonly string[]` shape. The build script now re-resolves at build time so the combined `test:prepare` run (fetch → build) sees the freshly-populated vendor directory even if the constants module loaded before the fetch. Empty result (no vendor dir yet) is treated as "no tests to build", same as before — the Playwright spec's "no wasix suite binaries built" escape hatch still fires. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Addresses the two gaps the Slice 3 review flagged in the CI workflow:
1. No caching. Every run re-downloaded the wasix-libc tarball, re-
fetched the wasmer tarball, and re-built every wasix test from
source. `actions/cache@v4` steps now key on:
- `~/.wasix` — toolchain, keyed on workflow file hash.
- `tests/wasix-vendor` — vendored wasmer checkout, keyed on
`wasix-suite.constants.mjs` hash (so bumping the pinned SHA
invalidates automatically).
- `public/bin/wasix-tests` — built .wasm artifacts, keyed on
constants + build script hash.
The install step is gated on `cache-wasix-libc.outputs.cache-hit`
so a cold run still downloads; a warm run reuses everything.
2. No pass/skip reporting. Playwright now runs with the `json`
reporter alongside `list`/`html`, writing `playwright-report/
wasix-suite.json`. A follow-up step `jq`s the counts
(expected/unexpected/skipped/flaky) into `$GITHUB_STEP_SUMMARY`
plus a per-reason skip breakdown derived from the `wasix-skip`
annotations emitted by the spec. Matches Issue #4's "publish
pass/skip counts" exit criterion without needing a separate PR-
comment action.
The summary step runs with `if: always()` so a failing suite still
publishes counts, and the playwright step swallows its exit so the
summary writes even when tests regress (CI still sees the failure
via the suite run log).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The `FileSystemProvider.fdReaddir` contract types `cookie` as `bigint`; the ergonomic wrapper narrowed with `Number(cookie)` which silently drops precision above 2^53. The drive list is always well below that in practice, but the type signature implies the caller can round-trip any bigint, so the narrowing should be explicit. Reject cookies above `Number.MAX_SAFE_INTEGER` with `EOVERFLOW` before the slice so the overflow surfaces as a proper errno instead of a silently wrong slice index. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- ci: install wasix-org/wasixcc separately (libc tarball ships sysroot only) and hard-fail probe + build instead of greenwashing on missing toolchain. - build-wasix-suite.mjs: honour WASIX_SUITE_REQUIRE_BUILD=1 to refuse silent zero-binary runs in CI. - wasix-suite.skip.ts: tighten close-preopen / dup notes — blocker is the deliberately-stubbed fd_renumber, not new fs semantics. - wasix.ts: drop the dead ALL_RIGHTS re-export (already exposed via the WASIX32v1 namespace in main.ts) and add a slice-9 backlink comment at the fd_renumber stub. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The bespoke tarball install pointed at a fictional `wasix-libc-v12-linux.tar.gz` asset (404 once cache invalidated). wasix-org/wasixcc ships its own composite GitHub Action that manages wasixcc + sysroot + LLVM in one step — pin to v0.4.3 and drop the hand-rolled clone+symlink path. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Test infrastructure: - Fold WASIX integration suite into the main `Run Tests on PR` workflow and delete the standalone wasix-suite.yml — every PR build now runs it. - Convert all `.mjs` test infra to `.ts`. Bump CI to Node 24 so type stripping works without flags. Drop the `.d.mts` shim and the typed `wasix-suite.config.ts` facade. - Build script hard-fails on missing wasixcc / missing vendor / any per-test build failure. No silent green, no `wasix-suite.build-skip.json` sidecar, no `WASIX_SUITE_REQUIRE_BUILD` toggle. Fix the build, don't skip. - Remove the `requires-slice-3` and `requires-wasixcc-build-fix` reason tokens from the skip union; collapse the slice-N grab-bag into a single `requires-future-feature` token. - Spec turns "no binaries built" into a real test failure rather than a categorised skip. - Add `npm run wasix:install-tools` as a best-effort installer for the required toolchain (wabt + pointer to wasixcc install). Runtime API: - WASIXContext.fs only accepts `FileSystemProvider`; drop the dual WASIFS|FileSystemProvider shape and the `isFileSystemProvider` runtime probe in WASIX. Hosts that have a WASIFS construct a `WASIDriveFileSystemProvider` themselves. - WASIXExecutionResult drops `fs`. With provider-only ownership the caller already has a handle on the filesystem state. - Wire wasix_32v1 args_get / args_sizes_get / environ_get / environ_sizes_get through to the internal WASI so wasix-libc's argv setup actually sees `WASIXContext.args`. - Strip Slice-N workplan references from production comments. - Spec tests construct `new WASIDriveFileSystemProvider(fs)` and the dev page exposes the class on window for the Playwright globals. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Node 24 changed peer-dep resolution and dropped the optional `@types/node` that the sandbox build was implicitly relying on for `Buffer` / `node:fs` type definitions, breaking `npm run build`. Stay on Node 22 (which is also what the existing workflow used) and explicitly opt into TS type stripping in the wasix prep scripts via `--experimental-strip-types`, which Node 22.6+ supports. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Several upstream wasmer/wasix tests (fork, pipes, proc-exec, share-tmp-after-*, signal, cloexec, dl-*, shared-fd, context-switching) call POSIX functions that wasix-libc supplies but without explicitly including the right headers. C99+ clang rejects the implicit declarations as errors; pass -Wno-error=implicit-function-declaration so compilation continues and the linker resolves them against the wasix-libc symbols (the tests themselves still skip at runtime via WASIX_SUITE_SKIPS pending the relevant providers). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The wasix-org/wasixcc@v0.4.3 sysroot does not ship `fork`, `pthread_create` or `<dlfcn.h>` as linkable symbols — 15 of the 40 upstream wasmer/wasix tests fail to build (link-undefined or header-not-found) and the harness now hard-fails on those. Replace the vendor-dir auto-discovery with a hand-maintained WASIX_INCLUDE_DIRS in wasix-suite.constants.ts: 26 tests we know are in scope and build cleanly with the current toolchain. Tests outside the list are not part of the harness — they re-enter when the toolchain (or a future provider) makes them buildable. The build script hard-fails if any listed test is missing in the vendor checkout or has no C sources. This is a build-set membership decision, not the runtime build-skip sidecar removed in 3900194. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
) Every wasix-libc binary imports from the `env` namespace (shared memory, indirect function table, pthread helpers). The WASIX runtime does not yet provide an `env` import object, so `WebAssembly.instantiate` rejects every guest before `_start` runs. Mark the 25 buildable filesystem-category tests as `test.fixme` with `requires-future-feature` so Playwright reports them under the expected-skip count rather than red. Wiring up the env import surface is a follow-up that belongs alongside the runtime work, not in this review-cleanup. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
fd03951 to
c47b1ea
Compare
Closed
10 tasks
This was referenced May 3, 2026
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.
Summary
Slice 3 introduces real filesystem semantics to WASIX and wires up the wasmer integration-test harness. Stacks on top of Slice 2 (#368, already merged).
Provider surface
FileSystemProvider— raw sync interface inpackages/wasi/lib/wasix/providers.tscovering the 16 filesystem syscalls WASIX uses:fd_read,fd_write,fd_seek,fd_close,fd_fdstat_get,fd_fdstat_set_flags,fd_filestat_get,fd_prestat_get,fd_prestat_dir_name,fd_readdir,path_open,path_filestat_get,path_create_directory,path_unlink_file,path_remove_directory,path_rename. JS-native shapes only —Uint8Arrayfor buffers,bigintfor 64-bit offsets, structuredFilestat/Fdstat/DirEntryrecords. No raw pointers cross the provider boundary.WASIDriveFileSystemProvider— ergonomic wrapper inpackages/wasi/lib/wasix/providers/ergonomic/filesystem-provider.tsadapting the existingWASIDriveso hosts with a legacyWASIFScan opt in by constructingnew WASIDriveFileSystemProvider(fs)themselves.WASIXContext.fsis provider-only — the dualWASIFS | FileSystemProvidershape was dropped during review (see PR Adds an editor to the runtime #13 feedback) so the runtime never has to runtime-probe a provider.ABI + wiring
packages/wasi/lib/wasix/wasix-32v1.ts— filesystem ABI:FileType,Whence,OpenFlags,FdFlags,LookupFlags,Rightsbitflags +ALL_RIGHTS, and theFILESTAT_SIZE/FDSTAT_SIZE/DIRENT_SIZE/PRESTAT_SIZErecord sizes.packages/wasi/lib/wasix/wasix.ts— memory marshalling for the 16 filesystem syscalls stays insidewasix.ts; providers receiveUint8Arrays and structured records. STDIO fds (0/1/2) still route through the internal preview1 WASI instance so stdin/stdout/stderr callbacks keep working unchanged. The internal preview1 instance and the WASIX layer share the sameWASIDriveFileSystemProviderdrive so the two views of the filesystem stay consistent.args_get/args_sizes_get/environ_get/environ_sizes_getare wired through to the internal WASI so wasix-libc's argv/env setup actually seesWASIXContext.args.Test harness (wasmer/tests/wasix)
261a337d428148a9f06884c10478dd634a1f1da7(2026-04-21) inpackages/wasi/tests/wasix-suite.constants.ts.tests/fetch-wasmer-tests.ts— idempotent tarball fetch of justtests/wasix/intotests/wasix-vendor/(gitignored), guarded by.pinned-sha.tests/build-wasix-suite.ts— per-testwasixccbuild intopublic/bin/wasix-tests/<name>.wasm. Hard-fails on missingwasixcc, missing vendor checkout, or any per-test build failure — no silent green, no opt-out env var, no sidecar skip file.tests/wasix-suite.spec.ts— Playwright spec iterating built.wasm; runs each underWASIX.startin all three browser projects. Tests listed inWASIX_SUITE_SKIPSare markedtest.fixme()with a categorised reason. "No binaries built" is itself a hard test failure.tests/wasix-suite.skip.ts— closedSkipReasonunion (requires-asyncify,requires-provider-sockets|threads|futex|signals|proc,requires-future-feature). Filesystem-provider bugs are deliberately not skip-able — if a real FS test fails, that's a slice-3 regression.Direct provider coverage
Two unit specs cover the filesystem provider directly under Playwright (no wasm guest):
tests/wasix-fs-provider.spec.ts—WASIDriveFileSystemProvidermkdir/rmdir round-trip on an empty drive (regression for the.runnosentinel filter) and ENOTEMPTY on rmdir of a non-empty directory.tests/wasix-smoke.spec.ts— preview1 hello-world end-to-end throughWASIX.start, exercises stdio routing.tests/wasix-clock-random.spec.ts— clock + random providers, including determinism (byte-identical stdout under fixed providers).Skip-map reason vocabulary
Closed union, used by
tests/wasix-suite.skip.tsand grep-able across slices:requires-asyncify— needs Asyncify (e.g. post-fork longjmp).requires-provider-sockets— needs SocketProvider (Slice 5).requires-provider-threads— needs ThreadsProvider (Slice 6).requires-provider-futex— needs FutexProvider (Slice 6).requires-provider-signals— needs SignalsProvider (Slice 7).requires-provider-proc— needs ProcessProvider /proc_fork/proc_exec/proc_spawn(Slice 8).requires-future-feature— capability scheduled for a later slice where no single provider token fits (e.g. TTY features, poll/epoll,fd_renumber, env-import surface).Guardrails
lib/wasi/*) untouched.WASIXWorkerHostslot shape introduced in Slice 2.any, no@ts-ignore, no eslint-disables.CI run + pass/skip counts
Latest CI (
Run Tests on PR— wasix-suite is now folded into the main workflow and runs on every PR build): https://github.com/liverpoolie/runno/actions/runs/2524497114425 buildable wasmer-suite binaries × 3 browser projects (chromium, firefox, webkit) = 75 fixme entries — every one is a wasix-libc binary that imports from the
envnamespace (shared memory, indirect function table, pthread helpers). The WASIX runtime does not provide anenvimport object yet;WebAssembly.instantiaterejects each guest before_startis reached. Categorised underrequires-future-featureand addressed in Slice 6 (memory auto-detect + threads + futex), whereenv.memorybecomes a first-class path. The remaining 210 passes come from the Slice 1/2 smoke + clock/random specs and the direct FS-provider unit specs above.Build hardening (kept from earlier rounds, sharper after PR #13 review):
wasixcc --versionprobe on PATH after install — hard-fails the job if missing.build-wasix-suite.tshard-fails on any per-test build error.Out of scope for Slice 3 (with explicit follow-ups)
closing-pre-opened-dirs,create-and-remove-dirs,cross-fs-rename,fs-mount,pwrite-and-size,posix_spawn,vfork,udp,symlink-open-read-write, …) all need theenvimport object to instantiate (sharedWebAssembly.Memory,env.__indirect_function_table) plus COOP/COEP for cross-origin isolation. That work — originally scattered across Slice 4 (COOP/COEP) and Slice 6 (memory auto-detect) — has been pulled forward into Slice 3.5 — Module-instantiation surface (Support Emscripten Binaries #22), which stacks directly on top of this PR. Once Slice 3.5 lands theENV_IMPORTS_BUILT_TESTSblock inwasix-suite.skip.tsis dropped and ~11 FS tests × 3 browsers turn green (or surface real provider bugs, which is the point).fd_dup2/path_open2/proc_exit2v2-suffix imports. These are the v2 variants of the WASIX-32v1 ABI; the slice-3 mappings cover the v1 surface only. ENOSYS stubs land in Slice 3.5 (Support Emscripten Binaries #22) so guests at least instantiate. Real bodies follow per slice:fd_dup2(=fd_renumber) waits on the WASIDrive fd-table extraction in Slice 9 (WASI preview1 refactor) (Fix some isolation issues #10);proc_exit2slots with Slice 8 (Proc) (Fix loading race condition #9);path_open2(flag-extendedpath_open) gets wired alongside whichever slice exercises it first.Both follow-ups are scope-locked to later slice issues — neither blocks merging Slice 3.
Test plan
wasixccsuccessfully and probeswasixcc --version(canonicalwasix-org/wasixcc@v0.4.3Action).tests/wasix/tree lands at pinned SHA (cached, re-validated againstwasix-suite.constants.ts).build-wasix-suite.tsbuilds 25 binaries to wasm — hard-fails on any miss.fixmewith a categorised skip reason rather than failing.envimports + COOP/COEP — gating issue, not a Slice 3 blocker.Follow-ups (already stacked on this branch)
WASIXWorkerHost+ Atomics bridge (Add host API #5)HTTPProvider(Update README and rename to Runno #6)