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
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/// Main interpreter structure that contains all components defines in [`InterpreterTypes`].s
27#[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    /// Create new interpreter
43    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
73/// Default types for Ethereum interpreter.
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    type Output = InterpreterAction;
89}
90
91// TODO InterpreterAction should be replaces with InterpreterTypes::Output.
92impl<IW: InterpreterTypes> Interpreter<IW> {
93    /// Executes the instruction at the current instruction pointer.
94    ///
95    /// Internally it will increment instruction pointer by one.
96    #[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        // Get current opcode.
103        let opcode = self.bytecode.opcode();
104
105        // SAFETY: In analysis we are doing padding of bytecode so that we are sure that last
106        // byte instruction is STOP so we are safe to just increment program_counter bcs on last instruction
107        // it will do noop and just stop execution of this contract
108        self.bytecode.relative_jump(1);
109
110        // Execute instruction.
111        instruction_table[opcode as usize](self, host)
112    }
113
114    /// Resets the control to the initial state. so that we can run the interpreter again.
115    #[inline]
116    pub fn reset_control(&mut self) {
117        self.control
118            .set_next_action(InterpreterAction::None, InstructionResult::Continue);
119    }
120
121    /// Takes the next action from the control and returns it.
122    #[inline]
123    pub fn take_next_action(&mut self) -> InterpreterAction {
124        // Return next action if it is some.
125        let action = self.control.take_next_action();
126        if action.is_some() {
127            return action;
128        }
129        // If not, return action without output as it is a halt.
130        InterpreterAction::Return {
131            result: InterpreterResult {
132                result: self.control.instruction_result(),
133                // Return empty bytecode
134                output: Bytes::new(),
135                gas: *self.control.gas(),
136            },
137        }
138    }
139
140    /// Executes the interpreter until it returns or stops.
141    #[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        // Main loop
150        while self.control.instruction_result().is_continue() {
151            self.step(instruction_table, host);
152        }
153
154        self.take_next_action()
155    }
156}
157
158/// The result of an interpreter operation.
159#[derive(Clone, Debug, PartialEq, Eq)]
160#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
161pub struct InterpreterResult {
162    /// The result of the instruction execution.
163    pub result: InstructionResult,
164    /// The output of the instruction execution.
165    pub output: Bytes,
166    /// The gas usage information.
167    pub gas: Gas,
168}
169
170impl InterpreterResult {
171    /// Returns a new `InterpreterResult` with the given values.
172    pub fn new(result: InstructionResult, output: Bytes, gas: Gas) -> Self {
173        Self {
174            result,
175            output,
176            gas,
177        }
178    }
179
180    /// Returns whether the instruction result is a success.
181    #[inline]
182    pub const fn is_ok(&self) -> bool {
183        self.result.is_ok()
184    }
185
186    /// Returns whether the instruction result is a revert.
187    #[inline]
188    pub const fn is_revert(&self) -> bool {
189        self.result.is_revert()
190    }
191
192    /// Returns whether the instruction result is an error.
193    #[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}