@@ -252,6 +252,18 @@ function TraceDrawerContent(): JSX.Element {
252252 [ programsTrace , formatPcToInstruction , currentStep ] ,
253253 ) ;
254254
255+ // Compiler transform tags per trace step, so the instruction list can
256+ // mark which instructions the optimizer rewrote (e.g. the spliced
257+ // instructions of an inlined body) without stepping onto each one.
258+ const transformsByStep = useMemo < string [ ] [ ] > (
259+ ( ) =>
260+ trace . map ( ( s ) => {
261+ const fi = formatPcToInstruction . get ( s . pc ) ;
262+ return fi ? extractTransformFromInstruction ( fi ) : [ ] ;
263+ } ) ,
264+ [ trace , formatPcToInstruction ] ,
265+ ) ;
266+
255267 // Resolve argument values for call stack frames
256268 const argCacheRef = useRef < Map < number , ResolvedArg [ ] > > ( new Map ( ) ) ;
257269
@@ -721,9 +733,11 @@ function TraceDrawerContent(): JSX.Element {
721733 { currentCallInfo && (
722734 < div
723735 className = { `call-info-bar ${
724- currentCallInfo . isTailCall
725- ? "call-info-tailcall"
726- : `call-info-${ currentCallInfo . kind } `
736+ currentCallInfo . isInline
737+ ? "call-info-inline"
738+ : currentCallInfo . isTailCall
739+ ? "call-info-tailcall"
740+ : `call-info-${ currentCallInfo . kind } `
727741 } `}
728742 >
729743 { formatCallBanner ( currentCallInfo ) }
@@ -737,6 +751,7 @@ function TraceDrawerContent(): JSX.Element {
737751 trace = { trace }
738752 currentStep = { currentStep }
739753 onStepClick = { setCurrentStep }
754+ transformsByStep = { transformsByStep }
740755 />
741756 </ div >
742757
@@ -848,12 +863,15 @@ interface OpcodeListProps {
848863 trace : TraceStep [ ] ;
849864 currentStep : number ;
850865 onStepClick : ( index : number ) => void ;
866+ /** Compiler transform tags per trace step (same index as `trace`). */
867+ transformsByStep : string [ ] [ ] ;
851868}
852869
853870function OpcodeList ( {
854871 trace,
855872 currentStep,
856873 onStepClick,
874+ transformsByStep,
857875} : OpcodeListProps ) : JSX . Element {
858876 // Render the full instruction list; the panel scrolls internally.
859877 // Keep the active step scrolled into view as the trace advances.
@@ -867,18 +885,47 @@ function OpcodeList({
867885 < div className = "opcode-list" >
868886 { trace . map ( ( step , index ) => {
869887 const isActive = index === currentStep ;
888+ const transforms = transformsByStep [ index ] ?? [ ] ;
889+ const isInline = transforms . includes ( "inline" ) ;
890+ const isTailCall = transforms . includes ( "tailcall" ) ;
891+ const className = [
892+ "opcode-item" ,
893+ isActive ? "active" : "" ,
894+ isInline ? "opcode-item-inline" : "" ,
895+ isTailCall ? "opcode-item-tailcall" : "" ,
896+ ]
897+ . filter ( Boolean )
898+ . join ( " " ) ;
870899 return (
871900 < div
872901 key = { index }
873902 ref = { isActive ? activeRef : undefined }
874- className = { `opcode-item ${ isActive ? "active" : "" } ` }
903+ className = { className }
875904 onClick = { ( ) => onStepClick ( index ) }
876905 >
877906 < span className = "opcode-index" > { index + 1 } </ span >
878907 < span className = "opcode-pc" >
879908 0x{ step . pc . toString ( 16 ) . padStart ( 4 , "0" ) }
880909 </ span >
881910 < code className = "opcode-name" > { step . opcode } </ code >
911+ { isInline && (
912+ < span
913+ className = "opcode-transform-tag opcode-transform-inline"
914+ title = { 'transform: ["inline"] — spliced from the inlined body' }
915+ >
916+ ⧉ inline
917+ </ span >
918+ ) }
919+ { isTailCall && (
920+ < span
921+ className = "opcode-transform-tag opcode-transform-tailcall"
922+ title = {
923+ 'transform: ["tailcall"] — tail-call optimized back-edge'
924+ }
925+ >
926+ ⮌ tailcall
927+ </ span >
928+ ) }
882929 </ div >
883930 ) ;
884931 } ) }
@@ -1065,6 +1112,17 @@ function formatCallBanner(info: CallInfo): string {
10651112 if ( info . isTailCall ) {
10661113 return `Tail call: ${ name } (frame reused)` ;
10671114 }
1115+ if ( info . isInline ) {
1116+ // No call actually occurs — the body was spliced in at compile time.
1117+ switch ( info . kind ) {
1118+ case "invoke" :
1119+ return `Inlined ${ name } ${ params } (no call — body spliced in)` ;
1120+ case "return" :
1121+ return `End of inlined ${ name } ()` ;
1122+ case "revert" :
1123+ return `Reverted in inlined ${ name } ()` ;
1124+ }
1125+ }
10681126 switch ( info . kind ) {
10691127 case "invoke" : {
10701128 const prefix = info . callType === "create" ? "Creating" : "Calling" ;
0 commit comments