Tracked under #106 (Epic ADR-0).
Background
Three wit-bindgen runtime fixtures fail with wasm unreachable after meld fusion: resource_floats, resource_with_lists, resource-import-and-export. Root cause: rustc/LLVM assume(ptr.is_aligned()) debug-assert fires when leaf code dereferences the rep as a Box<T> pointer when the rep is actually a small handle integer.
Convergent diagnosis from prototype paths D + E:
meld-core/src/merger.rs:739 redirected ALL [resource-*] imports of any re-exporter through one shared ht_* regardless of which resource the import was for
meld-core/src/adapter/fact.rs:582 did the same per-component lookup for borrow handling
Rekeyed HandleTableInfo from HashMap<usize, _> to HashMap<(usize, String, String), _>. Per-resource discrimination throughout: redirect logic uses [export] prefix + resource_graph.resource_definer to determine the owner of each [resource-*] import; consumer-side imports (without [export] prefix) fall back to ANY component's handle table for the matching (iface, resource_name); \$N dedup suffix is stripped before lookup.
Status:
- ✅ 73-test wit-bindgen suite: 0 regressions
- ✅ Resource handle routing is now correctly per-resource
- ✅ Original
& 7 align trap eliminated (leaf no longer derefs handle as Box)
- ❌ The trio still traps at runtime, but with a different error:
unknown handle index 0x110004
Remaining bug
The trap value 0x110004 = table_base_addr + ENTRY_SIZE — the first entry in meld's per-resource handle table memory. wasmtime's canonical-ABI rejects it as an unknown handle.
Hypothesis: in the wit-bindgen-rust pattern, intermediate's exports.float resource is built around a Box<Float { inner_handle: leaf_imports_handle }>. Path B routes intermediate's [resource-new] to ht_new(box_ptr) which returns 0x110004. But when intermediate's Float.add() returns a NEW Float, the cabi-export shim chains through both layers — the outer ht_new and the inner canonical resource.new for leaf — and somewhere a memory-address handle ends up where wasmtime expects a canonical handle.
This is structurally similar to the opaque-rep drop bug from path I (https://github.com/pulseengine/wit-bindgen/tree/feat/opaque-rep-attribute): when wit-bindgen-rust uses Box::new(InnerHandle { ... }) as the rep, the outer handle and inner handle live at different layers, and the canonical-ABI machinery only knows about one.
Reproducer
```bash
git checkout feat/issue-92-shim-module
cargo run --release --bin meld -- fuse tests/wit_bindgen/fixtures/resource_floats.wasm -o /tmp/floats.wasm --component
wasm-tools validate /tmp/floats.wasm # passes
wasmtime --invoke='run()' /tmp/floats.wasm
Error: unknown handle index 1114116 (= 0x110004)
```
Two paths forward
- Wrap the boundary — insert a memory-address ↔ canonical-handle translation shim in `component_wrap.rs` so the fused module's per-resource handle table values get unwrapped to canonical handles at every cross-boundary point. Estimated: 100-200 LOC, deeper investigation needed to find every leak.
- Pivot to opaque-rep upstream — extend pulseengine/wit-bindgen feat/opaque-rep-attribute to support methods (constructor-only works today). Once upstream, re-exporter components opt out of the boxed-rep pattern and meld's per-resource routing covers the rest. Estimated: ~50-100 LOC in wit-bindgen `bindgen.rs` + new fixture.
Related
- Commits: e027bb1, c104b1b
- Branch: feat/issue-92-shim-module
- wit-bindgen fork: pulseengine/wit-bindgen feat/opaque-rep-attribute (commit 236ef4bb)
Tracked under #106 (Epic ADR-0).
Background
Three wit-bindgen runtime fixtures fail with
wasm unreachableafter meld fusion:resource_floats,resource_with_lists,resource-import-and-export. Root cause: rustc/LLVMassume(ptr.is_aligned())debug-assert fires when leaf code dereferences the rep as aBox<T>pointer when the rep is actually a small handle integer.Convergent diagnosis from prototype paths D + E:
meld-core/src/merger.rs:739redirected ALL[resource-*]imports of any re-exporter through one sharedht_*regardless of which resource the import was formeld-core/src/adapter/fact.rs:582did the same per-component lookup for borrow handlingPath B (commits e027bb1 + c104b1b)
Rekeyed
HandleTableInfofromHashMap<usize, _>toHashMap<(usize, String, String), _>. Per-resource discrimination throughout: redirect logic uses[export]prefix + resource_graph.resource_definer to determine the owner of each[resource-*]import; consumer-side imports (without[export]prefix) fall back to ANY component's handle table for the matching(iface, resource_name);\$Ndedup suffix is stripped before lookup.Status:
& 7align trap eliminated (leaf no longer derefs handle as Box)unknown handle index 0x110004Remaining bug
The trap value
0x110004=table_base_addr + ENTRY_SIZE— the first entry in meld's per-resource handle table memory. wasmtime's canonical-ABI rejects it as an unknown handle.Hypothesis: in the wit-bindgen-rust pattern, intermediate's exports.float resource is built around a Box<Float { inner_handle: leaf_imports_handle }>. Path B routes intermediate's
[resource-new]toht_new(box_ptr)which returns 0x110004. But when intermediate'sFloat.add()returns a NEW Float, the cabi-export shim chains through both layers — the outer ht_new and the inner canonical resource.new for leaf — and somewhere a memory-address handle ends up where wasmtime expects a canonical handle.This is structurally similar to the opaque-rep drop bug from path I (https://github.com/pulseengine/wit-bindgen/tree/feat/opaque-rep-attribute): when wit-bindgen-rust uses
Box::new(InnerHandle { ... })as the rep, the outer handle and inner handle live at different layers, and the canonical-ABI machinery only knows about one.Reproducer
```bash
git checkout feat/issue-92-shim-module
cargo run --release --bin meld -- fuse tests/wit_bindgen/fixtures/resource_floats.wasm -o /tmp/floats.wasm --component
wasm-tools validate /tmp/floats.wasm # passes
wasmtime --invoke='run()' /tmp/floats.wasm
Error: unknown handle index 1114116 (= 0x110004)
```
Two paths forward
Related