zkevm_assembly/
error.rs

1//!
2//! The common error.
3//!
4
5use crate::assembly::operand::{FullOperand, NonMemoryOperand};
6use std::collections::HashMap;
7use thiserror::Error;
8
9#[derive(Debug, Error)]
10pub enum Error {
11    /// The file opening error.
12    #[error("file opening: {0}")]
13    FileOpening(std::io::Error),
14    /// The file metadata error.
15    #[error("file metadata: {0}")]
16    FileMetadata(std::io::Error),
17    /// The file reading error.
18    #[error("file reading: {0}")]
19    FileReading(std::io::Error),
20    #[error(transparent)]
21    AssemblyParseError(#[from] AssemblyParseError),
22}
23
24#[derive(Debug, Error, PartialEq)]
25pub enum AssemblyParseError {
26    #[error("assembly code cannot be empty")]
27    EmptyCode,
28    #[error("assembly code cannot be larger than {0} instructions")]
29    CodeTooLarge(usize),
30    #[error("can not parse data section element: {0}")]
31    DataSectionInvalid(SectionReadError),
32    #[error("can not parse globals section element: {0}")]
33    GlobalsSectionInvalid(SectionReadError),
34    #[error("can not parse text section element: {0}")]
35    TextSectionInvalid(SectionReadError),
36    #[error("there is a duplicate label in a code: {0}")]
37    DuplicateLabel(String),
38    #[error("there is no label `{0}` in data section of functions")]
39    LabelNotFound(String),
40    #[error("failed to resolve relocation for label `{0}` in data section")]
41    RelocationError(String),
42    #[error("Label {1} was tried to be used for either PC or constant at offset {0} that is more than `{2}` addressable space")]
43    CodeIsTooLong(usize, String, u64),
44}
45
46#[derive(Debug, Error, PartialEq)]
47pub enum SectionReadError {
48    #[error("cannot parse lines: {0:?}")]
49    LineReadError(HashMap<usize, (String, InstructionReadError)>),
50}
51
52#[derive(Debug, Error, PartialEq)]
53pub enum InstructionReadError {
54    /// Failed to parse text assembly
55    #[error("assembly parse error {0}")]
56    AssemblyParseError(AssemblyParseError),
57    /// The unknown register error.
58    #[error("unknown register `{0}`")]
59    UnknownRegister(String),
60    /// The invalid number error.
61    #[error("invalid number `{0}`: {1}")]
62    InvalidNumber(String, std::num::ParseIntError),
63    /// The invalid big number error.
64    #[error("invalid big number `{0}`: {1}")]
65    InvalidBigNumber(String, num_bigint::ParseBigIntError),
66    /// The invalid instruction argument.
67    #[error("failed to parse labeled constant value `{0}`")]
68    InvalidLabeledConstant(String),
69    /// The invalid instruction argument.
70    #[error(
71        "invalid argument {0}: expected `{1}`, found `{2}`",
72        index,
73        expected,
74        found
75    )]
76    InvalidArgument {
77        /// The argument position, starts from `0`.
78        index: usize,
79        /// The expected argument description.
80        expected: &'static str,
81        /// The invalid argument representation.
82        found: String,
83    },
84    #[error("failed to parse generic operand location: received `{0}`")]
85    InvalidGenericOperand(String),
86    #[error("failed to parse absolute-like `reg + imm` location: received `{0}`")]
87    InvalidAbsoluteLikeAddress(String),
88    #[error("failed to parse labeled constant operand location: received `{0}`")]
89    InvalidLabeledConstantOperand(String),
90    /// The invalid instruction argument.
91    #[error("found immediate `{0}` for location where register only is expected")]
92    InvalidOperandImmInRegLocation(String),
93    #[error(
94        "invalid operand for location that should be generic: on position `{index}`: {found:?}"
95    )]
96    InvalidOperandForGenericLocation { index: usize, found: FullOperand },
97    /// The invalid instruction argument.
98    #[error("invalid operand for location that is reg-only: on position `{index}`: {found:?}")]
99    InvalidOperandForRegLocation { index: usize, found: FullOperand },
100    #[error("invalid operand for location that is reg-only or imm-only: on position `{index}`: {found:?}")]
101    InvalidOperandForRegImmLocation { index: usize, found: FullOperand },
102    #[error("invalid operand for location that is reg-only in this version: on position `{index}`: {found:?}")]
103    InvalidRegImmInPlaceOfReg {
104        index: usize,
105        found: NonMemoryOperand,
106    },
107    /// The invalid instruction argument.
108    #[error("invalid operand for location that is label-only: on position `{index}`: {found:?}")]
109    InvalidOperandForLabelLocation { index: usize, found: FullOperand },
110    /// The invalid number of arguments.
111    #[error(
112        "invalid number of arguments: expected `{0}`, found `{1}`",
113        expected,
114        found
115    )]
116    InvalidArgumentCount {
117        /// The expected number of arguments.
118        expected: usize,
119        /// The invalid actual number of arguments.
120        found: usize,
121    },
122    /// The unknown argument error.
123    #[error("unknown argument `{0}`")]
124    UnknownArgument(String),
125    #[error(
126        "subtraction and negative literals are only supported in memory offsets, not in immediates"
127    )]
128    UnexpectedSubtraction,
129    #[error("integer overflow when computing the immediate")]
130    IntegerOverflow,
131    #[error("unknown symbol or label `{0}`")]
132    UnknownLabel(String),
133    #[error("unknown mnemonic `{0}`")]
134    UnknownMnemonic(String),
135    #[error("unexpected constant-like line {0:?} not in section")]
136    UnexpectedConstant(String),
137    #[error("unexpected line {0:?} in Text section")]
138    UnexpectedInstruction(String),
139    #[error("duplicate modifier `{0}` in the instruction")]
140    DuplicateModifier(String),
141    #[error("code is too long, can address {0} opcodes at maximum, encountered {1}")]
142    TooManyOpcodes(u64, u64),
143    #[error("code is too long, can address {0} words at maximum, encountered {1}")]
144    CodeIsTooLong(u64, u64),
145    // #[error("opcode has specific requirements for source and destination for it's variant `{0}`")]
146    // UnknownSourceOrDestination(String),
147}
148
149#[derive(Debug, Error, PartialEq)]
150pub enum BinaryParseError {
151    #[error("use_mem flag must be reset in Memory instruction")]
152    MemoryOpcodeInvalidFlag,
153    #[error("force stack flag can only be set for Stack memory type")]
154    UnexpectedForceStackFlag,
155    #[error("invalid register selector. At most one register can be selected per position.")]
156    InvalidRegisterSelector,
157    #[error("bytecode cannot be empty")]
158    EmptyBytecode,
159    #[error("bytecode length in bytes must be a multiple of {0}")]
160    InvalidBytecodeLength(usize),
161    #[error("bytecode length in bytes must be less than {0}")]
162    BytecodeTooLong(usize),
163    #[error("invalid opcode")]
164    InvalidOpcode,
165    #[error("Supported context fields indices: 0-5")]
166    UnknownContextField,
167}