Skip to content

web/programs-react: reconstruct inline virtual activations in the tracer#234

Merged
gnidan merged 1 commit into
transform-contextfrom
ui-inline-activation
Jul 3, 2026
Merged

web/programs-react: reconstruct inline virtual activations in the tracer#234
gnidan merged 1 commit into
transform-contextfrom
ui-inline-activation

Conversation

@gnidan

@gnidan gnidan commented Jul 3, 2026

Copy link
Copy Markdown
Member

Fixes the tracer's rendering of inlined internal calls (the level-2 `inline` transform from #230). Part of #23 (UI side). Targets `transform-context`.

Problem

An inlined body's instructions each carry a call context bearing both `invoke` and `return`. `extractCallInfoFromContext` checks `invoke` before `return`, so every inlined instruction read as an invoke and `buildCallStack` pushed a virtual frame per inline site but never popped — phantom `dbl > dbl` frames accumulated and leaked to the end of the trace, indistinguishable from real calls.

Change (programs-react)

  • `CallInfo`/`CallFrame`: add `isInline` (virtual-activation tag).
  • `extractCallInfoFromInstruction`: set `isInline` from the `inline` transform marker (alongside the existing `isTailCall`).
  • `buildCallStack`: tag virtual frames, and add a defensive per-instruction membership guard — once execution reaches an instruction lacking the `inline` marker, any trailing virtual frame is torn down, so a virtual activation can never leak into caller code.

Change (web + programs-react UI)

  • Render an `⧉ inline` chip (dashed, italic; shares the transform palette) on the call-stack frame in both the docs `TraceDrawer` and the standalone `CallStackDisplay`, mirroring the tailcall chip — visually distinct from a real call.

Verification

  • TDD: 6 new unit tests in `mockTrace.test.ts` (isInline extraction; virtual frame lifetime across a bracketed body; two gap-separated sites with no accumulation; defensive-guard force-pop; real frames stay `isInline`-falsy). Full programs-react suite green (47).
  • End-to-end against real O2 bytecode (`dbl` inlined at 2 sites): each site now shows one virtual `dbl` activation across its body and the stack returns to top level between/after sites — no phantom frames.

Notes

  • Robust to the current (pre-de-smear) emission: the consecutive-invoke dedup collapses the smeared per-instruction invokes into one frame and the guard pops it at the caller gap. The compiler-side de-smear (bracket invoke on entry / return on exit) is still tracked under Fix typos in format spec #23 for spec conformance + graceful degradation, but the UI no longer mis-renders regardless.
  • Deferred pending architect ruling: display semantics for a genuine single-instruction inlined body (frame visible at that step vs. push-then-pop). Not exercised by current examples.

Inlined internal calls (level-2 `inline` transform) produced
VIRTUAL activations that the call stack mis-rendered: because the
extractor checks invoke before return, an inlined instruction's
context (which carries both) always read as invoke, so buildCallStack
pushed a frame per inline site and never popped — phantom `dbl > dbl`
frames leaked to the end of the trace, indistinguishable from real
calls.

- CallInfo/CallFrame: add `isInline` (virtual activation tag).
- extractCallInfoFromInstruction: set `isInline` from the `inline`
  transform marker (alongside the existing `isTailCall`).
- buildCallStack: tag virtual frames; add a defensive per-instruction
  membership guard that tears down any trailing virtual frame once
  execution reaches an instruction without the `inline` marker, so a
  virtual activation can never leak into caller code.
- Render an `⧉ inline` chip (dashed, italic) on the call-stack frame
  in both the docs TraceDrawer and the standalone CallStackDisplay,
  mirroring the tailcall chip — distinct from a real call.

Verified end-to-end against real O2 bytecode: each inline site now
shows one virtual `dbl` activation across its body and the stack
returns to top level between/after sites (no phantom frames).
@github-actions

github-actions Bot commented Jul 3, 2026

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

@gnidan gnidan merged commit 410362d into transform-context Jul 3, 2026
4 checks passed
@gnidan gnidan deleted the ui-inline-activation branch July 3, 2026 00:49
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