evm_interpreter/eval/
mod.rs

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}