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	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}