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]
34#[collapse_debuginfo(yes)]
35macro_rules! state_gas {
36 ($interpreter:expr, $gas:expr) => {{
37 if !$interpreter.gas.record_state_cost($gas) {
38 $interpreter.halt_oog();
39 return;
40 }
41 }};
42 ($interpreter:expr, $gas:expr, $ret:expr) => {{
43 if !$interpreter.gas.record_state_cost($gas) {
44 $interpreter.halt_oog();
45 return $ret;
46 }
47 }};
48}
49
50#[macro_export]
52#[collapse_debuginfo(yes)]
53macro_rules! gas {
54 ($interpreter:expr, $gas:expr) => {
55 $crate::gas!($interpreter, $gas, ())
56 };
57 ($interpreter:expr, $gas:expr, $ret:expr) => {
58 if !$interpreter.gas.record_regular_cost($gas) {
59 $interpreter.halt_oog();
60 return $ret;
61 }
62 };
63}
64
65#[macro_export]
67#[collapse_debuginfo(yes)]
68macro_rules! berlin_load_account {
69 ($context:expr, $address:expr, $load_code:expr) => {
70 $crate::berlin_load_account!($context, $address, $load_code, ())
71 };
72 ($context:expr, $address:expr, $load_code:expr, $ret:expr) => {{
73 let cold_load_gas = $context.host.gas_params().cold_account_additional_cost();
74 let skip_cold_load = $context.interpreter.gas.remaining() < cold_load_gas;
75 match $context
76 .host
77 .load_account_info_skip_cold_load($address, $load_code, skip_cold_load)
78 {
79 Ok(account) => {
80 if account.is_cold {
81 $crate::gas!($context.interpreter, cold_load_gas, $ret);
82 }
83 account
84 }
85 Err(LoadError::ColdLoadSkipped) => {
86 $context.interpreter.halt_oog();
87 return $ret;
88 }
89 Err(LoadError::DBError) => {
90 $context.interpreter.halt_fatal();
91 return $ret;
92 }
93 }
94 }};
95}
96
97#[macro_export]
100#[collapse_debuginfo(yes)]
101macro_rules! resize_memory {
102 ($interpreter:expr, $gas_params:expr, $offset:expr, $len:expr) => {
103 $crate::resize_memory!($interpreter, $gas_params, $offset, $len, ())
104 };
105 ($interpreter:expr, $gas_params:expr, $offset:expr, $len:expr, $ret:expr) => {
106 if let Err(result) = $crate::interpreter::resize_memory(
107 &mut $interpreter.gas,
108 &mut $interpreter.memory,
109 $gas_params,
110 $offset,
111 $len,
112 ) {
113 $interpreter.halt(result);
114 return $ret;
115 }
116 };
117}
118
119#[macro_export]
121#[collapse_debuginfo(yes)]
122macro_rules! popn {
123 ([ $($x:ident),* ],$interpreter:expr $(,$ret:expr)? ) => {
124 let Some([$( $x ),*]) = $interpreter.stack.popn() else {
125 $interpreter.halt_underflow();
126 return $($ret)?;
127 };
128 };
129}
130
131#[doc(hidden)]
132#[macro_export]
133#[collapse_debuginfo(yes)]
134macro_rules! _count {
135 (@count) => { 0 };
136 (@count $head:tt $($tail:tt)*) => { 1 + _count!(@count $($tail)*) };
137 ($($arg:tt)*) => { _count!(@count $($arg)*) };
138}
139
140#[macro_export]
142#[collapse_debuginfo(yes)]
143macro_rules! popn_top {
144 ([ $($x:ident),* ], $top:ident, $interpreter:expr $(,$ret:expr)? ) => {
145 if $interpreter.stack.len() < (1 + $crate::_count!($($x)*)) {
154 $interpreter.halt_underflow();
155 return $($ret)?;
156 }
157 let ([$( $x ),*], $top) = unsafe { $interpreter.stack.popn_top().unwrap_unchecked() };
158 };
159}
160
161#[macro_export]
163#[collapse_debuginfo(yes)]
164macro_rules! push {
165 ($interpreter:expr, $x:expr $(,$ret:item)?) => (
166 if !($interpreter.stack.push($x)) {
167 $interpreter.halt_overflow();
168 return $($ret)?;
169 }
170 )
171}
172
173#[macro_export]
175#[collapse_debuginfo(yes)]
176macro_rules! as_u64_saturated {
177 ($v:expr) => {
178 u64::try_from($v).unwrap_or(u64::MAX)
179 };
180}
181
182#[macro_export]
184#[collapse_debuginfo(yes)]
185macro_rules! as_usize_saturated {
186 ($v:expr) => {
187 usize::try_from($v).unwrap_or(usize::MAX)
188 };
189}
190
191#[macro_export]
193#[collapse_debuginfo(yes)]
194macro_rules! as_isize_saturated {
195 ($v:expr) => {
196 isize::try_from($v).unwrap_or(isize::MAX)
197 };
198}
199
200#[macro_export]
202#[collapse_debuginfo(yes)]
203macro_rules! as_usize_or_fail {
204 ($interpreter:expr, $v:expr) => {
205 $crate::as_usize_or_fail_ret!($interpreter, $v, ())
206 };
207 ($interpreter:expr, $v:expr, $reason:expr) => {
208 $crate::as_usize_or_fail_ret!($interpreter, $v, $reason, ())
209 };
210}
211
212#[macro_export]
215#[collapse_debuginfo(yes)]
216macro_rules! as_usize_or_fail_ret {
217 ($interpreter:expr, $v:expr, $ret:expr) => {
218 $crate::as_usize_or_fail_ret!(
219 $interpreter,
220 $v,
221 $crate::InstructionResult::InvalidOperandOOG,
222 $ret
223 )
224 };
225
226 ($interpreter:expr, $v:expr, $reason:expr, $ret:expr) => {
227 match $v.as_limbs() {
228 x => {
229 if (x[0] > usize::MAX as u64) | (x[1] != 0) | (x[2] != 0) | (x[3] != 0) {
230 $interpreter.halt($reason);
231 return $ret;
232 }
233 x[0] as usize
234 }
235 }
236 };
237}