revm_interpreter/
instruction_context.rs

1use crate::{interpreter_types::Jumps, Interpreter, InterpreterTypes};
2
3use super::Instruction;
4
5/// Context passed to instruction implementations containing the host and interpreter.
6/// This struct provides access to both the host interface for external state operations
7/// and the interpreter state for stack, memory, and gas operations.
8pub struct InstructionContext<'a, H: ?Sized, ITy: InterpreterTypes> {
9    /// Reference to the host interface for accessing external blockchain state.
10    pub host: &'a mut H,
11    /// Reference to the interpreter containing execution state (stack, memory, gas, etc).
12    pub interpreter: &'a mut Interpreter<ITy>,
13}
14
15impl<H: ?Sized, ITy: InterpreterTypes> std::fmt::Debug for InstructionContext<'_, H, ITy> {
16    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17        f.debug_struct("InstructionContext")
18            .field("host", &"<host>")
19            .field("interpreter", &"<interpreter>")
20            .finish()
21    }
22}
23
24impl<H: ?Sized, ITy: InterpreterTypes> InstructionContext<'_, H, ITy> {
25    /// Executes the instruction at the current instruction pointer.
26    ///
27    /// Internally it will increment instruction pointer by one.
28    #[inline]
29    pub(crate) fn step(self, instruction_table: &[Instruction<ITy, H>; 256]) {
30        // Get current opcode.
31        let opcode = self.interpreter.bytecode.opcode();
32
33        // SAFETY: In analysis we are doing padding of bytecode so that we are sure that last
34        // byte instruction is STOP so we are safe to just increment program_counter bcs on last instruction
35        // it will do noop and just stop execution of this contract
36        self.interpreter.bytecode.relative_jump(1);
37
38        // Execute instruction.
39        instruction_table[opcode as usize](self)
40    }
41}