revm_handler/
instructions.rs

1use auto_impl::auto_impl;
2use interpreter::{
3    instructions::{instruction_table, InstructionTable},
4    Host, Instruction, InterpreterTypes,
5};
6use std::boxed::Box;
7
8/// Stores instructions for EVM.
9#[auto_impl(&, Arc, Rc)]
10pub trait InstructionProvider {
11    /// Context type.
12    type Context;
13    /// Interpreter types.
14    type InterpreterTypes: InterpreterTypes;
15
16    /// Returns the instruction table that is used by EvmTr to execute instructions.
17    fn instruction_table(&self) -> &InstructionTable<Self::InterpreterTypes, Self::Context>;
18}
19
20/// Ethereum instruction contains list of mainnet instructions that is used for Interpreter execution.
21pub struct EthInstructions<WIRE: InterpreterTypes, HOST> {
22    pub instruction_table: Box<InstructionTable<WIRE, HOST>>,
23}
24
25impl<WIRE, HOST> Clone for EthInstructions<WIRE, HOST>
26where
27    WIRE: InterpreterTypes,
28{
29    fn clone(&self) -> Self {
30        Self {
31            instruction_table: self.instruction_table.clone(),
32        }
33    }
34}
35
36impl<WIRE, HOST> EthInstructions<WIRE, HOST>
37where
38    WIRE: InterpreterTypes,
39    HOST: Host,
40{
41    /// Returns `EthInstructions` with mainnet spec.
42    pub fn new_mainnet() -> Self {
43        Self::new(instruction_table::<WIRE, HOST>())
44    }
45
46    /// Rerurns new `EthInstructions` with custom instruction table.
47    pub fn new(base_table: InstructionTable<WIRE, HOST>) -> Self {
48        Self {
49            instruction_table: Box::new(base_table),
50        }
51    }
52
53    /// Inserts a new instruction into the instruction table.s
54    pub fn insert_instruction(&mut self, opcode: u8, instruction: Instruction<WIRE, HOST>) {
55        self.instruction_table[opcode as usize] = instruction;
56    }
57}
58
59impl<IT, CTX> InstructionProvider for EthInstructions<IT, CTX>
60where
61    IT: InterpreterTypes,
62    CTX: Host,
63{
64    type InterpreterTypes = IT;
65    type Context = CTX;
66
67    fn instruction_table(&self) -> &InstructionTable<Self::InterpreterTypes, Self::Context> {
68        &self.instruction_table
69    }
70}
71
72impl<WIRE, HOST> Default for EthInstructions<WIRE, HOST>
73where
74    WIRE: InterpreterTypes,
75    HOST: Host,
76{
77    fn default() -> Self {
78        Self::new_mainnet()
79    }
80}