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::*,
12 table::{CustomInstruction, InstructionTable},
13 Gas, Host, Instruction, InstructionResult, InterpreterAction,
14};
15use core::cell::RefCell;
16pub use ext_bytecode::ExtBytecode;
17pub use input::InputsImpl;
18use loop_control::LoopControl as LoopControlImpl;
19use primitives::Bytes;
20use return_data::ReturnDataImpl;
21pub use runtime_flags::RuntimeFlags;
22pub use shared_memory::{num_words, MemoryGetter, SharedMemory, EMPTY_SHARED_MEMORY};
23use specification::hardfork::SpecId;
24pub use stack::{Stack, STACK_LIMIT};
25use std::rc::Rc;
26use subroutine_stack::SubRoutineImpl;
27
28#[derive(Debug, Clone)]
29#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
30pub struct Interpreter<WIRE: InterpreterTypes = EthInterpreter> {
31 pub bytecode: WIRE::Bytecode,
32 pub stack: WIRE::Stack,
33 pub return_data: WIRE::ReturnData,
34 pub memory: WIRE::Memory,
35 pub input: WIRE::Input,
36 pub sub_routine: WIRE::SubRoutineStack,
37 pub control: WIRE::Control,
38 pub runtime_flag: WIRE::RuntimeFlag,
39 pub extend: WIRE::Extend,
40}
41
42impl<EXT: Default, MG: MemoryGetter> Interpreter<EthInterpreter<EXT, MG>> {
43 pub fn new(
45 memory: Rc<RefCell<MG>>,
46 bytecode: ExtBytecode,
47 inputs: InputsImpl,
48 is_static: bool,
49 is_eof_init: bool,
50 spec_id: SpecId,
51 gas_limit: u64,
52 ) -> Self {
53 let runtime_flag = RuntimeFlags {
54 spec_id,
55 is_static,
56 is_eof: bytecode.is_eof(),
57 is_eof_init,
58 };
59
60 Self {
61 bytecode,
62 stack: Stack::new(),
63 return_data: ReturnDataImpl::default(),
64 memory,
65 input: inputs,
66 sub_routine: SubRoutineImpl::default(),
67 control: LoopControlImpl::new(gas_limit),
68 runtime_flag,
69 extend: EXT::default(),
70 }
71 }
72}
73
74pub 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}
89
90impl<IW: InterpreterTypes, H: Host> CustomInstruction for Instruction<IW, H> {
91 type Wire = IW;
92 type Host = H;
93
94 #[inline]
95 fn exec(&self, interpreter: &mut Interpreter<Self::Wire>, host: &mut Self::Host) {
96 (self)(interpreter, host);
97 }
98
99 #[inline]
100 fn from_base(instruction: Instruction<Self::Wire, Self::Host>) -> Self {
101 instruction
102 }
103}
104
105impl<IW: InterpreterTypes> Interpreter<IW> {
106 #[inline]
110 pub(crate) fn step<H: Host>(
111 &mut self,
112 instruction_table: &[Instruction<IW, H>; 256],
113 host: &mut H,
114 ) {
115 let opcode = self.bytecode.opcode();
117
118 self.bytecode.relative_jump(1);
122
123 instruction_table[opcode as usize].exec(self, host)
125 }
126
127 #[inline]
128 pub fn reset_control(&mut self) {
129 self.control
130 .set_next_action(InterpreterAction::None, InstructionResult::Continue);
131 }
132
133 pub fn take_next_action(&mut self) -> InterpreterAction {
134 let action = self.control.take_next_action();
136 if action.is_some() {
137 return action;
138 }
139 InterpreterAction::Return {
141 result: InterpreterResult {
142 result: self.control.instruction_result(),
143 output: Bytes::new(),
145 gas: *self.control.gas(),
146 },
147 }
148 }
149
150 pub fn run_plain<H: Host>(
152 &mut self,
153 instruction_table: &InstructionTable<IW, H>,
154 host: &mut H,
155 ) -> InterpreterAction {
156 self.reset_control();
157
158 while self.control.instruction_result().is_continue() {
160 self.step(instruction_table, host);
161 }
162
163 self.take_next_action()
164 }
165}
166
167#[derive(Clone, Debug, PartialEq, Eq)]
169#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
170pub struct InterpreterResult {
171 pub result: InstructionResult,
173 pub output: Bytes,
175 pub gas: Gas,
177}
178
179impl InterpreterResult {
180 pub fn new(result: InstructionResult, output: Bytes, gas: Gas) -> Self {
182 Self {
183 result,
184 output,
185 gas,
186 }
187 }
188
189 #[inline]
191 pub const fn is_ok(&self) -> bool {
192 self.result.is_ok()
193 }
194
195 #[inline]
197 pub const fn is_revert(&self) -> bool {
198 self.result.is_revert()
199 }
200
201 #[inline]
203 pub const fn is_error(&self) -> bool {
204 self.result.is_error()
205 }
206}
207
208#[cfg(test)]
209mod tests {
210 use super::*;
211 use bytecode::Bytecode;
212 use primitives::{Address, Bytes, U256};
213
214 #[test]
215 #[cfg(feature = "serde")]
216 fn test_interpreter_serde() {
217 let bytecode = Bytecode::new_raw(Bytes::from(&[0x60, 0x00, 0x60, 0x00, 0x01][..]));
218 let interpreter = Interpreter::<EthInterpreter>::new(
219 Rc::new(RefCell::new(SharedMemory::new())),
220 ExtBytecode::new(bytecode),
221 InputsImpl {
222 target_address: Address::ZERO,
223 caller_address: Address::ZERO,
224 input: Bytes::default(),
225 call_value: U256::ZERO,
226 },
227 false,
228 false,
229 SpecId::LATEST,
230 u64::MAX,
231 );
232
233 let serialized = bincode::serialize(&interpreter).unwrap();
234
235 let deserialized: Interpreter<EthInterpreter> = bincode::deserialize(&serialized).unwrap();
236
237 assert_eq!(
238 interpreter.bytecode.pc(),
239 deserialized.bytecode.pc(),
240 "Program counter should be preserved"
241 );
242 }
243}