[JSC] Fix wasm type parsing regression by making RTT formal canonicalized types
94e35cf parent — see above; this is 103a40a
// JSTests/wasm/stress/cross-module-rtt-identity.js
// Two separately compiled modules declare the same recursive struct type.
// Isorecursive canonicalization must map both to the same RTT pointer
// so that a ref.cast in module B on a value produced by module A succeeds.
const { makeLeaf, leafVal } = new WebAssembly.Instance(new WebAssembly.Module(M_A)).exports;
const { castAndRead } = new WebAssembly.Instance(new WebAssembly.Module(M_B)).exports;
const b = castAndRead(leaf);
if (b !== v)
throw new Error(`B castAndRead(${v}): expected ${v}, got ${b}`);
WebAssembly GC adds heap-allocated structs, arrays, and recursive types to wasm. Runtime Types (RTTs) are the objects that carry type identity; they are compared by pointer equality when executing ref.cast and subtype checks. Correct operation requires isorecursive canonicalization — two independently compiled modules declaring structurally identical recursive types must receive the same canonical RTT pointer, so cross-module ref.cast succeeds as the spec requires.
This commit removes TypeDefinition entirely from JSC's WebAssembly GC type system and unifies all runtime type representation around RTT. It introduces TypeSectionState to hold temporary parsing structures (Subtype, RecursionGroup, Projection) that live only during type-section parsing, after which everything is converted to canonical RTTs registered with the process-wide TypeInformation singleton. RTTs now hold RefPtr references to sibling RTTs, intentionally forming refcount cycles for mutually-recursive types that are permanently leaked (matching V8's current approach), pending a future cycle collector. The commit also fixes cross-module isorecursive RTT canonicalization and a performance regression from repeated traversal during GC structure construction (introduced in 312331@main).
Significance
This is a ground-up rewrite of the Wasm GC type infrastructure, and a single missed pointer escape from the temporary TypeSectionState becomes a use-after-free reachable by every cross-module ref.cast.