revm_interpreter/instructions/
macros.rs1#[macro_export]
5#[collapse_debuginfo(yes)]
6macro_rules! tri {
7 ($e:expr) => {
8 match $e {
9 Some(v) => v,
10 None => return None,
11 }
12 };
13}
14
15#[macro_export]
17#[collapse_debuginfo(yes)]
18macro_rules! require_non_staticcall {
19 ($interpreter:expr) => {
20 if $interpreter.runtime_flag.is_static() {
21 $interpreter.halt($crate::InstructionResult::StateChangeDuringStaticCall);
22 return;
23 }
24 };
25}
26
27#[macro_export]
30#[collapse_debuginfo(yes)]
31macro_rules! otry {
32 ($expression: expr) => {{
33 let Some(value) = $expression else {
34 return;
35 };
36 value
37 }};
38}
39
40#[macro_export]
42#[collapse_debuginfo(yes)]
43macro_rules! check {
44 ($interpreter:expr, $min:ident) => {
45 if !$interpreter
46 .runtime_flag
47 .spec_id()
48 .is_enabled_in(primitives::hardfork::SpecId::$min)
49 {
50 $interpreter.halt_not_activated();
51 return;
52 }
53 };
54}
55
56#[macro_export]
58#[collapse_debuginfo(yes)]
59macro_rules! gas {
60 ($interpreter:expr, $gas:expr) => {
61 $crate::gas!($interpreter, $gas, ())
62 };
63 ($interpreter:expr, $gas:expr, $ret:expr) => {
64 if !$interpreter.gas.record_cost($gas) {
65 $interpreter.halt_oog();
66 return $ret;
67 }
68 };
69}
70
71#[macro_export]
73#[collapse_debuginfo(yes)]
74macro_rules! berlin_load_account {
75 ($context:expr, $address:expr, $load_code:expr) => {
76 $crate::berlin_load_account!($context, $address, $load_code, ())
77 };
78 ($context:expr, $address:expr, $load_code:expr, $ret:expr) => {{
79 $crate::gas!($context.interpreter, WARM_STORAGE_READ_COST, $ret);
80 let skip_cold_load =
81 $context.interpreter.gas.remaining() < COLD_ACCOUNT_ACCESS_COST_ADDITIONAL;
82 match $context
83 .host
84 .load_account_info_skip_cold_load($address, $load_code, skip_cold_load)
85 {
86 Ok(account) => {
87 if account.is_cold {
88 $crate::gas!(
89 $context.interpreter,
90 COLD_ACCOUNT_ACCESS_COST_ADDITIONAL,
91 $ret
92 );
93 }
94 account
95 }
96 Err(LoadError::ColdLoadSkipped) => {
97 $context.interpreter.halt_oog();
98 return $ret;
99 }
100 Err(LoadError::DBError) => {
101 $context.interpreter.halt_fatal();
102 return $ret;
103 }
104 }
105 }};
106}
107
108#[macro_export]
110#[collapse_debuginfo(yes)]
111macro_rules! gas_or_fail {
112 ($interpreter:expr, $gas:expr) => {
113 $crate::gas_or_fail!($interpreter, $gas, ())
114 };
115 ($interpreter:expr, $gas:expr, $ret:expr) => {
116 match $gas {
117 Some(gas_used) => $crate::gas!($interpreter, gas_used, $ret),
118 None => {
119 $interpreter.halt_oog();
120 return $ret;
121 }
122 }
123 };
124}
125
126#[macro_export]
129#[collapse_debuginfo(yes)]
130macro_rules! resize_memory {
131 ($interpreter:expr, $offset:expr, $len:expr) => {
132 $crate::resize_memory!($interpreter, $offset, $len, ())
133 };
134 ($interpreter:expr, $offset:expr, $len:expr, $ret:expr) => {
135 #[cfg(feature = "memory_limit")]
136 if $interpreter.memory.limit_reached($offset, $len) {
137 $interpreter.halt_memory_limit_oog();
138 return $ret;
139 }
140 if !$crate::interpreter::resize_memory(
141 &mut $interpreter.gas,
142 &mut $interpreter.memory,
143 $offset,
144 $len,
145 ) {
146 $interpreter.halt_memory_oog();
147 return $ret;
148 }
149 };
150}
151
152#[macro_export]
154#[collapse_debuginfo(yes)]
155macro_rules! popn {
156 ([ $($x:ident),* ],$interpreter:expr $(,$ret:expr)? ) => {
157 let Some([$( $x ),*]) = $interpreter.stack.popn() else {
158 $interpreter.halt_underflow();
159 return $($ret)?;
160 };
161 };
162}
163
164#[doc(hidden)]
165#[macro_export]
166#[collapse_debuginfo(yes)]
167macro_rules! _count {
168 (@count) => { 0 };
169 (@count $head:tt $($tail:tt)*) => { 1 + _count!(@count $($tail)*) };
170 ($($arg:tt)*) => { _count!(@count $($arg)*) };
171}
172
173#[macro_export]
175#[collapse_debuginfo(yes)]
176macro_rules! popn_top {
177 ([ $($x:ident),* ], $top:ident, $interpreter:expr $(,$ret:expr)? ) => {
178 if $interpreter.stack.len() < (1 + $crate::_count!($($x)*)) {
187 $interpreter.halt_underflow();
188 return $($ret)?;
189 }
190 let ([$( $x ),*], $top) = unsafe { $interpreter.stack.popn_top().unwrap_unchecked() };
191 };
192}
193
194#[macro_export]
196#[collapse_debuginfo(yes)]
197macro_rules! push {
198 ($interpreter:expr, $x:expr $(,$ret:item)?) => (
199 if !($interpreter.stack.push($x)) {
200 $interpreter.halt_overflow();
201 return $($ret)?;
202 }
203 )
204}
205
206#[macro_export]
208#[collapse_debuginfo(yes)]
209macro_rules! as_u64_saturated {
210 ($v:expr) => {
211 match $v.as_limbs() {
212 x => {
213 if (x[1] == 0) & (x[2] == 0) & (x[3] == 0) {
214 x[0]
215 } else {
216 u64::MAX
217 }
218 }
219 }
220 };
221}
222
223#[macro_export]
225#[collapse_debuginfo(yes)]
226macro_rules! as_usize_saturated {
227 ($v:expr) => {
228 usize::try_from($crate::as_u64_saturated!($v)).unwrap_or(usize::MAX)
229 };
230}
231
232#[macro_export]
234#[collapse_debuginfo(yes)]
235macro_rules! as_isize_saturated {
236 ($v:expr) => {
237 isize::try_from($crate::as_u64_saturated!($v)).unwrap_or(isize::MAX)
240 };
241}
242
243#[macro_export]
245#[collapse_debuginfo(yes)]
246macro_rules! as_usize_or_fail {
247 ($interpreter:expr, $v:expr) => {
248 $crate::as_usize_or_fail_ret!($interpreter, $v, ())
249 };
250 ($interpreter:expr, $v:expr, $reason:expr) => {
251 $crate::as_usize_or_fail_ret!($interpreter, $v, $reason, ())
252 };
253}
254
255#[macro_export]
258#[collapse_debuginfo(yes)]
259macro_rules! as_usize_or_fail_ret {
260 ($interpreter:expr, $v:expr, $ret:expr) => {
261 $crate::as_usize_or_fail_ret!(
262 $interpreter,
263 $v,
264 $crate::InstructionResult::InvalidOperandOOG,
265 $ret
266 )
267 };
268
269 ($interpreter:expr, $v:expr, $reason:expr, $ret:expr) => {
270 match $v.as_limbs() {
271 x => {
272 if (x[0] > usize::MAX as u64) | (x[1] != 0) | (x[2] != 0) | (x[3] != 0) {
273 $interpreter.halt($reason);
274 return $ret;
275 }
276 x[0] as usize
277 }
278 }
279 };
280}