Skip to content

bugc: mark a function's return on its exit jump - #349

Merged
gnidan merged 1 commit into
mainfrom
bugc-return-at-exit
Oct 7, 2026
Merged

gnidan merged 1 commit into
mainfrom
bugc-return-at-exit

Conversation

@gnidan

@gnidan gnidan commented Oct 7, 2026

Copy link
Copy Markdown
Member

bugc put a function's return context on the caller's continuation JUMPDEST, one instruction after the callee's JUMP back. Since instruction contexts are postconditions, and the trace viewer's buildCallStack popped a frame one step after the step that observes a return, the callee's frame stayed on the call stack for two steps after control was back in the caller. The entry side was already exact.

This moves the return to the callee's exit JUMP, where the format's documentation (the tracing guide and the return context spec page) already says it goes. After that JUMP runs, the return value is at stack slot 0, as it was after the continuation JUMPDEST, so data keeps the same pointer; it is left out when there is no value. The continuation JUMPDEST keeps only the call site's code range. buildCallStack now pops a frame on the step that observes the return, so a real call's frame is on from the callee's entry JUMPDEST through its exit JUMP and gone at the first step back in the caller.

A function with several return statements gets a return on each exit. Tail-call back-edges and inlined bodies keep their contexts as they were. A new test checks the timing against real traces at every optimization level, for nested calls, recursion and a function with two exits, and reads the return value through each exit's data pointer.

This aligns bugc with the documented placement and makes frame timing exact for real calls; the larger question of what each edge of a call should be marked with is #348. Known gaps that remain:

  • An inlined body of one instruction carries both its invoke and its return, so no step shows its frame. Before, the frame showed for one step, on the caller's next instruction.
  • At the first step back in the caller, the caller's local variables are not listed yet; they appear one step later, after the continuation JUMPDEST. The callee's exit cannot list them, since a function can have several callers.
  • An inlined body's frame still opens one step late, because its invoke is on the body's first instruction.

@gnidan
gnidan force-pushed the bugc-return-at-exit branch from 0346f89 to 5883000 Compare October 7, 2026 00:21
@github-actions

github-actions Bot commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-10-07 00:41 UTC

Put the return context on the callee's JUMP back to the caller, with
the return value at stack slot 0, and leave the continuation JUMPDEST
with only the call site's code range. buildCallStack now pops a frame
on the return's postcondition step instead of one step later.
@gnidan
gnidan force-pushed the bugc-return-at-exit branch from 5883000 to a42be64 Compare October 7, 2026 00:29
@gnidan
gnidan merged commit 8714233 into main Oct 7, 2026
7 checks passed
@gnidan
gnidan deleted the bugc-return-at-exit branch October 7, 2026 00:37
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