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 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
18// imports
19use 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/// Main interpreter structure that contains all components defines in [`InterpreterTypes`].s
31#[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    /// Create new interpreter
47    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    /// Sets the bytecode that is going to be executed
77    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
102/// Default types for Ethereum interpreter.
103pub 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
120// TODO InterpreterAction should be replaces with InterpreterTypes::Output.
121impl<IW: InterpreterTypes> Interpreter<IW> {
122    /// Executes the instruction at the current instruction pointer.
123    ///
124    /// Internally it will increment instruction pointer by one.
125    #[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        // Get current opcode.
132        let opcode = self.bytecode.opcode();
133
134        // SAFETY: In analysis we are doing padding of bytecode so that we are sure that last
135        // byte instruction is STOP so we are safe to just increment program_counter bcs on last instruction
136        // it will do noop and just stop execution of this contract
137        self.bytecode.relative_jump(1);
138
139        // Execute instruction.
140        instruction_table[opcode as usize](self, host)
141    }
142
143    /// Resets the control to the initial state. so that we can run the interpreter again.
144    #[inline]
145    pub fn reset_control(&mut self) {
146        self.control
147            .set_next_action(InterpreterAction::None, InstructionResult::Continue);
148    }
149
150    /// Takes the next action from the control and returns it.
151    #[inline]
152    pub fn take_next_action(&mut self) -> InterpreterAction {
153        // Return next action if it is some.
154        let action = self.control.take_next_action();
155        if action.is_some() {
156            return action;
157        }
158        // If not, return action without output as it is a halt.
159        InterpreterAction::Return {
160            result: InterpreterResult {
161                result: self.control.instruction_result(),
162                // Return empty bytecode
163                output: Bytes::new(),
164                gas: *self.control.gas(),
165            },
166        }
167    }
168
169    /// Executes the interpreter until it returns or stops.
170    #[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        // Main loop
179        while self.control.instruction_result().is_continue() {
180            self.step(instruction_table, host);
181        }
182
183        self.take_next_action()
184    }
185}
186
187/// The result of an interpreter operation.
188#[derive(Clone, Debug, PartialEq, Eq)]
189#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
190pub struct InterpreterResult {
191    /// The result of the instruction execution.
192    pub result: InstructionResult,
193    /// The output of the instruction execution.
194    pub output: Bytes,
195    /// The gas usage information.
196    pub gas: Gas,
197}
198
199impl InterpreterResult {
200    /// Returns a new `InterpreterResult` with the given values.
201    pub fn new(result: InstructionResult, output: Bytes, gas: Gas) -> Self {
202        Self {
203            result,
204            output,
205            gas,
206        }
207    }
208
209    /// Returns whether the instruction result is a success.
210    #[inline]
211    pub const fn is_ok(&self) -> bool {
212        self.result.is_ok()
213    }
214
215    /// Returns whether the instruction result is a revert.
216    #[inline]
217    pub const fn is_revert(&self) -> bool {
218        self.result.is_revert()
219    }
220
221    /// Returns whether the instruction result is an error.
222    #[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}