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.host.gas_params().cold_account_additional_cost();
55 let skip_cold_load = $context.interpreter.gas.remaining() < cold_load_gas;
56 match $context
57 .host
58 .load_account_info_skip_cold_load($address, $load_code, skip_cold_load)
59 {
60 Ok(account) => {
61 if account.is_cold {
62 $crate::gas!($context.interpreter, cold_load_gas, $ret);
63 }
64 account
65 }
66 Err(LoadError::ColdLoadSkipped) => {
67 $context.interpreter.halt_oog();
68 return $ret;
69 }
70 Err(LoadError::DBError) => {
71 $context.interpreter.halt_fatal();
72 return $ret;
73 }
74 }
75 }};
76}
77
78#[macro_export]
81#[collapse_debuginfo(yes)]
82macro_rules! resize_memory {
83 ($interpreter:expr, $gas_params:expr, $offset:expr, $len:expr) => {
84 $crate::resize_memory!($interpreter, $gas_params, $offset, $len, ())
85 };
86 ($interpreter:expr, $gas_params:expr, $offset:expr, $len:expr, $ret:expr) => {
87 if let Err(result) = $crate::interpreter::resize_memory(
88 &mut $interpreter.gas,
89 &mut $interpreter.memory,
90 $gas_params,
91 $offset,
92 $len,
93 ) {
94 $interpreter.halt(result);
95 return $ret;
96 }
97 };
98}
99
100#[macro_export]
102#[collapse_debuginfo(yes)]
103macro_rules! popn {
104 ([ $($x:ident),* ],$interpreter:expr $(,$ret:expr)? ) => {
105 let Some([$( $x ),*]) = $interpreter.stack.popn() else {
106 $interpreter.halt_underflow();
107 return $($ret)?;
108 };
109 };
110}
111
112#[doc(hidden)]
113#[macro_export]
114#[collapse_debuginfo(yes)]
115macro_rules! _count {
116 (@count) => { 0 };
117 (@count $head:tt $($tail:tt)*) => { 1 + _count!(@count $($tail)*) };
118 ($($arg:tt)*) => { _count!(@count $($arg)*) };
119}
120
121#[macro_export]
123#[collapse_debuginfo(yes)]
124macro_rules! popn_top {
125 ([ $($x:ident),* ], $top:ident, $interpreter:expr $(,$ret:expr)? ) => {
126 if $interpreter.stack.len() < (1 + $crate::_count!($($x)*)) {
135 $interpreter.halt_underflow();
136 return $($ret)?;
137 }
138 let ([$( $x ),*], $top) = unsafe { $interpreter.stack.popn_top().unwrap_unchecked() };
139 };
140}
141
142#[macro_export]
144#[collapse_debuginfo(yes)]
145macro_rules! push {
146 ($interpreter:expr, $x:expr $(,$ret:item)?) => (
147 if !($interpreter.stack.push($x)) {
148 $interpreter.halt_overflow();
149 return $($ret)?;
150 }
151 )
152}
153
154#[macro_export]
156#[collapse_debuginfo(yes)]
157macro_rules! as_u64_saturated {
158 ($v:expr) => {
159 match $v.as_limbs() {
160 x => {
161 if (x[1] == 0) & (x[2] == 0) & (x[3] == 0) {
162 x[0]
163 } else {
164 u64::MAX
165 }
166 }
167 }
168 };
169}
170
171#[macro_export]
173#[collapse_debuginfo(yes)]
174macro_rules! as_usize_saturated {
175 ($v:expr) => {
176 usize::try_from($crate::as_u64_saturated!($v)).unwrap_or(usize::MAX)
177 };
178}
179
180#[macro_export]
182#[collapse_debuginfo(yes)]
183macro_rules! as_isize_saturated {
184 ($v:expr) => {
185 isize::try_from($crate::as_u64_saturated!($v)).unwrap_or(isize::MAX)
188 };
189}
190
191#[macro_export]
193#[collapse_debuginfo(yes)]
194macro_rules! as_usize_or_fail {
195 ($interpreter:expr, $v:expr) => {
196 $crate::as_usize_or_fail_ret!($interpreter, $v, ())
197 };
198 ($interpreter:expr, $v:expr, $reason:expr) => {
199 $crate::as_usize_or_fail_ret!($interpreter, $v, $reason, ())
200 };
201}
202
203#[macro_export]
206#[collapse_debuginfo(yes)]
207macro_rules! as_usize_or_fail_ret {
208 ($interpreter:expr, $v:expr, $ret:expr) => {
209 $crate::as_usize_or_fail_ret!(
210 $interpreter,
211 $v,
212 $crate::InstructionResult::InvalidOperandOOG,
213 $ret
214 )
215 };
216
217 ($interpreter:expr, $v:expr, $reason:expr, $ret:expr) => {
218 match $v.as_limbs() {
219 x => {
220 if (x[0] > usize::MAX as u64) | (x[1] != 0) | (x[2] != 0) | (x[3] != 0) {
221 $interpreter.halt($reason);
222 return $ret;
223 }
224 x[0] as usize
225 }
226 }
227 };
228}