summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenry Gressmann <mail@henrygressmann.de>2024-05-12 20:20:21 +0200
committerHenry Gressmann <mail@henrygressmann.de>2024-05-12 20:20:21 +0200
commite771c6df456f6c6655a7850defffdbb5cc574461 (patch)
tree1fbb5ab216ac99d70cc6ddfd3ac53b9d3aab8d5f
parentb2b39468325b9ed7043fed48a15a77b83b13d63e (diff)
chore: clippy fixes and more tests
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
-rw-r--r--crates/parser/src/conversion.rs2
-rw-r--r--crates/parser/src/visit.rs3
-rw-r--r--crates/tinywasm/src/lib.rs1
-rw-r--r--crates/tinywasm/src/runtime/interpreter/mod.rs27
-rw-r--r--crates/tinywasm/src/runtime/stack/call_stack.rs2
-rw-r--r--crates/tinywasm/src/runtime/stack/value_stack.rs44
-rw-r--r--crates/tinywasm/src/runtime/value.rs28
7 files changed, 75 insertions, 32 deletions
diff --git a/crates/parser/src/conversion.rs b/crates/parser/src/conversion.rs
index 4e4434b..31056a3 100644
--- a/crates/parser/src/conversion.rs
+++ b/crates/parser/src/conversion.rs
@@ -137,7 +137,7 @@ pub(crate) fn convert_module_table(table: wasmparser::Table<'_>) -> Result<Table
None => None,
};
- Ok(TableType { element_type: convert_reftype(&table.ty.element_type), size_initial: size_initial, size_max })
+ Ok(TableType { element_type: convert_reftype(&table.ty.element_type), size_initial, size_max })
}
pub(crate) fn convert_module_globals<'a, T: IntoIterator<Item = wasmparser::Result<wasmparser::Global<'a>>>>(
diff --git a/crates/parser/src/visit.rs b/crates/parser/src/visit.rs
index 8b9e15d..df6fc7a 100644
--- a/crates/parser/src/visit.rs
+++ b/crates/parser/src/visit.rs
@@ -110,7 +110,8 @@ impl FunctionBuilder {
#[inline]
fn visit(&mut self, op: Instruction) -> Result<()> {
- Ok(self.instructions.push(op))
+ self.instructions.push(op);
+ Ok(())
}
}
diff --git a/crates/tinywasm/src/lib.rs b/crates/tinywasm/src/lib.rs
index 4a644fd..0bc17d6 100644
--- a/crates/tinywasm/src/lib.rs
+++ b/crates/tinywasm/src/lib.rs
@@ -3,6 +3,7 @@
no_crate_inject,
attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_assignments, unused_variables))
))]
+#![allow(unexpected_cfgs, clippy::reserve_after_initialization)]
#![warn(missing_docs, missing_debug_implementations, rust_2018_idioms, unreachable_pub)]
#![cfg_attr(nightly, feature(error_in_core))]
#![cfg_attr(not(feature = "unsafe"), deny(unsafe_code))]
diff --git a/crates/tinywasm/src/runtime/interpreter/mod.rs b/crates/tinywasm/src/runtime/interpreter/mod.rs
index 5e1500f..404e4fe 100644
--- a/crates/tinywasm/src/runtime/interpreter/mod.rs
+++ b/crates/tinywasm/src/runtime/interpreter/mod.rs
@@ -138,7 +138,7 @@ fn exec_one(cf: &mut CallFrame, stack: &mut Stack, store: &mut Store, module: &M
CallIndirect(type_addr, table_addr) => {
let table = store.get_table(module.resolve_table_addr(*table_addr))?;
- let table_idx = stack.values.pop_t::<u32>()?;
+ let table_idx: u32 = stack.values.pop()?.into();
// verify that the table is of the right type, this should be validated by the parser already
let func_ref = {
@@ -188,7 +188,7 @@ fn exec_one(cf: &mut CallFrame, stack: &mut Stack, store: &mut Store, module: &M
If(args, else_offset, end_offset) => {
// truthy value is on the top of the stack, so enter the then block
- if stack.values.pop_t::<i32>()? != 0 {
+ if i32::from(stack.values.pop()?) != 0 {
cf.enter_block(
BlockFrame::new(
cf.instr_ptr,
@@ -259,8 +259,8 @@ fn exec_one(cf: &mut CallFrame, stack: &mut Stack, store: &mut Store, module: &M
return Err(Error::Other(format!("br_table out of bounds: {} >= {}", end, cf.instructions().len())));
}
- let idx = stack.values.pop_t::<i32>()? as usize;
- match cf.instructions()[start..end].get(idx) {
+ let idx: i32 = stack.values.pop()?.into();
+ match cf.instructions()[start..end].get(idx as usize) {
None => break_to!(cf, stack, default),
Some(BrLabel(to)) => break_to!(cf, stack, to),
_ => return Err(Error::Other("br_table with invalid label".to_string())),
@@ -269,7 +269,7 @@ fn exec_one(cf: &mut CallFrame, stack: &mut Stack, store: &mut Store, module: &M
Br(v) => break_to!(cf, stack, v),
BrIf(v) => {
- if stack.values.pop_t::<i32>()? != 0 {
+ if i32::from(stack.values.pop()?) != 0 {
break_to!(cf, stack, v);
}
}
@@ -329,8 +329,9 @@ fn exec_one(cf: &mut CallFrame, stack: &mut Stack, store: &mut Store, module: &M
let mem = store.get_mem(module.resolve_mem_addr(*addr))?;
let mut mem = mem.borrow_mut();
let prev_size = mem.page_count() as i32;
+ let pages_delta: i32 = stack.values.pop()?.into();
- match mem.grow(stack.values.pop_t::<i32>()?) {
+ match mem.grow(pages_delta) {
Some(_) => stack.values.push(prev_size.into()),
None => stack.values.push((-1).into()),
}
@@ -366,9 +367,9 @@ fn exec_one(cf: &mut CallFrame, stack: &mut Stack, store: &mut Store, module: &M
}
MemoryInit(data_index, mem_index) => {
- let size = stack.values.pop_t::<i32>()? as usize;
- let offset = stack.values.pop_t::<i32>()? as usize;
- let dst = stack.values.pop_t::<i32>()? as usize;
+ let size = i32::from(stack.values.pop()?) as usize;
+ let offset = i32::from(stack.values.pop()?) as usize;
+ let dst = i32::from(stack.values.pop()?) as usize;
let data = match &store.get_data(module.resolve_data_addr(*data_index))?.data {
Some(data) => data,
@@ -561,7 +562,7 @@ fn exec_one(cf: &mut CallFrame, stack: &mut Stack, store: &mut Store, module: &M
TableGet(table_index) => {
let table_idx = module.resolve_table_addr(*table_index);
let table = store.get_table(table_idx)?;
- let idx = stack.values.pop_t::<u32>()?;
+ let idx: u32 = stack.values.pop()?.into();
let v = table.borrow().get_wasm_val(idx)?;
stack.values.push(v.into());
}
@@ -569,8 +570,8 @@ fn exec_one(cf: &mut CallFrame, stack: &mut Stack, store: &mut Store, module: &M
TableSet(table_index) => {
let table_idx = module.resolve_table_addr(*table_index);
let table = store.get_table(table_idx)?;
- let val = stack.values.pop_t::<u32>()?;
- let idx = stack.values.pop_t::<u32>()?;
+ let val = stack.values.pop()?.into();
+ let idx = stack.values.pop()?.into();
table.borrow_mut().set(idx, val)?;
}
@@ -632,7 +633,7 @@ fn exec_one(cf: &mut CallFrame, stack: &mut Stack, store: &mut Store, module: &M
stack.values.push((local + *val).into());
}
I32StoreLocal { local, const_i32: consti32, offset, mem_addr } => {
- let (mem_addr, offset) = (*mem_addr as u32, *offset as u32);
+ let (mem_addr, offset) = (*mem_addr as u32, *offset);
let mem = store.get_mem(module.resolve_mem_addr(mem_addr))?;
let val = consti32.to_le_bytes();
let addr: u64 = cf.get_local(*local).into();
diff --git a/crates/tinywasm/src/runtime/stack/call_stack.rs b/crates/tinywasm/src/runtime/stack/call_stack.rs
index 060d530..8002385 100644
--- a/crates/tinywasm/src/runtime/stack/call_stack.rs
+++ b/crates/tinywasm/src/runtime/stack/call_stack.rs
@@ -20,7 +20,7 @@ impl CallStack {
let mut stack = Vec::new();
stack.reserve_exact(CALL_STACK_SIZE);
- let mut stack = Self { stack: stack };
+ let mut stack = Self { stack };
stack.push(initial_frame).unwrap();
stack
}
diff --git a/crates/tinywasm/src/runtime/stack/value_stack.rs b/crates/tinywasm/src/runtime/stack/value_stack.rs
index 354898e..8a3f3fa 100644
--- a/crates/tinywasm/src/runtime/stack/value_stack.rs
+++ b/crates/tinywasm/src/runtime/stack/value_stack.rs
@@ -82,17 +82,6 @@ impl ValueStack {
}
#[inline]
- pub(crate) fn pop_t<T: From<RawWasmValue>>(&mut self) -> Result<T> {
- match self.stack.pop() {
- Some(v) => Ok(v.into()),
- None => {
- cold(); // 20+ performance improvement most of the time
- Err(Error::ValueStackUnderflow)
- }
- }
- }
-
- #[inline]
pub(crate) fn pop(&mut self) -> Result<RawWasmValue> {
match self.stack.pop() {
Some(v) => Ok(v),
@@ -144,11 +133,38 @@ mod tests {
stack.push(2.into());
stack.push(3.into());
assert_eq!(stack.len(), 3);
- assert_eq!(stack.pop_t::<i32>().unwrap(), 3);
+ assert_eq!(i32::from(stack.pop().unwrap()), 3);
assert_eq!(stack.len(), 2);
- assert_eq!(stack.pop_t::<i32>().unwrap(), 2);
+ assert_eq!(i32::from(stack.pop().unwrap()), 2);
assert_eq!(stack.len(), 1);
- assert_eq!(stack.pop_t::<i32>().unwrap(), 1);
+ assert_eq!(i32::from(stack.pop().unwrap()), 1);
assert_eq!(stack.len(), 0);
}
+
+ #[test]
+ fn test_truncate_keep() {
+ macro_rules! test_macro {
+ ($( $n:expr, $end_keep:expr, $expected:expr ),*) => {
+ $(
+ let mut stack = ValueStack::default();
+ stack.push(1.into());
+ stack.push(2.into());
+ stack.push(3.into());
+ stack.push(4.into());
+ stack.push(5.into());
+ stack.truncate_keep($n, $end_keep);
+ assert_eq!(stack.len(), $expected);
+ )*
+ };
+ }
+
+ test_macro! {
+ 0, 0, 0,
+ 1, 0, 1,
+ 0, 1, 1,
+ 1, 1, 2,
+ 2, 1, 3,
+ 2, 2, 4
+ }
+ }
}
diff --git a/crates/tinywasm/src/runtime/value.rs b/crates/tinywasm/src/runtime/value.rs
index 55aa9fe..2865308 100644
--- a/crates/tinywasm/src/runtime/value.rs
+++ b/crates/tinywasm/src/runtime/value.rs
@@ -83,12 +83,36 @@ impl_from_raw_wasm_value!(i64, |x| x as u64, |x: [u8; 8]| i64::from_ne_bytes(x[0
impl_from_raw_wasm_value!(u8, |x| x as u64, |x: [u8; 8]| u8::from_ne_bytes(x[0..1].try_into().unwrap()));
impl_from_raw_wasm_value!(u16, |x| x as u64, |x: [u8; 8]| u16::from_ne_bytes(x[0..2].try_into().unwrap()));
impl_from_raw_wasm_value!(u32, |x| x as u64, |x: [u8; 8]| u32::from_ne_bytes(x[0..4].try_into().unwrap()));
-impl_from_raw_wasm_value!(u64, |x| x as u64, |x: [u8; 8]| u64::from_ne_bytes(x[0..8].try_into().unwrap()));
+impl_from_raw_wasm_value!(u64, |x| x, |x: [u8; 8]| u64::from_ne_bytes(x[0..8].try_into().unwrap()));
impl_from_raw_wasm_value!(i8, |x| x as u64, |x: [u8; 8]| i8::from_ne_bytes(x[0..1].try_into().unwrap()));
impl_from_raw_wasm_value!(i16, |x| x as u64, |x: [u8; 8]| i16::from_ne_bytes(x[0..2].try_into().unwrap()));
impl_from_raw_wasm_value!(f32, |x| f32::to_bits(x) as u64, |x: [u8; 8]| f32::from_bits(u32::from_ne_bytes(
x[0..4].try_into().unwrap()
)));
-impl_from_raw_wasm_value!(f64, |x| f64::to_bits(x) as u64, |x: [u8; 8]| f64::from_bits(u64::from_ne_bytes(
+impl_from_raw_wasm_value!(f64, f64::to_bits, |x: [u8; 8]| f64::from_bits(u64::from_ne_bytes(
x[0..8].try_into().unwrap()
)));
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_raw_wasm_value() {
+ macro_rules! test_macro {
+ ($( $ty:ty => $val:expr ),*) => {
+ $(
+ let raw: RawWasmValue = $val.into();
+ let val: $ty = raw.into();
+ assert_eq!(val, $val);
+ )*
+ };
+ }
+
+ test_macro! {
+ i32 => 0, i64 => 0, u8 => 0, u16 => 0, u32 => 0, u64 => 0, i8 => 0, i16 => 0, f32 => 0.0, f64 => 0.0,
+ i32 => i32::MIN, i64 => i64::MIN, u8 => u8::MIN, u16 => u16::MIN, u32 => u32::MIN, u64 => u64::MIN, i8 => i8::MIN, i16 => i16::MIN, f32 => f32::MIN, f64 => f64::MIN,
+ i32 => i32::MAX, i64 => i64::MAX, u8 => u8::MAX, u16 => u16::MAX, u32 => u32::MAX, u64 => u64::MAX, i8 => i8::MAX, i16 => i16::MAX, f32 => f32::MAX, f64 => f64::MAX
+ }
+ }
+}