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.
21#[derive(Debug)]
22pub struct EthInstructions<WIRE: InterpreterTypes, HOST: ?Sized> {
23    /// Table containing instruction implementations indexed by opcode.
24    pub instruction_table: Box<InstructionTable<WIRE, HOST>>,
25}
26
27impl<WIRE, HOST: Host + ?Sized> Clone for EthInstructions<WIRE, HOST>
28where
29    WIRE: InterpreterTypes,
30{
31    fn clone(&self) -> Self {
32        Self {
33            instruction_table: self.instruction_table.clone(),
34        }
35    }
36}
37
38impl<WIRE, HOST> EthInstructions<WIRE, HOST>
39where
40    WIRE: InterpreterTypes,
41    HOST: Host,
42{
43    /// Returns `EthInstructions` with mainnet spec.
44    pub fn new_mainnet() -> Self {
45        Self::new(instruction_table::<WIRE, HOST>())
46    }
47
48    /// Returns a new instance of `EthInstructions` with custom instruction table.
49    #[inline]
50    pub fn new(base_table: InstructionTable<WIRE, HOST>) -> Self {
51        Self {
52            instruction_table: Box::new(base_table),
53        }
54    }
55
56    /// Inserts a new instruction into the instruction table.
57    #[inline]
58    pub fn insert_instruction(&mut self, opcode: u8, instruction: Instruction<WIRE, HOST>) {
59        self.instruction_table[opcode as usize] = instruction;
60    }
61}
62
63impl<IT, CTX> InstructionProvider for EthInstructions<IT, CTX>
64where
65    IT: InterpreterTypes,
66    CTX: Host,
67{
68    type InterpreterTypes = IT;
69    type Context = CTX;
70
71    fn instruction_table(&self) -> &InstructionTable<Self::InterpreterTypes, Self::Context> {
72        &self.instruction_table
73    }
74}
75
76impl<WIRE, HOST> Default for EthInstructions<WIRE, HOST>
77where
78    WIRE: InterpreterTypes,
79    HOST: Host,
80{
81    fn default() -> Self {
82        Self::new_mainnet()
83    }
84}