Repository navigation
Return aggregates from extern functions through an output pointer - #75
Merged
Merged
Conversation
An extern that returns a tuple, struct, array, enum or f32x4 now receives
a trailing output pointer and returns void, so a host can hand back
compound results without a platform-specific struct-return ABI:
extern fn host_pair(x: i32) -> (i32, i32)
void host_pair(void* ctx, int32_t x, int32_t* out)
The rule lives in one place, TypeID::extern_returns_via_pointer, and every
backend consults it, so the same host function works on the Cranelift,
LLVM, VM and stack backends. f32x4 goes through the pointer too (four
floats) rather than a vector return register, which libffi cannot marshal
and which differs across platforms; Cranelift and LLVM reload the vector
after the call.
The checker rejects extern return types no backend can marshal (function
types, i8/u8/u32) with a message listing the supported set. The output
slot is 16-byte aligned on Cranelift and LLVM, since the host stores
through it as int32_t*/float*/double*. VM codegen checks the libffi
argument budget at compile time instead of panicking on the first call.
Tests run the same program and host function on every enabled backend for
tuple, struct, array, enum and f32x4 results, plus a golden test for the
checker error.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The VM's libffi path handles bool, i32, f32, f64, slices and references and panics in codegen on anything else, while the JIT silently passed a struct or f32x4 parameter as a pointer. Check the parameter types in the type checker so the same program is accepted or rejected everywhere, and document the supported set in lyte.h. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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.
Summary
An extern that returns a tuple, struct, array, enum or
f32x4now receives a trailing output pointer and returns void:TypeID::extern_returns_via_pointerinsrc/types.rsis the single definition; Cranelift, LLVM, VM and stack codegen all use it. Previously each backend had its own predicate and they had already drifted (f32x4was by-value on Cranelift/LLVM and by-pointer on VM/stack, so no one host function worked everywhere).f32x4goes through the pointer as four floats on all backends. Vector return registers are not portable and libffi cannot marshal them. Cranelift and LLVM reload the vector after the call.i8/u8/u32) and parameter types outside bool, i32, f32, f64, slices and references are rejected at check time with a message listing the supported set. Previously a struct orf32x4parameter compiled on the JIT but panicked in VM codegen.int32_t*/float*/double*.lyte.hdocuments the rule, including supported parameter types, enums (int32_t* out) andf32x4(float* out).Tests
compiler.rs: one shared runner per backend andassert_extern_all_backends; tuple, struct, array, enum andf32x4each run the identical program and host function on VM, stack, Cranelift and LLVM.tests/cases/checker/extern_fn_ret_type.lyteandextern_fn_param_type.lytefor the checker errors;tests/cases/extern_tuple_ret.lytecovers all five by-pointer kinds in check mode.cargo test --workspacepasses with default features, andcargo test -p lyte -p lyte-cli --features llvmpasses against LLVM 19.1.7.🤖 Generated with Claude Code