1#[macro_use]
2mod macros;
3mod arithmetic;
4mod bitwise;
5mod misc;
6mod system;
7
8use alloc::boxed::Box;
9use core::ops::{BitAnd, BitOr, BitXor};
10use primitive_types::U256;
11
12use crate::{
13 error::{CallCreateOpcode, CallCreateTrap, ExitException, ExitSucceed},
14 etable::Control,
15 machine::Machine,
16 opcode::Opcode,
17 runtime::{GasState, RuntimeBackend, RuntimeEnvironment, RuntimeState},
18};
19
20pub fn eval_pass<S, H, Tr>(
21 _machine: &mut Machine<S>,
22 _handle: &mut H,
23 _position: usize,
24) -> Control<Tr> {
25 Control::Continue(1)
26}
27
28pub fn eval_stop<S, H, Tr>(
29 _machine: &mut Machine<S>,
30 _handle: &mut H,
31 _position: usize,
32) -> Control<Tr> {
33 Control::Exit(ExitSucceed::Stopped.into())
34}
35
36pub fn eval_add<S, H, Tr>(
37 machine: &mut Machine<S>,
38 _handle: &mut H,
39 _position: usize,
40) -> Control<Tr> {
41 op2_u256_tuple!(machine, overflowing_add)
42}
43
44pub fn eval_mul<S, H, Tr>(
45 machine: &mut Machine<S>,
46 _handle: &mut H,
47 _position: usize,
48) -> Control<Tr> {
49 op2_u256_tuple!(machine, overflowing_mul)
50}
51
52pub fn eval_sub<S, H, Tr>(
53 machine: &mut Machine<S>,
54 _handle: &mut H,
55 _position: usize,
56) -> Control<Tr> {
57 op2_u256_tuple!(machine, overflowing_sub)
58}
59
60pub fn eval_div<S, H, Tr>(
61 machine: &mut Machine<S>,
62 _handle: &mut H,
63 _position: usize,
64) -> Control<Tr> {
65 op2_u256_fn!(machine, self::arithmetic::div)
66}
67
68pub fn eval_sdiv<S, H, Tr>(
69 machine: &mut Machine<S>,
70 _handle: &mut H,
71 _position: usize,
72) -> Control<Tr> {
73 op2_u256_fn!(machine, self::arithmetic::sdiv)
74}
75
76pub fn eval_mod<S, H, Tr>(
77 machine: &mut Machine<S>,
78 _handle: &mut H,
79 _position: usize,
80) -> Control<Tr> {
81 op2_u256_fn!(machine, self::arithmetic::rem)
82}
83
84pub fn eval_smod<S, H, Tr>(
85 machine: &mut Machine<S>,
86 _handle: &mut H,
87 _position: usize,
88) -> Control<Tr> {
89 op2_u256_fn!(machine, self::arithmetic::srem)
90}
91
92pub fn eval_addmod<S, H, Tr>(
93 machine: &mut Machine<S>,
94 _handle: &mut H,
95 _position: usize,
96) -> Control<Tr> {
97 op3_u256_fn!(machine, self::arithmetic::addmod)
98}
99
100pub fn eval_mulmod<S, H, Tr>(
101 machine: &mut Machine<S>,
102 _handle: &mut H,
103 _position: usize,
104) -> Control<Tr> {
105 op3_u256_fn!(machine, self::arithmetic::mulmod)
106}
107
108pub fn eval_exp<S, H, Tr>(
109 machine: &mut Machine<S>,
110 _handle: &mut H,
111 _position: usize,
112) -> Control<Tr> {
113 op2_u256_fn!(machine, self::arithmetic::exp)
114}
115
116pub fn eval_signextend<S, H, Tr>(
117 machine: &mut Machine<S>,
118 _handle: &mut H,
119 _position: usize,
120) -> Control<Tr> {
121 op2_u256_fn!(machine, self::arithmetic::signextend)
122}
123
124pub fn eval_lt<S, H, Tr>(
125 machine: &mut Machine<S>,
126 _handle: &mut H,
127 _position: usize,
128) -> Control<Tr> {
129 op2_u256_bool_ref!(machine, lt)
130}
131
132pub fn eval_gt<S, H, Tr>(
133 machine: &mut Machine<S>,
134 _handle: &mut H,
135 _position: usize,
136) -> Control<Tr> {
137 op2_u256_bool_ref!(machine, gt)
138}
139
140pub fn eval_slt<S, H, Tr>(
141 machine: &mut Machine<S>,
142 _handle: &mut H,
143 _position: usize,
144) -> Control<Tr> {
145 op2_u256_fn!(machine, self::bitwise::slt)
146}
147
148pub fn eval_sgt<S, H, Tr>(
149 machine: &mut Machine<S>,
150 _handle: &mut H,
151 _position: usize,
152) -> Control<Tr> {
153 op2_u256_fn!(machine, self::bitwise::sgt)
154}
155
156pub fn eval_eq<S, H, Tr>(
157 machine: &mut Machine<S>,
158 _handle: &mut H,
159 _position: usize,
160) -> Control<Tr> {
161 op2_u256_bool_ref!(machine, eq)
162}
163
164pub fn eval_iszero<S, H, Tr>(
165 machine: &mut Machine<S>,
166 _handle: &mut H,
167 _position: usize,
168) -> Control<Tr> {
169 op1_u256_fn!(machine, self::bitwise::iszero)
170}
171
172pub fn eval_and<S, H, Tr>(
173 machine: &mut Machine<S>,
174 _handle: &mut H,
175 _position: usize,
176) -> Control<Tr> {
177 op2_u256!(machine, bitand)
178}
179
180pub fn eval_or<S, H, Tr>(
181 machine: &mut Machine<S>,
182 _handle: &mut H,
183 _position: usize,
184) -> Control<Tr> {
185 op2_u256!(machine, bitor)
186}
187
188pub fn eval_xor<S, H, Tr>(
189 machine: &mut Machine<S>,
190 _handle: &mut H,
191 _position: usize,
192) -> Control<Tr> {
193 op2_u256!(machine, bitxor)
194}
195
196pub fn eval_not<S, H, Tr>(
197 machine: &mut Machine<S>,
198 _handle: &mut H,
199 _position: usize,
200) -> Control<Tr> {
201 op1_u256_fn!(machine, self::bitwise::not)
202}
203
204pub fn eval_byte<S, H, Tr>(
205 machine: &mut Machine<S>,
206 _handle: &mut H,
207 _position: usize,
208) -> Control<Tr> {
209 op2_u256_fn!(machine, self::bitwise::byte)
210}
211
212pub fn eval_shl<S, H, Tr>(
213 machine: &mut Machine<S>,
214 _handle: &mut H,
215 _position: usize,
216) -> Control<Tr> {
217 op2_u256_fn!(machine, self::bitwise::shl)
218}
219
220pub fn eval_shr<S, H, Tr>(
221 machine: &mut Machine<S>,
222 _handle: &mut H,
223 _position: usize,
224) -> Control<Tr> {
225 op2_u256_fn!(machine, self::bitwise::shr)
226}
227
228pub fn eval_sar<S, H, Tr>(
229 machine: &mut Machine<S>,
230 _handle: &mut H,
231 _position: usize,
232) -> Control<Tr> {
233 op2_u256_fn!(machine, self::bitwise::sar)
234}
235
236pub fn eval_codesize<S, H, Tr>(
237 machine: &mut Machine<S>,
238 _handle: &mut H,
239 _position: usize,
240) -> Control<Tr> {
241 self::misc::codesize(machine)
242}
243
244pub fn eval_codecopy<S, H, Tr>(
245 machine: &mut Machine<S>,
246 _handle: &mut H,
247 _position: usize,
248) -> Control<Tr> {
249 self::misc::codecopy(machine)
250}
251
252pub fn eval_calldataload<S, H, Tr>(
253 machine: &mut Machine<S>,
254 _handle: &mut H,
255 _position: usize,
256) -> Control<Tr> {
257 self::misc::calldataload(machine)
258}
259
260pub fn eval_calldatasize<S, H, Tr>(
261 machine: &mut Machine<S>,
262 _handle: &mut H,
263 _position: usize,
264) -> Control<Tr> {
265 self::misc::calldatasize(machine)
266}
267
268pub fn eval_calldatacopy<S, H, Tr>(
269 machine: &mut Machine<S>,
270 _handle: &mut H,
271 _position: usize,
272) -> Control<Tr> {
273 self::misc::calldatacopy(machine)
274}
275
276pub fn eval_pop<S, H, Tr>(
277 machine: &mut Machine<S>,
278 _handle: &mut H,
279 _position: usize,
280) -> Control<Tr> {
281 self::misc::pop(machine)
282}
283
284pub fn eval_mload<S, H, Tr>(
285 machine: &mut Machine<S>,
286 _handle: &mut H,
287 _position: usize,
288) -> Control<Tr> {
289 self::misc::mload(machine)
290}
291
292pub fn eval_mstore<S, H, Tr>(
293 machine: &mut Machine<S>,
294 _handle: &mut H,
295 _position: usize,
296) -> Control<Tr> {
297 self::misc::mstore(machine)
298}
299
300pub fn eval_mstore8<S, H, Tr>(
301 machine: &mut Machine<S>,
302 _handle: &mut H,
303 _position: usize,
304) -> Control<Tr> {
305 self::misc::mstore8(machine)
306}
307
308pub fn eval_jump<S, H, Tr>(
309 machine: &mut Machine<S>,
310 _handle: &mut H,
311 _position: usize,
312) -> Control<Tr> {
313 self::misc::jump(machine)
314}
315
316pub fn eval_jumpi<S, H, Tr>(
317 machine: &mut Machine<S>,
318 _handle: &mut H,
319 _position: usize,
320) -> Control<Tr> {
321 self::misc::jumpi(machine)
322}
323
324pub fn eval_pc<S, H, Tr>(
325 machine: &mut Machine<S>,
326 _handle: &mut H,
327 position: usize,
328) -> Control<Tr> {
329 self::misc::pc(machine, position)
330}
331
332pub fn eval_msize<S, H, Tr>(
333 machine: &mut Machine<S>,
334 _handle: &mut H,
335 _position: usize,
336) -> Control<Tr> {
337 self::misc::msize(machine)
338}
339
340pub fn eval_jumpdest<S, H, Tr>(
341 _machine: &mut Machine<S>,
342 _handle: &mut H,
343 _position: usize,
344) -> Control<Tr> {
345 Control::Continue(1)
346}
347
348pub fn eval_mcopy<S, H, Tr>(
349 machine: &mut Machine<S>,
350 _handle: &mut H,
351 _position: usize,
352) -> Control<Tr> {
353 self::misc::mcopy(machine)
354}
355
356macro_rules! eval_push {
357 ($($num:expr),*) => {
358 $(paste::paste! {
359 pub fn [<eval_push $num>]<S, H, Tr>(
360 machine: &mut Machine<S>,
361 _handle: &mut H,
362 position: usize,
363 ) -> Control<Tr> {
364 self::misc::push(machine, $num, position)
365 }
366 })*
367 };
368}
369
370eval_push! {
371 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
372 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32
373}
374
375macro_rules! eval_dup {
376 ($($num:expr),*) => {
377 $(paste::paste! {
378 pub fn [<eval_dup $num>]<S, H, Tr>(
379 machine: &mut Machine<S>,
380 _handle: &mut H,
381 _position: usize,
382 ) -> Control<Tr> {
383 self::misc::dup(machine, $num)
384 }
385 })*
386 };
387}
388
389eval_dup! { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }
390
391macro_rules! eval_swap {
392 ($($num:expr),*) => {
393 $(paste::paste! {
394 pub fn [<eval_swap $num>]<S, H, Tr>(
395 machine: &mut Machine<S>,
396 _handle: &mut H,
397 _position: usize,
398 ) -> Control<Tr> {
399 self::misc::swap(machine, $num)
400 }
401 })*
402 };
403}
404
405eval_swap! { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }
406
407pub fn eval_return<S, H, Tr>(
408 machine: &mut Machine<S>,
409 _handle: &mut H,
410 _position: usize,
411) -> Control<Tr> {
412 self::misc::ret(machine)
413}
414
415pub fn eval_revert<S, H, Tr>(
416 machine: &mut Machine<S>,
417 _handle: &mut H,
418 _position: usize,
419) -> Control<Tr> {
420 self::misc::revert(machine)
421}
422
423pub fn eval_invalid<S, H, Tr>(
424 _machine: &mut Machine<S>,
425 _handle: &mut H,
426 _position: usize,
427) -> Control<Tr> {
428 Control::Exit(ExitException::DesignatedInvalid.into())
429}
430
431pub fn eval_unknown<S, H, Tr>(
432 machine: &mut Machine<S>,
433 _handle: &mut H,
434 position: usize,
435) -> Control<Tr> {
436 Control::Exit(ExitException::InvalidOpcode(Opcode(machine.code()[position])).into())
437}
438
439pub fn eval_sha3<S: AsRef<RuntimeState>, H: RuntimeEnvironment + RuntimeBackend, Tr>(
440 machine: &mut Machine<S>,
441 _handle: &mut H,
442 _position: usize,
443) -> Control<Tr> {
444 self::system::sha3(machine)
445}
446
447pub fn eval_address<S: AsRef<RuntimeState>, H: RuntimeEnvironment + RuntimeBackend, Tr>(
448 machine: &mut Machine<S>,
449 _handle: &mut H,
450 _position: usize,
451) -> Control<Tr> {
452 self::system::address(machine)
453}
454
455pub fn eval_balance<S: AsRef<RuntimeState>, H: RuntimeEnvironment + RuntimeBackend, Tr>(
456 machine: &mut Machine<S>,
457 handle: &mut H,
458 _position: usize,
459) -> Control<Tr> {
460 self::system::balance(machine, handle)
461}
462
463pub fn eval_selfbalance<S: AsRef<RuntimeState>, H: RuntimeEnvironment + RuntimeBackend, Tr>(
464 machine: &mut Machine<S>,
465 handle: &mut H,
466 _position: usize,
467) -> Control<Tr> {
468 self::system::selfbalance(machine, handle)
469}
470
471pub fn eval_origin<S: AsRef<RuntimeState>, H: RuntimeEnvironment + RuntimeBackend, Tr>(
472 machine: &mut Machine<S>,
473 handle: &mut H,
474 _position: usize,
475) -> Control<Tr> {
476 self::system::origin(machine, handle)
477}
478
479pub fn eval_caller<S: AsRef<RuntimeState>, H: RuntimeEnvironment + RuntimeBackend, Tr>(
480 machine: &mut Machine<S>,
481 _handle: &mut H,
482 _position: usize,
483) -> Control<Tr> {
484 self::system::caller(machine)
485}
486
487pub fn eval_callvalue<S: AsRef<RuntimeState>, H: RuntimeEnvironment + RuntimeBackend, Tr>(
488 machine: &mut Machine<S>,
489 _handle: &mut H,
490 _position: usize,
491) -> Control<Tr> {
492 self::system::callvalue(machine)
493}
494
495pub fn eval_gasprice<S: AsRef<RuntimeState>, H: RuntimeEnvironment + RuntimeBackend, Tr>(
496 machine: &mut Machine<S>,
497 handle: &mut H,
498 _position: usize,
499) -> Control<Tr> {
500 self::system::gasprice(machine, handle)
501}
502
503pub fn eval_extcodesize<S: AsRef<RuntimeState>, H: RuntimeEnvironment + RuntimeBackend, Tr>(
504 machine: &mut Machine<S>,
505 handle: &mut H,
506 _position: usize,
507) -> Control<Tr> {
508 self::system::extcodesize(machine, handle)
509}
510
511pub fn eval_extcodehash<S: AsRef<RuntimeState>, H: RuntimeEnvironment + RuntimeBackend, Tr>(
512 machine: &mut Machine<S>,
513 handle: &mut H,
514 _position: usize,
515) -> Control<Tr> {
516 self::system::extcodehash(machine, handle)
517}
518
519pub fn eval_extcodecopy<S: AsRef<RuntimeState>, H: RuntimeEnvironment + RuntimeBackend, Tr>(
520 machine: &mut Machine<S>,
521 handle: &mut H,
522 _position: usize,
523) -> Control<Tr> {
524 self::system::extcodecopy(machine, handle)
525}
526
527pub fn eval_returndatasize<S: AsRef<RuntimeState>, H: RuntimeEnvironment + RuntimeBackend, Tr>(
528 machine: &mut Machine<S>,
529 _handle: &mut H,
530 _position: usize,
531) -> Control<Tr> {
532 self::system::returndatasize(machine)
533}
534
535pub fn eval_returndatacopy<S: AsRef<RuntimeState>, H: RuntimeEnvironment + RuntimeBackend, Tr>(
536 machine: &mut Machine<S>,
537 _handle: &mut H,
538 _position: usize,
539) -> Control<Tr> {
540 self::system::returndatacopy(machine)
541}
542
543pub fn eval_blockhash<S: AsRef<RuntimeState>, H: RuntimeEnvironment + RuntimeBackend, Tr>(
544 machine: &mut Machine<S>,
545 handle: &mut H,
546 _position: usize,
547) -> Control<Tr> {
548 self::system::blockhash(machine, handle)
549}
550
551pub fn eval_coinbase<S: AsRef<RuntimeState>, H: RuntimeEnvironment + RuntimeBackend, Tr>(
552 machine: &mut Machine<S>,
553 handle: &mut H,
554 _position: usize,
555) -> Control<Tr> {
556 self::system::coinbase(machine, handle)
557}
558
559pub fn eval_timestamp<S: AsRef<RuntimeState>, H: RuntimeEnvironment + RuntimeBackend, Tr>(
560 machine: &mut Machine<S>,
561 handle: &mut H,
562 _position: usize,
563) -> Control<Tr> {
564 self::system::timestamp(machine, handle)
565}
566
567pub fn eval_number<S: AsRef<RuntimeState>, H: RuntimeEnvironment + RuntimeBackend, Tr>(
568 machine: &mut Machine<S>,
569 handle: &mut H,
570 _position: usize,
571) -> Control<Tr> {
572 self::system::number(machine, handle)
573}
574
575pub fn eval_difficulty<S: AsRef<RuntimeState>, H: RuntimeEnvironment + RuntimeBackend, Tr>(
576 machine: &mut Machine<S>,
577 handle: &mut H,
578 _position: usize,
579) -> Control<Tr> {
580 self::system::prevrandao(machine, handle)
581}
582
583pub fn eval_gaslimit<S: AsRef<RuntimeState>, H: RuntimeEnvironment + RuntimeBackend, Tr>(
584 machine: &mut Machine<S>,
585 handle: &mut H,
586 _position: usize,
587) -> Control<Tr> {
588 self::system::gaslimit(machine, handle)
589}
590
591pub fn eval_sload<S: AsRef<RuntimeState>, H: RuntimeEnvironment + RuntimeBackend, Tr>(
592 machine: &mut Machine<S>,
593 handle: &mut H,
594 _position: usize,
595) -> Control<Tr> {
596 self::system::sload(machine, handle)
597}
598
599pub fn eval_sstore<S: AsRef<RuntimeState>, H: RuntimeEnvironment + RuntimeBackend, Tr>(
600 machine: &mut Machine<S>,
601 handle: &mut H,
602 _position: usize,
603) -> Control<Tr> {
604 self::system::sstore(machine, handle)
605}
606
607pub fn eval_gas<S: GasState, H: RuntimeEnvironment + RuntimeBackend, Tr>(
608 machine: &mut Machine<S>,
609 handle: &mut H,
610 _position: usize,
611) -> Control<Tr> {
612 self::system::gas(machine, handle)
613}
614
615pub fn eval_tload<S: AsRef<RuntimeState>, H: RuntimeEnvironment + RuntimeBackend, Tr>(
616 machine: &mut Machine<S>,
617 handle: &mut H,
618 _position: usize,
619) -> Control<Tr> {
620 self::system::tload(machine, handle)
621}
622
623pub fn eval_tstore<S: AsRef<RuntimeState>, H: RuntimeEnvironment + RuntimeBackend, Tr>(
624 machine: &mut Machine<S>,
625 handle: &mut H,
626 _position: usize,
627) -> Control<Tr> {
628 self::system::tstore(machine, handle)
629}
630
631macro_rules! eval_log {
632 ($($num:expr),*) => {
633 $(paste::paste! {
634 pub fn [<eval_log $num>]<S: AsRef<RuntimeState>, H: RuntimeEnvironment + RuntimeBackend, Tr>(
635 machine: &mut Machine<S>,
636 handle: &mut H,
637 _position: usize,
638 ) -> Control<Tr> {
639 self::system::log(machine, $num, handle)
640 }
641 })*
642 };
643}
644
645eval_log! { 0, 1, 2, 3, 4 }
646
647pub fn eval_suicide<S: AsRef<RuntimeState>, H: RuntimeEnvironment + RuntimeBackend, Tr>(
648 machine: &mut Machine<S>,
649 handle: &mut H,
650 _position: usize,
651) -> Control<Tr> {
652 self::system::suicide(machine, handle)
653}
654
655pub fn eval_chainid<S: AsRef<RuntimeState>, H: RuntimeEnvironment + RuntimeBackend, Tr>(
656 machine: &mut Machine<S>,
657 handle: &mut H,
658 _position: usize,
659) -> Control<Tr> {
660 self::system::chainid(machine, handle)
661}
662
663pub fn eval_basefee<S: AsRef<RuntimeState>, H: RuntimeEnvironment + RuntimeBackend, Tr>(
664 machine: &mut Machine<S>,
665 handle: &mut H,
666 _position: usize,
667) -> Control<Tr> {
668 self::system::basefee(machine, handle)
669}
670
671pub fn eval_call_create_trap<
672 S: AsRef<RuntimeState> + AsMut<RuntimeState>,
673 H,
674 Tr: From<CallCreateTrap>,
675>(
676 machine: &mut Machine<S>,
677 _handle: &mut H,
678 position: usize,
679) -> Control<Tr> {
680 let raw_opcode = Opcode(machine.code()[position]);
681
682 let opcode = match raw_opcode {
683 Opcode::CREATE => CallCreateOpcode::Create,
684 Opcode::CREATE2 => CallCreateOpcode::Create2,
685 Opcode::CALL => CallCreateOpcode::Call,
686 Opcode::CALLCODE => CallCreateOpcode::CallCode,
687 Opcode::DELEGATECALL => CallCreateOpcode::DelegateCall,
688 Opcode::STATICCALL => CallCreateOpcode::StaticCall,
689 _ => return Control::Exit(Err(ExitException::InvalidOpcode(raw_opcode).into())),
690 };
691
692 let trap = match CallCreateTrap::new_from(opcode, machine) {
693 Ok(trap) => trap,
694 Err(err) => return Control::Exit(Err(err)),
695 };
696
697 Control::Trap(Box::new(trap.into()))
698}