@@ -27,7 +27,10 @@ pub mod tx_info;
27
27
/// Utility functions and helpers for instruction implementation.
28
28
pub mod utility;
29
29
30
- use crate :: { interpreter_types:: InterpreterTypes , Host , InstructionContext } ;
30
+ use crate :: {
31
+ interpreter_types:: { InterpreterTypes , Jumps , LoopControl } ,
32
+ Host , InstructionContext ,
33
+ } ;
31
34
32
35
/// EVM opcode function signature.
33
36
pub type Instruction < W , H > = fn ( InstructionContext < ' _ , H , W > ) ;
@@ -211,6 +214,59 @@ const fn instruction_table_impl<WIRE: InterpreterTypes, H: Host + ?Sized>(
211
214
table
212
215
}
213
216
217
+ /// Returns the tail call instruction table for the given interpreter types and host.
218
+ #[ inline]
219
+ pub const fn instruction_table_tail < WIRE : InterpreterTypes , H : Host + ?Sized > (
220
+ ) -> [ Instruction < WIRE , H > ; 256 ] {
221
+ const {
222
+ macro_rules! wrap {
223
+ ( $( $idx: expr) ,* $( , ) ?) => {
224
+ [
225
+ $(
226
+ tail_call_instr:: <$idx, H , WIRE >,
227
+ ) *
228
+ ]
229
+ } ;
230
+ }
231
+ #[ rustfmt:: skip]
232
+ let x = wrap ! (
233
+ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 ,
234
+ 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30 , 31 ,
235
+ 32 , 33 , 34 , 35 , 36 , 37 , 38 , 39 , 40 , 41 , 42 , 43 , 44 , 45 , 46 , 47 ,
236
+ 48 , 49 , 50 , 51 , 52 , 53 , 54 , 55 , 56 , 57 , 58 , 59 , 60 , 61 , 62 , 63 ,
237
+ 64 , 65 , 66 , 67 , 68 , 69 , 70 , 71 , 72 , 73 , 74 , 75 , 76 , 77 , 78 , 79 ,
238
+ 80 , 81 , 82 , 83 , 84 , 85 , 86 , 87 , 88 , 89 , 90 , 91 , 92 , 93 , 94 , 95 ,
239
+ 96 , 97 , 98 , 99 , 100 , 101 , 102 , 103 , 104 , 105 , 106 , 107 , 108 , 109 , 110 , 111 ,
240
+ 112 , 113 , 114 , 115 , 116 , 117 , 118 , 119 , 120 , 121 , 122 , 123 , 124 , 125 , 126 , 127 ,
241
+ 128 , 129 , 130 , 131 , 132 , 133 , 134 , 135 , 136 , 137 , 138 , 139 , 140 , 141 , 142 , 143 ,
242
+ 144 , 145 , 146 , 147 , 148 , 149 , 150 , 151 , 152 , 153 , 154 , 155 , 156 , 157 , 158 , 159 ,
243
+ 160 , 161 , 162 , 163 , 164 , 165 , 166 , 167 , 168 , 169 , 170 , 171 , 172 , 173 , 174 , 175 ,
244
+ 176 , 177 , 178 , 179 , 180 , 181 , 182 , 183 , 184 , 185 , 186 , 187 , 188 , 189 , 190 , 191 ,
245
+ 192 , 193 , 194 , 195 , 196 , 197 , 198 , 199 , 200 , 201 , 202 , 203 , 204 , 205 , 206 , 207 ,
246
+ 208 , 209 , 210 , 211 , 212 , 213 , 214 , 215 , 216 , 217 , 218 , 219 , 220 , 221 , 222 , 223 ,
247
+ 224 , 225 , 226 , 227 , 228 , 229 , 230 , 231 , 232 , 233 , 234 , 235 , 236 , 237 , 238 , 239 ,
248
+ 240 , 241 , 242 , 243 , 244 , 245 , 246 , 247 , 248 , 249 , 250 , 251 , 252 , 253 , 254 , 255 ,
249
+ ) ;
250
+ x
251
+ }
252
+ }
253
+
254
+ pub ( crate ) fn tail_call_instr < const OP : u8 , H : Host + ?Sized , W : InterpreterTypes > (
255
+ mut context : InstructionContext < ' _ , H , W > ,
256
+ ) {
257
+ ( const { instruction_table :: < W , H > ( ) [ OP as usize ] } ) ( context. reborrow ( ) ) ;
258
+
259
+ if context. interpreter . bytecode . is_end ( ) {
260
+ return ;
261
+ }
262
+
263
+ let instruction_table = const { & instruction_table_tail :: < W , H > ( ) } ;
264
+ let opcode = context. interpreter . bytecode . opcode ( ) ;
265
+ context. interpreter . bytecode . relative_jump ( 1 ) ;
266
+ /* become */
267
+ instruction_table[ opcode as usize ] ( context) ;
268
+ }
269
+
214
270
#[ cfg( test) ]
215
271
mod tests {
216
272
use super :: instruction_table;
0 commit comments