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