WebAssembly GC
26.1 Why WasmGC?
Before GC, managed languages had to compile their own garbage collector into linear memory: big binaries, no cycle collection with JS objects, and slower startup.
WasmGC adds host-managed structs and arrays: the engine's GC collects them, and they can reference JS objects and vice versa.
26.2 GC Types and Instructions
any ⊃ eq ⊃ (i31, struct, array), func, extern, plus bottom types (none, nofunc, noextern)
struct.new, struct.new_default, struct.get(_s/_u), struct.set
array.new, array.new_fixed, array.new_data, array.get/set, array.len, array.fill, array.copy
Unboxed 31-bit integers (ref.i31, i31.get_s) ref.test, ref.cast, br_on_cast, br_on_cast_fail
(type $B (sub $A (struct ...))), final types, recursive type groups (rec ...)
any.convert_extern, extern.convert_any
(module
(type $Point (struct (field $x (mut f64)) (field $y (mut f64))))
(type $Points (array (mut (ref null $Point))))
(type $Bytes (array (mut i8)))
(func $make (export "makePoint") (param $x f64) (param $y f64) (result (ref $Point))
(struct.new $Point (local.get $x) (local.get $y)))
(func (export "length") (param $p (ref $Point)) (result f64)
(f64.sqrt
(f64.add
(f64.mul (struct.get $Point $x (local.get $p)) (struct.get $Point $x (local.get $p)))
(f64.mul (struct.get $Point $y (local.get $p)) (struct.get $Point $y (local.get $p))))))
(func (export "makeArray") (param $n i32) (result (ref $Points))
(array.new_default $Points (local.get $n)))
(func (export "castTest") (param $r anyref) (result i32)
(ref.test (ref $Point) (local.get $r))))26.3 Who Uses WasmGC
Kotlin/Wasm, Dart/Flutter web, Java (J2Wasm: Google Sheets), Scala.js, OCaml (wasm_of_ocaml), Scheme (Hoot), and more. It typically gives smaller downloads and faster startup than shipping a GC.
Supported in Chrome/Edge (119+), Firefox (120+), and Safari (18.2+), plus Wasmtime (newer versions) and Node.js.