[3/3] feat(fpi): support payload-carrying variants in typed FPI signatures - #1241
Open
greenhat wants to merge 6 commits into
Open
[3/3] feat(fpi): support payload-carrying variants in typed FPI signatures#1241greenhat wants to merge 6 commits into
greenhat wants to merge 6 commits into
Conversation
greenhat
force-pushed
the
i1177-payload-enum-fpi
branch
from
July 6, 2026 07:24
60e737e to
7ea6654
Compare
greenhat
force-pushed
the
i1177-payload-enum-fpi
branch
from
July 6, 2026 09:09
7d7479d to
c01aca1
Compare
greenhat
marked this pull request as ready for review
July 6, 2026 10:00
greenhat
force-pushed
the
fix-spill-prunning
branch
from
July 7, 2026 05:04
5e58631 to
c3e2aa6
Compare
greenhat
force-pushed
the
i1177-payload-enum-fpi
branch
from
July 7, 2026 05:36
9b047b0 to
a9ed032
Compare
greenhat
force-pushed
the
fix-spill-prunning
branch
from
July 10, 2026 09:37
c3e2aa6 to
8eefc18
Compare
greenhat
force-pushed
the
i1177-payload-enum-fpi
branch
from
July 10, 2026 11:01
a9ed032 to
1daa909
Compare
greenhat
force-pushed
the
fix-spill-prunning
branch
from
August 3, 2026 07:02
8eefc18 to
f8571df
Compare
Canonical ABI lowering has supported WIT variant/option/result end to end since #111, but typed FPI rejected payload-carrying enums in two independent places, so a foreign procedure could not take or return an option, result, or payload variant even though the same signature worked on a regular component boundary. Lift both gates and validate at the boundary instead: validate_fpi_value_type now recurses into variant case payloads (pointer-like payloads are still rejected with a precise location), direct arguments and decoded results get discriminant validation mirroring the direct and transformed component wrappers, and indirect arguments are reloaded through the canonical ABI load walk, which switches on the runtime discriminant to load the active case and traps on out-of-range values. The static layout helpers (flat_tuple_layout, canonical_flat_layout) and the NonCLikeEnum error are removed: payload variants have no static flat layout, and the load walk is now the single source of truth on that path. Mockchain FPI coverage exercises option<felt>, result<felt, u64>, and a mixed-width (u64 + felt) variant round-tripping with transformed payloads in the direct shape, a variant loaded from the argument tuple past the sixteen-value threshold, and an account-to-account variant call. Closes #1177
The FPI planner validated only arity and pointer placement of the core import, so a malformed `fpi-*` import with matching arity but wrong scalar widths could reach felt conversion and be misinterpreted. Build the expected core signature from the canonical lowered one, with canonical pointer parameters as core `i32`, and check equivalence, mirroring the non-FPI lowering paths. Also reject canonical layout offsets that do not fit `i32` in `offset_addr` instead of wrapping, and extend mockchain coverage: the tupled-argument fixture carries a mixed-width (u64 + felt) payload variant with a non-zero high limb over the argument tuple, and the account-to-account fixture asserts both u64 limbs of the bumped value.
Typed FPI validation ran inside the FPI lowering generator, after the import signature had already gone through canonical flattening. Unsupported types therefore failed with flattening errors first: `u128`/`u256` hit the `unimplemented!` in `flatten_type` and panicked, and pointer-like payloads (which convert to `unknown` before enum construction) surfaced as a generic "requires flattening" failure instead of the typed FPI diagnostic with its per-case location. Run `validate_fpi_typed_signature` immediately after FPI import detection, keyed by the import path rather than the generated core path, and turn the `flatten_type` `unimplemented!` for wide integers into a normal unsupported-type error. Generate-level regressions cover a `u256` result (previously a panic) and a pointer payload inside an enum (previously the generic flattening error).
The pointer-to-`i32` expected-core-signature mapping existed twice: in `plan_fpi_call` and in a byte-identical test helper, so the tests matched production by construction rather than by intent, and the two copies disagreed (inertly) on which calling convention to carry. Move the mapping into `expected_core_signature` next to `check_core_wasm_signature_equivalence`, use it from both, and document that the carried calling convention is not compared by the equivalence check.
…t path The transformed import lowering still built its expected core signature by replacing the last parameter with `i32` by hand — the mapping that `expected_core_signature` was introduced to share. On this path the two forms are equivalent: parameter tuples and lists are rejected earlier, so the result out-pointer is the only pointer parameter, and import-mode flattening already leaves the result list empty.
Deleting the static-layout helpers also deleted the only unit-level pin that a `u64` record field following a `u8` field lands at offset 8; that behavior now lives in `canonical_abi_info`/`next_field32` shared by the canonical load/store walks, and no FPI integration fixture crosses a padded 8-byte-aligned struct field. Pin the field offsets and the record's size and alignment directly. Also deduplicate the pointer-payload enum fixture into `test_support` and drop the always-2 `expected_imports` parameter from the world-import injection test helper.
greenhat
force-pushed
the
i1177-payload-enum-fpi
branch
from
August 3, 2026 07:55
1daa909 to
fb4f39c
Compare
Contributor
Author
|
Rebased(ported) and ready. |
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.
Close #1177
This PR is stacked on #1250 and should be merged after it.
Canonical ABI lowering has supported WIT variant/option/result end to end since #111, but typed FPI rejected payload-carrying enums in two independent places, so a foreign procedure could not take or return an option, result, or payload variant even though the same signature worked on a regular component boundary.