@@ -2,11 +2,12 @@ use alloc::string::ToString;
2
2
use alloy_primitives:: map:: HashMap ;
3
3
use alloy_rpc_types_trace:: opcode:: OpcodeGas ;
4
4
use revm:: {
5
+ bytecode:: opcode:: { self , OpCode } ,
5
6
interpreter:: {
6
- opcode :: { self , OpCode } ,
7
+ interpreter_types :: { Immediates , Jumps , LoopControl } ,
7
8
Interpreter ,
8
9
} ,
9
- Database , EvmContext , Inspector ,
10
+ Inspector ,
10
11
} ;
11
12
12
13
/// An Inspector that counts opcodes and measures gas usage per opcode.
@@ -58,80 +59,81 @@ impl OpcodeGasInspector {
58
59
}
59
60
}
60
61
61
- impl < DB > Inspector < DB > for OpcodeGasInspector
62
- where
63
- DB : Database ,
64
- {
65
- fn step ( & mut self , interp : & mut Interpreter , _context : & mut EvmContext < DB > ) {
66
- let opcode_value = interp. current_opcode ( ) ;
62
+ impl < CTX > Inspector < CTX > for OpcodeGasInspector {
63
+ fn step ( & mut self , interp : & mut Interpreter , _context : & mut CTX ) {
64
+ let opcode_value = interp. bytecode . opcode ( ) ;
67
65
if let Some ( opcode) = OpCode :: new ( opcode_value) {
68
66
// keep track of opcode counts
69
67
* self . opcode_counts . entry ( opcode) . or_default ( ) += 1 ;
70
68
71
69
// keep track of the last opcode executed
72
- self . last_opcode_gas_remaining = Some ( ( opcode, interp. gas ( ) . remaining ( ) ) ) ;
70
+ self . last_opcode_gas_remaining = Some ( ( opcode, interp. control . gas ( ) . remaining ( ) ) ) ;
73
71
}
74
72
}
75
73
76
- fn step_end ( & mut self , interp : & mut Interpreter , _context : & mut EvmContext < DB > ) {
74
+ fn step_end ( & mut self , interp : & mut Interpreter , _context : & mut CTX ) {
77
75
// update gas usage for the last opcode
78
76
if let Some ( ( opcode, gas_remaining) ) = self . last_opcode_gas_remaining . take ( ) {
79
- let gas_cost = gas_remaining. saturating_sub ( interp. gas ( ) . remaining ( ) ) ;
77
+ let gas_cost = gas_remaining. saturating_sub ( interp. control . gas ( ) . remaining ( ) ) ;
80
78
* self . opcode_gas . entry ( opcode) . or_default ( ) += gas_cost;
81
79
}
82
80
}
83
81
}
84
82
85
- /// Accepts [OpCode] and a slice of bytecode immediately after it and returns the size of immediate
83
+ /// Accepts Bytecode that implements [Immediates] and returns the size of immediate
86
84
/// value.
87
85
///
88
86
/// Primarily needed to handle a special case of RJUMPV opcode.
89
- pub fn immediate_size ( op : OpCode , bytes_after : & [ u8 ] ) -> u8 {
90
- match op. get ( ) {
91
- opcode:: RJUMPV => {
92
- if bytes_after. is_empty ( ) {
93
- return 0 ;
94
- }
95
- 1 + ( bytes_after[ 0 ] + 1 ) * 2
96
- }
97
- _ => op. info ( ) . immediate_size ( ) ,
87
+ pub fn immediate_size ( bytecode : & impl Immediates ) -> u8 {
88
+ let opcode = bytecode. read_u8 ( ) ;
89
+ if opcode == opcode:: RJUMPV {
90
+ let vtable_size = bytecode. read_slice ( 2 ) [ 2 ] ;
91
+ return 1 + ( vtable_size + 1 ) * 2 ;
98
92
}
93
+ let Some ( opcode) = OpCode :: new ( opcode) else { return 0 } ;
94
+ opcode. info ( ) . immediate_size ( )
99
95
}
100
96
101
97
#[ cfg( test) ]
102
98
mod tests {
103
99
use super :: * ;
104
100
use revm:: {
105
- db:: { CacheDB , EmptyDB } ,
106
- interpreter:: { opcode, Contract } ,
101
+ bytecode:: Bytecode ,
102
+ database:: CacheDB ,
103
+ database_interface:: EmptyDB ,
104
+ interpreter:: { interpreter:: ExtBytecode , InputsImpl , SharedMemory } ,
105
+ primitives:: { hardfork:: SpecId , Bytes } ,
106
+ Context , MainContext ,
107
107
} ;
108
+ use std:: { cell:: RefCell , rc:: Rc } ;
108
109
109
110
#[ test]
110
111
fn test_opcode_counter_inspector ( ) {
111
112
let mut opcode_counter = OpcodeGasInspector :: new ( ) ;
112
- let contract = Contract :: default ( ) ;
113
- let mut interpreter = Interpreter :: new ( contract, 10000 , false ) ;
114
- let db = CacheDB :: new ( EmptyDB :: default ( ) ) ;
115
113
116
- let opcodes = [
117
- OpCode :: new ( opcode:: ADD ) . unwrap ( ) ,
118
- OpCode :: new ( opcode:: ADD ) . unwrap ( ) ,
119
- OpCode :: new ( opcode:: ADD ) . unwrap ( ) ,
120
- OpCode :: new ( opcode:: BYTE ) . unwrap ( ) ,
121
- ] ;
114
+ let opcodes = [ opcode:: ADD , opcode:: ADD , opcode:: ADD , opcode:: BYTE ] ;
115
+
116
+ let bytecode = Bytecode :: new_raw ( Bytes :: from ( opcodes) ) ;
117
+ let mut interpreter = Interpreter :: new (
118
+ Rc :: new ( RefCell :: new ( SharedMemory :: new ( ) ) ) ,
119
+ ExtBytecode :: new ( bytecode) ,
120
+ InputsImpl :: default ( ) ,
121
+ false ,
122
+ false ,
123
+ SpecId :: LATEST ,
124
+ u64:: MAX ,
125
+ ) ;
126
+ let db = CacheDB :: new ( EmptyDB :: default ( ) ) ;
122
127
123
- for & opcode in & opcodes {
124
- interpreter . instruction_pointer = & opcode . get ( ) ;
125
- opcode_counter. step ( & mut interpreter, & mut EvmContext :: new ( db . clone ( ) ) ) ;
128
+ let mut context = Context :: mainnet ( ) . with_db ( db ) ;
129
+ for _ in & opcodes {
130
+ opcode_counter. step ( & mut interpreter, & mut context ) ;
126
131
}
127
132
}
128
133
129
134
#[ test]
130
135
fn test_with_variety_of_opcodes ( ) {
131
136
let mut opcode_counter = OpcodeGasInspector :: new ( ) ;
132
- let contract = Contract :: default ( ) ;
133
- let mut interpreter = Interpreter :: new ( contract, 2024 , false ) ;
134
- let db = CacheDB :: new ( EmptyDB :: default ( ) ) ;
135
137
136
138
let opcodes = [
137
139
opcode:: PUSH1 ,
@@ -142,9 +144,21 @@ mod tests {
142
144
opcode:: STOP ,
143
145
] ;
144
146
145
- for opcode in opcodes. iter ( ) {
146
- interpreter. instruction_pointer = opcode;
147
- opcode_counter. step ( & mut interpreter, & mut EvmContext :: new ( db. clone ( ) ) ) ;
147
+ let bytecode = Bytecode :: new_raw ( Bytes :: from ( opcodes) ) ;
148
+ let mut interpreter = Interpreter :: new (
149
+ Rc :: new ( RefCell :: new ( SharedMemory :: new ( ) ) ) ,
150
+ ExtBytecode :: new ( bytecode) ,
151
+ InputsImpl :: default ( ) ,
152
+ false ,
153
+ false ,
154
+ SpecId :: LATEST ,
155
+ u64:: MAX ,
156
+ ) ;
157
+ let db = CacheDB :: new ( EmptyDB :: default ( ) ) ;
158
+
159
+ let mut context = Context :: mainnet ( ) . with_db ( db) ;
160
+ for _ in opcodes. iter ( ) {
161
+ opcode_counter. step ( & mut interpreter, & mut context) ;
148
162
}
149
163
}
150
164
}
0 commit comments