revm_interpreter/instructions/
macros.rs
1#[macro_export]
5macro_rules! require_non_staticcall {
6 ($interp:expr) => {
7 if $interp.is_static {
8 $interp.instruction_result = $crate::InstructionResult::StateChangeDuringStaticCall;
9 return;
10 }
11 };
12}
13
14#[macro_export]
16macro_rules! require_eof {
17 ($interp:expr) => {
18 if !$interp.is_eof {
19 $interp.instruction_result = $crate::InstructionResult::EOFOpcodeDisabledInLegacy;
20 return;
21 }
22 };
23}
24
25#[macro_export]
27macro_rules! require_init_eof {
28 ($interp:expr) => {
29 if !$interp.is_eof_init {
30 $interp.instruction_result = $crate::InstructionResult::ReturnContractInNotInitEOF;
31 return;
32 }
33 };
34}
35
36#[macro_export]
38macro_rules! check {
39 ($interp:expr, $min:ident) => {
40 if const {
41 !<SPEC as $crate::primitives::Spec>::SPEC_ID
42 .is_enabled_in($crate::primitives::SpecId::$min)
43 } {
44 $interp.instruction_result = $crate::InstructionResult::NotActivated;
45 return;
46 }
47 };
48}
49
50#[macro_export]
52macro_rules! gas {
53 ($interp:expr, $gas:expr) => {
54 $crate::gas!($interp, $gas, ())
55 };
56 ($interp:expr, $gas:expr, $ret:expr) => {
57 if !$interp.gas.record_cost($gas) {
58 $interp.instruction_result = $crate::InstructionResult::OutOfGas;
59 return $ret;
60 }
61 };
62}
63
64#[macro_export]
66macro_rules! refund {
67 ($interp:expr, $gas:expr) => {
68 $interp.gas.record_refund($gas)
69 };
70}
71
72#[macro_export]
74macro_rules! gas_or_fail {
75 ($interp:expr, $gas:expr) => {
76 match $gas {
77 Some(gas_used) => $crate::gas!($interp, gas_used),
78 None => {
79 $interp.instruction_result = $crate::InstructionResult::OutOfGas;
80 return;
81 }
82 }
83 };
84}
85
86#[macro_export]
89macro_rules! resize_memory {
90 ($interp:expr, $offset:expr, $len:expr) => {
91 $crate::resize_memory!($interp, $offset, $len, ())
92 };
93 ($interp:expr, $offset:expr, $len:expr, $ret:expr) => {
94 let new_size = $offset.saturating_add($len);
95 if new_size > $interp.shared_memory.len() {
96 #[cfg(feature = "memory_limit")]
97 if $interp.shared_memory.limit_reached(new_size) {
98 $interp.instruction_result = $crate::InstructionResult::MemoryLimitOOG;
99 return $ret;
100 }
101
102 if !$crate::interpreter::resize_memory(
104 &mut $interp.shared_memory,
105 &mut $interp.gas,
106 new_size,
107 ) {
108 $interp.instruction_result = $crate::InstructionResult::MemoryOOG;
109 return $ret;
110 }
111 }
112 };
113}
114
115#[macro_export]
117macro_rules! pop_address {
118 ($interp:expr, $x1:ident) => {
119 $crate::pop_address_ret!($interp, $x1, ())
120 };
121 ($interp:expr, $x1:ident, $x2:ident) => {
122 $crate::pop_address_ret!($interp, $x1, $x2, ())
123 };
124}
125
126#[macro_export]
128macro_rules! pop_address_ret {
129 ($interp:expr, $x1:ident, $ret:expr) => {
130 if $interp.stack.len() < 1 {
131 $interp.instruction_result = $crate::InstructionResult::StackUnderflow;
132 return $ret;
133 }
134 let $x1 = $crate::primitives::Address::from_word($crate::primitives::B256::from(unsafe {
136 $interp.stack.pop_unsafe()
137 }));
138 };
139 ($interp:expr, $x1:ident, $x2:ident, $ret:expr) => {
140 if $interp.stack.len() < 2 {
141 $interp.instruction_result = $crate::InstructionResult::StackUnderflow;
142 return $ret;
143 }
144 let $x1 = $crate::primitives::Address::from_word($crate::primitives::B256::from(unsafe {
146 $interp.stack.pop_unsafe()
147 }));
148 let $x2 = $crate::primitives::Address::from_word($crate::primitives::B256::from(unsafe {
149 $interp.stack.pop_unsafe()
150 }));
151 };
152}
153
154#[macro_export]
156macro_rules! pop {
157 ($interp:expr, $x1:ident) => {
158 $crate::pop_ret!($interp, $x1, ())
159 };
160 ($interp:expr, $x1:ident, $x2:ident) => {
161 $crate::pop_ret!($interp, $x1, $x2, ())
162 };
163 ($interp:expr, $x1:ident, $x2:ident, $x3:ident) => {
164 $crate::pop_ret!($interp, $x1, $x2, $x3, ())
165 };
166 ($interp:expr, $x1:ident, $x2:ident, $x3:ident, $x4:ident) => {
167 $crate::pop_ret!($interp, $x1, $x2, $x3, $x4, ())
168 };
169 ($interp:expr, $x1:ident, $x2:ident, $x3:ident, $x4:ident, $x5:ident) => {
170 $crate::pop_ret!($interp, $x1, $x2, $x3, $x4, $x5, ())
171 };
172}
173
174#[macro_export]
177macro_rules! pop_ret {
178 ($interp:expr, $x1:ident, $ret:expr) => {
179 if $interp.stack.len() < 1 {
180 $interp.instruction_result = $crate::InstructionResult::StackUnderflow;
181 return $ret;
182 }
183 let $x1 = unsafe { $interp.stack.pop_unsafe() };
185 };
186 ($interp:expr, $x1:ident, $x2:ident, $ret:expr) => {
187 if $interp.stack.len() < 2 {
188 $interp.instruction_result = $crate::InstructionResult::StackUnderflow;
189 return $ret;
190 }
191 let ($x1, $x2) = unsafe { $interp.stack.pop2_unsafe() };
193 };
194 ($interp:expr, $x1:ident, $x2:ident, $x3:ident, $ret:expr) => {
195 if $interp.stack.len() < 3 {
196 $interp.instruction_result = $crate::InstructionResult::StackUnderflow;
197 return $ret;
198 }
199 let ($x1, $x2, $x3) = unsafe { $interp.stack.pop3_unsafe() };
201 };
202 ($interp:expr, $x1:ident, $x2:ident, $x3:ident, $x4:ident, $ret:expr) => {
203 if $interp.stack.len() < 4 {
204 $interp.instruction_result = $crate::InstructionResult::StackUnderflow;
205 return $ret;
206 }
207 let ($x1, $x2, $x3, $x4) = unsafe { $interp.stack.pop4_unsafe() };
209 };
210 ($interp:expr, $x1:ident, $x2:ident, $x3:ident, $x4:ident, $x5:ident, $ret:expr) => {
211 if $interp.stack.len() < 5 {
212 $interp.instruction_result = $crate::InstructionResult::StackUnderflow;
213 return $ret;
214 }
215 let ($x1, $x2, $x3, $x4, $x5) = unsafe { $interp.stack.pop5_unsafe() };
217 };
218}
219
220#[macro_export]
223macro_rules! pop_top {
224 ($interp:expr, $x1:ident) => {
225 if $interp.stack.len() < 1 {
226 $interp.instruction_result = $crate::InstructionResult::StackUnderflow;
227 return;
228 }
229 let $x1 = unsafe { $interp.stack.top_unsafe() };
231 };
232 ($interp:expr, $x1:ident, $x2:ident) => {
233 if $interp.stack.len() < 2 {
234 $interp.instruction_result = $crate::InstructionResult::StackUnderflow;
235 return;
236 }
237 let ($x1, $x2) = unsafe { $interp.stack.pop_top_unsafe() };
239 };
240 ($interp:expr, $x1:ident, $x2:ident, $x3:ident) => {
241 if $interp.stack.len() < 3 {
242 $interp.instruction_result = $crate::InstructionResult::StackUnderflow;
243 return;
244 }
245 let ($x1, $x2, $x3) = unsafe { $interp.stack.pop2_top_unsafe() };
247 };
248}
249
250#[macro_export]
252macro_rules! push_b256 {
253 ($interp:expr, $($x:expr),* $(,)?) => ($(
254 match $interp.stack.push_b256($x) {
255 Ok(()) => {},
256 Err(e) => {
257 $interp.instruction_result = e;
258 return;
259 },
260 }
261 )*)
262}
263
264#[macro_export]
266macro_rules! push {
267 ($interp:expr, $($x:expr),* $(,)?) => ($(
268 match $interp.stack.push($x) {
269 Ok(()) => {},
270 Err(e) => {
271 $interp.instruction_result = e;
272 return;
273 }
274 }
275 )*)
276}
277
278#[macro_export]
280macro_rules! as_u64_saturated {
281 ($v:expr) => {
282 match $v.as_limbs() {
283 x => {
284 if (x[1] == 0) & (x[2] == 0) & (x[3] == 0) {
285 x[0]
286 } else {
287 u64::MAX
288 }
289 }
290 }
291 };
292}
293
294#[macro_export]
296macro_rules! as_usize_saturated {
297 ($v:expr) => {
298 usize::try_from($crate::as_u64_saturated!($v)).unwrap_or(usize::MAX)
299 };
300}
301
302#[macro_export]
304macro_rules! as_isize_saturated {
305 ($v:expr) => {
306 isize::try_from($crate::as_u64_saturated!($v)).unwrap_or(isize::MAX)
309 };
310}
311
312#[macro_export]
314macro_rules! as_usize_or_fail {
315 ($interp:expr, $v:expr) => {
316 $crate::as_usize_or_fail_ret!($interp, $v, ())
317 };
318 ($interp:expr, $v:expr, $reason:expr) => {
319 $crate::as_usize_or_fail_ret!($interp, $v, $reason, ())
320 };
321}
322
323#[macro_export]
326macro_rules! as_usize_or_fail_ret {
327 ($interp:expr, $v:expr, $ret:expr) => {
328 $crate::as_usize_or_fail_ret!(
329 $interp,
330 $v,
331 $crate::InstructionResult::InvalidOperandOOG,
332 $ret
333 )
334 };
335
336 ($interp:expr, $v:expr, $reason:expr, $ret:expr) => {
337 match $v.as_limbs() {
338 x => {
339 if (x[0] > usize::MAX as u64) | (x[1] != 0) | (x[2] != 0) | (x[3] != 0) {
340 $interp.instruction_result = $reason;
341 return $ret;
342 }
343 x[0] as usize
344 }
345 }
346 };
347}