ADR-005 — Object layout via WasmGC struct types (closed-world)

Status: Accepted Date: 2026-04-27

This ADR is a sub-decision of ADR-001 — it concerns the static specialization path for JS objects.

Context

JavaScript objects are open: any property key may be added, deleted, or replaced at runtime, including with values of unrelated types. A naïve representation handles this by storing every object as a hash map of string keys to boxed values. Property access is then a hash lookup at every site, even when the program never adds or removes properties from a given object.

In practice, the great majority of JS objects encountered in real code have a stable set of property names that is determined by their constructor or literal site. Class instances, factory functions returning literals, and records produced by JSON parsers all fall in this category. The closed-world analysis from ADR-001 can determine this set statically within a compilation unit, by examining all read and write sites that reach the allocation.

Decision

Compile JS objects to typed WasmGC structs when the closed-world analysis proves the property set is statically known. Each distinct shape becomes a declared struct type in the Wasm type section. Property reads lower to struct.get; property writes lower to struct.set.

When the analysis cannot prove a stable shape (dynamic indexing, unrestricted assignment, reflective access), the object falls back to a map-backed representation reachable through externref, with all property operations going through the slow path.

Consequences

Positive: property access on stably shaped objects is a single typed Wasm instruction rather than a hash lookup. Class instantiation is allocation of a typed struct, not a map. Field types are unboxed where the analysis proved the type (f64 for numeric fields, i32 for booleans, struct refs for nested objects). Memory layout is decided once, at compile time, and is visible in the type section.

Negative: shapes that the analysis cannot prove fall back to the slow path, with no graceful in-between. Adding a previously-unanalyzed dynamic write site can cause an entire shape to deoptimize to the boxed representation. Hot polymorphic dispatch across many shapes is not specialized further than the analysis can prove statically.

Alternatives rejected