Merge train: #9647 #9648 #9649 (llhttp differential closes #9611) - #9653
Merged
Conversation
added 4 commits
September 3, 2026 21:13
…bits (#9611) Closes the last open verification item on #9611 — the llhttp differential — and fixes the bug that verification found. THE DIFFERENTIAL. `crates/perry/tests/issue_9611_llhttp_differential.rs` drives both WebAssembly builds of llhttp that undici ships, the way undici drives them: a windowed `Uint8Array` over the engine's linear memory is filled with the socket chunk, `llhttp_execute` runs, and the parser calls back into JS. It covers whole-message, byte-at-a-time and 4 KiB chunkings of simple, chunked, pipelined, 100-continue, many-header and 300 KiB-body responses, and reads every callback span BOTH out of linear memory and through undici's own trick of mapping the wasm pointer back into the source chunk — a span that is right in one view and wrong in the other fails loudly instead of silently agreeing with itself. node's trace is the checked-in oracle; both builds reproduce it identically. THE BUG IT FOUND. The wasm host held the imports object as raw NaN-boxed bits (`perry_wasm_host_instance_set_import_context`), and nothing rooted or rewrote them. A collection triggered INSIDE one import callback relocated the object, so every later import in the same call resolved a stale pointer, `call_wasm_import` returned 0, and the host substituted the import's default result — wasm continued with no error reported anywhere. Through llhttp that silently dropped `on_message_complete`: a truncated HTTP response reported as a clean parse, on cc's network path. It is not a regression from the zero-copy change. The same binary shape reproduces on a perry built from `666481e27` (the commit before #9611 landed), and the minimiser isolates it to allocation volume inside the callback, not to memory growth: big_nobuild body=307200 build=false pages=3->6 complete=1 big_build body=307200 build=true pages=6->6 complete=0 and tenuring the imports object before instantiation — so a copying minor cannot move it — restores complete=1 on every run. That is the diagnosis. THE FIX. The host now holds an opaque token; the imports object stays on the runtime side in `WASM_IMPORT_OBJECTS`, which a registered scanner rewrites when a collection moves it. The token is assigned at instantiation, so the start function is covered too, and the per-call `perry_wasm_host_instance_set_import_context` store is gone — one less FFI call on the export path. The scanner is rewrite-only (`visit_metadata_nanbox_f64_slot`), matching the memory binding beside it: every path that can reach an import already roots the imports object on the stack, so this table is a lookup side table, not the reference that keeps the object alive. Marking would instead pin the imports object of every instance ever created. Verified on Linux: byte-identical to node on both llhttp builds; the wasm ESM suite, 14 wasm-host tests and 3,037 runtime tests pass; the root-holder and file-size gates pass. Disabling only the rewrite fails the new test at exactly the right line: node : message_complete perry: execute len=307243 ret=0 errpos=-76384 Claude-Session: https://claude.ai/code/session_01VxP3FEDgV4zUocSDBhD8qh
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.
Lands three fixes, all cherry-picked clean:
Validation:
run_lint_gates.shall 62 gates pass; release build green; RUST_TEST_THREADS=1 perry-runtime 3060/0;issue_9611_llhttp_differentialgreen (215s).Rebase-merge preserving authorship.