diff --git a/packages/programs-react/src/utils/mockTrace.ts b/packages/programs-react/src/utils/mockTrace.ts index 78af909c3..23d8483ed 100644 --- a/packages/programs-react/src/utils/mockTrace.ts +++ b/packages/programs-react/src/utils/mockTrace.ts @@ -298,15 +298,19 @@ export function buildCallStack( } if (callInfo.kind === "invoke") { - // The compiler emits invoke on both the caller JUMP and - // callee entry JUMPDEST. Skip if the top frame already - // matches this call. + // The compiler emits invoke on both the caller JUMP + // and callee entry JUMPDEST for the same call. These + // occur on consecutive trace steps. Only skip if the + // top frame matches AND was pushed on the immediately + // preceding step — otherwise this is a new call (e.g. + // recursion with the same function name). const top = stack[stack.length - 1]; - if ( - !top || - top.identifier !== callInfo.identifier || - top.callType !== callInfo.callType - ) { + const isDuplicate = + top && + top.identifier === callInfo.identifier && + top.callType === callInfo.callType && + top.stepIndex === i - 1; + if (!isDuplicate) { stack.push({ identifier: callInfo.identifier, stepIndex: i, diff --git a/packages/web/src/theme/ProgramExample/TraceDrawer.tsx b/packages/web/src/theme/ProgramExample/TraceDrawer.tsx index 088fa8d3f..99cdea4b8 100644 --- a/packages/web/src/theme/ProgramExample/TraceDrawer.tsx +++ b/packages/web/src/theme/ProgramExample/TraceDrawer.tsx @@ -118,14 +118,18 @@ function TraceDrawerContent(): JSX.Element { if (info.kind === "invoke") { // The compiler emits invoke on both the caller - // JUMP and callee entry JUMPDEST. Skip if the - // top frame already matches this call. + // JUMP and callee entry JUMPDEST for the same + // call. These occur on consecutive trace steps. + // Only skip if the top frame matches AND was + // pushed on the immediately preceding step — + // otherwise this is a new call (e.g. recursion). const top = frames[frames.length - 1]; - if ( - !top || - top.identifier !== info.identifier || - top.callType !== info.callType - ) { + const isDuplicate = + top && + top.identifier === info.identifier && + top.callType === info.callType && + top.stepIndex === i - 1; + if (!isDuplicate) { frames.push({ identifier: info.identifier, stepIndex: i,