Bridge f32/f64 across closure calls on the stack backend - #43
Merged
Conversation
f32/f64 return values come back through t0 (the int window) and must be moved into the float/double window. The direct-call path did this with BitsToFF/BitsToDD, but both CallClosure sites only handled the Void placeholder case, so the next float-window op ran on an empty window and produced a garbage result (the f-window balance check flagged it too). Factor the fixup into bridge_call_result and use it at both sites. Fixes #40. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The mirror image of the return-value bug: op_call_closure copies args out of the int TOS window, so f32/f64 arguments that rode through the float window need FToBitsF/DToBitsD first. The direct-call path did this; both CallClosure sites pushed args with a bare translate_expr, so a non-literal float argument reached the callee as garbage. Factor arg pushing into push_closure_args and extend the golden test. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Aug 26, 2026
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.
Fixes #40.
Problem
On the
stackbackend, closure calls mishandledf32/f64in both directions.jit,vm, andasmwere correct.The interpreter passes floats through the int window across a call boundary:
op_call/op_call_closurecopy arguments out of the int TOS window, and return values come back throught0. The direct-call path bridges both ends (FToBitsF/DToBitsDgoing in,BitsToFF/BitsToDDcoming out). BothCallClosuresites did neither — they only pushed a placeholder for theVoidcase.Returns (the reported bug in #40) — the next float-window op ran on an empty window, which the compiler's own balance check flagged as
apply: f-window underflow at op 3 (FToBitsF): in=0 delta=-1:Arguments (found in review, second commit) — the mirror image. A non-literal float argument reached the callee as garbage; a literal happened to work, which is why it hid:
Fix
Two helpers now own the
CallClosureABI, used by both call sites:push_closure_args— bridgesf32/f64args into the int window before the call.bridge_call_result— pushes theVoidplaceholder, or bridges anf32/f64return back into the float/double window.Test
tests/cases/lambdas/lambda_float_return.lytecovers f32 and f64 returns from a closure passed to a higher-order function, a call through a local variable holding a closure, and f32/f64 arguments passed non-literally. Golden tests run once per backend, so all of this is checked on jit/vm/asm/stack.cargo test --workspaceis green (358 lib + 4 golden + 21 lsp).Out of scope
Two adjacent pre-existing bugs found during review, filed separately rather than expanded into this PR:
stackand panic onvm; theCallClosuresites also never grew theReference/Sliceparameter coercion the direct-call path has.CallClosuresite: there's currently no working way to reach the indirect-expression site with a float-returning closure.🤖 Generated with Claude Code