Skip to content

fix(soroban): support scalar-array returns and unsigned enum tag - #1983

Open
salaheldinsoliman wants to merge 2 commits into
mainfrom
fix/soroban-array-enum-abi
Open

fix(soroban): support scalar-array returns and unsigned enum tag#1983
salaheldinsoliman wants to merge 2 commits into
mainfrom
fix/soroban-array-enum-abi

Conversation

@salaheldinsoliman

Copy link
Copy Markdown
Contributor

Summary

Stacked on #1982 (requires the allocator element-size fix to be correct at runtime).

Two ABI fixes:

Scalar-array returns. encode_vector blitted the array's raw memory as if it already contained encoded Vals — only correct for SorobanHandle elements (decoded arguments passed straight through). A freshly built scalar array (uint64[]) returned garbage. It now encodes each element through soroban_encode_arg into a Val buffer inside a counted loop, registering the loop counter for phi insertion (new_dirty_tracker/set_phis) so it is not constant-folded into an infinite loop. The return-type gate is lifted only for scalar-element arrays; string/bytes/bytesN/struct element types stay rejected pending verified encodings (the unsupported_parameters testcase now asserts on bytes[]).

Enum returns. Enum discriminants were encoded with the signed I32 Val tag but decoded as Uint(32), failing with ConversionError. Encode with U32.

Tests

  • array_return: returning a fresh uint64[]; array-arg → array-return round trip.
  • other_custom_types: enum and struct-with-enum-field ABI round trips (toward the upstream other_custom_types example).

🤖 Generated with Claude Code

salaheldinsoliman and others added 2 commits July 26, 2026 21:38
Codegen lowers array allocation to vector_new with an element count and a
separate element size, but the Soroban branch dropped the element size and
soroban_alloc_init treated the count as a byte size. Multi-byte-element
dynamic arrays were under-allocated: a uint64[3] got a 3-byte payload, so
element stores overflowed into adjacent heap allocations and the elements'
high bytes were never zero-initialized.

Thread elem_size through soroban_alloc_init and size the payload as
members * elem_size, keeping len/size in element units. Regression tests
land with the scalar-array return support stacked on top of this change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: salaheldinsoliman <salaheldin_sameh@aucegypt.edu>
encode_vector blitted the array's raw memory as if it already contained
encoded Vals, which is only correct for SorobanHandle elements (decoded
arguments passed straight through). A freshly built scalar array returned
garbage once past the return-type gate. Encode each element through
soroban_encode_arg into a Val buffer inside a counted loop, registering the
loop counter for phi insertion so it is not folded to a constant.

Lift the return-type gate for scalar-element arrays only; string, bytes/
bytesN, and struct element types stay rejected pending verified encodings
(the unsupported_parameters testcase now uses bytes[] for that assertion).

Enum discriminants were encoded with the signed I32 Val tag but decoded as
Uint(32), so enum returns failed with ConversionError; encode with U32.

Tests: array_return (fresh uint64[] return + arg/return round trip) and
other_custom_types (enum and struct-with-enum-field ABI round trips).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: salaheldinsoliman <salaheldin_sameh@aucegypt.edu>
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