fitzgen opened PR #13230 from fitzgen:passive-element-segment-gc-roots-endianness to bytecodealliance:main:
Passive element segments were registered as GC roots by converting a
*mut ValRawto a*mut VMGcRef. Because we always store GC refs as little endian insideValRaw, regardless of the target architecture's endianness, this cast is only valid on little endian systems. This bug was not exposed until the introduction of the copying collector in
https://github.com/bytecodealliance/wasmtime/pull/13107The fix that this commit makes is to add another kind of GC root for
ValRaw, where we can get and set the GC root usingValRawinternally, to ensure that the endianness (and incidentally also the GC ref offsets within theValRaw) are matched up correctly between the GC root's definition and the collector's use of it. This brings us to three kinds of GC roots: Wasm stack roots,VMGcRefroots, andValRawroots.FWIW, I initially tried to make
VMGcRefalso always store its data as little endian, but this was a larger, more-invasive change and with feedback like https://github.com/bytecodealliance/wasmtime/pull/13193#discussion_r3140185859 suggesting the use of[u8; 4]instead ofu32to make the byte ordering explicit, we breakrustc's niche type optimizations (sinceVMGcRefis non-zero right now). I also investigated makingPassiveElementSegmentanenumor either funcrefs or externrefs, similar to what we do forwasmtime::runtime::vm::Table. This also led to an outsized amount of code churn and didn't feel like it was paying for itself. Ultimately, I abandoned these approaches, preferring the one taken in this commit instead.<!--
Please make sure you include the following information:
If this work has been discussed elsewhere, please include a link to that
conversation. If it was discussed in an issue, just mention "issue #...".Explain why this change is needed. If the details are in an issue already,
this can be brief.Our development process is documented in the Wasmtime book:
https://docs.wasmtime.dev/contributing-development-process.htmlPlease ensure all communication follows the code of conduct:
https://github.com/bytecodealliance/wasmtime/blob/main/CODE_OF_CONDUCT.md
-->
fitzgen requested pchickey for a review on PR #13230.
fitzgen requested wasmtime-core-reviewers for a review on PR #13230.
fitzgen edited PR #13230:
Passive element segments were registered as GC roots by converting a
*mut ValRawto a*mut VMGcRef. Because we always store GC refs as little endian insideValRaw, regardless of the target architecture's endianness, this cast is only valid on little endian systems. This bug was not exposed until the introduction of the copying collector in
https://github.com/bytecodealliance/wasmtime/pull/13107The fix that this commit makes is to add another kind of GC root for
ValRaw, where we can get and set the GC root usingValRawinternally, to ensure that the endianness (and incidentally also the GC ref offsets within theValRaw) are matched up correctly between the GC root's definition and the collector's use of it. This brings us to three kinds of GC roots: Wasm stack roots,VMGcRefroots, andValRawroots.FWIW, I initially tried to make
VMGcRefalso always store its data as little endian, but this was a larger, more-invasive change and with feedback like https://github.com/bytecodealliance/wasmtime/pull/13193#discussion_r3140185859 suggesting the use of[u8; 4]instead ofu32to make the byte ordering explicit, we breakrustc's niche type optimizations (sinceVMGcRefis non-zero right now). I also investigated makingPassiveElementSegmentanenumor either funcrefs or GC refs, similar to what we do forwasmtime::runtime::vm::Table. This also led to an outsized amount of code churn and didn't feel like it was paying for itself. Ultimately, I abandoned these approaches, preferring the one taken in this commit instead.<!--
Please make sure you include the following information:
If this work has been discussed elsewhere, please include a link to that
conversation. If it was discussed in an issue, just mention "issue #...".Explain why this change is needed. If the details are in an issue already,
this can be brief.Our development process is documented in the Wasmtime book:
https://docs.wasmtime.dev/contributing-development-process.htmlPlease ensure all communication follows the code of conduct:
https://github.com/bytecodealliance/wasmtime/blob/main/CODE_OF_CONDUCT.md
-->
fitzgen updated PR #13230.
:memo: alexcrichton submitted PR review:
Nice find!
:speech_balloon: alexcrichton created PR review comment:
I think this (and docs below) may want a small update because
'adoesn't look to be in-scope for this type or nearby? (perhaps it was in a historical version?)
:thumbs_up: alexcrichton submitted PR review.
fitzgen updated PR #13230.
fitzgen updated PR #13230.
fitzgen has enabled auto merge for PR #13230.
fitzgen added PR #13230 Fix passive element segment GC roots' endianness to the merge queue.
:check: fitzgen merged PR #13230.
fitzgen removed PR #13230 Fix passive element segment GC roots' endianness from the merge queue.
Last updated: May 03 2026 at 22:13 UTC