revm_handler/
instructions.rs1use auto_impl::auto_impl;
2use interpreter::{
3 instructions::{gas_table_spec, GasTable, 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 fn gas_table(&self) -> &GasTable;
22}
23
24#[derive(Debug)]
26pub struct EthInstructions<WIRE: InterpreterTypes, HOST: ?Sized> {
27 pub spec: SpecId,
29 inner: Box<EthInstructionsInner<WIRE, HOST>>,
30}
31
32#[derive(Debug)]
33struct EthInstructionsInner<WIRE: InterpreterTypes, HOST: ?Sized> {
34 instruction_table: InstructionTable<WIRE, HOST>,
36 gas_table: GasTable,
38}
39
40impl<WIRE, HOST: Host + ?Sized> Clone for EthInstructions<WIRE, HOST>
41where
42 WIRE: InterpreterTypes,
43{
44 fn clone(&self) -> Self {
45 Self {
46 spec: self.spec,
47 inner: self.inner.clone(),
48 }
49 }
50}
51
52impl<WIRE, HOST: Host + ?Sized> Clone for EthInstructionsInner<WIRE, HOST>
53where
54 WIRE: InterpreterTypes,
55{
56 fn clone(&self) -> Self {
57 *self
58 }
59}
60impl<WIRE, HOST: Host + ?Sized> Copy for EthInstructionsInner<WIRE, HOST> where
61 WIRE: InterpreterTypes
62{
63}
64
65impl<WIRE, HOST> EthInstructions<WIRE, HOST>
66where
67 WIRE: InterpreterTypes,
68 HOST: Host,
69{
70 #[deprecated(since = "0.2.0", note = "use new_mainnet_with_spec instead")]
72 pub fn new_mainnet() -> Self {
73 let spec = SpecId::default();
74 Self::new_mainnet_with_spec(spec)
75 }
76
77 pub fn new_mainnet_with_spec(spec: SpecId) -> Self {
79 Self::new(interpreter::instruction_table(), gas_table_spec(spec), spec)
80 }
81
82 pub fn new(
84 instruction_table: InstructionTable<WIRE, HOST>,
85 gas_table: GasTable,
86 spec: SpecId,
87 ) -> Self {
88 Self {
89 spec,
90 inner: Box::new(EthInstructionsInner {
91 instruction_table,
92 gas_table,
93 }),
94 }
95 }
96
97 #[inline]
99 pub fn insert_instruction(
100 &mut self,
101 opcode: u8,
102 instruction: Instruction<WIRE, HOST>,
103 gas: u16,
104 ) {
105 self.inner.instruction_table[opcode as usize] = instruction;
106 self.inner.gas_table[opcode as usize] = gas;
107 }
108
109 #[inline]
111 pub fn insert_gas(&mut self, opcode: u8, gas: u16) {
112 self.inner.gas_table[opcode as usize] = gas;
113 }
114
115 #[inline]
117 pub fn instruction_table(&self) -> &InstructionTable<WIRE, HOST> {
118 &self.inner.instruction_table
119 }
120
121 #[inline]
123 pub fn instruction_table_mut(&mut self) -> &mut InstructionTable<WIRE, HOST> {
124 &mut self.inner.instruction_table
125 }
126
127 #[inline]
129 pub fn gas_table(&self) -> &GasTable {
130 &self.inner.gas_table
131 }
132
133 #[inline]
135 pub fn gas_table_mut(&mut self) -> &mut GasTable {
136 &mut self.inner.gas_table
137 }
138}
139
140impl<IT, CTX> InstructionProvider for EthInstructions<IT, CTX>
141where
142 IT: InterpreterTypes,
143 CTX: Host,
144{
145 type InterpreterTypes = IT;
146 type Context = CTX;
147
148 #[inline]
149 fn instruction_table(&self) -> &InstructionTable<Self::InterpreterTypes, Self::Context> {
150 self.instruction_table()
151 }
152
153 #[inline]
154 fn gas_table(&self) -> &GasTable {
155 self.gas_table()
156 }
157}