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}