1#![allow(clippy::explicit_auto_deref)]
3
4use crate::stdlib::prelude::*;
5use crate::types::builtin_name::BuiltinName;
6
7use thiserror_no_std::Error;
8
9use crate::Felt252;
10use crate::{
11 types::{
12 errors::math_errors::MathError,
13 relocatable::{MaybeRelocatable, Relocatable},
14 },
15 vm::errors::{
16 exec_scope_errors::ExecScopeError, hint_errors::HintError, memory_errors::MemoryError,
17 runner_errors::RunnerError, trace_errors::TraceError,
18 },
19};
20
21pub const HINT_ERROR_STR: &str = "Got an exception while executing a hint: ";
22
23#[derive(Debug, Error)]
24pub enum VirtualMachineError {
25 #[error(transparent)]
26 RunnerError(#[from] RunnerError),
27 #[error(transparent)]
28 Memory(#[from] MemoryError),
29 #[error(transparent)]
30 Math(#[from] MathError),
31 #[error(transparent)]
32 TracerError(#[from] TraceError),
33 #[error(transparent)]
34 MainScopeError(#[from] ExecScopeError),
35 #[error(transparent)]
36 Other(anyhow::Error),
37 #[error("Instruction should be an int")]
38 InvalidInstructionEncoding,
39 #[error("Invalid op1_register value: {0}")]
40 InvalidOp1Reg(u128),
41 #[error("In immediate mode, off2 should be 1")]
42 ImmShouldBe1,
43 #[error("op0 must be known in double dereference")]
44 UnknownOp0,
45 #[error("Invalid ap_update value: {0}")]
46 InvalidApUpdate(u128),
47 #[error("Invalid pc_update value: {0}")]
48 InvalidPcUpdate(u128),
49 #[error("Res.UNCONSTRAINED cannot be used with ApUpdate.ADD")]
50 UnconstrainedResAdd,
51 #[error("Res.UNCONSTRAINED cannot be used with PcUpdate.JUMP")]
52 UnconstrainedResJump,
53 #[error("Res.UNCONSTRAINED cannot be used with PcUpdate.JUMP_REL")]
54 UnconstrainedResJumpRel,
55 #[error("Res.UNCONSTRAINED cannot be used with Opcode.ASSERT_EQ")]
56 UnconstrainedResAssertEq,
57 #[error("A relocatable value as Res cannot be used with PcUpdate.JUMP_REL")]
58 JumpRelNotInt,
59 #[error(
60 "Failed to compute Res.MUL: Could not complete computation of non pure values {} * {}", (*.0).0, (*.0).1
61 )]
62 ComputeResRelocatableMul(Box<(MaybeRelocatable, MaybeRelocatable)>),
63 #[error(
64 "Failed to compute operand, attempted to use {0} for an OpcodeExtension that is neither Stone nor QM31Operation"
65 )]
66 InvalidTypedOperationOpcodeExtension(Box<str>),
67 #[error("Couldn't compute operand {}. Unknown value for memory cell {}", (*.0).0, (*.0).1)]
68 FailedToComputeOperands(Box<(String, Relocatable)>),
69 #[error("An ASSERT_EQ instruction failed: {} != {}.", (*.0).0, (*.0).1)]
70 DiffAssertValues(Box<(MaybeRelocatable, MaybeRelocatable)>),
71 #[error("Call failed to write return-pc (inconsistent op0): {} != {}. Did you forget to increment ap?", (*.0).0, (*.0).1)]
72 CantWriteReturnPc(Box<(MaybeRelocatable, MaybeRelocatable)>),
73 #[error("Call failed to write return-fp (inconsistent dst): {} != {}. Did you forget to increment ap?", (*.0).0, (*.0).1)]
74 CantWriteReturnFp(Box<(MaybeRelocatable, MaybeRelocatable)>),
75 #[error("Couldn't get or load dst")]
76 NoDst,
77 #[error("Invalid res value: {0}")]
78 InvalidRes(u128),
79 #[error("Invalid opcode value: {0}")]
80 InvalidOpcode(u128),
81 #[error("Invalid opcode extension value: {0}")]
82 InvalidOpcodeExtension(u128),
83 #[error("This is not implemented")]
84 NotImplemented,
85 #[error("Inconsistent auto-deduction for {}, expected {}, got {:?}", (*.0).0, (*.0).1, (*.0).2)]
86 InconsistentAutoDeduction(Box<(BuiltinName, MaybeRelocatable, Option<MaybeRelocatable>)>),
87 #[error("Invalid hint encoding at pc: {0}")]
88 InvalidHintEncoding(Box<MaybeRelocatable>),
89 #[error("Expected output builtin to be present")]
90 NoOutputBuiltin,
91 #[error("Expected range_check builtin to be present")]
92 NoRangeCheckBuiltin,
93 #[error("Expected ecdsa builtin to be present")]
94 NoSignatureBuiltin,
95 #[error("Expected {0} to be present")]
96 NoModBuiltin(BuiltinName),
97 #[error("Div out of range: 0 < {} <= {}", (*.0).0, (*.0).1)]
98 OutOfValidRange(Box<(Felt252, Felt252)>),
99 #[error("Failed to compare {} and {}, cant compare a relocatable to an integer value", (*.0).0, (*.0).1)]
100 DiffTypeComparison(Box<(MaybeRelocatable, MaybeRelocatable)>),
101 #[error("Failed to compare {} and {}, cant compare two relocatable values of different segment indexes", (*.0).0, (*.0).1)]
102 DiffIndexComp(Box<(Relocatable, Relocatable)>),
103 #[error("Couldn't convert usize to u32")]
104 NoneInMemoryRange,
105 #[error("Expected integer, found: {0:?}")]
106 ExpectedIntAtRange(Box<Option<MaybeRelocatable>>),
107 #[error("Could not convert slice to array")]
108 SliceToArrayError,
109 #[error("Failed to compile hint: {0}")]
110 CompileHintFail(Box<str>),
111 #[error("op1_addr is Op1Addr.IMM, but no immediate was given")]
112 NoImm,
113 #[error("Execution reached the end of the program. Requested remaining steps: {0}.")]
114 EndOfProgram(usize),
115 #[error("Could not reach the end of the program. Executed steps: {0}.")]
116 StepsLimit(u64),
117 #[error("Could not reach the end of the program. RunResources has no remaining steps.")]
118 UnfinishedExecution,
119 #[error("Current run is not finished")]
120 RunNotFinished,
121 #[error("Invalid argument count, expected {} but got {}", (*.0).0, (*.0).1)]
122 InvalidArgCount(Box<(usize, usize)>),
123 #[error("Couldn't parse prime: {0}")]
124 CouldntParsePrime(Box<str>),
125 #[error("{HINT_ERROR_STR}{}", (*.0).1)]
126 Hint(Box<(usize, HintError)>),
127 #[error("Unexpected Failure")]
128 Unexpected,
129 #[error("Out of bounds access to builtin segment")]
130 OutOfBoundsBuiltinSegmentAccess,
131 #[error("Out of bounds access to program segment")]
132 OutOfBoundsProgramSegmentAccess,
133 #[error("Security Error: Invalid Memory Value: temporary address not relocated: {0}")]
134 InvalidMemoryValueTemporaryAddress(Box<Relocatable>),
135 #[error("accessed_addresses is None.")]
136 MissingAccessedAddresses,
137 #[error("Failed to write the output builtin content")]
138 FailedToWriteOutput,
139 #[error("Failed to find index {0} in the vm's relocation table")]
140 RelocationNotFound(usize),
141 #[error("{} batch size is not {}", (*.0).0, (*.0).1)]
142 ModBuiltinBatchSize(Box<(BuiltinName, usize)>),
143 #[error("Blake2s opcode invalid operand: op{0} does not point to {1} u32 numbers.")]
144 Blake2sInvalidOperand(u8, u8),
145 #[error("Blake2s opcode invalid flags {0}")]
146 InvalidBlake2sFlags(u128),
147 #[error("QM31 add mul opcode invalid flags {0}")]
148 InvalidQM31AddMulFlags(u128),
149}
150
151#[cfg(test)]
152mod tests {
153 use super::*;
154
155 #[test]
156 fn test_vm_error_size() {
158 let size = crate::stdlib::mem::size_of::<VirtualMachineError>();
159 assert!(size <= 32, "{size}")
160 }
161}