Skip to content

[3/3] feat(fpi): support payload-carrying variants in typed FPI signatures - #1241

Open
greenhat wants to merge 6 commits into
fix-spill-prunningfrom
i1177-payload-enum-fpi
Open

[3/3] feat(fpi): support payload-carrying variants in typed FPI signatures#1241
greenhat wants to merge 6 commits into
fix-spill-prunningfrom
i1177-payload-enum-fpi

Conversation

@greenhat

@greenhat greenhat commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

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.

@greenhat
greenhat force-pushed the i1177-payload-enum-fpi branch from 60e737e to 7ea6654 Compare July 6, 2026 07:24
@greenhat
greenhat changed the base branch from next to fix-spill-prunning July 6, 2026 07:25
@greenhat greenhat changed the title feat(fpi): support payload-carrying variants in typed FPI signatures [3/3] feat(fpi): support payload-carrying variants in typed FPI signatures Jul 6, 2026
@greenhat
greenhat force-pushed the i1177-payload-enum-fpi branch from 7d7479d to c01aca1 Compare July 6, 2026 09:09
@greenhat
greenhat marked this pull request as ready for review July 6, 2026 10:00
@greenhat
greenhat requested a review from bitwalker July 6, 2026 10:00
@greenhat
greenhat force-pushed the fix-spill-prunning branch from 5e58631 to c3e2aa6 Compare July 7, 2026 05:04
@greenhat
greenhat force-pushed the i1177-payload-enum-fpi branch from 9b047b0 to a9ed032 Compare July 7, 2026 05:36
@greenhat
greenhat force-pushed the fix-spill-prunning branch from c3e2aa6 to 8eefc18 Compare July 10, 2026 09:37
@greenhat
greenhat force-pushed the i1177-payload-enum-fpi branch from a9ed032 to 1daa909 Compare July 10, 2026 11:01
@greenhat
greenhat force-pushed the fix-spill-prunning branch from 8eefc18 to f8571df Compare August 3, 2026 07:02
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
greenhat force-pushed the i1177-payload-enum-fpi branch from 1daa909 to fb4f39c Compare August 3, 2026 07:55
@greenhat

greenhat commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

Rebased(ported) and ready.

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.

Support payload-carrying variants (WIT variant/option/result) in FPI signatures

1 participant