revm_interpreter/
interpreter.rs

1pub mod ext_bytecode;
2mod input;
3mod loop_control;
4mod return_data;
5mod runtime_flags;
6mod shared_memory;
7mod stack;
8mod subroutine_stack;
9
10// re-exports
11pub 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
20// imports
21use 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/// Main interpreter structure that contains all components defines in [`InterpreterTypes`].s
29#[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    /// Create new interpreter
45    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    /// Sets the bytecode that is going to be executed
75    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
101/// Default types for Ethereum interpreter.
102pub 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    /// Executes the instruction at the current instruction pointer.
121    ///
122    /// Internally it will increment instruction pointer by one.
123    #[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        // Get current opcode.
130        let opcode = self.bytecode.opcode();
131
132        // SAFETY: In analysis we are doing padding of bytecode so that we are sure that last
133        // byte instruction is STOP so we are safe to just increment program_counter bcs on last instruction
134        // it will do noop and just stop execution of this contract
135        self.bytecode.relative_jump(1);
136
137        // Execute instruction.
138        instruction_table[opcode as usize](self, host)
139    }
140
141    /// Resets the control to the initial state. so that we can run the interpreter again.
142    #[inline]
143    pub fn reset_control(&mut self) {
144        self.control
145            .set_next_action(InterpreterAction::None, InstructionResult::Continue);
146    }
147
148    /// Takes the next action from the control and returns it.
149    #[inline]
150    pub fn take_next_action(&mut self) -> InterpreterAction {
151        // Return next action if it is some.
152        let action = self.control.take_next_action();
153        if action != InterpreterAction::None {
154            return action;
155        }
156        // If not, return action without output as it is a halt.
157        InterpreterAction::Return {
158            result: InterpreterResult {
159                result: self.control.instruction_result(),
160                // Return empty bytecode
161                output: Bytes::new(),
162                gas: *self.control.gas(),
163            },
164        }
165    }
166
167    /// Executes the interpreter until it returns or stops.
168    #[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        // Main loop
177        while self.control.instruction_result().is_continue() {
178            self.step(instruction_table, host);
179        }
180
181        self.take_next_action()
182    }
183}
184
185/// The result of an interpreter operation.
186#[derive(Clone, Debug, PartialEq, Eq)]
187#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
188pub struct InterpreterResult {
189    /// The result of the instruction execution.
190    pub result: InstructionResult,
191    /// The output of the instruction execution.
192    pub output: Bytes,
193    /// The gas usage information.
194    pub gas: Gas,
195}
196
197impl InterpreterResult {
198    /// Returns a new `InterpreterResult` with the given values.
199    pub fn new(result: InstructionResult, output: Bytes, gas: Gas) -> Self {
200        Self {
201            result,
202            output,
203            gas,
204        }
205    }
206
207    /// Returns whether the instruction result is a success.
208    #[inline]
209    pub const fn is_ok(&self) -> bool {
210        self.result.is_ok()
211    }
212
213    /// Returns whether the instruction result is a revert.
214    #[inline]
215    pub const fn is_revert(&self) -> bool {
216        self.result.is_revert()
217    }
218
219    /// Returns whether the instruction result is an error.
220    #[inline]
221    pub const fn is_error(&self) -> bool {
222        self.result.is_error()
223    }
224}
225
226// Special implementation for types where Output can be created from InterpreterAction
227impl<IW: InterpreterTypes> Interpreter<IW>
228where
229    IW::Output: From<InterpreterAction>,
230{
231    /// Takes the next action from the control and returns it as the specific Output type.
232    #[inline]
233    pub fn take_next_action_as_output(&mut self) -> IW::Output {
234        From::from(self.take_next_action())
235    }
236
237    /// Executes the interpreter until it returns or stops, returning the specific Output type.
238    #[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}