Skip to content

fuse --memory shared --address-rebase rejects components with memory.grow (default wasip2 allocator) — blocks single-address-space MCU lowering (jess/gale Pixhawk) #299

Description

@avrabe

Surfaced by the issue-hunt (via gale#89), confirmed as a meld-local issue

meld fuse --memory shared --address-rebase (the single-address-space MCU lowering the jess/gale Pixhawk pipeline needs) fails:

unsupported component feature: memory.grow not supported with address rebasing

Both gale-app-demo and gale-kiln carry one memory.grow each — emitted by the default Rust / wit-bindgen wasip2 allocator. The multi-memory fallback isn't MCU-lowerable (2 memories × 1088 KB; synth loud-rejects). So the canonical dissolve meld fuse → loom → synth cannot currently produce the monolithic single-address-space core for the drone target. (gale#89 documents the gale-side view.)

This is correct fail-loud, not a bug — but it's a hard capability gap

meld's refusal is sound-by-construction (SR-37 + memory_probe.rs): MemoryStrategy::SharedMemory freezes the static memory layout at fuse time, so a runtime memory.grow would corrupt the shared single-address-space layout (merger Bug #7). The module_uses_memory_grow probe gates Auto→shared exactly on memory.grow absence, and a parse failure conservatively counts as "uses grow." So the gate must stay; this issue is about adding a sound path, not relaxing it.

Options (the actual work)

  1. Sound memory.grow lowering under address-rebasing (preferred): reserve a bounded static heap region per fused component and rewrite memory.grow → a bounded bump within that reservation, failing loud (trap / AbiError::Oom) on exhaustion. Preserves the frozen-layout soundness invariant AND accepts default-allocator components. Touches segments.rs (address-rebase), memory_probe.rs/MemoryStrategy, and the rebase math in rewriter.rs. Needs an ls_*-gated oracle + a Kani/▢ bound-check.
  2. Documented no-grow input contract + actionable diagnostic: make the error point to the remediation (build components no_std/no-grow, or pre-strip the allocator's grow when a static max is known) — the path gale#89 pursues on the gale side. Cheaper; pushes the requirement upstream.
  3. Allocator pre-pass: when a static heap max is declared, replace the wasip2 allocator's memory.grow with a pre-sized static reservation before fusion.

Cross-refs

  • gale#89 — gale-side dissolve constraints (components must be no_std/no-grow).
  • gale#63 — runtime hosting of the fused async components (Pixhawk 6X-RT).
  • meld#298 — drop vestigial cabi_realloc to unblock --memory shared (related, distinct blocker).
  • meld#172 (closed) — --memory multi default rejected by wasm-opt/synth.

Honest scope note

Option 2 is a same-day diagnostic+docs improvement that unblocks the pipeline if gale components go no-grow (gale#89). Option 1 is the general fix (any default-allocator component MCU-lowerable) and is the larger, oracle-gated piece. Recommend shipping Option 2's diagnostic now and scoping Option 1 as the real capability.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions