diff --git a/components/Editor/ExtraColumn.tsx b/components/Editor/ExtraColumn.tsx index ff9d5f1..7348e58 100644 --- a/components/Editor/ExtraColumn.tsx +++ b/components/Editor/ExtraColumn.tsx @@ -25,6 +25,7 @@ const ExtraColumn = ({ const { casmInstructions, activeCasmInstructionIndex, + errorCasmInstructionIndex, sierraStatements, casmToSierraMap, currentSierraVariables, @@ -45,6 +46,7 @@ const ExtraColumn = ({ instructions={casmInstructions} codeType={codeType} activeIndexes={[activeCasmInstructionIndex]} + errorIndexes={[errorCasmInstructionIndex]} variables={{}} /> ) : codeType === CodeType.Sierra ? ( @@ -52,6 +54,7 @@ const ExtraColumn = ({ instructions={sierraStatements} codeType={codeType} activeIndexes={casmToSierraMap[activeCasmInstructionIndex] ?? []} + errorIndexes={casmToSierraMap[errorCasmInstructionIndex] ?? []} variables={currentSierraVariables || {}} /> ) : ( diff --git a/components/Editor/InstructionsTable.tsx b/components/Editor/InstructionsTable.tsx index 39a241a..9d39faa 100644 --- a/components/Editor/InstructionsTable.tsx +++ b/components/Editor/InstructionsTable.tsx @@ -13,11 +13,13 @@ const sierraVariableRe = /\[(\d+)\]/ export const InstructionsTable = ({ instructions, activeIndexes, + errorIndexes, variables, codeType, }: { instructions: IInstruction[] activeIndexes: number[] + errorIndexes: number[] variables: SierraVariables codeType: CodeType }) => { @@ -126,15 +128,18 @@ export const InstructionsTable = ({ {instructions.map((instruction, index) => { const isActive = activeIndexes.includes(index) + const isError = errorIndexes.includes(index) return ( (rowRefs.current[index] = el)} key={index} className={cn( 'border-b border-gray-200 dark:border-black-500', - isActive - ? 'text-gray-900 dark:text-gray-200' - : 'text-gray-400 dark:text-gray-600', + { + 'text-gray-900 dark:text-gray-200': isActive, + 'text-gray-400 dark:text-gray-600': !isActive, + 'bg-red-100 dark:bg-red-500/10': isError, + }, )} > diff --git a/components/Editor/index.tsx b/components/Editor/index.tsx index c071fe7..24faa0a 100644 --- a/components/Editor/index.tsx +++ b/components/Editor/index.tsx @@ -62,6 +62,7 @@ const Editor = ({ readOnly = false }: Props) => { serializedOutput, casmInstructions, activeCasmInstructionIndex, + errorCasmInstructionIndex, sierraStatements, casmToSierraMap, currentSierraVariables, @@ -364,6 +365,7 @@ const Editor = ({ readOnly = false }: Props) => { instructions={casmInstructions} codeType={codeType} activeIndexes={[activeCasmInstructionIndex]} + errorIndexes={[errorCasmInstructionIndex]} variables={{}} /> ) : codeType === CodeType.Sierra ? ( @@ -373,6 +375,9 @@ const Editor = ({ readOnly = false }: Props) => { activeIndexes={ casmToSierraMap[activeCasmInstructionIndex] ?? [] } + errorIndexes={ + casmToSierraMap[errorCasmInstructionIndex] ?? [] + } variables={currentSierraVariables || {}} /> ) : ( diff --git a/components/Tracer/index.tsx b/components/Tracer/index.tsx index 50d4145..8f7aa87 100644 --- a/components/Tracer/index.tsx +++ b/components/Tracer/index.tsx @@ -3,7 +3,11 @@ import { useContext, useEffect, useState, useRef, useReducer } from 'react' import cn from 'classnames' import { Priority, useRegisterActions } from 'kbar' -import { CairoVMApiContext, BreakPoints } from 'context/cairoVMApiContext' +import { + CairoVMApiContext, + BreakPoints, + ProgramExecutionState, +} from 'context/cairoVMApiContext' import Console from '../Editor/Console' @@ -54,6 +58,7 @@ enum IConsoleTab { export const Tracer = () => { const { + executionState, tracerData, breakPoints, onExecutionStepChange, @@ -65,6 +70,10 @@ export const Tracer = () => { const trace = tracerData?.trace const currentTraceEntry = tracerData?.trace[executionTraceStepNumber] + const errorTraceEntry = + executionState === ProgramExecutionState.Error + ? tracerData?.trace.at(-2) + : null const currentCallstackEntry = tracerData?.callstack[executionTraceStepNumber] const [selectedConsoleTab, setSelectedConsoleTab] = useState( @@ -190,6 +199,11 @@ export const Tracer = () => { currentFocus={currentFocus.idx} breakpoints={breakPoints} toogleBreakPoint={toogleBreakPoint} + errorTraceEntry={ + executionState === ProgramExecutionState.Error + ? errorTraceEntry + : null + } /> )} @@ -351,6 +365,7 @@ function InstructionsTable({ currentFocus, breakpoints, toogleBreakPoint, + errorTraceEntry, }: { memory: TracerData['memory'] pcInstMap: TracerData['pcInstMap'] @@ -358,8 +373,10 @@ function InstructionsTable({ currentFocus: number breakpoints: BreakPoints toogleBreakPoint: (addr: string) => void + errorTraceEntry?: TraceEntry | null }) { const { pc, ap, fp } = currentTraceEntry + const errorPc = errorTraceEntry?.pc || 0 const [hoveredAddr, setHoveredAddr] = useState('') @@ -387,6 +404,7 @@ function InstructionsTable({ {Object.keys(memory).map((addr) => { const isCurrent = pc.toString() == addr + const isError = errorPc.toString() == addr const addrNum = Number(addr) const isFocus = currentFocus == addrNum const hasBreakpoint = breakpoints[addr] @@ -394,11 +412,14 @@ function InstructionsTable({ setHoveredAddr(addr)} onMouseLeave={() => setHoveredAddr('')} > diff --git a/context/cairoVMApiContext.tsx b/context/cairoVMApiContext.tsx index 2cdf13c..c2007b4 100644 --- a/context/cairoVMApiContext.tsx +++ b/context/cairoVMApiContext.tsx @@ -38,6 +38,7 @@ type ContextProps = { tracerData?: TracerData executionTraceStepNumber: number activeCasmInstructionIndex: number + errorCasmInstructionIndex: number sierraStatements: IInstruction[] casmToSierraMap: CasmToSierraMap currentTraceEntry?: TraceEntry @@ -63,6 +64,7 @@ export const CairoVMApiContext = createContext({ executionPanicMessage: '', executionTraceStepNumber: 0, activeCasmInstructionIndex: 0, + errorCasmInstructionIndex: 0, sierraStatements: [], casmToSierraMap: {}, breakPoints: {}, @@ -105,6 +107,12 @@ export const CairoVMApiProvider: React.FC = ({ tracerData?.entryToSierraVarsMap[executionTraceStepNumber] const activeCasmInstructionIndex = tracerData?.pcToInstIndexesMap[(currentTraceEntry?.pc ?? 0).toString()] ?? 0 + const errorTraceEntry = + executionState === ProgramExecutionState.Error + ? tracerData?.trace.at(-2) + : null + const errorCasmInstructionIndex = + tracerData?.pcToInstIndexesMap[(errorTraceEntry?.pc ?? 0).toString()] ?? -1 function onExecutionStepChange(stepNumber: number) { setExecutionTraceStepNumber(stepNumber) @@ -169,7 +177,11 @@ export const CairoVMApiProvider: React.FC = ({ : ProgramExecutionState.Error, ) - setExecutionTraceStepNumber(0) + setExecutionTraceStepNumber( + data.is_execution_successful === true + ? 0 + : data.tracer_data.trace.length - 2, + ) setCasmCode(data.casm_program_code) setSierraCode(data.sierra_program_code) setCairoLangCompilerVersion(data.cairo_lang_compiler_version) @@ -225,6 +237,7 @@ export const CairoVMApiProvider: React.FC = ({ currentTraceEntry, currentSierraVariables, activeCasmInstructionIndex, + errorCasmInstructionIndex, sierraStatements, casmToSierraMap, breakPoints,