Skip to content
This repository was archived by the owner on Oct 3, 2025. It is now read-only.

Commit bcb8ebf

Browse files
wip: another v128 attempt
Signed-off-by: Henry Gressmann <[email protected]>
1 parent 2bcf333 commit bcb8ebf

File tree

11 files changed

+98
-54
lines changed

11 files changed

+98
-54
lines changed

crates/tinywasm/src/func.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1+
use crate::runtime::{CallFrame, Stack, WasmValueRepr};
12
use crate::{log, runtime::RawWasmValue, unlikely, Function};
3+
use crate::{Error, FuncContext, Result, Store};
24
use alloc::{boxed::Box, format, string::String, string::ToString, vec, vec::Vec};
35
use tinywasm_types::{FuncType, ModuleInstanceAddr, ValType, WasmValue};
46

5-
use crate::runtime::{CallFrame, Stack};
6-
use crate::{Error, FuncContext, Result, Store};
7-
87
#[derive(Debug)]
98
/// A function handle
109
pub struct FuncHandle {

crates/tinywasm/src/runtime/interpreter/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,7 @@ impl<'store, 'stack> Executor<'store, 'stack> {
724724
instr_ptr,
725725
end_instr_offset,
726726
stack_ptr: self.stack.values.len() as u32 - params as u32,
727+
large_stack_ptr: 0,
727728
results,
728729
params,
729730
ty,

crates/tinywasm/src/runtime/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ mod value;
44

55
use crate::Result;
66
pub use stack::*;
7-
pub(crate) use value::RawWasmValue;
7+
pub use value::{LargeRawWasmValue, RawWasmValue, WasmValueRepr};
88

99
#[allow(rustdoc::private_intra_doc_links)]
1010
/// A WebAssembly runtime.
Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,32 @@
11
mod block_stack;
22
mod call_stack;
3+
mod large_value_stack;
34
mod value_stack;
45

5-
pub(crate) use self::{call_stack::CallStack, value_stack::ValueStack};
66
pub(crate) use block_stack::{BlockFrame, BlockStack, BlockType};
7-
pub(crate) use call_stack::CallFrame;
7+
pub(crate) use call_stack::{CallFrame, CallStack};
8+
pub(crate) use large_value_stack::LargeValueStack;
9+
pub(crate) use value_stack::ValueStack;
10+
11+
use super::RawWasmValue;
812

913
/// A WebAssembly Stack
1014
#[derive(Debug)]
1115
pub struct Stack {
12-
pub(crate) values: ValueStack,
16+
pub(crate) values: ValueStack<RawWasmValue>,
17+
pub(crate) large_values: LargeValueStack,
18+
1319
pub(crate) blocks: BlockStack,
1420
pub(crate) call_stack: CallStack,
1521
}
1622

1723
impl Stack {
1824
pub(crate) fn new(call_frame: CallFrame) -> Self {
19-
Self { values: ValueStack::default(), blocks: BlockStack::new(), call_stack: CallStack::new(call_frame) }
25+
Self {
26+
values: ValueStack::default(),
27+
blocks: BlockStack::new(),
28+
call_stack: CallStack::new(call_frame),
29+
large_values: LargeValueStack::default(),
30+
}
2031
}
2132
}

crates/tinywasm/src/runtime/stack/block_stack.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ impl BlockStack {
5454
pub(crate) struct BlockFrame {
5555
pub(crate) instr_ptr: usize, // position of the instruction pointer when the block was entered
5656
pub(crate) end_instr_offset: u32, // position of the end instruction of the block
57-
pub(crate) stack_ptr: u32, // position of the stack pointer when the block was entered
57+
58+
pub(crate) stack_ptr: u32, // position of the stack pointer when the block was entered
59+
pub(crate) large_stack_ptr: u32, // position of the large stack pointer when the block was entered
5860

5961
pub(crate) results: u8,
6062
pub(crate) params: u8,

crates/tinywasm/src/runtime/stack/call_stack.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ impl CallFrame {
7272
pub(crate) fn break_to(
7373
&mut self,
7474
break_to_relative: u32,
75-
values: &mut super::ValueStack,
75+
values: &mut super::ValueStack<RawWasmValue>,
7676
blocks: &mut super::BlockStack,
7777
) -> Option<()> {
7878
let break_to = blocks.get_relative_to(break_to_relative, self.block_ptr)?;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
use alloc::vec::Vec;
2+
3+
use crate::runtime::LargeRawWasmValue;
4+
5+
#[derive(Debug)]
6+
pub(crate) struct LargeValueStack(Vec<LargeRawWasmValue>);
7+
8+
impl Default for LargeValueStack {
9+
fn default() -> Self {
10+
Self(Vec::new())
11+
}
12+
}

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

Lines changed: 33 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,41 @@
1-
use crate::{cold, runtime::RawWasmValue, unlikely, Error, Result};
1+
use crate::{cold, runtime::WasmValueRepr, unlikely, Error, Result};
22
use alloc::vec::Vec;
33
use tinywasm_types::{ValType, WasmValue};
44

55
pub(crate) const MIN_VALUE_STACK_SIZE: usize = 1024 * 128;
66

77
#[derive(Debug)]
8-
pub(crate) struct ValueStack {
9-
stack: Vec<RawWasmValue>,
10-
}
8+
pub(crate) struct ValueStack<T>(Vec<T>);
119

12-
impl Default for ValueStack {
10+
impl<T> Default for ValueStack<T> {
1311
fn default() -> Self {
14-
Self { stack: Vec::with_capacity(MIN_VALUE_STACK_SIZE) }
12+
Self(Vec::with_capacity(MIN_VALUE_STACK_SIZE))
1513
}
1614
}
1715

18-
impl ValueStack {
16+
impl<T: From<WasmValue> + Copy + WasmValueRepr> ValueStack<T> {
1917
#[inline]
2018
pub(crate) fn extend_from_typed(&mut self, values: &[WasmValue]) {
21-
self.stack.extend(values.iter().map(|v| RawWasmValue::from(*v)));
19+
self.0.extend(values.iter().map(|v| T::from(*v)));
2220
}
2321

2422
#[inline(always)]
25-
pub(crate) fn replace_top(&mut self, func: fn(RawWasmValue) -> RawWasmValue) -> Result<()> {
23+
pub(crate) fn replace_top(&mut self, func: fn(T) -> T) -> Result<()> {
2624
let v = self.last_mut()?;
2725
*v = func(*v);
2826
Ok(())
2927
}
3028

3129
#[inline(always)]
32-
pub(crate) fn calculate(&mut self, func: fn(RawWasmValue, RawWasmValue) -> RawWasmValue) -> Result<()> {
30+
pub(crate) fn calculate(&mut self, func: fn(T, T) -> T) -> Result<()> {
3331
let v2 = self.pop()?;
3432
let v1 = self.last_mut()?;
3533
*v1 = func(*v1, v2);
3634
Ok(())
3735
}
3836

3937
#[inline(always)]
40-
pub(crate) fn calculate_trap(
41-
&mut self,
42-
func: fn(RawWasmValue, RawWasmValue) -> Result<RawWasmValue>,
43-
) -> Result<()> {
38+
pub(crate) fn calculate_trap(&mut self, func: fn(T, T) -> Result<T>) -> Result<()> {
4439
let v2 = self.pop()?;
4540
let v1 = self.last_mut()?;
4641
*v1 = func(*v1, v2)?;
@@ -49,13 +44,13 @@ impl ValueStack {
4944

5045
#[inline(always)]
5146
pub(crate) fn len(&self) -> usize {
52-
self.stack.len()
47+
self.0.len()
5348
}
5449

5550
#[inline]
5651
pub(crate) fn truncate_keep(&mut self, n: u32, end_keep: u32) {
5752
let total_to_keep = n + end_keep;
58-
let len = self.stack.len() as u32;
53+
let len = self.0.len() as u32;
5954
assert!(len >= total_to_keep, "Total to keep should be less than or equal to self.top");
6055

6156
if len <= total_to_keep {
@@ -65,22 +60,22 @@ impl ValueStack {
6560
let items_to_remove = len - total_to_keep;
6661
let remove_start_index = (len - items_to_remove - end_keep) as usize;
6762
let remove_end_index = (len - end_keep) as usize;
68-
self.stack.drain(remove_start_index..remove_end_index);
63+
self.0.drain(remove_start_index..remove_end_index);
6964
}
7065

7166
#[inline(always)]
72-
pub(crate) fn push(&mut self, value: RawWasmValue) {
73-
self.stack.push(value);
67+
pub(crate) fn push(&mut self, value: T) {
68+
self.0.push(value);
7469
}
7570

7671
#[inline(always)]
77-
pub(crate) fn extend_from_slice(&mut self, values: &[RawWasmValue]) {
78-
self.stack.extend_from_slice(values);
72+
pub(crate) fn extend_from_slice(&mut self, values: &[T]) {
73+
self.0.extend_from_slice(values);
7974
}
8075

8176
#[inline]
82-
pub(crate) fn last_mut(&mut self) -> Result<&mut RawWasmValue> {
83-
match self.stack.last_mut() {
77+
pub(crate) fn last_mut(&mut self) -> Result<&mut T> {
78+
match self.0.last_mut() {
8479
Some(v) => Ok(v),
8580
None => {
8681
cold();
@@ -90,8 +85,8 @@ impl ValueStack {
9085
}
9186

9287
#[inline]
93-
pub(crate) fn last(&self) -> Result<&RawWasmValue> {
94-
match self.stack.last() {
88+
pub(crate) fn last(&self) -> Result<&T> {
89+
match self.0.last() {
9590
Some(v) => Ok(v),
9691
None => {
9792
cold();
@@ -101,8 +96,8 @@ impl ValueStack {
10196
}
10297

10398
#[inline(always)]
104-
pub(crate) fn pop(&mut self) -> Result<RawWasmValue> {
105-
match self.stack.pop() {
99+
pub(crate) fn pop(&mut self) -> Result<T> {
100+
match self.0.pop() {
106101
Some(v) => Ok(v),
107102
None => {
108103
cold();
@@ -119,35 +114,36 @@ impl ValueStack {
119114
#[inline]
120115
pub(crate) fn break_to(&mut self, new_stack_size: u32, result_count: u8) {
121116
let start = new_stack_size as usize;
122-
let end = self.stack.len() - result_count as usize;
123-
self.stack.drain(start..end);
117+
let end = self.0.len() - result_count as usize;
118+
self.0.drain(start..end);
124119
}
125120

126121
#[inline]
127-
pub(crate) fn last_n(&self, n: usize) -> Result<&[RawWasmValue]> {
128-
let len = self.stack.len();
122+
pub(crate) fn last_n(&self, n: usize) -> Result<&[T]> {
123+
let len = self.0.len();
129124
if unlikely(len < n) {
130125
return Err(Error::ValueStackUnderflow);
131126
}
132-
Ok(&self.stack[len - n..len])
127+
Ok(&self.0[len - n..len])
133128
}
134129

135130
#[inline]
136-
pub(crate) fn pop_n_rev(&mut self, n: usize) -> Result<alloc::vec::Drain<'_, RawWasmValue>> {
137-
if unlikely(self.stack.len() < n) {
131+
pub(crate) fn pop_n_rev(&mut self, n: usize) -> Result<alloc::vec::Drain<'_, T>> {
132+
if unlikely(self.0.len() < n) {
138133
return Err(Error::ValueStackUnderflow);
139134
}
140-
Ok(self.stack.drain((self.stack.len() - n)..))
135+
Ok(self.0.drain((self.0.len() - n)..))
141136
}
142137
}
143138

144139
#[cfg(test)]
145140
mod tests {
146141
use super::*;
142+
use crate::runtime::RawWasmValue;
147143

148144
#[test]
149145
fn test_value_stack() {
150-
let mut stack = ValueStack::default();
146+
let mut stack: ValueStack<RawWasmValue> = ValueStack::default();
151147
stack.push(1.into());
152148
stack.push(2.into());
153149
stack.push(3.into());
@@ -165,7 +161,7 @@ mod tests {
165161
macro_rules! test_macro {
166162
($( $n:expr, $end_keep:expr, $expected:expr ),*) => {
167163
$(
168-
let mut stack = ValueStack::default();
164+
let mut stack: ValueStack<RawWasmValue> = ValueStack::default();
169165
stack.push(1.into());
170166
stack.push(2.into());
171167
stack.push(3.into());

crates/tinywasm/src/runtime/value.rs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,33 @@ use tinywasm_types::{ValType, WasmValue};
99
#[derive(Clone, Copy, Default, PartialEq, Eq)]
1010
pub struct RawWasmValue([u8; 8]);
1111

12+
/// A large raw wasm value, used for 128-bit values.
13+
///
14+
/// This is the internal representation of vector values.
15+
///
16+
/// See [`WasmValue`] for the public representation.
17+
#[derive(Clone, Copy, Default, PartialEq, Eq)]
18+
pub struct LargeRawWasmValue([u8; 16]);
19+
1220
impl Debug for RawWasmValue {
1321
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1422
write!(f, "RawWasmValue({})", 0)
1523
}
1624
}
1725

18-
impl RawWasmValue {
19-
#[inline(always)]
20-
pub fn raw_value(&self) -> [u8; 8] {
21-
self.0
26+
impl Debug for LargeRawWasmValue {
27+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
28+
write!(f, "LargeRawWasmValue({})", 0)
2229
}
30+
}
31+
32+
pub trait WasmValueRepr {
33+
fn attach_type(self, ty: ValType) -> WasmValue;
34+
}
2335

36+
impl WasmValueRepr for RawWasmValue {
2437
#[inline]
25-
pub fn attach_type(self, ty: ValType) -> WasmValue {
38+
fn attach_type(self, ty: ValType) -> WasmValue {
2639
match ty {
2740
ValType::I32 => WasmValue::I32(self.into()),
2841
ValType::I64 => WasmValue::I64(self.into()),
@@ -40,6 +53,13 @@ impl RawWasmValue {
4053
}
4154
}
4255

56+
impl RawWasmValue {
57+
#[inline(always)]
58+
pub fn raw_value(&self) -> [u8; 8] {
59+
self.0
60+
}
61+
}
62+
4363
impl From<WasmValue> for RawWasmValue {
4464
#[inline]
4565
fn from(v: WasmValue) -> Self {

crates/tinywasm/src/store/global.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ use core::cell::Cell;
33
use alloc::{format, string::ToString};
44
use tinywasm_types::*;
55

6-
use crate::{runtime::RawWasmValue, unlikely, Error, Result};
6+
use crate::{
7+
runtime::{RawWasmValue, WasmValueRepr},
8+
unlikely, Error, Result,
9+
};
710

811
/// A WebAssembly Global Instance
912
///

0 commit comments

Comments
 (0)