feat: PIC package composition (level 2) — N packages, one memory, CompositionBuilder API#38
Merged
Merged
Conversation
…positionBuilder API
Package A imports and calls package B while SHARING one linear memory (per
docs/pic-composition.md level 2), on the 0.8.x PIC loader. Unlike the level-1
CompositionBuilder (separate memories, cross-memory byte-copy bridge), a
consumer's import is wired to a provider's export in the SAME memory — no copy.
- src/runtime/pic_composition.rs: PicCompositionBuilder / PicComposition. build()
topologically instantiates each PIC package at a disjoint __memory_base + stack
+ table_base in one shared Memory on one shared in-wasm allocator; wires each
cross-package import via a thin shim that calls the provider's export in-memory
and re-labels the ABI status (0→1) so the consumer's __import_impl FREES the
provider's result buffer. call() also frees its own buffers — no per-call leak.
- packages/{doubler-pic,adder-pic}: PIC builds (originals stay non-PIC for the
level-1 tests); adder imports math.double + math.big from doubler.
- tests/pic_composition.rs:
- pic_composition_builder_adder_calls_doubler — adder.process(5)=11 etc via the
real PicCompositionBuilder API.
- pic_composition_cross_package_returns_do_not_leak — 40 large (~256KiB) cross-
package returns through the 4MiB shared heap; a leak would exhaust it in ~15.
- pic_two_package_composition_adder_calls_doubler — the hand-rolled loader proof.
Follow-up (level 3): static-merge the proven PIC side modules into one .wasm.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
56b7917 to
edfbcba
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PIC package composition (level 2) — N packages, one memory,
CompositionBuilderAPIPackage A imports and calls package B while sharing one linear memory (the level-2 spec, #37), on the 0.8.x PIC loader. Unlike the level-1
CompositionBuilder(separate memories, a cross-memory byte-copy bridge), a consumer's import is wired to a provider's export in the same memory — no copy.The API
How
src/runtime/pic_composition.rs:build()topologically instantiates each PIC package at a disjoint__memory_base+ stack + table_base in one sharedMemory, on one shared in-wasm allocator. Each cross-package import is wired via a thin shim that calls the provider's export in-memory and re-labels the ABI status (0→1) so the consumer's__import_implfrees the provider's result buffer (same shared allocator).call()frees its own buffers — no per-call leak.packages/{doubler-pic,adder-pic}: PIC builds (originals stay non-PIC for the level-1 tests).Tests
adder.process(5)=11(and more) via the realPicCompositionBuilder.pic_composition 16/16; full workspace green; clippy + fmt clean; CI builds the two new fixtures.
Follow-up (level 3): static-merge the (now proven) PIC side modules into one passable
.wasm.🤖 Generated with Claude Code