next.js
4811e49e - test(turbo-tasks): run the wasm tests with a Node wasi host (#97789)

Commit
28 days ago
test(turbo-tasks): run the wasm tests with a Node wasi host (#97789) ### What? Adds a Node host so `wasm32-wasip1-threads` test binaries can run, and wires the `turbo-rcstr`, `turbo-tasks`, and `turbo-tasks-backend` library tests into the WASI CI job. It also provides the WASI allocation symbols expected by the `lz4-sys` dependency introduced by the base PR, allowing those test binaries to link. ### Why? The Rust test binaries require host functionality that stock WASI runners do not provide. Turbopack stores its link-time task registries in WebAssembly custom sections and imports a host callback to read them. Its multithreaded runtime also requires shared memory and thread spawning through Node Workers. The base PR replaces `lzzzz` with `lz4`. `lz4-sys 1.11.1` compiles its C sources against custom allocation shims on `wasm32-wasi*`, but excludes the Rust implementations when the target OS is WASI. Without equivalent symbols supplied by the consuming crate, test links fail on unresolved malloc, calloc, and free shims. Running these suites in CI gives the remaining WASI layers direct regression coverage instead of relying on native-only tests. ### How? The Node cargo target runner provides WASI preview1, imported shared memory, and the complete two-phase [`link-section` custom-section protocol](https://github.com/mmastrac/linktime/blob/ae29e51d94a955df2442ed6418b8a712c1f2bfb3/link-section/docs/PREAMBLE.md#wasm). [`@emnapi/wasi-threads`](https://github.com/toyobayashi/emnapi/tree/main/packages/wasi-threads) supplies Worker lifecycle, compiled-module transfer, load/start ordering, and cleanup for the [`wasi.thread-spawn`](https://github.com/WebAssembly/wasi-threads) import that Node's WASI runtime does not provide. The module is compiled once, then the structured-cloneable `WebAssembly.Module` and shared memory are sent to Workers. A small adapter around the package's lower-level `ThreadManager` and `ThreadMessageHandler` APIs preserves Rust's original one-argument ABI: the high-level `WASIThreads` wrapper requires guest `malloc`/`free` exports for that ABI, and Rust test binaries do not export them. Worker identifiers come from a shared atomic counter because Tokio Workers can spawn additional Workers while the main WebAssembly thread is parked. On WASI, `turbo-persistence` supplies the three allocation symbols required by liblz4 and forwards them to WASI libc, keeping allocation and deallocation within the same allocator. Native builds do not compile these wrappers. Tests that depend on unavailable platform behavior remain visible as WASI-only ignored tests with explicit reasons. Native runs keep the full test set enabled. A following stacked PR replaces the unsupported `parking_lot` parker and re-enables the corresponding contention tests. The workflow installs and builds the workspace before running the host because both the package dependency and compiled production support used by a later stack layer must be available. ### Verification - Node 20 host unit tests: 9/9 - Exact combined WASI CI command: `turbo-rcstr` 12 passed / 1 ignored; `turbo-tasks` 68 / 44; `turbo-tasks-backend` 65 / 35 - Full 111-test `turbo-tasks` binary through the package-managed host: 95 passed / 16 ignored - No Worker-side `WebAssembly.compile`; the compiled module is transferred by `ThreadManager` - `pnpm install --lockfile-only --offline` with a frozen lockfile <!-- NEXT_JS_LLM --> <!-- fleet b6d0486f-97c7-42a7-bdaf-3490774cdec3 --> Co-authored-by: vercel-fleet-prod[bot] <318278635+vercel-fleet-prod[bot]@users.noreply.github.com> Co-authored-by: Luke Sandberg <210140+lukesandberg@users.noreply.github.com> Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
Author
Parents
Loading