Skip to content

programs-react: fix call stack for the flat tail-call back-edge#248

Merged
gnidan merged 1 commit into
mainfrom
ui-tco-callstack-fix
Jul 11, 2026
Merged

programs-react: fix call stack for the flat tail-call back-edge#248
gnidan merged 1 commit into
mainfrom
ui-tco-callstack-fix

Conversation

@gnidan

@gnidan gnidan commented Jul 11, 2026

Copy link
Copy Markdown
Member

A tail-call-optimized back-edge is emitted as a single instruction
whose context carries both a return (the iteration that is ending)
and an invoke (the iteration that is beginning). buildCallStack
had no case for this combined shape — it acted on whichever
discriminant it read first, so a tail-recursive loop either pushed a
fresh frame every iteration (stack grows without bound) or popped the
frame away (stack collapses to empty). Neither reflects what actually
happens: the activation is reused, so depth should stay constant.

This detects the combined shape structurally — a context carrying both
an invoke and a return — and reuses the top frame in place, taking the
next iteration's identity from the invoke leaf. Recognizes both the
flat multi-discriminator context and a gather-wrapped one.

Unit coverage added for the back-edge (constant depth, reused
identity) plus a regression check that ordinary calls still push and
pop.

The compiler emits a tail-call-optimized back-edge as a single
instruction carrying both a `return` (the iteration that is ending)
and an `invoke` (the iteration that is beginning) on one context.
`buildCallStack` had no case for this: it read whichever discriminant
it encountered first and either pushed a second frame (invoke) or
popped the frame away (return), so a tail-recursive loop's call stack
grew without bound or collapsed to empty instead of staying at
constant depth.

Detect the combined shape structurally — an instruction whose context
carries both an invoke and a return — and reuse the top frame in
place, taking the next iteration's identity from the invoke leaf.
Depth is unchanged, which is what a reused activation should show.

Adds unit coverage for the flat back-edge (constant depth, reused
identity) alongside a regression check that ordinary calls still push
and pop.
@github-actions

github-actions Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-07-11 01:31 UTC

@gnidan gnidan merged commit 1bd32a1 into main Jul 11, 2026
4 checks passed
@gnidan gnidan deleted the ui-tco-callstack-fix branch July 11, 2026 01:26
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