revm_interpreter/
interpreter_types.rs1use crate::{Gas, InstructionResult, InterpreterAction};
2use bytecode::eof::CodeInfo;
3use core::ops::{Deref, Range};
4use primitives::{hardfork::SpecId, Address, Bytes, B256, U256};
5
6pub trait Immediates {
8 fn read_i16(&self) -> i16;
9 fn read_u16(&self) -> u16;
10
11 fn read_i8(&self) -> i8;
12 fn read_u8(&self) -> u8;
13
14 fn read_offset_i16(&self, offset: isize) -> i16;
15 fn read_offset_u16(&self, offset: isize) -> u16;
16
17 fn read_slice(&self, len: usize) -> &[u8];
18}
19
20pub trait InputsTr {
22 fn target_address(&self) -> Address;
23 fn caller_address(&self) -> Address;
24 fn input(&self) -> &[u8];
25 fn call_value(&self) -> U256;
26}
27
28pub trait LegacyBytecode {
32 fn bytecode_len(&self) -> usize;
34 fn bytecode_slice(&self) -> &[u8];
36}
37
38pub trait Jumps {
40 fn relative_jump(&mut self, offset: isize);
42 fn absolute_jump(&mut self, offset: usize);
45 fn is_valid_legacy_jump(&mut self, offset: usize) -> bool;
47 fn pc(&self) -> usize;
49 fn opcode(&self) -> u8;
51}
52
53pub trait MemoryTr {
55 fn set_data(&mut self, memory_offset: usize, data_offset: usize, len: usize, data: &[u8]);
61 fn set(&mut self, memory_offset: usize, data: &[u8]);
67
68 fn size(&self) -> usize;
70
71 fn copy(&mut self, destination: usize, source: usize, len: usize);
76
77 fn slice(&self, range: Range<usize>) -> impl Deref<Target = [u8]> + '_;
83
84 fn slice_len(&self, offset: usize, len: usize) -> impl Deref<Target = [u8]> + '_ {
88 self.slice(offset..offset + len)
89 }
90
91 fn resize(&mut self, new_size: usize) -> bool;
97}
98
99pub trait EofContainer {
101 fn eof_container(&self, index: usize) -> Option<&Bytes>;
103}
104
105pub trait SubRoutineStack {
107 fn len(&self) -> usize;
109
110 fn is_empty(&self) -> bool {
112 self.len() == 0
113 }
114
115 fn routine_idx(&self) -> usize;
117
118 fn set_routine_idx(&mut self, idx: usize);
123
124 fn push(&mut self, old_program_counter: usize, new_idx: usize) -> bool;
126
127 fn pop(&mut self) -> Option<usize>;
129}
130
131pub trait StackTr {
133 fn len(&self) -> usize;
135
136 fn is_empty(&self) -> bool {
138 self.len() == 0
139 }
140
141 #[must_use]
148 fn push(&mut self, value: U256) -> bool;
149
150 #[must_use]
154 fn push_b256(&mut self, value: B256) -> bool {
155 self.push(value.into())
156 }
157
158 #[must_use]
160 fn popn<const N: usize>(&mut self) -> Option<[U256; N]>;
161
162 #[must_use]
164 fn popn_top<const POPN: usize>(&mut self) -> Option<([U256; POPN], &mut U256)>;
165
166 #[must_use]
168 fn top(&mut self) -> Option<&mut U256> {
169 self.popn_top::<0>().map(|(_, top)| top)
170 }
171
172 #[must_use]
174 fn pop(&mut self) -> Option<U256> {
175 self.popn::<1>().map(|[value]| value)
176 }
177
178 #[must_use]
182 fn pop_address(&mut self) -> Option<Address> {
183 self.pop().map(|value| Address::from(value.to_be_bytes()))
184 }
185
186 #[must_use]
192 fn exchange(&mut self, n: usize, m: usize) -> bool;
193
194 #[must_use]
200 fn dup(&mut self, n: usize) -> bool;
201}
202
203pub trait EofData {
205 fn data(&self) -> &[u8];
207 fn data_slice(&self, offset: usize, len: usize) -> &[u8];
209 fn data_size(&self) -> usize;
211}
212
213pub trait EofCodeInfo {
215 fn code_info(&self, idx: usize) -> Option<&CodeInfo>;
217
218 fn code_section_pc(&self, idx: usize) -> Option<usize>;
220}
221
222pub trait ReturnData {
224 fn buffer(&self) -> &[u8];
226
227 fn set_buffer(&mut self, bytes: Bytes);
229
230 fn clear(&mut self) {
232 self.set_buffer(Bytes::new());
233 }
234}
235
236pub trait LoopControl {
237 fn set_instruction_result(&mut self, result: InstructionResult);
238 fn set_next_action(&mut self, action: InterpreterAction, result: InstructionResult);
239 fn gas(&self) -> &Gas;
240 fn gas_mut(&mut self) -> &mut Gas;
241 fn instruction_result(&self) -> InstructionResult;
242 fn take_next_action(&mut self) -> InterpreterAction;
243}
244
245pub trait RuntimeFlag {
246 fn is_static(&self) -> bool;
247 fn is_eof(&self) -> bool;
248 fn is_eof_init(&self) -> bool;
249 fn spec_id(&self) -> SpecId;
250}
251
252pub trait Interp {
253 type Instruction;
254 type Action;
255
256 fn run(&mut self, instructions: &[Self::Instruction; 256]) -> Self::Action;
257}
258
259pub trait InterpreterTypes {
260 type Stack: StackTr;
261 type Memory: MemoryTr;
262 type Bytecode: Jumps + Immediates + LegacyBytecode + EofData + EofContainer + EofCodeInfo;
263 type ReturnData: ReturnData;
264 type Input: InputsTr;
265 type SubRoutineStack: SubRoutineStack;
266 type Control: LoopControl;
267 type RuntimeFlag: RuntimeFlag;
268 type Extend;
269 type Output;
270}