revm_handler/
instructions.rs1use auto_impl::auto_impl;
2use interpreter::{
3 instructions::{instruction_table_gas_changes_spec, InstructionTable},
4 Host, Instruction, InterpreterTypes,
5};
6use primitives::hardfork::SpecId;
7use std::boxed::Box;
8
9#[auto_impl(&mut, Box)]
11pub trait InstructionProvider {
12 type Context;
14 type InterpreterTypes: InterpreterTypes;
16
17 fn instruction_table(&self) -> &InstructionTable<Self::InterpreterTypes, Self::Context>;
19}
20
21#[derive(Debug)]
23pub struct EthInstructions<WIRE: InterpreterTypes, HOST: ?Sized> {
24 pub instruction_table: Box<InstructionTable<WIRE, HOST>>,
26 pub spec: SpecId,
28}
29
30impl<WIRE, HOST: Host + ?Sized> Clone for EthInstructions<WIRE, HOST>
31where
32 WIRE: InterpreterTypes,
33{
34 fn clone(&self) -> Self {
35 Self {
36 instruction_table: self.instruction_table.clone(),
37 spec: self.spec,
38 }
39 }
40}
41
42impl<WIRE, HOST> EthInstructions<WIRE, HOST>
43where
44 WIRE: InterpreterTypes,
45 HOST: Host,
46{
47 pub fn new_mainnet() -> Self {
49 let spec = SpecId::default();
50 Self::new(instruction_table_gas_changes_spec(spec), spec)
51 }
52
53 pub fn new_mainnet_with_spec(spec: SpecId) -> Self {
55 Self::new(instruction_table_gas_changes_spec(spec), spec)
56 }
57
58 #[inline]
60 pub fn new(base_table: InstructionTable<WIRE, HOST>, spec: SpecId) -> Self {
61 Self {
62 instruction_table: Box::new(base_table),
63 spec,
64 }
65 }
66
67 #[inline]
69 pub fn insert_instruction(&mut self, opcode: u8, instruction: Instruction<WIRE, HOST>) {
70 self.instruction_table[opcode as usize] = instruction;
71 }
72}
73
74impl<IT, CTX> InstructionProvider for EthInstructions<IT, CTX>
75where
76 IT: InterpreterTypes,
77 CTX: Host,
78{
79 type InterpreterTypes = IT;
80 type Context = CTX;
81
82 fn instruction_table(&self) -> &InstructionTable<Self::InterpreterTypes, Self::Context> {
83 &self.instruction_table
84 }
85}
86
87impl<WIRE, HOST> Default for EthInstructions<WIRE, HOST>
88where
89 WIRE: InterpreterTypes,
90 HOST: Host,
91{
92 fn default() -> Self {
93 Self::new_mainnet()
94 }
95}