ReviewOS

zig-utils/zig-js

WebAssembly GC: runtime objects, casts, and precise tracing

#299
Closed chris opened this 9 days ago ·
9 days ago

Parent: #267 Depends on: #298 Related: #144, #145 Roadmap: #142, #134

Implement Wasm GC allocation and execution with precise host-GC integration.

Acceptance:

  • Execute struct/array allocation and access, packed fields, casts/tests, br_on_cast variants, ref conversions, and reference equality.
  • Preserve canonical Wasm reference identity across calls, tables, globals, exceptions, imports, exports, and cross-instance linking.
  • Trace all live Wasm fields, frames, aggregates, and wrappers precisely; reclaim unreachable graphs and tear down failures exactly once.
  • Define weak/reference and future moving-collector rewrite boundaries without permanently pinning aggregates.
  • Add cycles, deep graphs, mutation, stress, leak, failure injection, concurrent publication, and ThreadSanitizer witnesses.
9 days ago

First runtime checkpoint pushed in cee0ca7.

Implemented:

  • tagged, unboxed i31 references;
  • ref.i31, i31.get_s, and i31.get_u with exact low-31-bit behavior;
  • reference equality for i31/aggregate identity slots;
  • generic GC null representation, ref.is_null, and ref.as_non_null trapping;
  • GC-aware host signature/default slot classification;
  • rejection of non-defaultable non-null GC locals (a validation edge found while wiring runtime slots).

Focused production-root evidence: 3/3 passed, 0 failed, 0 skipped, 0 leaked. The deterministic non-defaultable-local validator witness is also green.

Aggregate slots are tagged but cannot allocate yet. The next checkpoint is the instance-owned aggregate store plus precise graph tracing; struct/array opcodes will only be enabled once that ownership path is failure-atomic.

9 days ago

Runtime progress pushed in four isolated mainline checkpoints:

  • a9eabd1: failure-atomic instance-owned aggregate headers/fields, stable identity, cyclic graph teardown
  • a1eaaef: struct/array construction, packed reads, mutation, length/fill, bounds traps
  • 89f83d5: data/element construction, initialization, and overlap-safe array.copy
  • f63444e: runtime tests/casts and br_on_cast/br_on_cast_fail refinement
  • c6611cd: quiescent mark/sweep for cyclic aggregate graphs with allocation-failure-no-sweep behavior

Focused production-root witnesses are green with zero leaks, including cycles, mutation, packing, segment operations, overlap, casts, traps, and exhaustive allocation failure.

The collector is intentionally not installed at arbitrary checkpoints yet. The next invariant is active-execution/external-wrapper root registration, so collection cannot race a parallel invocation or reclaim an aggregate returned across the host boundary.

9 days ago

Three precise-lifetime checkpoints are now on main:

  • 34dea125: stable external root handles for escaped aggregates, with a moving-collector rewrite boundary
  • b4933a84: type-erased, allocation-free traversal from host GC roots through cyclic Wasm aggregate graphs to nested JavaScript references
  • 7be5f42d: canonical exported GC-object wrappers, signed i31 conversion, exact wrapper finalization, and native sweep after host GC

The end-to-end JS API witness covers opaque/non-extensible/null-prototype exported objects, same-reference === round trips, distinct aggregate identity, live-wrapper retention, weak-wrapper reclamation, and zero leaks. The existing seven focused runtime tests and the 39-test Wasm API group remain green.

Still open before closing #299: table/global/exception/cross-instance identity paths, extern/any conversions, canonical type identity across linked modules, weak/moving rewrite stress, concurrent publication, and the requested deep/stress/TSan evidence.

9 days ago

Completed on main in small checkpoints through 0b87c6c.

Delivered:

  • runtime semantics for all 33 pinned GC instructions, including extern conversions;
  • structs, arrays, packed fields, bulk segment operations, casts, cast branches, i31, equality, and exact traps;
  • canonical recursive type identity across independently decoded modules;
  • stable opaque wrappers and future-moving-collector root handles across calls, tables, globals, exceptions, imports, exports, and cross-instance links;
  • precise host tracing and instance-owned mark/sweep for cycles, deep graphs, active frames, nested host values, weak wrappers, and exception payloads;
  • failure-atomic allocation and collection, exact wrapper finalization, and dead-graph reclamation.

Terminal focused evidence:

  • Wasm GC runtime: 10/10 passed, 0 failed, 0 skipped, 0 leaked;
  • WebAssembly API: 40/40 passed, 0 failed, 0 skipped, 0 leaked;
  • eight-way canonical wrapper publication: clean under ThreadSanitizer;
  • 4,096-node graph: iterative trace, precise retention, exact reclamation.

README and WebAssembly docs now carry the concise current status. Upstream corpus scoring remains deliberately separate in #300.

Sign in to comment on this issue.