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