Expand description
Box / unbox helpers — the unified mechanism for moving values
between language types and the universal (ref $Object) slot
type used by arrays, unknown, and erased generics.
Functions§
- emit_
box - Emit Wasm instructions that wrap the value currently on top of
the stack (of language type
ty) into a(ref $Object). - emit_
cast_ to - Emit Wasm instructions that pop a
(ref null $Object)from the stack and produce aty-typed value. - emit_
coerce_ to_ return_ slot - Coerce the returned value on top of the stack (static type
source_ty) into the enclosing body’sReturnTarget. - emit_
coerce_ to_ slot - Coerce a
source_ty-typed value into the Wasm slot type fortarget_ty. Boxes primitives (f64/i32 → ref); WasmGC subtyping handles ref→ref cases. - emit_
coerce_ to_ wasm_ slot - Coerce a
source_ty-typed value into an already-known Wasm slot type. - emit_
condition_ to_ i32 - Consume the condition value (static type
cond_ty) on the stack and leave an i32 where nonzero = truthy, per JS semantics:null,"",0,-0,NaN,false, and0nare falsy; everything else is truthy. - emit_
narrowing_ cast - Emit the Wasm cast from
cast_info.from_tytocast_info.to_ty. The cast is unchecked — codegen trusts the typechecker’s narrowing decision; the Wasm-level cast traps if the predicate’s runtime check was unsound. - emit_
nominal_ instance_ test - Emit the nominal class-membership test for the value on top of the stack
(any
(ref null $Object)-compatible ref), leaving an i32 (0/1): walk the value’s vtable parent chain, comparing each link byref.eqagainst the target class’s vtable-singleton global. Value identity, notref.test— same-shape sibling classes canonicalize to one WasmGC type, so shape can’t carryinstanceof. Non-class values (strings, boxed primitives, structural objects, closures) exit false at the$ClassVTabletest — their vtables are plain$VTablesubtypes. - emit_
unerase - Recover
ty’s value type from a slot that stores it erased — a box cell’s payload, keyed onslot_value_type. - target_
allows_ null - Whether
emit_cast_tolets anullreach the target rather than lifting to non-null first. True for the targets whose lowering is a nullable(ref null $Object): bareNull, nullable unions, and the no-op erased/dynamic types —unknown,never, an erased generic (which can hold null after instantiation, e.g.T = string | null), and a recursion back-edge whose body may listnull.emit_cast_to’sUnionarm usesRefCastNullablefor the same reason. A union’s nullability is its lowering, not whether a member is spellednull:T | numberlowers nullable becauseTdoes.