Parents: #493, #486 Related: #141, #487, #490
Problem
When a Wasm exception reference is published, publishExceptionReference deduplicates direct and nested externref roots through std.AutoHashMapUnmanaged(u64, void). Externrefs carry arbitrary JavaScript Value.bits, Wasm tags can declare many parameters, and Zig hashes those attacker-influenced bits with fixed Wyhash seed 0. A caller can therefore precompute collision-heavy payload families on the exception/error path.
The resulting WasmException.externrefs slice is internal tracing metadata. Its order is unobservable; only exact root identity and uniqueness matter.
Scope
- Replace fixed-seed hashing with bounded worst-case
O(n log n)sort-and-unique over exactValue.bits. - Gather direct
externref/hostrefroots and roots retained by nestedexnrefpayloads into invocation-owned scratch, sort without another allocation, compact duplicates in place, and copy only the unique prefix into owner storage. - Preserve exact Value identity, nested exception reachability, payload order, wrapper/rethrow identity, moving-GC rewriting, concurrent publication, and allocation-failure rollback.
- Keep final root ownership and teardown unchanged while reducing temporary hash-table overhead.
No-workaround rules
- No tag/payload count reduction, rejected externref values, hash-only equality, deterministic/public/address/time-derived fallback seed, linear quadratic deduplication, skipped duplicate roots without exact proof, global mutable seed, leaked scratch, or changed observable exception payload order.
- No unrelated Wasm decode/validation, JS exception-constructor, GC aggregate, or public/private ABI change.
Acceptance
- Published native exception roots use no default-context map and have a documented worst-case complexity bound.
- A precomputed default-Wyhash collision family deduplicates to the exact unique
Value.bitsset, including direct and nested roots. - Empty, duplicate-heavy, moving-GC, rethrow/wrapper identity, concurrent publication, and exhaustive OOM tests pass.
- Focused Debug, ReleaseSafe, TSan/no-GIL, Wasm API/spec, and GC lifetime gates pass.
- Exact-parent Wasm conformance inventories have nonzero accounting and zero regressions.
- Full unit and threadfuzz gates pass.