#[macro_export]
macro_rules! require_non_staticcall {
($interp:expr) => {
if $interp.is_static {
$interp.instruction_result = $crate::InstructionResult::StateChangeDuringStaticCall;
return;
}
};
}
#[macro_export]
macro_rules! require_eof {
($interp:expr) => {
if !$interp.is_eof {
$interp.instruction_result = $crate::InstructionResult::EOFOpcodeDisabledInLegacy;
return;
}
};
}
#[macro_export]
macro_rules! require_init_eof {
($interp:expr) => {
if !$interp.is_eof_init {
$interp.instruction_result = $crate::InstructionResult::ReturnContractInNotInitEOF;
return;
}
};
}
#[macro_export]
macro_rules! check {
($interp:expr, $min:ident) => {
if !<SPEC as $crate::primitives::Spec>::enabled($crate::primitives::SpecId::$min) {
$interp.instruction_result = $crate::InstructionResult::NotActivated;
return;
}
};
}
#[macro_export]
macro_rules! gas {
($interp:expr, $gas:expr) => {
$crate::gas!($interp, $gas, ())
};
($interp:expr, $gas:expr, $ret:expr) => {
if !$interp.gas.record_cost($gas) {
$interp.instruction_result = $crate::InstructionResult::OutOfGas;
return $ret;
}
};
}
#[macro_export]
macro_rules! refund {
($interp:expr, $gas:expr) => {
$interp.gas.record_refund($gas)
};
}
#[macro_export]
macro_rules! gas_or_fail {
($interp:expr, $gas:expr) => {
match $gas {
Some(gas_used) => $crate::gas!($interp, gas_used),
None => {
$interp.instruction_result = $crate::InstructionResult::OutOfGas;
return;
}
}
};
}
#[macro_export]
macro_rules! resize_memory {
($interp:expr, $offset:expr, $len:expr) => {
$crate::resize_memory!($interp, $offset, $len, ())
};
($interp:expr, $offset:expr, $len:expr, $ret:expr) => {
let size = $offset.saturating_add($len);
if size > $interp.shared_memory.len() {
let rounded_size = $crate::interpreter::next_multiple_of_32(size);
#[cfg(feature = "memory_limit")]
if $interp.shared_memory.limit_reached(size) {
$interp.instruction_result = $crate::InstructionResult::MemoryLimitOOG;
return $ret;
}
let words_num = rounded_size / 32;
if !$interp
.gas
.record_memory($crate::gas::memory_gas(words_num))
{
$interp.instruction_result = $crate::InstructionResult::MemoryLimitOOG;
return $ret;
}
$interp.shared_memory.resize(rounded_size);
}
};
}
#[macro_export]
macro_rules! pop_address {
($interp:expr, $x1:ident) => {
pop_address_ret!($interp, $x1, ())
};
($interp:expr, $x1:ident, $x2:ident) => {
pop_address_ret!($interp, $x1, $x2, ())
};
}
#[macro_export]
macro_rules! pop_address_ret {
($interp:expr, $x1:ident, $ret:expr) => {
if $interp.stack.len() < 1 {
$interp.instruction_result = $crate::InstructionResult::StackUnderflow;
return $ret;
}
let $x1 = $crate::primitives::Address::from_word($crate::primitives::B256::from(unsafe {
$interp.stack.pop_unsafe()
}));
};
($interp:expr, $x1:ident, $x2:ident, $ret:expr) => {
if $interp.stack.len() < 2 {
$interp.instruction_result = $crate::InstructionResult::StackUnderflow;
return $ret;
}
let $x1 = $crate::primitives::Address::from_word($crate::primitives::B256::from(unsafe {
$interp.stack.pop_unsafe()
}));
let $x2 = $crate::primitives::Address::from_word($crate::primitives::B256::from(unsafe {
$interp.stack.pop_unsafe()
}));
};
}
#[macro_export]
macro_rules! pop {
($interp:expr, $x1:ident) => {
$crate::pop_ret!($interp, $x1, ())
};
($interp:expr, $x1:ident, $x2:ident) => {
$crate::pop_ret!($interp, $x1, $x2, ())
};
($interp:expr, $x1:ident, $x2:ident, $x3:ident) => {
$crate::pop_ret!($interp, $x1, $x2, $x3, ())
};
($interp:expr, $x1:ident, $x2:ident, $x3:ident, $x4:ident) => {
$crate::pop_ret!($interp, $x1, $x2, $x3, $x4, ())
};
($interp:expr, $x1:ident, $x2:ident, $x3:ident, $x4:ident, $x5:ident) => {
pop_ret!($interp, $x1, $x2, $x3, $x4, $x5, ())
};
}
#[macro_export]
macro_rules! pop_ret {
($interp:expr, $x1:ident, $ret:expr) => {
if $interp.stack.len() < 1 {
$interp.instruction_result = $crate::InstructionResult::StackUnderflow;
return $ret;
}
let $x1 = unsafe { $interp.stack.pop_unsafe() };
};
($interp:expr, $x1:ident, $x2:ident, $ret:expr) => {
if $interp.stack.len() < 2 {
$interp.instruction_result = $crate::InstructionResult::StackUnderflow;
return $ret;
}
let ($x1, $x2) = unsafe { $interp.stack.pop2_unsafe() };
};
($interp:expr, $x1:ident, $x2:ident, $x3:ident, $ret:expr) => {
if $interp.stack.len() < 3 {
$interp.instruction_result = $crate::InstructionResult::StackUnderflow;
return $ret;
}
let ($x1, $x2, $x3) = unsafe { $interp.stack.pop3_unsafe() };
};
($interp:expr, $x1:ident, $x2:ident, $x3:ident, $x4:ident, $ret:expr) => {
if $interp.stack.len() < 4 {
$interp.instruction_result = $crate::InstructionResult::StackUnderflow;
return $ret;
}
let ($x1, $x2, $x3, $x4) = unsafe { $interp.stack.pop4_unsafe() };
};
($interp:expr, $x1:ident, $x2:ident, $x3:ident, $x4:ident, $x5:ident, $ret:expr) => {
if $interp.stack.len() < 4 {
$interp.instruction_result = $crate::InstructionResult::StackUnderflow;
return $ret;
}
let ($x1, $x2, $x3, $x4, $x5) = unsafe { $interp.stack.pop5_unsafe() };
};
}
#[macro_export]
macro_rules! pop_top {
($interp:expr, $x1:ident) => {
if $interp.stack.len() < 1 {
$interp.instruction_result = $crate::InstructionResult::StackUnderflow;
return;
}
let $x1 = unsafe { $interp.stack.top_unsafe() };
};
($interp:expr, $x1:ident, $x2:ident) => {
if $interp.stack.len() < 2 {
$interp.instruction_result = $crate::InstructionResult::StackUnderflow;
return;
}
let ($x1, $x2) = unsafe { $interp.stack.pop_top_unsafe() };
};
($interp:expr, $x1:ident, $x2:ident, $x3:ident) => {
if $interp.stack.len() < 3 {
$interp.instruction_result = $crate::InstructionResult::StackUnderflow;
return;
}
let ($x1, $x2, $x3) = unsafe { $interp.stack.pop2_top_unsafe() };
};
}
#[macro_export]
macro_rules! push_b256 {
($interp:expr, $($x:expr),* $(,)?) => ($(
match $interp.stack.push_b256($x) {
Ok(()) => {},
Err(e) => {
$interp.instruction_result = e;
return;
},
}
)*)
}
#[macro_export]
macro_rules! push {
($interp:expr, $($x:expr),* $(,)?) => ($(
match $interp.stack.push($x) {
Ok(()) => {},
Err(e) => {
$interp.instruction_result = e;
return;
}
}
)*)
}
#[macro_export]
macro_rules! as_u64_saturated {
($v:expr) => {{
let x: &[u64; 4] = $v.as_limbs();
if x[1] == 0 && x[2] == 0 && x[3] == 0 {
x[0]
} else {
u64::MAX
}
}};
}
#[macro_export]
macro_rules! as_usize_saturated {
($v:expr) => {
usize::try_from($crate::as_u64_saturated!($v)).unwrap_or(usize::MAX)
};
}
#[macro_export]
macro_rules! as_isize_saturated {
($v:expr) => {
isize::try_from($crate::as_u64_saturated!($v)).unwrap_or(isize::MAX)
};
}
#[macro_export]
macro_rules! as_usize_or_fail {
($interp:expr, $v:expr) => {
$crate::as_usize_or_fail_ret!($interp, $v, ())
};
($interp:expr, $v:expr, $reason:expr) => {
$crate::as_usize_or_fail_ret!($interp, $v, $reason, ())
};
}
#[macro_export]
macro_rules! as_usize_or_fail_ret {
($interp:expr, $v:expr, $ret:expr) => {
$crate::as_usize_or_fail_ret!(
$interp,
$v,
$crate::InstructionResult::InvalidOperandOOG,
$ret
)
};
($interp:expr, $v:expr, $reason:expr, $ret:expr) => {{
let x = $v.as_limbs();
if x[1] != 0 || x[2] != 0 || x[3] != 0 {
$interp.instruction_result = $reason;
return $ret;
}
let Ok(val) = usize::try_from(x[0]) else {
$interp.instruction_result = $reason;
return $ret;
};
val
}};
}