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 #[deprecated(since = "0.2.0", note = "use new_mainnet_with_spec instead")]
49 pub fn new_mainnet() -> Self {
50 let spec = SpecId::default();
51 Self::new(instruction_table_gas_changes_spec(spec), spec)
52 }
53
54 pub fn new_mainnet_with_spec(spec: SpecId) -> Self {
56 Self::new(instruction_table_gas_changes_spec(spec), spec)
57 }
58
59 #[inline]
61 pub fn new(base_table: InstructionTable<WIRE, HOST>, spec: SpecId) -> Self {
62 Self {
63 instruction_table: Box::new(base_table),
64 spec,
65 }
66 }
67
68 #[inline]
70 pub fn insert_instruction(&mut self, opcode: u8, instruction: Instruction<WIRE, HOST>) {
71 self.instruction_table[opcode as usize] = instruction;
72 }
73}
74
75impl<IT, CTX> InstructionProvider for EthInstructions<IT, CTX>
76where
77 IT: InterpreterTypes,
78 CTX: Host,
79{
80 type InterpreterTypes = IT;
81 type Context = CTX;
82
83 fn instruction_table(&self) -> &InstructionTable<Self::InterpreterTypes, Self::Context> {
84 &self.instruction_table
85 }
86}