#[macro_export]
#[collapse_debuginfo(yes)]
macro_rules! require_non_staticcall {
($interpreter:expr) => {
if $interpreter.runtime_flag.is_static() {
$interpreter.halt($crate::InstructionResult::StateChangeDuringStaticCall);
return;
}
};
}
#[macro_export]
#[collapse_debuginfo(yes)]
macro_rules! check {
($interpreter:expr, $min:ident) => {
if !$interpreter
.runtime_flag
.spec_id()
.is_enabled_in(primitives::hardfork::SpecId::$min)
{
$interpreter.halt_not_activated();
return;
}
};
}
#[macro_export]
#[collapse_debuginfo(yes)]
macro_rules! state_gas {
($interpreter:expr, $gas:expr) => {{
if !$interpreter.gas.record_state_cost($gas) {
$interpreter.halt_oog();
return;
}
}};
($interpreter:expr, $gas:expr, $ret:expr) => {{
if !$interpreter.gas.record_state_cost($gas) {
$interpreter.halt_oog();
return $ret;
}
}};
}
#[macro_export]
#[collapse_debuginfo(yes)]
macro_rules! gas {
($interpreter:expr, $gas:expr) => {
$crate::gas!($interpreter, $gas, ())
};
($interpreter:expr, $gas:expr, $ret:expr) => {
if !$interpreter.gas.record_regular_cost($gas) {
$interpreter.halt_oog();
return $ret;
}
};
}
#[macro_export]
#[collapse_debuginfo(yes)]
macro_rules! berlin_load_account {
($context:expr, $address:expr, $load_code:expr) => {
$crate::berlin_load_account!($context, $address, $load_code, ())
};
($context:expr, $address:expr, $load_code:expr, $ret:expr) => {{
let cold_load_gas = $context.host.gas_params().cold_account_additional_cost();
let skip_cold_load = $context.interpreter.gas.remaining() < cold_load_gas;
match $context
.host
.load_account_info_skip_cold_load($address, $load_code, skip_cold_load)
{
Ok(account) => {
if account.is_cold {
$crate::gas!($context.interpreter, cold_load_gas, $ret);
}
account
}
Err(LoadError::ColdLoadSkipped) => {
$context.interpreter.halt_oog();
return $ret;
}
Err(LoadError::DBError) => {
$context.interpreter.halt_fatal();
return $ret;
}
}
}};
}
#[macro_export]
#[collapse_debuginfo(yes)]
macro_rules! resize_memory {
($interpreter:expr, $gas_params:expr, $offset:expr, $len:expr) => {
$crate::resize_memory!($interpreter, $gas_params, $offset, $len, ())
};
($interpreter:expr, $gas_params:expr, $offset:expr, $len:expr, $ret:expr) => {
if let Err(result) = $crate::interpreter::resize_memory(
&mut $interpreter.gas,
&mut $interpreter.memory,
$gas_params,
$offset,
$len,
) {
$interpreter.halt(result);
return $ret;
}
};
}
#[macro_export]
#[collapse_debuginfo(yes)]
macro_rules! popn {
([ $($x:ident),* ],$interpreter:expr $(,$ret:expr)? ) => {
let Some([$( $x ),*]) = $interpreter.stack.popn() else {
$interpreter.halt_underflow();
return $($ret)?;
};
};
}
#[doc(hidden)]
#[macro_export]
#[collapse_debuginfo(yes)]
macro_rules! _count {
(@count) => { 0 };
(@count $head:tt $($tail:tt)*) => { 1 + _count!(@count $($tail)*) };
($($arg:tt)*) => { _count!(@count $($arg)*) };
}
#[macro_export]
#[collapse_debuginfo(yes)]
macro_rules! popn_top {
([ $($x:ident),* ], $top:ident, $interpreter:expr $(,$ret:expr)? ) => {
if $interpreter.stack.len() < (1 + $crate::_count!($($x)*)) {
$interpreter.halt_underflow();
return $($ret)?;
}
let ([$( $x ),*], $top) = unsafe { $interpreter.stack.popn_top().unwrap_unchecked() };
};
}
#[macro_export]
#[collapse_debuginfo(yes)]
macro_rules! push {
($interpreter:expr, $x:expr $(,$ret:item)?) => (
if !($interpreter.stack.push($x)) {
$interpreter.halt_overflow();
return $($ret)?;
}
)
}
#[macro_export]
#[collapse_debuginfo(yes)]
macro_rules! as_u64_saturated {
($v:expr) => {
u64::try_from($v).unwrap_or(u64::MAX)
};
}
#[macro_export]
#[collapse_debuginfo(yes)]
macro_rules! as_usize_saturated {
($v:expr) => {
usize::try_from($v).unwrap_or(usize::MAX)
};
}
#[macro_export]
#[collapse_debuginfo(yes)]
macro_rules! as_isize_saturated {
($v:expr) => {
isize::try_from($v).unwrap_or(isize::MAX)
};
}
#[macro_export]
#[collapse_debuginfo(yes)]
macro_rules! as_usize_or_fail {
($interpreter:expr, $v:expr) => {
$crate::as_usize_or_fail_ret!($interpreter, $v, ())
};
($interpreter:expr, $v:expr, $reason:expr) => {
$crate::as_usize_or_fail_ret!($interpreter, $v, $reason, ())
};
}
#[macro_export]
#[collapse_debuginfo(yes)]
macro_rules! as_usize_or_fail_ret {
($interpreter:expr, $v:expr, $ret:expr) => {
$crate::as_usize_or_fail_ret!(
$interpreter,
$v,
$crate::InstructionResult::InvalidOperandOOG,
$ret
)
};
($interpreter:expr, $v:expr, $reason:expr, $ret:expr) => {
match $v.as_limbs() {
x => {
if (x[0] > usize::MAX as u64) | (x[1] != 0) | (x[2] != 0) | (x[3] != 0) {
$interpreter.halt($reason);
return $ret;
}
x[0] as usize
}
}
};
}