Skip to content

bugc: carry the call-site source range on the TCO back-edge JUMP#273

Merged
gnidan merged 1 commit into
mainfrom
compiler-tco-callsite-code
Jul 23, 2026
Merged

bugc: carry the call-site source range on the TCO back-edge JUMP#273
gnidan merged 1 commit into
mainfrom
compiler-tco-callsite-code

Conversation

@gnidan

@gnidan gnidan commented Jul 23, 2026

Copy link
Copy Markdown
Member

When tail-call optimization rewrites a tail-recursive call into a
back-edge JUMP, that JUMP carries a flat {return, invoke, transform: ["tailcall"]} context so a debugger still sees the recursive
call in the trace. Until now it mapped only to the callee declaration —
the call expression the user wrote had no instruction pointing back to
it.

This carries the call site's own code range on the back-edge JUMP,
composed flat alongside the invoke/return (disjoint keys). It completes
the call-site source-range story that #263 established for a real caller
JUMP ({invoke, code}) and its continuation JUMPDEST ({return, code}),
and #267 carried through inlining — now the tail-call case matches.

The call expression's range already lives on the original call
terminator's operationDebug; the TCO pass captures it onto the
TailCall IR object (mirroring the existing declarationLoc /
declarationSourceId fields), and codegen composes it into the JUMP's
context. Emission-only: no execution semantics change, and the range is
dropped cleanly when a function has no source location.

@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-07-23 22:16 UTC

@gnidan

gnidan commented Jul 23, 2026

Copy link
Copy Markdown
Member Author

Review notes from the format/pointers side:

  • Flat composition is correct here — the back-edge JUMP's context is built fresh in buildTailCallJumpOptions ({return, invoke} + code spread flat, transform appended). A runtime dump at level 3 confirms a single flat object with disjoint keys (return, invoke, code, transform), so flat is right and gather would be wrong per the spec's when-to-gather guidance.
  • The code shape matches what bugc: carry the call-site source range on invoke/return contexts #263 emits on the real-caller JUMP ({source: {id}, range}), and the emitted range is the recursive call expression itself, correctly distinct from the function's declaration range.
  • Compiled the tail-recursion example at levels 2 and 3 and validated the runtime program against schema:ethdebug/format/program — valid at both.
  • callSiteLoc/callSiteSourceId mirror the existing declarationLoc/declarationSourceId pattern, and missing call-site info degrades gracefully via guarded spreads. Since bugc never emits compilation, rebuilding the range from the loc pair is lossless in practice.

This completes the call-site story from #263/#267 for the tail-call case.

@gnidan
gnidan merged commit e2bf58a into main Jul 23, 2026
4 checks passed
@gnidan
gnidan deleted the compiler-tco-callsite-code branch July 23, 2026 22:12
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