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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions