Skip to content

feat: pack compose — static composition into one self-contained .wasm#39

Merged
colinrozzi merged 1 commit into
mainfrom
pack-compose
Jul 13, 2026
Merged

feat: pack compose — static composition into one self-contained .wasm#39
colinrozzi merged 1 commit into
mainfrom
pack-compose

Conversation

@colinrozzi

Copy link
Copy Markdown
Owner

What

packr compose <manifest.toml> — statically composes compiled packages (allocator + providers + consumers) into a single self-contained .wasm with zero imports that runs on any stock runtime. Cross-package imports become direct internal calls; wasm-tools validate clean.

Proven end-to-end: adder.process(5) == 11 calling doubler.double internally, on a bare wasmtime with no harness (tests/compose.rs).

How

Pipeline (src/compose/static_compose.rs):

  1. binaryen wasm-merge fuses the modules + internalizes cross-imports (math.double → doubler, pack:alloc → the merged-in allocator). Each package is named by the import module-name its consumers use.
  2. A walrus pass unifies the several env.memory imports into one internal memory, bakes the allocator's __memory_base/__heap_base/__heap_end into constants, and exports the memory.

Requires wasm-merge (binaryen) — added to the flake dev shell.

Cleanup

Rips two superseded composers this replaces (net −2350 lines):

  • compose::StaticComposer — Apr-27 bump-allocator merger, wrong model since the 0.8.0 allocator decoupling.
  • runtime::CompositionBuilder — pre-PIC runtime composer, red since the PIC migration.

Both superseded by PicCompositionBuilder (runtime, #38) + pack compose (static). ParsedModule (used by inspect) is kept.

Note

Packaging win, not performance. The merge internalizes the call, but the packr ABI marshalling is fossilized into the compiled packages, so it stays. A by-reference shared-memory ABI would be the separate perf lever.

Test / CI

  • tests/compose.rs — full pipeline + bare-run assert (skips cleanly if binaryen absent).
  • Full suite green; clippy (CI scope) clean; fmt clean.
  • No ABI change, no fleet impact — additive, pack-internal.

🤖 Generated with Claude Code

…tained .wasm

`packr compose <manifest.toml>` merges compiled packages (allocator + providers
+ consumers) into a single ZERO-IMPORT .wasm that runs on any stock runtime, with
cross-package imports internalized to direct calls (validates under wasm-tools).

Pipeline: binaryen `wasm-merge` fuses modules + wires cross-imports; a `walrus`
pass unifies the several env.memory imports into one internal memory, bakes the
allocator's __memory_base/__heap_base/__heap_end into constants, and exports the
memory. Requires wasm-merge (binaryen), added to the dev shell.

Rips two superseded composers this replaces:
- compose::StaticComposer (bump-allocator merger, wrong model since 0.8.0)
- runtime::CompositionBuilder (pre-PIC runtime composer, red since PIC migration)
both superseded by PicCompositionBuilder (runtime) + pack compose (static).

Packaging win, not perf: the ABI marshalling stays fossilized in the packages.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@colinrozzi colinrozzi enabled auto-merge (squash) July 13, 2026 02:57
@colinrozzi colinrozzi merged commit 7aee144 into main Jul 13, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant