Skip to main content

Module arena_bind

Module arena_bind 

Source
Expand description

#418 — bind the passed-through embedder import env::__cabi_arena_realloc to a synthesized in-module arena allocator, unlocking the fully SELF-CONTAINED dissolve.

§The seam this closes

The BYO-OS lean-MCU dissolve (gale#89) builds grow-free components with the wit-bindgen cabi-realloc-extern feature: cabi_realloc stays exported but its body routes to an embedder-provided env::__cabi_arena_realloc import. On the --relocatable host-link path that import is DELIBERATELY left as an undefined symbol the TCB’s native allocator satisfies at link (#420 locks that layering — nothing here changes it). But on the default SELF-CONTAINED path the same import previously degraded the compile to an ET_REL “link me with the Kiln bridge” object: the one unresolved seam blocking a fully self-contained image.

§The binding (a wasm→wasm rewrite, not new codegen)

When the arena import is the module’s ONLY import, replace it with a DEFINED WebAssembly function implementing the #418 contract, compiled through synth’s ordinary pipeline like any other module function:

  • signature (old_ptr, old_len, align, new_len) -> ptr (i32×4 → i32);
  • old_len == 0 && new_len == 0 → return align verbatim;
  • bump allocation from a fresh mutable cursor global (appended at the end of the global index space), aligned up per call;
  • realloc preserves min(old_len, new_len) bytes (byte-copy loop);
  • BOUNDED arena [arena_base, arena_end) — exhaustion (or a zero / non-power-of-two-shaped align wrap) executes unreachable, i.e. traps, and NEVER calls memory.grow.

arena_base mirrors the shipped used-extent rule (main.rs #237/#354): max(data_end, every i32-const global init ≤ linmem) — the latter covers both the __stack_pointer class and wasm-ld’s __data_end/__heap_base layout globals — rounded up to 16 (floor 16 so the allocator never returns a null-looking pointer). arena_end = the initial linear-memory size (grow-free modules never extend it).

§Why the rewrite is index-preserving

The wasm function index space is imports-first. Removing the SOLE function import and prepending the allocator as the FIRST defined function gives it the import’s old index — every call, ref.func, export, and element entry keeps its meaning without any remapping. Untouched sections are copied byte-for-byte; only import (dropped), function/code (one entry prepended) and global (one entry appended) change.

Structs§

BoundArena
A successful #418 binding.

Enums§

ArenaBind
Outcome of bind_cabi_arena_realloc.

Constants§

ARENA_IMPORT_FIELD
ARENA_IMPORT_MODULE
The core-module field name of the embedder arena import (#418). The kebab cabi-arena-realloc is component-surface only and never reaches synth.

Functions§

bind_cabi_arena_realloc
Bind a sole env::__cabi_arena_realloc function import to a synthesized in-module arena allocator (#418). See the module docs for the contract.