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 loop_control::LoopControl as LoopControlImpl;
14pub use return_data::ReturnDataImpl;
15pub use runtime_flags::RuntimeFlags;
16pub use shared_memory::{num_words, SharedMemory};
17pub use stack::{Stack, STACK_LIMIT};
18pub use subroutine_stack::{SubRoutineImpl, SubRoutineReturnFrame};
19
20use crate::{
22 interpreter_types::*, CallInput, Gas, Host, Instruction, InstructionResult, InstructionTable,
23 InterpreterAction,
24};
25use bytecode::Bytecode;
26use primitives::{hardfork::SpecId, Address, Bytes, U256};
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 bytecode_address: None,
89 caller_address: Address::ZERO,
90 input: CallInput::default(),
91 call_value: U256::ZERO,
92 },
93 false,
94 false,
95 SpecId::default(),
96 u64::MAX,
97 )
98 }
99}
100
101pub struct EthInterpreter<EXT = (), MG = SharedMemory> {
103 _phantom: core::marker::PhantomData<fn() -> (EXT, MG)>,
104}
105
106impl<EXT> InterpreterTypes for EthInterpreter<EXT> {
107 type Stack = Stack;
108 type Memory = SharedMemory;
109 type Bytecode = ExtBytecode;
110 type ReturnData = ReturnDataImpl;
111 type Input = InputsImpl;
112 type SubRoutineStack = SubRoutineImpl;
113 type Control = LoopControlImpl;
114 type RuntimeFlag = RuntimeFlags;
115 type Extend = EXT;
116 type Output = InterpreterAction;
117}
118
119impl<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 != InterpreterAction::None {
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
226impl<IW: InterpreterTypes> Interpreter<IW>
228where
229 IW::Output: From<InterpreterAction>,
230{
231 #[inline]
233 pub fn take_next_action_as_output(&mut self) -> IW::Output {
234 From::from(self.take_next_action())
235 }
236
237 #[inline]
239 pub fn run_plain_as_output<H: Host + ?Sized>(
240 &mut self,
241 instruction_table: &InstructionTable<IW, H>,
242 host: &mut H,
243 ) -> IW::Output {
244 From::from(self.run_plain(instruction_table, host))
245 }
246}
247
248#[cfg(test)]
249mod tests {
250 #[test]
251 #[cfg(feature = "serde")]
252 fn test_interpreter_serde() {
253 use super::*;
254 use bytecode::Bytecode;
255 use primitives::{Address, Bytes, U256};
256
257 let bytecode = Bytecode::new_raw(Bytes::from(&[0x60, 0x00, 0x60, 0x00, 0x01][..]));
258 let interpreter = Interpreter::<EthInterpreter>::new(
259 SharedMemory::new(),
260 ExtBytecode::new(bytecode),
261 InputsImpl {
262 target_address: Address::ZERO,
263 caller_address: Address::ZERO,
264 bytecode_address: None,
265 input: CallInput::Bytes(Bytes::default()),
266 call_value: U256::ZERO,
267 },
268 false,
269 false,
270 SpecId::default(),
271 u64::MAX,
272 );
273
274 let serialized = bincode::serialize(&interpreter).unwrap();
275
276 let deserialized: Interpreter<EthInterpreter> = bincode::deserialize(&serialized).unwrap();
277
278 assert_eq!(
279 interpreter.bytecode.pc(),
280 deserialized.bytecode.pc(),
281 "Program counter should be preserved"
282 );
283 }
284}