Skip to content

Commit daf508c

Browse files
DaniPopesfubuloubu
authored andcommitted
feat(interpreter): export utility macros (bluealloy#1203)
* feat(interpreter): export utility macros * chore: rename memory resize macro * chore: dollar crate
1 parent cc8682f commit daf508c

File tree

11 files changed

+92
-47
lines changed

11 files changed

+92
-47
lines changed

crates/interpreter/src/gas.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,9 @@ impl Gas {
111111
true
112112
}
113113

114-
/// used in shared_memory_resize! macro to record gas used for memory expansion.
114+
/// Records memory expansion gas.
115+
///
116+
/// Used in [`resize_memory!`](crate::resize_memory).
115117
#[inline]
116118
pub fn record_memory(&mut self, gas_memory: u64) -> bool {
117119
if gas_memory > self.memory {

crates/interpreter/src/instructions/arithmetic.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use super::i256::{i256_div, i256_mod};
22
use crate::{
33
gas,
44
primitives::{Spec, U256},
5-
Host, InstructionResult, Interpreter,
5+
Host, Interpreter,
66
};
77

88
pub fn wrapping_add<H: Host>(interpreter: &mut Interpreter, _host: &mut H) {

crates/interpreter/src/instructions/bitwise.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use super::i256::{i256_cmp, i256_sign_compl, two_compl, Sign};
22
use crate::{
33
gas,
44
primitives::{Spec, U256},
5-
Host, InstructionResult, Interpreter,
5+
Host, Interpreter,
66
};
77
use core::cmp::Ordering;
88

crates/interpreter/src/instructions/control.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ fn return_inner(interpreter: &mut Interpreter, instruction_result: InstructionRe
4949
let mut output = Bytes::default();
5050
if len != 0 {
5151
let offset = as_usize_or_fail!(interpreter, offset);
52-
shared_memory_resize!(interpreter, offset, len);
52+
resize_memory!(interpreter, offset, len);
5353

5454
output = interpreter.shared_memory.slice(offset, len).to_vec().into()
5555
}

crates/interpreter/src/instructions/host.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ pub use call_helpers::{calc_call_gas, get_memory_input_and_out_ranges};
55
use crate::{
66
gas::{self, COLD_ACCOUNT_ACCESS_COST, WARM_STORAGE_READ_COST},
77
interpreter::{Interpreter, InterpreterAction},
8-
primitives::{Address, Bytes, Log, LogData, Spec, SpecId::*, B256, U256},
8+
primitives::{Bytes, Log, LogData, Spec, SpecId::*, B256, U256},
99
CallContext, CallInputs, CallScheme, CreateInputs, CreateScheme, Host, InstructionResult,
1010
SStoreResult, Transfer, MAX_INITCODE_SIZE,
1111
};
@@ -112,7 +112,7 @@ pub fn extcodecopy<H: Host, SPEC: Spec>(interpreter: &mut Interpreter, host: &mu
112112
}
113113
let memory_offset = as_usize_or_fail!(interpreter, memory_offset);
114114
let code_offset = min(as_usize_saturated!(code_offset), code.len());
115-
shared_memory_resize!(interpreter, memory_offset, len);
115+
resize_memory!(interpreter, memory_offset, len);
116116

117117
// Note: this can't panic because we resized memory to fit.
118118
interpreter
@@ -204,7 +204,7 @@ pub fn log<const N: usize, H: Host>(interpreter: &mut Interpreter, host: &mut H)
204204
Bytes::new()
205205
} else {
206206
let offset = as_usize_or_fail!(interpreter, offset);
207-
shared_memory_resize!(interpreter, offset, len);
207+
resize_memory!(interpreter, offset, len);
208208
Bytes::copy_from_slice(interpreter.shared_memory.slice(offset, len))
209209
};
210210

@@ -278,7 +278,7 @@ pub fn create<const IS_CREATE2: bool, H: Host, SPEC: Spec>(
278278
}
279279

280280
let code_offset = as_usize_or_fail!(interpreter, code_offset);
281-
shared_memory_resize!(interpreter, code_offset, len);
281+
resize_memory!(interpreter, code_offset, len);
282282
code = Bytes::copy_from_slice(interpreter.shared_memory.slice(code_offset, len));
283283
}
284284

crates/interpreter/src/instructions/host/call_helpers.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub fn get_memory_input_and_out_ranges(
1515
let in_len = as_usize_or_fail_ret!(interpreter, in_len, None);
1616
let input = if in_len != 0 {
1717
let in_offset = as_usize_or_fail_ret!(interpreter, in_offset, None);
18-
shared_memory_resize!(interpreter, in_offset, in_len, None);
18+
resize_memory!(interpreter, in_offset, in_len, None);
1919
Bytes::copy_from_slice(interpreter.shared_memory.slice(in_offset, in_len))
2020
} else {
2121
Bytes::new()
@@ -24,7 +24,7 @@ pub fn get_memory_input_and_out_ranges(
2424
let out_len = as_usize_or_fail_ret!(interpreter, out_len, None);
2525
let out_offset = if out_len != 0 {
2626
let out_offset = as_usize_or_fail_ret!(interpreter, out_offset, None);
27-
shared_memory_resize!(interpreter, out_offset, out_len, None);
27+
resize_memory!(interpreter, out_offset, out_len, None);
2828
out_offset
2929
} else {
3030
usize::MAX //unrealistic value so we are sure it is not used

crates/interpreter/src/instructions/host_env.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::{
22
gas,
33
primitives::{Spec, SpecId::*, U256},
4-
Host, InstructionResult, Interpreter,
4+
Host, Interpreter,
55
};
66

77
/// EIP-1344: ChainID opcode

crates/interpreter/src/instructions/macros.rs

+69-26
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,70 @@
1+
//! Utility macros to help implementementing opcode instruction functions.
2+
3+
/// Fails the instruction if the current call is static.
4+
#[macro_export]
15
macro_rules! check_staticcall {
26
($interp:expr) => {
37
if $interp.is_static {
4-
$interp.instruction_result = InstructionResult::StateChangeDuringStaticCall;
8+
$interp.instruction_result = $crate::InstructionResult::StateChangeDuringStaticCall;
59
return;
610
}
711
};
812
}
913

14+
/// Fails the instruction if the `min` is not enabled in `SPEC`.
15+
#[macro_export]
1016
macro_rules! check {
1117
($interp:expr, $min:ident) => {
1218
// TODO: Force const-eval on the condition with a `const {}` block once they are stable
1319
if !<SPEC as $crate::primitives::Spec>::enabled($crate::primitives::SpecId::$min) {
14-
$interp.instruction_result = InstructionResult::NotActivated;
20+
$interp.instruction_result = $crate::InstructionResult::NotActivated;
1521
return;
1622
}
1723
};
1824
}
1925

26+
/// Records a `gas` cost and fails the instruction if it would exceed the available gas.
2027
#[macro_export]
2128
macro_rules! gas {
2229
($interp:expr, $gas:expr) => {
23-
gas!($interp, $gas, ())
30+
$crate::gas!($interp, $gas, ())
2431
};
2532
($interp:expr, $gas:expr, $ret:expr) => {
2633
if !$interp.gas.record_cost($gas) {
27-
$interp.instruction_result = InstructionResult::OutOfGas;
34+
$interp.instruction_result = $crate::InstructionResult::OutOfGas;
2835
return $ret;
2936
}
3037
};
3138
}
3239

40+
/// Records a `gas` refund.
41+
#[macro_export]
3342
macro_rules! refund {
3443
($interp:expr, $gas:expr) => {
3544
$interp.gas.record_refund($gas)
3645
};
3746
}
3847

48+
/// Same as [`gas!`], but with `gas` as an option.
49+
#[macro_export]
3950
macro_rules! gas_or_fail {
4051
($interp:expr, $gas:expr) => {
4152
match $gas {
42-
Some(gas_used) => gas!($interp, gas_used),
53+
Some(gas_used) => $crate::gas!($interp, gas_used),
4354
None => {
44-
$interp.instruction_result = InstructionResult::OutOfGas;
55+
$interp.instruction_result = $crate::InstructionResult::OutOfGas;
4556
return;
4657
}
4758
}
4859
};
4960
}
5061

62+
/// Resizes the interpreter memory if necessary. Fails the instruction if the memory or gas limit
63+
/// is exceeded.
5164
#[macro_export]
52-
macro_rules! shared_memory_resize {
65+
macro_rules! resize_memory {
5366
($interp:expr, $offset:expr, $len:expr) => {
54-
shared_memory_resize!($interp, $offset, $len, ())
67+
$crate::resize_memory!($interp, $offset, $len, ())
5568
};
5669
($interp:expr, $offset:expr, $len:expr, $ret:expr) => {
5770
let size = $offset.saturating_add($len);
@@ -61,7 +74,7 @@ macro_rules! shared_memory_resize {
6174

6275
#[cfg(feature = "memory_limit")]
6376
if $interp.shared_memory.limit_reached(size) {
64-
$interp.instruction_result = InstructionResult::MemoryLimitOOG;
77+
$interp.instruction_result = $crate::InstructionResult::MemoryLimitOOG;
6578
return $ret;
6679
}
6780

@@ -71,34 +84,43 @@ macro_rules! shared_memory_resize {
7184
.gas
7285
.record_memory($crate::gas::memory_gas(words_num))
7386
{
74-
$interp.instruction_result = InstructionResult::MemoryLimitOOG;
87+
$interp.instruction_result = $crate::InstructionResult::MemoryLimitOOG;
7588
return $ret;
7689
}
7790
$interp.shared_memory.resize(rounded_size);
7891
}
7992
};
8093
}
8194

95+
/// Pops `Address` values from the stack. Fails the instruction if the stack is too small.
96+
#[macro_export]
8297
macro_rules! pop_address {
8398
($interp:expr, $x1:ident) => {
8499
if $interp.stack.len() < 1 {
85-
$interp.instruction_result = InstructionResult::StackUnderflow;
100+
$interp.instruction_result = $crate::InstructionResult::StackUnderflow;
86101
return;
87102
}
88103
// SAFETY: Length is checked above.
89-
let $x1 = Address::from_word(B256::from(unsafe { $interp.stack.pop_unsafe() }));
104+
let $x1 = $crate::primitives::Address::from_word($crate::primitives::B256::from(unsafe {
105+
$interp.stack.pop_unsafe()
106+
}));
90107
};
91108
($interp:expr, $x1:ident, $x2:ident) => {
92109
if $interp.stack.len() < 2 {
93-
$interp.instruction_result = InstructionResult::StackUnderflow;
110+
$interp.instruction_result = $crate::InstructionResult::StackUnderflow;
94111
return;
95112
}
96113
// SAFETY: Length is checked above.
97-
let $x1 = Address::from_word(B256::from(unsafe { $interp.stack.pop_unsafe() }));
98-
let $x2 = Address::from_word(B256::from(unsafe { $interp.stack.pop_unsafe() }));
114+
let $x1 = $crate::primitives::Address::from_word($crate::primitives::B256::from(unsafe {
115+
$interp.stack.pop_unsafe()
116+
}));
117+
let $x2 = $crate::primitives::Address::from_word($crate::primitives::B256::from(unsafe {
118+
$interp.stack.pop_unsafe()
119+
}));
99120
};
100121
}
101122

123+
/// Pops `U256` values from the stack. Fails the instruction if the stack is too small.
102124
#[macro_export]
103125
macro_rules! pop {
104126
($interp:expr, $x1:ident) => {
@@ -115,69 +137,75 @@ macro_rules! pop {
115137
};
116138
}
117139

140+
/// Pops `U256` values from the stack, and returns `ret`.
141+
/// Fails the instruction if the stack is too small.
118142
#[macro_export]
119143
macro_rules! pop_ret {
120144
($interp:expr, $x1:ident, $ret:expr) => {
121145
if $interp.stack.len() < 1 {
122-
$interp.instruction_result = InstructionResult::StackUnderflow;
146+
$interp.instruction_result = $crate::InstructionResult::StackUnderflow;
123147
return $ret;
124148
}
125149
// SAFETY: Length is checked above.
126150
let $x1 = unsafe { $interp.stack.pop_unsafe() };
127151
};
128152
($interp:expr, $x1:ident, $x2:ident, $ret:expr) => {
129153
if $interp.stack.len() < 2 {
130-
$interp.instruction_result = InstructionResult::StackUnderflow;
154+
$interp.instruction_result = $crate::InstructionResult::StackUnderflow;
131155
return $ret;
132156
}
133157
// SAFETY: Length is checked above.
134158
let ($x1, $x2) = unsafe { $interp.stack.pop2_unsafe() };
135159
};
136160
($interp:expr, $x1:ident, $x2:ident, $x3:ident, $ret:expr) => {
137161
if $interp.stack.len() < 3 {
138-
$interp.instruction_result = InstructionResult::StackUnderflow;
162+
$interp.instruction_result = $crate::InstructionResult::StackUnderflow;
139163
return $ret;
140164
}
141165
// SAFETY: Length is checked above.
142166
let ($x1, $x2, $x3) = unsafe { $interp.stack.pop3_unsafe() };
143167
};
144168
($interp:expr, $x1:ident, $x2:ident, $x3:ident, $x4:ident, $ret:expr) => {
145169
if $interp.stack.len() < 4 {
146-
$interp.instruction_result = InstructionResult::StackUnderflow;
170+
$interp.instruction_result = $crate::InstructionResult::StackUnderflow;
147171
return $ret;
148172
}
149173
// SAFETY: Length is checked above.
150174
let ($x1, $x2, $x3, $x4) = unsafe { $interp.stack.pop4_unsafe() };
151175
};
152176
}
153177

178+
/// Pops `U256` values from the stack, and returns a reference to the top of the stack.
179+
/// Fails the instruction if the stack is too small.
180+
#[macro_export]
154181
macro_rules! pop_top {
155182
($interp:expr, $x1:ident) => {
156183
if $interp.stack.len() < 1 {
157-
$interp.instruction_result = InstructionResult::StackUnderflow;
184+
$interp.instruction_result = $crate::InstructionResult::StackUnderflow;
158185
return;
159186
}
160187
// SAFETY: Length is checked above.
161188
let $x1 = unsafe { $interp.stack.top_unsafe() };
162189
};
163190
($interp:expr, $x1:ident, $x2:ident) => {
164191
if $interp.stack.len() < 2 {
165-
$interp.instruction_result = InstructionResult::StackUnderflow;
192+
$interp.instruction_result = $crate::InstructionResult::StackUnderflow;
166193
return;
167194
}
168195
// SAFETY: Length is checked above.
169196
let ($x1, $x2) = unsafe { $interp.stack.pop_top_unsafe() };
170197
};
171198
($interp:expr, $x1:ident, $x2:ident, $x3:ident) => {
172199
if $interp.stack.len() < 3 {
173-
$interp.instruction_result = InstructionResult::StackUnderflow;
200+
$interp.instruction_result = $crate::InstructionResult::StackUnderflow;
174201
return;
175202
}
176203
// SAFETY: Length is checked above.
177204
let ($x1, $x2, $x3) = unsafe { $interp.stack.pop2_top_unsafe() };
178205
};
179206
}
180207

208+
/// Pushes `B256` values onto the stack. Fails the instruction if the stack is full.
181209
#[macro_export]
182210
macro_rules! push_b256 {
183211
($interp:expr, $($x:expr),* $(,)?) => ($(
@@ -191,6 +219,7 @@ macro_rules! push_b256 {
191219
)*)
192220
}
193221

222+
/// Pushes a `B256` value onto the stack. Fails the instruction if the stack is full.
194223
#[macro_export]
195224
macro_rules! push {
196225
($interp:expr, $($x:expr),* $(,)?) => ($(
@@ -204,6 +233,8 @@ macro_rules! push {
204233
)*)
205234
}
206235

236+
/// Converts a `U256` value to a `u64`, saturating to `MAX` if the value is too large.
237+
#[macro_export]
207238
macro_rules! as_u64_saturated {
208239
($v:expr) => {{
209240
let x: &[u64; 4] = $v.as_limbs();
@@ -215,24 +246,36 @@ macro_rules! as_u64_saturated {
215246
}};
216247
}
217248

249+
/// Converts a `U256` value to a `usize`, saturating to `MAX` if the value is too large.
250+
#[macro_export]
218251
macro_rules! as_usize_saturated {
219252
($v:expr) => {
220-
usize::try_from(as_u64_saturated!($v)).unwrap_or(usize::MAX)
253+
usize::try_from($crate::as_u64_saturated!($v)).unwrap_or(usize::MAX)
221254
};
222255
}
223256

257+
/// Converts a `U256` value to a `usize`, failing the instruction if the value is too large.
258+
#[macro_export]
224259
macro_rules! as_usize_or_fail {
225260
($interp:expr, $v:expr) => {
226-
as_usize_or_fail_ret!($interp, $v, ())
261+
$crate::as_usize_or_fail_ret!($interp, $v, ())
227262
};
228263
($interp:expr, $v:expr, $reason:expr) => {
229-
as_usize_or_fail_ret!($interp, $v, $reason, ())
264+
$crate::as_usize_or_fail_ret!($interp, $v, $reason, ())
230265
};
231266
}
232267

268+
/// Converts a `U256` value to a `usize` and returns `ret`,
269+
/// failing the instruction if the value is too large.
270+
#[macro_export]
233271
macro_rules! as_usize_or_fail_ret {
234272
($interp:expr, $v:expr, $ret:expr) => {
235-
as_usize_or_fail_ret!($interp, $v, InstructionResult::InvalidOperandOOG, $ret)
273+
$crate::as_usize_or_fail_ret!(
274+
$interp,
275+
$v,
276+
$crate::InstructionResult::InvalidOperandOOG,
277+
$ret
278+
)
236279
};
237280

238281
($interp:expr, $v:expr, $reason:expr, $ret:expr) => {{

0 commit comments

Comments
 (0)