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::*,
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    /// Create new interpreter
44    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    /// Executes the instruction at the current instruction pointer.
107    ///
108    /// Internally it will increment instruction pointer by one.
109    #[inline]
110    pub(crate) fn step<H: Host>(
111        &mut self,
112        instruction_table: &[Instruction<IW, H>; 256],
113        host: &mut H,
114    ) {
115        // Get current opcode.
116        let opcode = self.bytecode.opcode();
117
118        // SAFETY: In analysis we are doing padding of bytecode so that we are sure that last
119        // byte instruction is STOP so we are safe to just increment program_counter bcs on last instruction
120        // it will do noop and just stop execution of this contract
121        self.bytecode.relative_jump(1);
122
123        // Execute instruction.
124        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        // Return next action if it is some.
135        let action = self.control.take_next_action();
136        if action.is_some() {
137            return action;
138        }
139        // If not, return action without output as it is a halt.
140        InterpreterAction::Return {
141            result: InterpreterResult {
142                result: self.control.instruction_result(),
143                // Return empty bytecode
144                output: Bytes::new(),
145                gas: *self.control.gas(),
146            },
147        }
148    }
149
150    /// Executes the interpreter until it returns or stops.
151    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        // Main loop
159        while self.control.instruction_result().is_continue() {
160            self.step(instruction_table, host);
161        }
162
163        self.take_next_action()
164    }
165}
166
167/// The result of an interpreter operation.
168#[derive(Clone, Debug, PartialEq, Eq)]
169#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
170pub struct InterpreterResult {
171    /// The result of the instruction execution.
172    pub result: InstructionResult,
173    /// The output of the instruction execution.
174    pub output: Bytes,
175    /// The gas usage information.
176    pub gas: Gas,
177}
178
179impl InterpreterResult {
180    /// Returns a new `InterpreterResult` with the given values.
181    pub fn new(result: InstructionResult, output: Bytes, gas: Gas) -> Self {
182        Self {
183            result,
184            output,
185            gas,
186        }
187    }
188
189    /// Returns whether the instruction result is a success.
190    #[inline]
191    pub const fn is_ok(&self) -> bool {
192        self.result.is_ok()
193    }
194
195    /// Returns whether the instruction result is a revert.
196    #[inline]
197    pub const fn is_revert(&self) -> bool {
198        self.result.is_revert()
199    }
200
201    /// Returns whether the instruction result is an error.
202    #[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}