Skip to content

Commit 4b4f7ba

Browse files
chore: refactor stack_op
Signed-off-by: Henry <mail@henrygressmann.de>
1 parent 479b540 commit 4b4f7ba

File tree

4 files changed

+95
-174
lines changed

4 files changed

+95
-174
lines changed

crates/tinywasm/src/interpreter/executor.rs

Lines changed: 84 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -50,23 +50,50 @@ impl<'store, const BUDGETED: bool> Executor<'store, BUDGETED> {
5050
#[inline(always)]
5151
fn exec<const ITERATIONS: usize>(&mut self) -> Result<Option<()>> {
5252
macro_rules! stack_op {
53-
(simd_unary $method:ident) => { stack_op!(unary Value128, |v| v.$method()) };
54-
(simd_binary $method:ident) => { stack_op!(binary Value128, |a, b| a.$method(b)) };
55-
(unary $ty:ty, |$v:ident| $expr:expr) => { self.store.stack.values.unary::<$ty>(|$v| Ok($expr))? };
56-
(binary $ty:ty, |$a:ident, $b:ident| $expr:expr) => { self.store.stack.values.binary::<$ty>(|$a, $b| Ok($expr))? };
57-
(binary try $ty:ty, |$a:ident, $b:ident| $expr:expr) => { self.store.stack.values.binary::<$ty>(|$a, $b| $expr)? };
58-
(unary $from:ty => $to:ty, |$v:ident| $expr:expr) => { self.store.stack.values.unary_into::<$from, $to>(|$v| Ok($expr))? };
59-
(binary $from:ty => $to:ty, |$a:ident, $b:ident| $expr:expr) => { self.store.stack.values.binary_into::<$from, $to>(|$a, $b| Ok($expr))? };
60-
(binary_into2 $from:ty => $to:ty, |$a:ident, $b:ident| $expr:expr) => {{
61-
let $b = self.store.stack.values.pop::<$from>();
62-
let $a = self.store.stack.values.pop::<$from>();
53+
(unary $ty:ty, |$v:ident| $expr:expr) => {{
54+
let $v = self.store.stack.values.pop::<$ty>();
55+
self.store.stack.values.push::<$ty>($expr)?;
56+
}};
57+
(binary $ty:ty, |$lhs:ident, $rhs:ident| $expr:expr) => {{
58+
let $rhs = self.store.stack.values.pop::<$ty>();
59+
let $lhs = self.store.stack.values.pop::<$ty>();
60+
self.store.stack.values.push::<$ty>($expr)?;
61+
}};
62+
(binary try $ty:ty, |$lhs:ident, $rhs:ident| $expr:expr) => {{
63+
let $rhs = self.store.stack.values.pop::<$ty>();
64+
let $lhs = self.store.stack.values.pop::<$ty>();
65+
self.store.stack.values.push::<$ty>($expr?)?;
66+
}};
67+
(unary $from:ty => $to:ty, |$v:ident| $expr:expr) => {{
68+
let $v = self.store.stack.values.pop::<$from>();
69+
self.store.stack.values.push::<$to>($expr)?;
70+
}};
71+
(binary $from:ty => $to:ty, |$lhs:ident, $rhs:ident| $expr:expr) => {{
72+
let $rhs = self.store.stack.values.pop::<$from>();
73+
let $lhs = self.store.stack.values.pop::<$from>();
74+
self.store.stack.values.push::<$to>($expr)?;
75+
}};
76+
(binary_into2 $from:ty => $to:ty, |$lhs:ident, $rhs:ident| $expr:expr) => {{
77+
let $rhs = self.store.stack.values.pop::<$from>();
78+
let $lhs = self.store.stack.values.pop::<$from>();
6379
let out = $expr;
6480
self.store.stack.values.push::<$to>(out.0)?;
6581
self.store.stack.values.push::<$to>(out.1)?;
6682
}};
67-
(binary $a:ty, $b:ty, |$lhs:ident, $rhs:ident| $expr:expr) => { stack_op!(binary $a, $b => $b, |$lhs, $rhs| $expr) };
68-
(binary $a:ty, $b:ty => $res:ty, |$lhs:ident, $rhs:ident| $expr:expr) => { self.store.stack.values.binary_mixed::<$a, $b, $res>(|$lhs, $rhs| Ok($expr))? };
69-
(ternary $ty:ty, |$a:ident, $b:ident, $c:ident| $expr:expr) => { self.store.stack.values.ternary::<$ty>(|$a, $b, $c| Ok($expr))? };
83+
(binary $lhs_ty:ty, $rhs_ty:ty, |$lhs:ident, $rhs:ident| $expr:expr) => {
84+
stack_op!(binary $lhs_ty, $rhs_ty => $rhs_ty, |$lhs, $rhs| $expr)
85+
};
86+
(binary $lhs_ty:ty, $rhs_ty:ty => $res:ty, |$lhs:ident, $rhs:ident| $expr:expr) => {{
87+
let $rhs = self.store.stack.values.pop::<$rhs_ty>();
88+
let $lhs = self.store.stack.values.pop::<$lhs_ty>();
89+
self.store.stack.values.push::<$res>($expr)?;
90+
}};
91+
(ternary $ty:ty, |$a:ident, $b:ident, $c:ident| $expr:expr) => {{
92+
let $c = self.store.stack.values.pop::<$ty>();
93+
let $b = self.store.stack.values.pop::<$ty>();
94+
let $a = self.store.stack.values.pop::<$ty>();
95+
self.store.stack.values.push::<$ty>($expr)?;
96+
}};
7097
(quaternary_into2 $from:ty => $to:ty, |$a:ident, $b:ident, $c:ident, $d:ident| $expr:expr) => {{
7198
let $d = self.store.stack.values.pop::<$from>();
7299
let $c = self.store.stack.values.pop::<$from>();
@@ -121,39 +148,16 @@ impl<'store, const BUDGETED: bool> Executor<'store, BUDGETED> {
121148
JumpIfZero(ip) => if self.exec_jump_if_zero(*ip) { continue; },
122149
JumpIfNonZero(ip) => if self.exec_jump_if_non_zero(*ip) { continue; },
123150
DropKeepSmall { base32, keep32, base64, keep64, base128, keep128, base_ref, keep_ref } => {
124-
let b32 = self.cf.stack_base().s32 + *base32 as u32;
125-
let k32 = *keep32 as usize;
126-
self.store.stack.values.stack_32.truncate_keep(b32 as usize, k32);
127-
let b64 = self.cf.stack_base().s64 + *base64 as u32;
128-
let k64 = *keep64 as usize;
129-
self.store.stack.values.stack_64.truncate_keep(b64 as usize, k64);
130-
let b128 = self.cf.stack_base().s128 + *base128 as u32;
131-
let k128 = *keep128 as usize;
132-
self.store.stack.values.stack_128.truncate_keep(b128 as usize, k128);
133-
let bref = self.cf.stack_base().sref + *base_ref as u32;
134-
let kref = *keep_ref as usize;
135-
self.store.stack.values.stack_ref.truncate_keep(bref as usize, kref);
136-
}
137-
DropKeep32(base, keep) => {
138-
let b = self.cf.stack_base().s32 + *base as u32;
139-
let k = *keep as usize;
140-
self.store.stack.values.stack_32.truncate_keep(b as usize, k);
141-
}
142-
DropKeep64(base, keep) => {
143-
let b = self.cf.stack_base().s64 + *base as u32;
144-
let k = *keep as usize;
145-
self.store.stack.values.stack_64.truncate_keep(b as usize, k);
146-
}
147-
DropKeep128(base, keep) => {
148-
let b = self.cf.stack_base().s128 + *base as u32;
149-
let k = *keep as usize;
150-
self.store.stack.values.stack_128.truncate_keep(b as usize, k);
151-
}
152-
DropKeepRef(base, keep) => {
153-
let b = self.cf.stack_base().sref + *base as u32;
154-
let k = *keep as usize;
155-
self.store.stack.values.stack_ref.truncate_keep(b as usize, k);
151+
let stack_base = self.cf.stack_base();
152+
self.store.stack.values.stack_32.truncate_keep((stack_base.s32 + *base32 as u32) as usize, *keep32 as usize);
153+
self.store.stack.values.stack_64.truncate_keep((stack_base.s64 + *base64 as u32) as usize, *keep64 as usize);
154+
self.store.stack.values.stack_128.truncate_keep((stack_base.s128 + *base128 as u32) as usize, *keep128 as usize);
155+
self.store.stack.values.stack_ref.truncate_keep((stack_base.sref + *base_ref as u32) as usize, *keep_ref as usize);
156156
}
157+
DropKeep32(base, keep) => self.store.stack.values.stack_32.truncate_keep((self.cf.stack_base().s32 + *base as u32) as usize, *keep as usize),
158+
DropKeep64(base, keep) => self.store.stack.values.stack_64.truncate_keep((self.cf.stack_base().s64 + *base as u32) as usize, *keep as usize),
159+
DropKeep128(base, keep) => self.store.stack.values.stack_128.truncate_keep((self.cf.stack_base().s128 + *base as u32) as usize, *keep as usize),
160+
DropKeepRef(base, keep) => self.store.stack.values.stack_ref.truncate_keep((self.cf.stack_base().sref + *base as u32) as usize, *keep as usize),
157161
BranchTable(default_ip, start, len) => { self.exec_branch_table(*default_ip, *start, *len); continue; }
158162
Return => { if self.exec_return() { return Ok(Some(())); } continue; }
159163
LocalGet32(local_index) => self.store.stack.values.push(self.store.stack.values.local_get::<Value32>(&self.cf, *local_index))?,
@@ -412,7 +416,7 @@ impl<'store, const BUDGETED: bool> Executor<'store, BUDGETED> {
412416
V128AndNot => stack_op!(binary Value128, |a, b| a.v128_andnot(b)),
413417
V128Or => stack_op!(binary Value128, |a, b| a.v128_or(b)),
414418
V128Xor => stack_op!(binary Value128, |a, b| a.v128_xor(b)),
415-
V128Bitselect => stack_op!(ternary Value128, |v1, v2, c| Value128::v128_bitselect(v1, v2, c)),
419+
V128Bitselect => stack_op!(ternary Value128, |a, b, c| Value128::v128_bitselect(a, b, c)),
416420
V128AnyTrue => stack_op!(unary Value128 => i32, |v| v.v128_any_true() as i32),
417421
I8x16Swizzle => stack_op!(binary Value128, |a, s| a.i8x16_swizzle(s)),
418422
I8x16RelaxedSwizzle => stack_op!(binary Value128, |a, s| a.i8x16_relaxed_swizzle(s)),
@@ -604,43 +608,43 @@ impl<'store, const BUDGETED: bool> Executor<'store, BUDGETED> {
604608
I8x16Shuffle(idx) => { let idx = self.func.data.v128_constants[*idx as usize].to_le_bytes(); stack_op!(binary Value128, |a, b| Value128::i8x16_shuffle(a, b, idx)) }
605609
I16x8Q15MulrSatS => stack_op!(binary Value128, |a, b| a.i16x8_q15mulr_sat_s(b)),
606610
I32x4DotI16x8S => stack_op!(binary Value128, |a, b| a.i32x4_dot_i16x8_s(b)),
607-
I8x16RelaxedLaneselect => stack_op!(ternary Value128, |v1, v2, c| Value128::i8x16_relaxed_laneselect(v1, v2, c)),
608-
I16x8RelaxedLaneselect => stack_op!(ternary Value128, |v1, v2, c| Value128::i16x8_relaxed_laneselect(v1, v2, c)),
609-
I32x4RelaxedLaneselect => stack_op!(ternary Value128, |v1, v2, c| Value128::i32x4_relaxed_laneselect(v1, v2, c)),
610-
I64x2RelaxedLaneselect => stack_op!(ternary Value128, |v1, v2, c| Value128::i64x2_relaxed_laneselect(v1, v2, c)),
611+
I8x16RelaxedLaneselect => stack_op!(ternary Value128, |a, b, c| Value128::i8x16_relaxed_laneselect(a, b, c)),
612+
I16x8RelaxedLaneselect => stack_op!(ternary Value128, |a, b, c| Value128::i16x8_relaxed_laneselect(a, b, c)),
613+
I32x4RelaxedLaneselect => stack_op!(ternary Value128, |a, b, c| Value128::i32x4_relaxed_laneselect(a, b, c)),
614+
I64x2RelaxedLaneselect => stack_op!(ternary Value128, |a, b, c| Value128::i64x2_relaxed_laneselect(a, b, c)),
611615
I16x8RelaxedQ15mulrS => stack_op!(binary Value128, |a, b| a.i16x8_relaxed_q15mulr_s(b)),
612616
I16x8RelaxedDotI8x16I7x16S => stack_op!(binary Value128, |a, b| a.i16x8_relaxed_dot_i8x16_i7x16_s(b)),
613617
I32x4RelaxedDotI8x16I7x16AddS => stack_op!(ternary Value128, |a, b, c| a.i32x4_relaxed_dot_i8x16_i7x16_add_s(b, c)),
614-
F32x4Ceil => stack_op!(simd_unary f32x4_ceil),
615-
F64x2Ceil => stack_op!(simd_unary f64x2_ceil),
616-
F32x4Floor => stack_op!(simd_unary f32x4_floor),
617-
F64x2Floor => stack_op!(simd_unary f64x2_floor),
618-
F32x4Trunc => stack_op!(simd_unary f32x4_trunc),
619-
F64x2Trunc => stack_op!(simd_unary f64x2_trunc),
620-
F32x4Nearest => stack_op!(simd_unary f32x4_nearest),
621-
F64x2Nearest => stack_op!(simd_unary f64x2_nearest),
622-
F32x4Abs => stack_op!(simd_unary f32x4_abs),
623-
F64x2Abs => stack_op!(simd_unary f64x2_abs),
624-
F32x4Neg => stack_op!(simd_unary f32x4_neg),
625-
F64x2Neg => stack_op!(simd_unary f64x2_neg),
626-
F32x4Sqrt => stack_op!(simd_unary f32x4_sqrt),
627-
F64x2Sqrt => stack_op!(simd_unary f64x2_sqrt),
628-
F32x4Add => stack_op!(simd_binary f32x4_add),
629-
F64x2Add => stack_op!(simd_binary f64x2_add),
630-
F32x4Sub => stack_op!(simd_binary f32x4_sub),
631-
F64x2Sub => stack_op!(simd_binary f64x2_sub),
632-
F32x4Mul => stack_op!(simd_binary f32x4_mul),
633-
F64x2Mul => stack_op!(simd_binary f64x2_mul),
634-
F32x4Div => stack_op!(simd_binary f32x4_div),
635-
F64x2Div => stack_op!(simd_binary f64x2_div),
636-
F32x4Min => stack_op!(simd_binary f32x4_min),
637-
F64x2Min => stack_op!(simd_binary f64x2_min),
638-
F32x4Max => stack_op!(simd_binary f32x4_max),
639-
F64x2Max => stack_op!(simd_binary f64x2_max),
640-
F32x4PMin => stack_op!(simd_binary f32x4_pmin),
641-
F32x4PMax => stack_op!(simd_binary f32x4_pmax),
642-
F64x2PMin => stack_op!(simd_binary f64x2_pmin),
643-
F64x2PMax => stack_op!(simd_binary f64x2_pmax),
618+
F32x4Ceil => stack_op!(unary Value128, |v| v.f32x4_ceil()),
619+
F64x2Ceil => stack_op!(unary Value128, |v| v.f64x2_ceil()),
620+
F32x4Floor => stack_op!(unary Value128, |v| v.f32x4_floor()),
621+
F64x2Floor => stack_op!(unary Value128, |v| v.f64x2_floor()),
622+
F32x4Trunc => stack_op!(unary Value128, |v| v.f32x4_trunc()),
623+
F64x2Trunc => stack_op!(unary Value128, |v| v.f64x2_trunc()),
624+
F32x4Nearest => stack_op!(unary Value128, |v| v.f32x4_nearest()),
625+
F64x2Nearest => stack_op!(unary Value128, |v| v.f64x2_nearest()),
626+
F32x4Abs => stack_op!(unary Value128, |v| v.f32x4_abs()),
627+
F64x2Abs => stack_op!(unary Value128, |v| v.f64x2_abs()),
628+
F32x4Neg => stack_op!(unary Value128, |v| v.f32x4_neg()),
629+
F64x2Neg => stack_op!(unary Value128, |v| v.f64x2_neg()),
630+
F32x4Sqrt => stack_op!(unary Value128, |v| v.f32x4_sqrt()),
631+
F64x2Sqrt => stack_op!(unary Value128, |v| v.f64x2_sqrt()),
632+
F32x4Add => stack_op!(binary Value128, |a, b| a.f32x4_add(b)),
633+
F64x2Add => stack_op!(binary Value128, |a, b| a.f64x2_add(b)),
634+
F32x4Sub => stack_op!(binary Value128, |a, b| a.f32x4_sub(b)),
635+
F64x2Sub => stack_op!(binary Value128, |a, b| a.f64x2_sub(b)),
636+
F32x4Mul => stack_op!(binary Value128, |a, b| a.f32x4_mul(b)),
637+
F64x2Mul => stack_op!(binary Value128, |a, b| a.f64x2_mul(b)),
638+
F32x4Div => stack_op!(binary Value128, |a, b| a.f32x4_div(b)),
639+
F64x2Div => stack_op!(binary Value128, |a, b| a.f64x2_div(b)),
640+
F32x4Min => stack_op!(binary Value128, |a, b| a.f32x4_min(b)),
641+
F64x2Min => stack_op!(binary Value128, |a, b| a.f64x2_min(b)),
642+
F32x4Max => stack_op!(binary Value128, |a, b| a.f32x4_max(b)),
643+
F64x2Max => stack_op!(binary Value128, |a, b| a.f64x2_max(b)),
644+
F32x4PMin => stack_op!(binary Value128, |a, b| a.f32x4_pmin(b)),
645+
F32x4PMax => stack_op!(binary Value128, |a, b| a.f32x4_pmax(b)),
646+
F64x2PMin => stack_op!(binary Value128, |a, b| a.f64x2_pmin(b)),
647+
F64x2PMax => stack_op!(binary Value128, |a, b| a.f64x2_pmax(b)),
644648
F32x4RelaxedMadd => stack_op!(ternary Value128, |a, b, c| a.f32x4_relaxed_madd(b, c)),
645649
F32x4RelaxedNmadd => stack_op!(ternary Value128, |a, b, c| a.f32x4_relaxed_nmadd(b, c)),
646650
F64x2RelaxedMadd => stack_op!(ternary Value128, |a, b, c| a.f64x2_relaxed_madd(b, c)),

crates/tinywasm/src/interpreter/num_helpers.rs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,17 @@ macro_rules! checked_conv_float {
3030
checked_conv_float!($from, $to, $to, $self)
3131
};
3232
// Conversion with an intermediate unsigned type and error checking (three types)
33-
($from:tt, $intermediate:tt, $to:tt, $self:expr) => {
34-
$self.store.stack.values.unary_into::<$from, $to>(|v| {
35-
let (min, max) = float_min_max!($from, $intermediate);
36-
if unlikely(v.is_nan()) {
37-
return Err(Error::Trap(crate::Trap::InvalidConversionToInt));
38-
}
39-
if unlikely(v <= min || v >= max) {
40-
return Err(Error::Trap(crate::Trap::IntegerOverflow));
41-
}
42-
Ok((v as $intermediate as $to).into())
43-
})?
44-
};
33+
($from:tt, $intermediate:tt, $to:tt, $self:expr) => {{
34+
let v = $self.store.stack.values.pop::<$from>();
35+
let (min, max) = float_min_max!($from, $intermediate);
36+
if unlikely(v.is_nan()) {
37+
return Err(Error::Trap(crate::Trap::InvalidConversionToInt));
38+
}
39+
if unlikely(v <= min || v >= max) {
40+
return Err(Error::Trap(crate::Trap::IntegerOverflow));
41+
}
42+
$self.store.stack.values.push::<$to>((v as $intermediate as $to).into())?;
43+
}};
4544
}
4645

4746
pub(crate) use checked_conv_float;

crates/tinywasm/src/interpreter/stack/value_stack.rs

Lines changed: 0 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,6 @@ impl<T: Copy + Default> Stack<T> {
5858
&self.data[self.len - 1]
5959
}
6060

61-
#[inline(always)]
62-
pub(crate) fn last_mut(&mut self) -> &mut T {
63-
if self.len == 0 {
64-
unreachable!("ValueStack underflow, this is a bug");
65-
}
66-
&mut self.data[self.len - 1]
67-
}
68-
6961
#[inline(always)]
7062
pub(crate) fn get(&self, index: usize) -> T {
7163
match self.data.get(index) {
@@ -203,53 +195,6 @@ impl ValueStack {
203195
self.stack_ref.select_many(counts.cref as usize, condition);
204196
}
205197

206-
#[inline(always)]
207-
pub(crate) fn unary<T: InternalValue>(&mut self, func: impl FnOnce(T) -> Result<T>) -> Result<()> {
208-
T::stack_apply1(self, func)
209-
}
210-
211-
#[inline(always)]
212-
pub(crate) fn unary_into<IN: InternalValue, OUT: InternalValue>(
213-
&mut self,
214-
func: impl FnOnce(IN) -> Result<OUT>,
215-
) -> Result<()> {
216-
let v = IN::stack_pop(self);
217-
OUT::stack_push(self, func(v)?)?;
218-
Ok(())
219-
}
220-
221-
#[inline(always)]
222-
pub(crate) fn binary<T: InternalValue>(&mut self, func: impl FnOnce(T, T) -> Result<T>) -> Result<()> {
223-
T::stack_apply2(self, func)
224-
}
225-
226-
#[inline(always)]
227-
pub(crate) fn binary_into<IN: InternalValue, OUT: InternalValue>(
228-
&mut self,
229-
func: impl FnOnce(IN, IN) -> Result<OUT>,
230-
) -> Result<()> {
231-
let rhs = IN::stack_pop(self);
232-
let lhs = IN::stack_pop(self);
233-
OUT::stack_push(self, func(lhs, rhs)?)?;
234-
Ok(())
235-
}
236-
237-
#[inline(always)]
238-
pub(crate) fn binary_mixed<A: InternalValue, B: InternalValue, OUT: InternalValue>(
239-
&mut self,
240-
func: impl FnOnce(A, B) -> Result<OUT>,
241-
) -> Result<()> {
242-
let rhs = B::stack_pop(self);
243-
let lhs = A::stack_pop(self);
244-
OUT::stack_push(self, func(lhs, rhs)?)?;
245-
Ok(())
246-
}
247-
248-
#[inline(always)]
249-
pub(crate) fn ternary<T: InternalValue>(&mut self, func: impl FnOnce(T, T, T) -> Result<T>) -> Result<()> {
250-
T::stack_apply3(self, func)
251-
}
252-
253198
pub(crate) fn pop_types<'a>(
254199
&'a mut self,
255200
val_types: impl IntoIterator<Item = &'a ValType>,

0 commit comments

Comments
 (0)