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 u64::try_from($v).unwrap_or(u64::MAX)
160 };
161}
162
163#[macro_export]
165#[collapse_debuginfo(yes)]
166macro_rules! as_usize_saturated {
167 ($v:expr) => {
168 usize::try_from($v).unwrap_or(usize::MAX)
169 };
170}
171
172#[macro_export]
174#[collapse_debuginfo(yes)]
175macro_rules! as_isize_saturated {
176 ($v:expr) => {
177 isize::try_from($v).unwrap_or(isize::MAX)
178 };
179}
180
181#[macro_export]
183#[collapse_debuginfo(yes)]
184macro_rules! as_usize_or_fail {
185 ($interpreter:expr, $v:expr) => {
186 $crate::as_usize_or_fail_ret!($interpreter, $v, ())
187 };
188 ($interpreter:expr, $v:expr, $reason:expr) => {
189 $crate::as_usize_or_fail_ret!($interpreter, $v, $reason, ())
190 };
191}
192
193#[macro_export]
196#[collapse_debuginfo(yes)]
197macro_rules! as_usize_or_fail_ret {
198 ($interpreter:expr, $v:expr, $ret:expr) => {
199 $crate::as_usize_or_fail_ret!(
200 $interpreter,
201 $v,
202 $crate::InstructionResult::InvalidOperandOOG,
203 $ret
204 )
205 };
206
207 ($interpreter:expr, $v:expr, $reason:expr, $ret:expr) => {
208 match $v.as_limbs() {
209 x => {
210 if (x[0] > usize::MAX as u64) | (x[1] != 0) | (x[2] != 0) | (x[3] != 0) {
211 $interpreter.halt($reason);
212 return $ret;
213 }
214 x[0] as usize
215 }
216 }
217 };
218}