[WebAssembly] Fix SpillPointers: spill potential pointers live at call sites for Boehm GC correctness#9
Draft
Copilot wants to merge 2 commits intorelease/16.xfrom
Draft
[WebAssembly] Fix SpillPointers: spill potential pointers live at call sites for Boehm GC correctness#9Copilot wants to merge 2 commits intorelease/16.xfrom
Copilot wants to merge 2 commits intorelease/16.xfrom
Conversation
… correctness Co-authored-by: PLUTOFX <110596339+PLUTOFX@users.noreply.github.com>
Copilot
AI
changed the title
[WIP] Investigate failed execution of WebAssembly outputs
[WebAssembly] Fix SpillPointers: spill potential pointers live at call sites for Boehm GC correctness
Mar 8, 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.
Three sunspider wasm test cases (
regexp-dna,string-unpack-code,string-tagcloud) crash withwasm trap: undefined element: out of bounds table accessinsidestring_buffer_reallocat acall_indirect. The root cause isWebAssemblySpillPointersfailing to keep certain heap-allocated pointer values visible to Boehm GC during calls.Bugs fixed in
WebAssemblySpillPointers.cppBug 1 — Wrong liveness condition (primary)
The spill gate was
liveAt(CallIdx) && liveAt(CallIdx.getRegSlot()), which only spills registers that survive past the call. This misses registers that are consumed as call arguments (live range ends atgetRegSlot()).The concrete failure: QuickJS computes
vtable + 20as an interior pointer to a GC-managed vtable and passes it directly as acall_indirectargument. It is not needed after the call, so the old check never spilled it. GC fires during the call, cannot trace the vtable through any shadow-stack root, and collects it. On the next accessvtable[12](the function-table index) is garbage → trap.Fix: drop the second condition; spill any potential pointer live at the call:
Bug 2 — Missing seeds for integer-typed pointer arguments (defensive)
Only
ptr-typed LLVM IR arguments were treated as potential pointer seeds. Runtimes like QuickJS routinely pass GC-traceable pointer values asi32/i64(e.g.,JSValueis a tagged pointer stored as an integer). Such arguments were invisible to the dataflow analysis and never spilled.Fix: unconditionally seed all
i32/i64ARGUMENTinstructions as potential pointers, regardless of the LLVM IR type annotation.Test update (
spill-pointers.ll)test_ptr_consumed_by_call: verifies that a pointer passed solely as a call argument (dead after the call) is still spilled — the case the old code missed.test_int_onlycomment to explain why it still emits no spills: the integer arguments die before the call site, soNeedSpillremains empty even with the broadened seeding.💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.