Memory management / Runtime and backend memory lowering

Backends may choose different allocation and GC representations. They may not choose different language semantics.

Runtime and backend memory lowering

Design contract

Backends may choose different allocation, GC, handle and ownership representations. They may not choose different language semantics.

Every backend must preserve shared read-only access, exclusive mutation, explicit copy behaviour, optional transfer safety, lifetime-topology legality, reactive liveness and GC-equivalent observable results.

GC is a permitted runtime representation for a statically legal lifetime topology. It is not a mechanism for accepting invalid retained edges, lateral lifetime promotion, unowned escapes or cross-region cycles.

Main backend paths

Backend-neutral semantics

GC baseline

GC can be host GC, Wasm GC, a runtime collector or another backend strategy. Exact current target support belongs in the progress matrix.

Internal RC, arenas, handles, regions, stack storage, pools and hybrid representations are permitted for valid topology. Source-visible RC and hidden unrestricted dynamic sharing are not permitted.

Debug and development configurations

Debug and development configurations may deliberately retain the GC baseline even where ownership-aware lowering is available.

Unless a configuration is specifically intended to exercise ownership behaviour, debuggability, instrumentation and predictable runtime behaviour take priority over deterministic-destruction optimisation.

Release configurations may still fall back to GC per value whenever ownership proof is unavailable. Profiles differ only in optimisation effort and physical representation, never in source legality.

Build-owned target and lifecycle planning

The build system owns reachability, target partition, page/request/mount/frame roots and page runtime topology. Backends consume explicit plans rather than selecting them.

See docs/build-system-design.md for project and link orchestration.

Moth-linked page memory and imported components

Each page may own one runtime and memory shared by its linked Moth Wasm variants. Imported WIT components are separate runtimes with component-private memory and communicate only through the closed value boundary. This is build architecture, not source memory semantics. The one-page/one-memory rule applies to Moth-linked Wasm variants, not arbitrary imported components. Imported components are not members of Moth page memory or the Moth lifetime graph and do not need to declare a GC strategy to Moth.

WIT value-only V1 profile

Moth imports general external Wasm libraries as WIT-described Wasm Components. The V1 component boundary is value-only. Every supported argument is lowered from a shared read of a Moth value into an independent component value, and every result is lifted into an independent Moth result graph. No Moth alias, lifetime owner, ownership state, or destruction responsibility crosses the component boundary.

The component may use any private allocation or garbage-collection strategy. That strategy is not part of the Moth binding contract and does not require a GC declaration.

Fixed facts

| Fact | WIT value-only V1 | |---|---| | Parameter source access | Shared read | | Boundary crossing | Independent semantic value | | Retained Moth reference | Never | | Result provenance | Independent result graph | | Result aliases an argument | Never | | Source call consumes argument | Never | | Destruction responsibility crosses | Never | | External lifetime owner | Component-private | | Cross-runtime allocation cycle | Impossible by contract |

Supported V1 WIT value families

Rejected V1 WIT surfaces

Unsupported interfaces must receive structured import diagnostics identifying:

Required importer metadata

The importer requires:

The boundary classification generates the fixed memory facts. The importer must not infer them from a generic Fresh result marker, and binding authors must not restate them per function. No uses_gc field is required.

Restricted host-binding profile

Existing Core, Builder, JavaScript-provider and curated platform bindings use a restricted host-binding profile.

Restricted host-binding V1 permits mutable access only to opaque foreign handles. Ordinary Moth values cross by value as non-retained inputs. A host operation that conceptually changes ordinary Moth data returns a fresh or independent result instead of mutating Moth storage through the boundary.

Deferred resource-capable profiles

A future resource-capable profile requires a separate complete design for identity, transfer, teardown, callbacks, async suspension, reentrancy, cycles and failures. It is not part of V1.

JavaScript lowering

Wasm lowering

src/backends/wasm/hir_to_lir/ownership.rs is the ownership projection seam, and Wasm LIR includes conditional DropIfOwned plus reserved retain support.

Runtime ownership metadata

Drop and retain behaviour

Fact consumption

Backends may consume:

Backends must not:

Reactive and mounted-fragment liveness

Live reactive subscriptions and mounted fragments can keep state observable. Ownership-aware lowering must not free a source or template instance while it remains observable. GC reachability is the semantic reference behaviour for already-legal topology. Finer invalidation granularity may improve performance but not lifetime semantics. Runtime fragment and reactive mount behaviour remain separate concerns.

Backend specialisation

Allowed optimisations include:

Requirements:

Fallback requirements

When a backend can't prove or implement an ownership optimisation safely, it must retain GC-managed behaviour for that value or feature on already-legal topology.

A missing optimisation is valid. A semantic divergence isn't. Unknown external retention is not a GC fallback.

What backends must not do

Common mistakes

Related reading