pallet_revive/vm/evm/instructions/
macros.rs1#[macro_export]
22macro_rules! tri {
23 ($e:expr) => {
24 match $e {
25 Some(v) => v,
26 None => return None,
27 }
28 };
29}
30
31#[macro_export]
33macro_rules! require_non_staticcall {
34 ($interpreter:expr) => {
35 if $interpreter.runtime_flag.is_static() {
36 $interpreter.halt(revm::interpreter::InstructionResult::StateChangeDuringStaticCall);
37 return;
38 }
39 };
40}
41
42#[macro_export]
45macro_rules! otry {
46 ($expression: expr) => {{
47 let Some(value) = $expression else {
48 return;
49 };
50 value
51 }};
52}
53
54#[macro_export]
56macro_rules! require_eof {
57 ($interpreter:expr) => {
58 if !$interpreter.runtime_flag.is_eof() {
59 $interpreter.halt(revm::interpreter::InstructionResult::EOFOpcodeDisabledInLegacy);
60 return;
61 }
62 };
63}
64
65#[macro_export]
67macro_rules! check {
68 ($interpreter:expr, $min:ident) => {
69 if !$interpreter
70 .runtime_flag
71 .spec_id()
72 .is_enabled_in(revm::primitives::hardfork::SpecId::$min)
73 {
74 $interpreter.halt(revm::interpreter::InstructionResult::NotActivated);
75 return;
76 }
77 };
78}
79
80#[macro_export]
82macro_rules! gas_legacy {
83 ($interpreter:expr, $gas:expr) => {
84 gas_legacy!($interpreter, $gas, ())
85 };
86 ($interpreter:expr, $gas:expr, $ret:expr) => {
87 if $interpreter.extend.gas_meter_mut().charge_evm_gas($gas).is_err() {
88 $interpreter.halt(revm::interpreter::InstructionResult::OutOfGas);
89 return $ret;
90 }
91 };
92}
93
94#[macro_export]
95macro_rules! gas {
96 ($interpreter:expr, $gas:expr) => {
97 gas!($interpreter, $gas, ())
98 };
99 ($interpreter:expr, $gas:expr, $ret:expr) => {
100 let meter = $interpreter.extend.gas_meter_mut();
101 if meter.charge_evm_gas(1).is_err() || meter.charge($gas).is_err() {
102 $interpreter.halt(revm::interpreter::InstructionResult::OutOfGas);
103 return $ret;
104 }
105 };
106}
107
108#[macro_export]
110macro_rules! gas_or_fail_legacy {
111 ($interpreter:expr, $gas:expr) => {
112 gas_or_fail_legacy!($interpreter, $gas, ())
113 };
114 ($interpreter:expr, $gas:expr, $ret:expr) => {
115 match $gas {
116 Some(gas_used) => gas_legacy!($interpreter, gas_used, $ret),
117 None => {
118 $interpreter.halt(revm::interpreter::InstructionResult::OutOfGas);
119 return $ret;
120 },
121 }
122 };
123}
124
125use crate::vm::Ext;
126use revm::interpreter::gas::{MemoryExtensionResult, MemoryGas};
127
128pub fn record_memory_expansion<E: Ext>(
131 memory: &mut MemoryGas,
132 ext: &mut E,
133 new_len: usize,
134) -> MemoryExtensionResult {
135 let Some(additional_cost) = memory.record_new_len(new_len) else {
136 return MemoryExtensionResult::Same;
137 };
138
139 if ext.gas_meter_mut().charge_evm_gas(additional_cost).is_err() {
140 return MemoryExtensionResult::OutOfGas;
141 }
142
143 MemoryExtensionResult::Extended
144}
145
146#[macro_export]
149macro_rules! resize_memory {
150 ($interpreter:expr, $offset:expr, $len:expr) => {
151 resize_memory!($interpreter, $offset, $len, ())
152 };
153 ($interpreter:expr, $offset:expr, $len:expr, $ret:expr) => {
154 let words_num = revm::interpreter::num_words($offset.saturating_add($len));
155 match crate::vm::evm::instructions::macros::record_memory_expansion(
156 $interpreter.gas.memory_mut(),
157 $interpreter.extend,
158 words_num,
159 ) {
160 revm::interpreter::gas::MemoryExtensionResult::Extended => {
161 $interpreter.memory.resize(words_num * 32);
162 },
163 revm::interpreter::gas::MemoryExtensionResult::OutOfGas => {
164 $interpreter.halt(revm::interpreter::InstructionResult::MemoryOOG);
165 return $ret;
166 },
167 revm::interpreter::gas::MemoryExtensionResult::Same => (), };
169 };
170}
171
172#[macro_export]
174macro_rules! popn {
175 ([ $($x:ident),* ],$interpreterreter:expr $(,$ret:expr)? ) => {
176 let Some([$( $x ),*]) = <_ as StackTr>::popn(&mut $interpreterreter.stack) else {
177 $interpreterreter.halt(revm::interpreter::InstructionResult::StackUnderflow);
178 return $($ret)?;
179 };
180 };
181}
182
183#[macro_export]
186macro_rules! popn_top {
187 ([ $($x:ident),* ], $top:ident, $interpreter:expr $(,$ret:expr)? ) => {
188 let Some(([$($x),*], $top)) = <_ as StackTr>::popn_top(&mut $interpreter.stack) else {
189 $interpreter.halt(revm::interpreter::InstructionResult::StackUnderflow);
190 return $($ret)?;
191 };
192 };
193}
194
195#[macro_export]
197macro_rules! push {
198 ($interpreter:expr, $x:expr $(,$ret:item)?) => (
199 if !($interpreter.stack.push($x)) {
200 $interpreter.halt(revm::interpreter::InstructionResult::StackOverflow);
201 return $($ret)?;
202 }
203 )
204}
205
206#[macro_export]
208macro_rules! as_u64_saturated {
209 ($v:expr) => {
210 match $v.as_limbs() {
211 x =>
212 if (x[1] == 0) & (x[2] == 0) & (x[3] == 0) {
213 x[0]
214 } else {
215 u64::MAX
216 },
217 }
218 };
219}
220
221#[macro_export]
223macro_rules! as_usize_saturated {
224 ($v:expr) => {
225 usize::try_from(as_u64_saturated!($v)).unwrap_or(usize::MAX)
226 };
227}
228
229#[macro_export]
231macro_rules! as_isize_saturated {
232 ($v:expr) => {
233 isize::try_from(as_u64_saturated!($v)).unwrap_or(isize::MAX)
236 };
237}
238
239#[macro_export]
241macro_rules! as_usize_or_fail {
242 ($interpreter:expr, $v:expr) => {
243 as_usize_or_fail_ret!($interpreter, $v, ())
244 };
245 ($interpreter:expr, $v:expr, $reason:expr) => {
246 as_usize_or_fail_ret!($interpreter, $v, $reason, ())
247 };
248}
249
250#[macro_export]
253macro_rules! as_usize_or_fail_ret {
254 ($interpreter:expr, $v:expr, $ret:expr) => {
255 as_usize_or_fail_ret!(
256 $interpreter,
257 $v,
258 revm::interpreter::InstructionResult::InvalidOperandOOG,
259 $ret
260 )
261 };
262
263 ($interpreter:expr, $v:expr, $reason:expr, $ret:expr) => {
264 match $v.as_limbs() {
265 x => {
266 if (x[0] > usize::MAX as u64) | (x[1] != 0) | (x[2] != 0) | (x[3] != 0) {
267 $interpreter.halt($reason);
268 return $ret;
269 }
270 x[0] as usize
271 },
272 }
273 };
274}