Stream: git-wasmtime

Topic: wasmtime / PR #13230 Fix passive element segment GC roots...


view this post on Zulip Wasmtime GitHub notifications bot (Apr 29 2026 at 13:27):

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 ValRaw to a *mut VMGcRef. Because we always store GC refs as little endian inside ValRaw, 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/13107

The fix that this commit makes is to add another kind of GC root for ValRaw, where we can get and set the GC root using ValRaw internally, to ensure that the endianness (and incidentally also the GC ref offsets within the ValRaw) 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, VMGcRef roots, and ValRaw roots.

FWIW, I initially tried to make VMGcRef also 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 of u32 to make the byte ordering explicit, we break rustc's niche type optimizations (since VMGcRef is non-zero right now). I also investigated making PassiveElementSegment an enum or either funcrefs or externrefs, similar to what we do for wasmtime::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:

Our development process is documented in the Wasmtime book:
https://docs.wasmtime.dev/contributing-development-process.html

Please ensure all communication follows the code of conduct:
https://github.com/bytecodealliance/wasmtime/blob/main/CODE_OF_CONDUCT.md
-->

view this post on Zulip Wasmtime GitHub notifications bot (Apr 29 2026 at 13:27):

fitzgen requested pchickey for a review on PR #13230.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 29 2026 at 13:27):

fitzgen requested wasmtime-core-reviewers for a review on PR #13230.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 29 2026 at 13:27):

fitzgen edited PR #13230:

Passive element segments were registered as GC roots by converting a *mut ValRaw to a *mut VMGcRef. Because we always store GC refs as little endian inside ValRaw, 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/13107

The fix that this commit makes is to add another kind of GC root for ValRaw, where we can get and set the GC root using ValRaw internally, to ensure that the endianness (and incidentally also the GC ref offsets within the ValRaw) 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, VMGcRef roots, and ValRaw roots.

FWIW, I initially tried to make VMGcRef also 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 of u32 to make the byte ordering explicit, we break rustc's niche type optimizations (since VMGcRef is non-zero right now). I also investigated making PassiveElementSegment an enum or either funcrefs or GC refs, similar to what we do for wasmtime::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:

Our development process is documented in the Wasmtime book:
https://docs.wasmtime.dev/contributing-development-process.html

Please ensure all communication follows the code of conduct:
https://github.com/bytecodealliance/wasmtime/blob/main/CODE_OF_CONDUCT.md
-->

view this post on Zulip Wasmtime GitHub notifications bot (Apr 29 2026 at 13:29):

fitzgen updated PR #13230.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 29 2026 at 13:38):

:memo: alexcrichton submitted PR review:

Nice find!

view this post on Zulip Wasmtime GitHub notifications bot (Apr 29 2026 at 13:38):

:speech_balloon: alexcrichton created PR review comment:

I think this (and docs below) may want a small update because 'a doesn't look to be in-scope for this type or nearby? (perhaps it was in a historical version?)

view this post on Zulip Wasmtime GitHub notifications bot (Apr 29 2026 at 13:38):

:thumbs_up: alexcrichton submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 29 2026 at 13:42):

fitzgen updated PR #13230.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 29 2026 at 13:45):

fitzgen updated PR #13230.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 29 2026 at 13:45):

fitzgen has enabled auto merge for PR #13230.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 29 2026 at 14:00):

fitzgen added PR #13230 Fix passive element segment GC roots' endianness to the merge queue.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 29 2026 at 14:25):

:check: fitzgen merged PR #13230.

view this post on Zulip Wasmtime GitHub notifications bot (Apr 29 2026 at 14:25):

fitzgen removed PR #13230 Fix passive element segment GC roots' endianness from the merge queue.


Last updated: May 03 2026 at 22:13 UTC