rtvm_interpreter/instructions/
macros.rs1#[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 !<SPEC as $crate::primitives::Spec>::enabled($crate::primitives::SpecId::$min) {
42 $interp.instruction_result = $crate::InstructionResult::NotActivated;
43 return;
44 }
45 };
46}
47
48#[macro_export]
50macro_rules! gas {
51 ($interp:expr, $gas:expr) => {
52 $crate::gas!($interp, $gas, ())
53 };
54 ($interp:expr, $gas:expr, $ret:expr) => {
55 if !$interp.gas.record_cost($gas) {
56 $interp.instruction_result = $crate::InstructionResult::OutOfGas;
57 return $ret;
58 }
59 };
60}
61
62#[macro_export]
64macro_rules! refund {
65 ($interp:expr, $gas:expr) => {
66 $interp.gas.record_refund($gas)
67 };
68}
69
70#[macro_export]
72macro_rules! gas_or_fail {
73 ($interp:expr, $gas:expr) => {
74 match $gas {
75 Some(gas_used) => $crate::gas!($interp, gas_used),
76 None => {
77 $interp.instruction_result = $crate::InstructionResult::OutOfGas;
78 return;
79 }
80 }
81 };
82}
83
84#[macro_export]
87macro_rules! resize_memory {
88 ($interp:expr, $offset:expr, $len:expr) => {
89 $crate::resize_memory!($interp, $offset, $len, ())
90 };
91 ($interp:expr, $offset:expr, $len:expr, $ret:expr) => {
92 let size = $offset.saturating_add($len);
93 if size > $interp.shared_memory.len() {
94 let rounded_size = $crate::interpreter::next_multiple_of_32(size);
96
97 #[cfg(feature = "memory_limit")]
98 if $interp.shared_memory.limit_reached(size) {
99 $interp.instruction_result = $crate::InstructionResult::MemoryLimitOOG;
100 return $ret;
101 }
102
103 let words_num = rounded_size / 32;
105 if !$interp
106 .gas
107 .record_memory($crate::gas::memory_gas(words_num))
108 {
109 $interp.instruction_result = $crate::InstructionResult::MemoryLimitOOG;
110 return $ret;
111 }
112 $interp.shared_memory.resize(rounded_size);
113 }
114 };
115}
116
117#[macro_export]
119macro_rules! pop_address {
120 ($interp:expr, $x1:ident) => {
121 pop_address_ret!($interp, $x1, ())
122 };
123 ($interp:expr, $x1:ident, $x2:ident) => {
124 pop_address_ret!($interp, $x1, $x2, ())
125 };
126}
127
128#[macro_export]
130macro_rules! pop_address_ret {
131 ($interp:expr, $x1:ident, $ret:expr) => {
132 if $interp.stack.len() < 1 {
133 $interp.instruction_result = $crate::InstructionResult::StackUnderflow;
134 return $ret;
135 }
136 let $x1 = $crate::primitives::Address::from_word($crate::primitives::B256::from(unsafe {
138 $interp.stack.pop_unsafe()
139 }));
140 };
141 ($interp:expr, $x1:ident, $x2:ident, $ret:expr) => {
142 if $interp.stack.len() < 2 {
143 $interp.instruction_result = $crate::InstructionResult::StackUnderflow;
144 return $ret;
145 }
146 let $x1 = $crate::primitives::Address::from_word($crate::primitives::B256::from(unsafe {
148 $interp.stack.pop_unsafe()
149 }));
150 let $x2 = $crate::primitives::Address::from_word($crate::primitives::B256::from(unsafe {
151 $interp.stack.pop_unsafe()
152 }));
153 };
154}
155
156#[macro_export]
158macro_rules! pop {
159 ($interp:expr, $x1:ident) => {
160 $crate::pop_ret!($interp, $x1, ())
161 };
162 ($interp:expr, $x1:ident, $x2:ident) => {
163 $crate::pop_ret!($interp, $x1, $x2, ())
164 };
165 ($interp:expr, $x1:ident, $x2:ident, $x3:ident) => {
166 $crate::pop_ret!($interp, $x1, $x2, $x3, ())
167 };
168 ($interp:expr, $x1:ident, $x2:ident, $x3:ident, $x4:ident) => {
169 $crate::pop_ret!($interp, $x1, $x2, $x3, $x4, ())
170 };
171 ($interp:expr, $x1:ident, $x2:ident, $x3:ident, $x4:ident, $x5:ident) => {
172 pop_ret!($interp, $x1, $x2, $x3, $x4, $x5, ())
173 };
174}
175
176#[macro_export]
179macro_rules! pop_ret {
180 ($interp:expr, $x1:ident, $ret:expr) => {
181 if $interp.stack.len() < 1 {
182 $interp.instruction_result = $crate::InstructionResult::StackUnderflow;
183 return $ret;
184 }
185 let $x1 = unsafe { $interp.stack.pop_unsafe() };
187 };
188 ($interp:expr, $x1:ident, $x2:ident, $ret:expr) => {
189 if $interp.stack.len() < 2 {
190 $interp.instruction_result = $crate::InstructionResult::StackUnderflow;
191 return $ret;
192 }
193 let ($x1, $x2) = unsafe { $interp.stack.pop2_unsafe() };
195 };
196 ($interp:expr, $x1:ident, $x2:ident, $x3:ident, $ret:expr) => {
197 if $interp.stack.len() < 3 {
198 $interp.instruction_result = $crate::InstructionResult::StackUnderflow;
199 return $ret;
200 }
201 let ($x1, $x2, $x3) = unsafe { $interp.stack.pop3_unsafe() };
203 };
204 ($interp:expr, $x1:ident, $x2:ident, $x3:ident, $x4:ident, $ret:expr) => {
205 if $interp.stack.len() < 4 {
206 $interp.instruction_result = $crate::InstructionResult::StackUnderflow;
207 return $ret;
208 }
209 let ($x1, $x2, $x3, $x4) = unsafe { $interp.stack.pop4_unsafe() };
211 };
212 ($interp:expr, $x1:ident, $x2:ident, $x3:ident, $x4:ident, $x5:ident, $ret:expr) => {
213 if $interp.stack.len() < 4 {
214 $interp.instruction_result = $crate::InstructionResult::StackUnderflow;
215 return $ret;
216 }
217 let ($x1, $x2, $x3, $x4, $x5) = unsafe { $interp.stack.pop5_unsafe() };
219 };
220}
221
222#[macro_export]
225macro_rules! pop_top {
226 ($interp:expr, $x1:ident) => {
227 if $interp.stack.len() < 1 {
228 $interp.instruction_result = $crate::InstructionResult::StackUnderflow;
229 return;
230 }
231 let $x1 = unsafe { $interp.stack.top_unsafe() };
233 };
234 ($interp:expr, $x1:ident, $x2:ident) => {
235 if $interp.stack.len() < 2 {
236 $interp.instruction_result = $crate::InstructionResult::StackUnderflow;
237 return;
238 }
239 let ($x1, $x2) = unsafe { $interp.stack.pop_top_unsafe() };
241 };
242 ($interp:expr, $x1:ident, $x2:ident, $x3:ident) => {
243 if $interp.stack.len() < 3 {
244 $interp.instruction_result = $crate::InstructionResult::StackUnderflow;
245 return;
246 }
247 let ($x1, $x2, $x3) = unsafe { $interp.stack.pop2_top_unsafe() };
249 };
250}
251
252#[macro_export]
254macro_rules! push_b256 {
255 ($interp:expr, $($x:expr),* $(,)?) => ($(
256 match $interp.stack.push_b256($x) {
257 Ok(()) => {},
258 Err(e) => {
259 $interp.instruction_result = e;
260 return;
261 },
262 }
263 )*)
264}
265
266#[macro_export]
268macro_rules! push {
269 ($interp:expr, $($x:expr),* $(,)?) => ($(
270 match $interp.stack.push($x) {
271 Ok(()) => {},
272 Err(e) => {
273 $interp.instruction_result = e;
274 return;
275 }
276 }
277 )*)
278}
279
280#[macro_export]
282macro_rules! as_u64_saturated {
283 ($v:expr) => {{
284 let x: &[u64; 4] = $v.as_limbs();
285 if x[1] == 0 && x[2] == 0 && x[3] == 0 {
286 x[0]
287 } else {
288 u64::MAX
289 }
290 }};
291}
292
293#[macro_export]
295macro_rules! as_usize_saturated {
296 ($v:expr) => {
297 usize::try_from($crate::as_u64_saturated!($v)).unwrap_or(usize::MAX)
298 };
299}
300
301#[macro_export]
303macro_rules! as_isize_saturated {
304 ($v:expr) => {
305 isize::try_from($crate::as_u64_saturated!($v)).unwrap_or(isize::MAX)
308 };
309}
310
311#[macro_export]
313macro_rules! as_usize_or_fail {
314 ($interp:expr, $v:expr) => {
315 $crate::as_usize_or_fail_ret!($interp, $v, ())
316 };
317 ($interp:expr, $v:expr, $reason:expr) => {
318 $crate::as_usize_or_fail_ret!($interp, $v, $reason, ())
319 };
320}
321
322#[macro_export]
325macro_rules! as_usize_or_fail_ret {
326 ($interp:expr, $v:expr, $ret:expr) => {
327 $crate::as_usize_or_fail_ret!(
328 $interp,
329 $v,
330 $crate::InstructionResult::InvalidOperandOOG,
331 $ret
332 )
333 };
334
335 ($interp:expr, $v:expr, $reason:expr, $ret:expr) => {{
336 let x = $v.as_limbs();
337 if x[1] != 0 || x[2] != 0 || x[3] != 0 {
338 $interp.instruction_result = $reason;
339 return $ret;
340 }
341 let Ok(val) = usize::try_from(x[0]) else {
342 $interp.instruction_result = $reason;
343 return $ret;
344 };
345 val
346 }};
347}