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