revm_interpreter/instructions/
macros.rs1#[macro_export]
5#[collapse_debuginfo(yes)]
6macro_rules! require_non_staticcall {
7 ($interpreter:expr) => {
8 if $interpreter.runtime_flag.is_static() {
9 $interpreter.halt($crate::InstructionResult::StateChangeDuringStaticCall);
10 return;
11 }
12 };
13}
14
15#[macro_export]
17#[collapse_debuginfo(yes)]
18macro_rules! check {
19 ($interpreter:expr, $min:ident) => {
20 if !$interpreter
21 .runtime_flag
22 .spec_id()
23 .is_enabled_in(primitives::hardfork::SpecId::$min)
24 {
25 $interpreter.halt_not_activated();
26 return;
27 }
28 };
29}
30
31#[macro_export]
33#[collapse_debuginfo(yes)]
34macro_rules! gas {
35 ($interpreter:expr, $gas:expr) => {
36 $crate::gas!($interpreter, $gas, ())
37 };
38 ($interpreter:expr, $gas:expr, $ret:expr) => {
39 if !$interpreter.gas.record_cost($gas) {
40 $interpreter.halt_oog();
41 return $ret;
42 }
43 };
44}
45
46#[macro_export]
48#[collapse_debuginfo(yes)]
49macro_rules! berlin_load_account {
50 ($context:expr, $address:expr, $load_code:expr) => {
51 $crate::berlin_load_account!($context, $address, $load_code, ())
52 };
53 ($context:expr, $address:expr, $load_code:expr, $ret:expr) => {{
54 let cold_load_gas = $context
55 .interpreter
56 .gas_params
57 .cold_account_additional_cost();
58 let skip_cold_load = $context.interpreter.gas.remaining() < cold_load_gas;
59 match $context
60 .host
61 .load_account_info_skip_cold_load($address, $load_code, skip_cold_load)
62 {
63 Ok(account) => {
64 if account.is_cold {
65 $crate::gas!($context.interpreter, cold_load_gas, $ret);
66 }
67 account
68 }
69 Err(LoadError::ColdLoadSkipped) => {
70 $context.interpreter.halt_oog();
71 return $ret;
72 }
73 Err(LoadError::DBError) => {
74 $context.interpreter.halt_fatal();
75 return $ret;
76 }
77 }
78 }};
79}
80
81#[macro_export]
84#[collapse_debuginfo(yes)]
85macro_rules! resize_memory {
86 ($interpreter:expr, $offset:expr, $len:expr) => {
87 $crate::resize_memory!($interpreter, $offset, $len, ())
88 };
89 ($interpreter:expr, $offset:expr, $len:expr, $ret:expr) => {
90 if let Err(result) = $crate::interpreter::resize_memory(
91 &mut $interpreter.gas,
92 &mut $interpreter.memory,
93 &$interpreter.gas_params,
94 $offset,
95 $len,
96 ) {
97 $interpreter.halt(result);
98 return $ret;
99 }
100 };
101}
102
103#[macro_export]
105#[collapse_debuginfo(yes)]
106macro_rules! popn {
107 ([ $($x:ident),* ],$interpreter:expr $(,$ret:expr)? ) => {
108 let Some([$( $x ),*]) = $interpreter.stack.popn() else {
109 $interpreter.halt_underflow();
110 return $($ret)?;
111 };
112 };
113}
114
115#[doc(hidden)]
116#[macro_export]
117#[collapse_debuginfo(yes)]
118macro_rules! _count {
119 (@count) => { 0 };
120 (@count $head:tt $($tail:tt)*) => { 1 + _count!(@count $($tail)*) };
121 ($($arg:tt)*) => { _count!(@count $($arg)*) };
122}
123
124#[macro_export]
126#[collapse_debuginfo(yes)]
127macro_rules! popn_top {
128 ([ $($x:ident),* ], $top:ident, $interpreter:expr $(,$ret:expr)? ) => {
129 if $interpreter.stack.len() < (1 + $crate::_count!($($x)*)) {
138 $interpreter.halt_underflow();
139 return $($ret)?;
140 }
141 let ([$( $x ),*], $top) = unsafe { $interpreter.stack.popn_top().unwrap_unchecked() };
142 };
143}
144
145#[macro_export]
147#[collapse_debuginfo(yes)]
148macro_rules! push {
149 ($interpreter:expr, $x:expr $(,$ret:item)?) => (
150 if !($interpreter.stack.push($x)) {
151 $interpreter.halt_overflow();
152 return $($ret)?;
153 }
154 )
155}
156
157#[macro_export]
159#[collapse_debuginfo(yes)]
160macro_rules! as_u64_saturated {
161 ($v:expr) => {
162 match $v.as_limbs() {
163 x => {
164 if (x[1] == 0) & (x[2] == 0) & (x[3] == 0) {
165 x[0]
166 } else {
167 u64::MAX
168 }
169 }
170 }
171 };
172}
173
174#[macro_export]
176#[collapse_debuginfo(yes)]
177macro_rules! as_usize_saturated {
178 ($v:expr) => {
179 usize::try_from($crate::as_u64_saturated!($v)).unwrap_or(usize::MAX)
180 };
181}
182
183#[macro_export]
185#[collapse_debuginfo(yes)]
186macro_rules! as_isize_saturated {
187 ($v:expr) => {
188 isize::try_from($crate::as_u64_saturated!($v)).unwrap_or(isize::MAX)
191 };
192}
193
194#[macro_export]
196#[collapse_debuginfo(yes)]
197macro_rules! as_usize_or_fail {
198 ($interpreter:expr, $v:expr) => {
199 $crate::as_usize_or_fail_ret!($interpreter, $v, ())
200 };
201 ($interpreter:expr, $v:expr, $reason:expr) => {
202 $crate::as_usize_or_fail_ret!($interpreter, $v, $reason, ())
203 };
204}
205
206#[macro_export]
209#[collapse_debuginfo(yes)]
210macro_rules! as_usize_or_fail_ret {
211 ($interpreter:expr, $v:expr, $ret:expr) => {
212 $crate::as_usize_or_fail_ret!(
213 $interpreter,
214 $v,
215 $crate::InstructionResult::InvalidOperandOOG,
216 $ret
217 )
218 };
219
220 ($interpreter:expr, $v:expr, $reason:expr, $ret:expr) => {
221 match $v.as_limbs() {
222 x => {
223 if (x[0] > usize::MAX as u64) | (x[1] != 0) | (x[2] != 0) | (x[3] != 0) {
224 $interpreter.halt($reason);
225 return $ret;
226 }
227 x[0] as usize
228 }
229 }
230 };
231}