1pub mod ext_bytecode;
2mod input;
3mod loop_control;
4mod return_data;
5mod runtime_flags;
6mod shared_memory;
7mod stack;
8mod subroutine_stack;
9
10pub use ext_bytecode::ExtBytecode;
12pub use input::InputsImpl;
13pub use runtime_flags::RuntimeFlags;
14pub use shared_memory::{num_words, SharedMemory};
15pub use stack::{Stack, STACK_LIMIT};
16pub use subroutine_stack::{SubRoutineImpl, SubRoutineReturnFrame};
17
18use crate::{
20 interpreter_types::*, Gas, Host, Instruction, InstructionResult, InstructionTable,
21 InterpreterAction,
22};
23use bytecode::Bytecode;
24use loop_control::LoopControl as LoopControlImpl;
25use primitives::{hardfork::SpecId, Address, Bytes, U256};
26use return_data::ReturnDataImpl;
27
28#[derive(Debug, Clone)]
30#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
31pub struct Interpreter<WIRE: InterpreterTypes = EthInterpreter> {
32 pub bytecode: WIRE::Bytecode,
33 pub stack: WIRE::Stack,
34 pub return_data: WIRE::ReturnData,
35 pub memory: WIRE::Memory,
36 pub input: WIRE::Input,
37 pub sub_routine: WIRE::SubRoutineStack,
38 pub control: WIRE::Control,
39 pub runtime_flag: WIRE::RuntimeFlag,
40 pub extend: WIRE::Extend,
41}
42
43impl<EXT: Default> Interpreter<EthInterpreter<EXT>> {
44 pub fn new(
46 memory: SharedMemory,
47 bytecode: ExtBytecode,
48 inputs: InputsImpl,
49 is_static: bool,
50 is_eof_init: bool,
51 spec_id: SpecId,
52 gas_limit: u64,
53 ) -> Self {
54 let runtime_flag = RuntimeFlags {
55 spec_id,
56 is_static,
57 is_eof: bytecode.is_eof(),
58 is_eof_init,
59 };
60
61 Self {
62 bytecode,
63 stack: Stack::new(),
64 return_data: ReturnDataImpl::default(),
65 memory,
66 input: inputs,
67 sub_routine: SubRoutineImpl::default(),
68 control: LoopControlImpl::new(gas_limit),
69 runtime_flag,
70 extend: EXT::default(),
71 }
72 }
73
74 pub fn with_bytecode(mut self, bytecode: Bytecode) -> Self {
76 self.bytecode = ExtBytecode::new(bytecode);
77 self
78 }
79}
80
81impl Default for Interpreter<EthInterpreter> {
82 fn default() -> Self {
83 Interpreter::new(
84 SharedMemory::new(),
85 ExtBytecode::new(Bytecode::default()),
86 InputsImpl {
87 target_address: Address::ZERO,
88 caller_address: Address::ZERO,
89 input: Bytes::default(),
90 call_value: U256::ZERO,
91 },
92 false,
93 false,
94 SpecId::default(),
95 u64::MAX,
96 )
97 }
98}
99
100pub struct EthInterpreter<EXT = (), MG = SharedMemory> {
102 _phantom: core::marker::PhantomData<fn() -> (EXT, MG)>,
103}
104
105impl<EXT> InterpreterTypes for EthInterpreter<EXT> {
106 type Stack = Stack;
107 type Memory = SharedMemory;
108 type Bytecode = ExtBytecode;
109 type ReturnData = ReturnDataImpl;
110 type Input = InputsImpl;
111 type SubRoutineStack = SubRoutineImpl;
112 type Control = LoopControlImpl;
113 type RuntimeFlag = RuntimeFlags;
114 type Extend = EXT;
115 type Output = InterpreterAction;
116}
117
118impl<IW: InterpreterTypes> Interpreter<IW> {
120 #[inline]
124 pub(crate) fn step<H: Host + ?Sized>(
125 &mut self,
126 instruction_table: &[Instruction<IW, H>; 256],
127 host: &mut H,
128 ) {
129 let opcode = self.bytecode.opcode();
131
132 self.bytecode.relative_jump(1);
136
137 instruction_table[opcode as usize](self, host)
139 }
140
141 #[inline]
143 pub fn reset_control(&mut self) {
144 self.control
145 .set_next_action(InterpreterAction::None, InstructionResult::Continue);
146 }
147
148 #[inline]
150 pub fn take_next_action(&mut self) -> InterpreterAction {
151 let action = self.control.take_next_action();
153 if action.is_some() {
154 return action;
155 }
156 InterpreterAction::Return {
158 result: InterpreterResult {
159 result: self.control.instruction_result(),
160 output: Bytes::new(),
162 gas: *self.control.gas(),
163 },
164 }
165 }
166
167 #[inline]
169 pub fn run_plain<H: Host + ?Sized>(
170 &mut self,
171 instruction_table: &InstructionTable<IW, H>,
172 host: &mut H,
173 ) -> InterpreterAction {
174 self.reset_control();
175
176 while self.control.instruction_result().is_continue() {
178 self.step(instruction_table, host);
179 }
180
181 self.take_next_action()
182 }
183}
184
185#[derive(Clone, Debug, PartialEq, Eq)]
187#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
188pub struct InterpreterResult {
189 pub result: InstructionResult,
191 pub output: Bytes,
193 pub gas: Gas,
195}
196
197impl InterpreterResult {
198 pub fn new(result: InstructionResult, output: Bytes, gas: Gas) -> Self {
200 Self {
201 result,
202 output,
203 gas,
204 }
205 }
206
207 #[inline]
209 pub const fn is_ok(&self) -> bool {
210 self.result.is_ok()
211 }
212
213 #[inline]
215 pub const fn is_revert(&self) -> bool {
216 self.result.is_revert()
217 }
218
219 #[inline]
221 pub const fn is_error(&self) -> bool {
222 self.result.is_error()
223 }
224}
225
226#[cfg(test)]
227mod tests {
228 #[test]
229 #[cfg(feature = "serde")]
230 fn test_interpreter_serde() {
231 use super::*;
232 use bytecode::Bytecode;
233 use primitives::{Address, Bytes, U256};
234
235 let bytecode = Bytecode::new_raw(Bytes::from(&[0x60, 0x00, 0x60, 0x00, 0x01][..]));
236 let interpreter = Interpreter::<EthInterpreter>::new(
237 SharedMemory::new(),
238 ExtBytecode::new(bytecode),
239 InputsImpl {
240 target_address: Address::ZERO,
241 caller_address: Address::ZERO,
242 input: Bytes::default(),
243 call_value: U256::ZERO,
244 },
245 false,
246 false,
247 SpecId::default(),
248 u64::MAX,
249 );
250
251 let serialized = bincode::serialize(&interpreter).unwrap();
252
253 let deserialized: Interpreter<EthInterpreter> = bincode::deserialize(&serialized).unwrap();
254
255 assert_eq!(
256 interpreter.bytecode.pc(),
257 deserialized.bytecode.pc(),
258 "Program counter should be preserved"
259 );
260 }
261}