diff options
| author | Henry Gressmann <mail@henrygressmann.de> | 2024-08-12 16:12:07 +0200 |
|---|---|---|
| committer | Henry Gressmann <mail@henrygressmann.de> | 2024-08-12 16:12:07 +0200 |
| commit | 06f81026eca6446d737e3759951ca15001a819c5 (patch) | |
| tree | e06d747eb225cac6e24557faa2694895d52741ae /crates | |
| parent | d33a0c66a17316755e572b3620fb030ec1e52f61 (diff) | |
chore: clean up code
Signed-off-by: Henry Gressmann <mail@henrygressmann.de>
Diffstat (limited to 'crates')
35 files changed, 322 insertions, 332 deletions
diff --git a/crates/cli/src/args.rs b/crates/cli/src/args.rs index 3959572..96c3605 100644 --- a/crates/cli/src/args.rs +++ b/crates/cli/src/args.rs @@ -5,7 +5,7 @@ use tinywasm::types::WasmValue; pub struct WasmArg(WasmValue); pub fn to_wasm_args(args: Vec<WasmArg>) -> Vec<WasmValue> { - args.into_iter().map(|a| a.into()).collect() + args.into_iter().map(Into::into).collect() } impl From<WasmArg> for WasmValue { @@ -18,14 +18,14 @@ impl FromStr for WasmArg { type Err = String; fn from_str(s: &str) -> std::prelude::v1::Result<Self, Self::Err> { let [ty, val]: [&str; 2] = - s.split(':').collect::<Vec<_>>().try_into().map_err(|e| format!("invalid arguments: {:?}", e))?; + s.split(':').collect::<Vec<_>>().try_into().map_err(|e| format!("invalid arguments: {e:?}"))?; let arg: WasmValue = match ty { "i32" => val.parse::<i32>().map_err(|e| format!("invalid argument value for i32: {e:?}"))?.into(), "i64" => val.parse::<i64>().map_err(|e| format!("invalid argument value for i64: {e:?}"))?.into(), "f32" => val.parse::<f32>().map_err(|e| format!("invalid argument value for f32: {e:?}"))?.into(), "f64" => val.parse::<f64>().map_err(|e| format!("invalid argument value for f64: {e:?}"))?.into(), - t => return Err(format!("Invalid arg type: {}", t)), + t => return Err(format!("Invalid arg type: {t}")), }; Ok(WasmArg(arg)) diff --git a/crates/cli/src/bin.rs b/crates/cli/src/bin.rs index 15e3fdc..6efbba1 100644 --- a/crates/cli/src/bin.rs +++ b/crates/cli/src/bin.rs @@ -14,7 +14,7 @@ mod util; mod wat; #[derive(FromArgs)] -/// TinyWasm CLI +/// `TinyWasm` CLI struct TinyWasmCli { #[argh(subcommand)] nested: TinyWasmSubcommand, @@ -40,7 +40,7 @@ impl FromStr for Engine { fn from_str(s: &str) -> Result<Self, Self::Err> { match s { "main" => Ok(Self::Main), - _ => Err(format!("unknown engine: {}", s)), + _ => Err(format!("unknown engine: {s}")), } } } @@ -98,19 +98,19 @@ fn main() -> Result<()> { }; match engine { - Engine::Main => run(module, func, to_wasm_args(args)), + Engine::Main => run(module, func, &to_wasm_args(args)), } } } } -fn run(module: Module, func: Option<String>, args: Vec<WasmValue>) -> Result<()> { +fn run(module: Module, func: Option<String>, args: &[WasmValue]) -> Result<()> { let mut store = tinywasm::Store::default(); let instance = module.instantiate(&mut store, None)?; if let Some(func) = func { let func = instance.exported_func_untyped(&store, &func)?; - let res = func.call(&mut store, &args)?; + let res = func.call(&mut store, args)?; info!("{res:?}"); } diff --git a/crates/parser/src/conversion.rs b/crates/parser/src/conversion.rs index c733dcc..10607a1 100644 --- a/crates/parser/src/conversion.rs +++ b/crates/parser/src/conversion.rs @@ -38,7 +38,7 @@ pub(crate) fn convert_module_element(element: wasmparser::Element<'_>) -> Result .collect::<Result<Vec<_>>>()? .into_boxed_slice(); - Ok(tinywasm_types::Element { kind, items, ty: convert_reftype(&ty), range: element.range }) + Ok(tinywasm_types::Element { kind, items, ty: convert_reftype(ty), range: element.range }) } } } @@ -76,23 +76,23 @@ pub(crate) fn convert_module_import(import: wasmparser::Import<'_>) -> Result<Im kind: match import.ty { wasmparser::TypeRef::Func(ty) => ImportKind::Function(ty), wasmparser::TypeRef::Table(ty) => ImportKind::Table(TableType { - element_type: convert_reftype(&ty.element_type), + element_type: convert_reftype(ty.element_type), size_initial: ty.initial.try_into().map_err(|_| { crate::ParseError::UnsupportedOperator(format!("Table size initial is too large: {}", ty.initial)) })?, size_max: match ty.maximum { Some(max) => Some(max.try_into().map_err(|_| { - crate::ParseError::UnsupportedOperator(format!("Table size max is too large: {}", max)) + crate::ParseError::UnsupportedOperator(format!("Table size max is too large: {max}")) })?), None => None, }, }), - wasmparser::TypeRef::Memory(ty) => ImportKind::Memory(convert_module_memory(ty)?), + wasmparser::TypeRef::Memory(ty) => ImportKind::Memory(convert_module_memory(ty)), wasmparser::TypeRef::Global(ty) => { ImportKind::Global(GlobalType { mutable: ty.mutable, ty: convert_valtype(&ty.content_type) }) } wasmparser::TypeRef::Tag(ty) => { - return Err(crate::ParseError::UnsupportedOperator(format!("Unsupported import kind: {:?}", ty))) + return Err(crate::ParseError::UnsupportedOperator(format!("Unsupported import kind: {ty:?}"))) } }, }) @@ -101,18 +101,15 @@ pub(crate) fn convert_module_import(import: wasmparser::Import<'_>) -> Result<Im pub(crate) fn convert_module_memories<T: IntoIterator<Item = wasmparser::Result<wasmparser::MemoryType>>>( memory_types: T, ) -> Result<Vec<MemoryType>> { - memory_types.into_iter().map(|memory| convert_module_memory(memory?)).collect::<Result<Vec<_>>>() + memory_types.into_iter().map(|memory| Ok(convert_module_memory(memory?))).collect::<Result<Vec<_>>>() } -pub(crate) fn convert_module_memory(memory: wasmparser::MemoryType) -> Result<MemoryType> { - Ok(MemoryType { - arch: match memory.memory64 { - true => MemoryArch::I64, - false => MemoryArch::I32, - }, +pub(crate) fn convert_module_memory(memory: wasmparser::MemoryType) -> MemoryType { + MemoryType { + arch: if memory.memory64 { MemoryArch::I64 } else { MemoryArch::I32 }, page_count_initial: memory.initial, page_count_max: memory.maximum, - }) + } } pub(crate) fn convert_module_tables<'a, T: IntoIterator<Item = wasmparser::Result<wasmparser::Table<'a>>>>( @@ -129,12 +126,12 @@ pub(crate) fn convert_module_table(table: wasmparser::Table<'_>) -> Result<Table let size_max = match table.ty.maximum { Some(max) => Some( max.try_into() - .map_err(|_| crate::ParseError::UnsupportedOperator(format!("Table size max is too large: {}", max)))?, + .map_err(|_| crate::ParseError::UnsupportedOperator(format!("Table size max is too large: {max}")))?, ), None => None, }; - Ok(TableType { element_type: convert_reftype(&table.ty.element_type), size_initial, size_max }) + Ok(TableType { element_type: convert_reftype(table.ty.element_type), size_initial, size_max }) } pub(crate) fn convert_module_globals( @@ -185,11 +182,11 @@ pub(crate) fn convert_module_code( for i in 0..validator.len_locals() { match validator.get_local_type(i) { - Some(wasmparser::ValType::I32) | Some(wasmparser::ValType::F32) => { + Some(wasmparser::ValType::I32 | wasmparser::ValType::F32) => { local_addr_map.push(local_counts.c32); local_counts.c32 += 1; } - Some(wasmparser::ValType::I64) | Some(wasmparser::ValType::F64) => { + Some(wasmparser::ValType::I64 | wasmparser::ValType::F64) => { local_addr_map.push(local_counts.c64); local_counts.c64 += 1; } @@ -225,7 +222,7 @@ pub(crate) fn convert_module_type(ty: wasmparser::RecGroup) -> Result<FuncType> Ok(FuncType { params, results }) } -pub(crate) fn convert_reftype(reftype: &wasmparser::RefType) -> ValType { +pub(crate) fn convert_reftype(reftype: wasmparser::RefType) -> ValType { match reftype { _ if reftype.is_func_ref() => ValType::RefFunc, _ if reftype.is_extern_ref() => ValType::RefExtern, @@ -240,7 +237,7 @@ pub(crate) fn convert_valtype(valtype: &wasmparser::ValType) -> ValType { wasmparser::ValType::F32 => ValType::F32, wasmparser::ValType::F64 => ValType::F64, wasmparser::ValType::V128 => ValType::V128, - wasmparser::ValType::Ref(r) => convert_reftype(r), + wasmparser::ValType::Ref(r) => convert_reftype(*r), } } @@ -260,7 +257,7 @@ pub(crate) fn process_const_operators(ops: OperatorsReader<'_>) -> Result<ConstI wasmparser::Operator::F32Const { value } => Ok(ConstInstruction::F32Const(f32::from_bits(value.bits()))), wasmparser::Operator::F64Const { value } => Ok(ConstInstruction::F64Const(f64::from_bits(value.bits()))), wasmparser::Operator::GlobalGet { global_index } => Ok(ConstInstruction::GlobalGet(*global_index)), - op => Err(crate::ParseError::UnsupportedOperator(format!("Unsupported const instruction: {:?}", op))), + op => Err(crate::ParseError::UnsupportedOperator(format!("Unsupported const instruction: {op:?}"))), } } diff --git a/crates/parser/src/error.rs b/crates/parser/src/error.rs index c32e026..7bd484f 100644 --- a/crates/parser/src/error.rs +++ b/crates/parser/src/error.rs @@ -42,19 +42,19 @@ impl Display for ParseError { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { Self::InvalidType => write!(f, "invalid type"), - Self::UnsupportedSection(section) => write!(f, "unsupported section: {}", section), - Self::DuplicateSection(section) => write!(f, "duplicate section: {}", section), - Self::EmptySection(section) => write!(f, "empty section: {}", section), - Self::UnsupportedOperator(operator) => write!(f, "unsupported operator: {}", operator), + Self::UnsupportedSection(section) => write!(f, "unsupported section: {section}"), + Self::DuplicateSection(section) => write!(f, "duplicate section: {section}"), + Self::EmptySection(section) => write!(f, "empty section: {section}"), + Self::UnsupportedOperator(operator) => write!(f, "unsupported operator: {operator}"), Self::ParseError { message, offset } => { - write!(f, "error parsing module: {} at offset {}", message, offset) + write!(f, "error parsing module: {message} at offset {offset}") } - Self::InvalidEncoding(encoding) => write!(f, "invalid encoding: {:?}", encoding), + Self::InvalidEncoding(encoding) => write!(f, "invalid encoding: {encoding:?}"), Self::InvalidLocalCount { expected, actual } => { - write!(f, "invalid local count: expected {}, actual {}", expected, actual) + write!(f, "invalid local count: expected {expected}, actual {actual}") } Self::EndNotReached => write!(f, "end of module not reached"), - Self::Other(message) => write!(f, "unknown error: {}", message), + Self::Other(message) => write!(f, "unknown error: {message}"), } } } diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs index a517c52..c931b9e 100644 --- a/crates/parser/src/lib.rs +++ b/crates/parser/src/lib.rs @@ -49,7 +49,7 @@ impl Parser { Self {} } - fn create_validator(&self) -> Validator { + fn create_validator() -> Validator { let features = WasmFeaturesInflated { bulk_memory: true, floats: true, @@ -85,7 +85,7 @@ impl Parser { /// Parse a [`TinyWasmModule`] from bytes pub fn parse_module_bytes(&self, wasm: impl AsRef<[u8]>) -> Result<TinyWasmModule> { let wasm = wasm.as_ref(); - let mut validator = self.create_validator(); + let mut validator = Self::create_validator(); let mut reader = ModuleReader::new(); for payload in wasmparser::Parser::new(0).parse_all(wasm) { @@ -115,7 +115,7 @@ impl Parser { pub fn parse_module_stream(&self, mut stream: impl std::io::Read) -> Result<TinyWasmModule> { use alloc::format; - let mut validator = self.create_validator(); + let mut validator = Self::create_validator(); let mut reader = ModuleReader::new(); let mut buffer = alloc::vec::Vec::new(); let mut parser = wasmparser::Parser::new(0); @@ -128,7 +128,7 @@ impl Parser { buffer.extend((0..hint).map(|_| 0u8)); let read_bytes = stream .read(&mut buffer[len..]) - .map_err(|e| ParseError::Other(format!("Error reading from stream: {}", e)))?; + .map_err(|e| ParseError::Other(format!("Error reading from stream: {e}")))?; buffer.truncate(len + read_bytes); eof = read_bytes == 0; } diff --git a/crates/parser/src/module.rs b/crates/parser/src/module.rs index 74da1d9..20ed00d 100644 --- a/crates/parser/src/module.rs +++ b/crates/parser/src/module.rs @@ -168,12 +168,12 @@ impl ModuleReader { validator.end(offset)?; self.end_reached = true; } - CustomSection(_reader) => { + CustomSection(reader) => { debug!("Found custom section"); - debug!("Skipping custom section: {:?}", _reader.name()); + debug!("Skipping custom section: {:?}", reader.name()); } UnknownSection { .. } => return Err(ParseError::UnsupportedSection("Unknown section".into())), - section => return Err(ParseError::UnsupportedSection(format!("Unsupported section: {:?}", section))), + section => return Err(ParseError::UnsupportedSection(format!("Unsupported section: {section:?}"))), }; Ok(()) @@ -196,7 +196,7 @@ impl ModuleReader { .map(|((instructions, locals), ty_idx)| { let mut params = ValueCountsSmall::default(); let ty = self.func_types.get(ty_idx as usize).expect("No func type for func, this is a bug").clone(); - for param in ty.params.iter() { + for param in &ty.params { match param { ValType::I32 | ValType::F32 => params.c32 += 1, ValType::I64 | ValType::F64 => params.c64 += 1, @@ -204,7 +204,7 @@ impl ModuleReader { ValType::RefExtern | ValType::RefFunc => params.cref += 1, } } - WasmFunction { instructions, params, locals, ty } + WasmFunction { instructions, locals, params, ty } }) .collect::<Vec<_>>() .into_boxed_slice(); diff --git a/crates/parser/src/visit.rs b/crates/parser/src/visit.rs index 1f282f7..73cf9b4 100644 --- a/crates/parser/src/visit.rs +++ b/crates/parser/src/visit.rs @@ -362,7 +362,7 @@ impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuild fn visit_i32_store(&mut self, memarg: wasmparser::MemArg) -> Self::Output { let arg = MemoryArg { offset: memarg.offset, mem_addr: memarg.memory }; let i32store = Instruction::I32Store { offset: arg.offset, mem_addr: arg.mem_addr }; - self.instructions.push(i32store) + self.instructions.push(i32store); } fn visit_local_get(&mut self, idx: u32) -> Self::Output { @@ -394,28 +394,28 @@ impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuild return; }; - match self.instructions.last() { - Some(Instruction::LocalGet32(from)) - | Some(Instruction::LocalGet64(from)) - | Some(Instruction::LocalGet128(from)) - | Some(Instruction::LocalGetRef(from)) => { - let from = *from; - self.instructions.pop(); - // validation will ensure that the last instruction is the correct local.get - match self.validator.get_operand_type(0) { - Some(Some(t)) => self.instructions.push(match t { - wasmparser::ValType::I32 => Instruction::LocalCopy32(from, resolved_idx), - wasmparser::ValType::F32 => Instruction::LocalCopy32(from, resolved_idx), - wasmparser::ValType::I64 => Instruction::LocalCopy64(from, resolved_idx), - wasmparser::ValType::F64 => Instruction::LocalCopy64(from, resolved_idx), - wasmparser::ValType::V128 => Instruction::LocalCopy128(from, resolved_idx), - wasmparser::ValType::Ref(_) => Instruction::LocalCopyRef(from, resolved_idx), - }), - _ => self.visit_unreachable(), - } - return; + if let Some( + Instruction::LocalGet32(from) + | Instruction::LocalGet64(from) + | Instruction::LocalGet128(from) + | Instruction::LocalGetRef(from), + ) = self.instructions.last() + { + let from = *from; + self.instructions.pop(); + // validation will ensure that the last instruction is the correct local.get + match self.validator.get_operand_type(0) { + Some(Some(t)) => self.instructions.push(match t { + wasmparser::ValType::I32 => Instruction::LocalCopy32(from, resolved_idx), + wasmparser::ValType::F32 => Instruction::LocalCopy32(from, resolved_idx), + wasmparser::ValType::I64 => Instruction::LocalCopy64(from, resolved_idx), + wasmparser::ValType::F64 => Instruction::LocalCopy64(from, resolved_idx), + wasmparser::ValType::V128 => Instruction::LocalCopy128(from, resolved_idx), + wasmparser::ValType::Ref(_) => Instruction::LocalCopyRef(from, resolved_idx), + }), + _ => self.visit_unreachable(), } - _ => {} + return; } match self.validator.get_operand_type(0) { @@ -453,11 +453,11 @@ impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuild } fn visit_i64_rotl(&mut self) -> Self::Output { - self.instructions.push(Instruction::I64Rotl) + self.instructions.push(Instruction::I64Rotl); } fn visit_i32_add(&mut self) -> Self::Output { - self.instructions.push(Instruction::I32Add) + self.instructions.push(Instruction::I32Add); } fn visit_block(&mut self, blockty: wasmparser::BlockType) -> Self::Output { @@ -466,7 +466,7 @@ impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuild wasmparser::BlockType::Empty => Instruction::Block(0), wasmparser::BlockType::FuncType(idx) => Instruction::BlockWithFuncType(idx, 0), wasmparser::BlockType::Type(ty) => Instruction::BlockWithType(convert_valtype(&ty), 0), - }) + }); } fn visit_loop(&mut self, ty: wasmparser::BlockType) -> Self::Output { @@ -475,7 +475,7 @@ impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuild wasmparser::BlockType::Empty => Instruction::Loop(0), wasmparser::BlockType::FuncType(idx) => Instruction::LoopWithFuncType(idx, 0), wasmparser::BlockType::Type(ty) => Instruction::LoopWithType(convert_valtype(&ty), 0), - }) + }); } fn visit_if(&mut self, ty: wasmparser::BlockType) -> Self::Output { @@ -484,12 +484,12 @@ impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuild wasmparser::BlockType::Empty => Instruction::If(0, 0), wasmparser::BlockType::FuncType(idx) => Instruction::IfWithFuncType(idx, 0, 0), wasmparser::BlockType::Type(ty) => Instruction::IfWithType(convert_valtype(&ty), 0, 0), - }) + }); } fn visit_else(&mut self) -> Self::Output { self.label_ptrs.push(self.instructions.len()); - self.instructions.push(Instruction::Else(0)) + self.instructions.push(Instruction::Else(0)); } fn visit_end(&mut self) -> Self::Output { @@ -536,15 +536,17 @@ impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuild .try_into() .expect("else_instr_end_offset is too large, tinywasm does not support blocks that large"); } - Some(Instruction::Block(end_offset)) - | Some(Instruction::BlockWithType(_, end_offset)) - | Some(Instruction::BlockWithFuncType(_, end_offset)) - | Some(Instruction::Loop(end_offset)) - | Some(Instruction::LoopWithFuncType(_, end_offset)) - | Some(Instruction::LoopWithType(_, end_offset)) - | Some(Instruction::If(_, end_offset)) - | Some(Instruction::IfWithFuncType(_, _, end_offset)) - | Some(Instruction::IfWithType(_, _, end_offset)) => { + Some( + Instruction::Block(end_offset) + | Instruction::BlockWithType(_, end_offset) + | Instruction::BlockWithFuncType(_, end_offset) + | Instruction::Loop(end_offset) + | Instruction::LoopWithFuncType(_, end_offset) + | Instruction::LoopWithType(_, end_offset) + | Instruction::If(_, end_offset) + | Instruction::IfWithFuncType(_, _, end_offset) + | Instruction::IfWithType(_, _, end_offset), + ) => { *end_offset = (current_instr_ptr - label_pointer) .try_into() .expect("else_instr_end_offset is too large, tinywasm does not support blocks that large"); @@ -554,7 +556,7 @@ impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuild } }; - self.instructions.push(Instruction::EndBlockFrame) + self.instructions.push(Instruction::EndBlockFrame); } fn visit_br_table(&mut self, targets: wasmparser::BrTable<'_>) -> Self::Output { @@ -569,15 +571,15 @@ impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuild } fn visit_call_indirect(&mut self, ty: u32, table: u32) -> Self::Output { - self.instructions.push(Instruction::CallIndirect(ty, table)) + self.instructions.push(Instruction::CallIndirect(ty, table)); } fn visit_f32_const(&mut self, val: wasmparser::Ieee32) -> Self::Output { - self.instructions.push(Instruction::F32Const(f32::from_bits(val.bits()))) + self.instructions.push(Instruction::F32Const(f32::from_bits(val.bits()))); } fn visit_f64_const(&mut self, val: wasmparser::Ieee64) -> Self::Output { - self.instructions.push(Instruction::F64Const(f64::from_bits(val.bits()))) + self.instructions.push(Instruction::F64Const(f64::from_bits(val.bits()))); } // Bulk Memory Operations @@ -594,16 +596,16 @@ impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuild } fn visit_table_copy(&mut self, dst_table: u32, src_table: u32) -> Self::Output { - self.instructions.push(Instruction::TableCopy { from: src_table, to: dst_table }) + self.instructions.push(Instruction::TableCopy { from: src_table, to: dst_table }); } // Reference Types fn visit_ref_null(&mut self, ty: wasmparser::HeapType) -> Self::Output { - self.instructions.push(Instruction::RefNull(convert_heaptype(ty))) + self.instructions.push(Instruction::RefNull(convert_heaptype(ty))); } fn visit_ref_is_null(&mut self) -> Self::Output { - self.instructions.push(Instruction::RefIsNull) + self.instructions.push(Instruction::RefIsNull); } fn visit_typed_select(&mut self, ty: wasmparser::ValType) -> Self::Output { @@ -614,7 +616,7 @@ impl<'a, R: WasmModuleResources> wasmparser::VisitOperator<'a> for FunctionBuild wasmparser::ValType::F64 => Instruction::Select64, wasmparser::ValType::V128 => Instruction::Select128, wasmparser::ValType::Ref(_) => Instruction::SelectRef, - }) + }); } define_primitive_operands! { diff --git a/crates/tinywasm/benches/argon2id.rs b/crates/tinywasm/benches/argon2id.rs index b951a56..0a8f033 100644 --- a/crates/tinywasm/benches/argon2id.rs +++ b/crates/tinywasm/benches/argon2id.rs @@ -1,6 +1,6 @@ use criterion::{criterion_group, criterion_main, Criterion}; use eyre::Result; -use tinywasm::*; +use tinywasm::{ModuleInstance, Store, types}; use types::{archive::AlignedVec, TinyWasmModule}; const WASM: &[u8] = include_bytes!("../../../examples/rust/out/argon2id.opt.wasm"); diff --git a/crates/tinywasm/benches/fibonacci.rs b/crates/tinywasm/benches/fibonacci.rs index 973423c..557d787 100644 --- a/crates/tinywasm/benches/fibonacci.rs +++ b/crates/tinywasm/benches/fibonacci.rs @@ -1,6 +1,6 @@ use criterion::{criterion_group, criterion_main, Criterion}; use eyre::Result; -use tinywasm::*; +use tinywasm::{ModuleInstance, Store, types}; use types::{archive::AlignedVec, TinyWasmModule}; const WASM: &[u8] = include_bytes!("../../../examples/rust/out/fibonacci.opt.wasm"); diff --git a/crates/tinywasm/benches/tinywasm.rs b/crates/tinywasm/benches/tinywasm.rs index 52bf4a8..cfc9cb8 100644 --- a/crates/tinywasm/benches/tinywasm.rs +++ b/crates/tinywasm/benches/tinywasm.rs @@ -1,6 +1,6 @@ use criterion::{criterion_group, criterion_main, Criterion}; use eyre::Result; -use tinywasm::*; +use tinywasm::{Extern, FuncContext, Imports, ModuleInstance, Store, types}; use types::{archive::AlignedVec, TinyWasmModule}; const WASM: &[u8] = include_bytes!("../../../examples/rust/out/tinywasm.opt.wasm"); diff --git a/crates/tinywasm/src/error.rs b/crates/tinywasm/src/error.rs index c2413a1..73df9a2 100644 --- a/crates/tinywasm/src/error.rs +++ b/crates/tinywasm/src/error.rs @@ -5,7 +5,7 @@ use tinywasm_types::FuncType; #[cfg(feature = "parser")] pub use tinywasm_parser::ParseError; -/// Errors that can occur for TinyWasm operations +/// Errors that can occur for `TinyWasm` operations #[derive(Debug)] pub enum Error { /// A WebAssembly trap occurred @@ -173,16 +173,16 @@ impl Display for Error { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { #[cfg(feature = "parser")] - Self::ParseError(err) => write!(f, "error parsing module: {:?}", err), + Self::ParseError(err) => write!(f, "error parsing module: {err:?}"), #[cfg(feature = "std")] - Self::Io(err) => write!(f, "I/O error: {}", err), + Self::Io(err) => write!(f, "I/O error: {err}"), - Self::Trap(trap) => write!(f, "trap: {}", trap), - Self::Linker(err) => write!(f, "linking error: {}", err), + Self::Trap(trap) => write!(f, "trap: {trap}"), + Self::Linker(err) => write!(f, "linking error: {err}"), Self::InvalidLabelType => write!(f, "invalid label type"), - Self::Other(message) => write!(f, "unknown error: {}", message), - Self::UnsupportedFeature(feature) => write!(f, "unsupported feature: {}", feature), + Self::Other(message) => write!(f, "unknown error: {message}"), + Self::UnsupportedFeature(feature) => write!(f, "unsupported feature: {feature}"), Self::FuncDidNotReturn => write!(f, "function did not return"), Self::InvalidStore => write!(f, "invalid store"), } @@ -205,21 +205,21 @@ impl Display for Trap { match self { Self::Unreachable => write!(f, "unreachable"), Self::MemoryOutOfBounds { offset, len, max } => { - write!(f, "out of bounds memory access: offset={}, len={}, max={}", offset, len, max) + write!(f, "out of bounds memory access: offset={offset}, len={len}, max={max}") } Self::TableOutOfBounds { offset, len, max } => { - write!(f, "out of bounds table access: offset={}, len={}, max={}", offset, len, max) + write!(f, "out of bounds table access: offset={offset}, len={len}, max={max}") } Self::DivisionByZero => write!(f, "integer divide by zero"), Self::InvalidConversionToInt => write!(f, "invalid conversion to integer"), Self::IntegerOverflow => write!(f, "integer overflow"), Self::CallStackOverflow => write!(f, "call stack exhausted"), - Self::UndefinedElement { index } => write!(f, "undefined element: index={}", index), + Self::UndefinedElement { index } => write!(f, "undefined element: index={index}"), Self::UninitializedElement { index } => { - write!(f, "uninitialized element: index={}", index) + write!(f, "uninitialized element: index={index}") } Self::IndirectCallTypeMismatch { expected, actual } => { - write!(f, "indirect call type mismatch: expected={:?}, actual={:?}", expected, actual) + write!(f, "indirect call type mismatch: expected={expected:?}, actual={actual:?}") } } } diff --git a/crates/tinywasm/src/func.rs b/crates/tinywasm/src/func.rs index f2017fe..466dd86 100644 --- a/crates/tinywasm/src/func.rs +++ b/crates/tinywasm/src/func.rs @@ -48,7 +48,7 @@ impl FuncHandle { return Err(Error::Other("Type mismatch".into())); } - let func_inst = store.get_func(&self.addr); + let func_inst = store.get_func(self.addr); let wasm_func = match &func_inst.func { Function::Host(host_func) => { let func = &host_func.clone().func; @@ -59,7 +59,7 @@ impl FuncHandle { }; // 6. Let f be the dummy frame - let call_frame = CallFrame::new(wasm_func.clone(), func_inst._owner, params, 0); + let call_frame = CallFrame::new(wasm_func.clone(), func_inst.owner, params, 0); // 7. Push the frame f to the call stack // & 8. Push the values to the stack (Not needed since the call frame owns the values) diff --git a/crates/tinywasm/src/imports.rs b/crates/tinywasm/src/imports.rs index 3d29dfc..e015635 100644 --- a/crates/tinywasm/src/imports.rs +++ b/crates/tinywasm/src/imports.rs @@ -346,7 +346,7 @@ impl Imports { ) -> Result<ResolvedImports> { let mut imports = ResolvedImports::new(); - for import in module.0.imports.iter() { + for import in &module.0.imports { let val = self.take(store, import).ok_or_else(|| LinkingError::unknown_import(import))?; match val { @@ -386,23 +386,23 @@ impl Imports { match (val, &import.kind) { (ExternVal::Global(global_addr), ImportKind::Global(ty)) => { - let global = store.get_global(&global_addr); + let global = store.get_global(global_addr); Self::compare_types(import, &global.ty, ty)?; imports.globals.push(global_addr); } (ExternVal::Table(table_addr), ImportKind::Table(ty)) => { - let table = store.get_table(&table_addr); + let table = store.get_table(table_addr); Self::compare_table_types(import, &table.kind, ty)?; imports.tables.push(table_addr); } (ExternVal::Memory(memory_addr), ImportKind::Memory(ty)) => { - let mem = store.get_mem(&memory_addr); + let mem = store.get_mem(memory_addr); let (size, kind) = { (mem.page_count, mem.kind) }; Self::compare_memory_types(import, &kind, ty, Some(size))?; imports.memories.push(memory_addr); } (ExternVal::Func(func_addr), ImportKind::Function(ty)) => { - let func = store.get_func(&func_addr); + let func = store.get_func(func_addr); let import_func_type = module .0 .func_types diff --git a/crates/tinywasm/src/instance.rs b/crates/tinywasm/src/instance.rs index 0f72676..eebf5ff 100644 --- a/crates/tinywasm/src/instance.rs +++ b/crates/tinywasm/src/instance.rs @@ -129,38 +129,38 @@ impl ModuleInstance { // resolve a function address to the global store address #[inline] - pub(crate) fn resolve_func_addr(&self, addr: FuncAddr) -> &FuncAddr { - &self.0.func_addrs[addr as usize] + pub(crate) fn resolve_func_addr(&self, addr: FuncAddr) -> FuncAddr { + self.0.func_addrs[addr as usize] } // resolve a table address to the global store address #[inline] - pub(crate) fn resolve_table_addr(&self, addr: TableAddr) -> &TableAddr { - &self.0.table_addrs[addr as usize] + pub(crate) fn resolve_table_addr(&self, addr: TableAddr) -> TableAddr { + self.0.table_addrs[addr as usize] } // resolve a memory address to the global store address #[inline] - pub(crate) fn resolve_mem_addr(&self, addr: MemAddr) -> &MemAddr { - &self.0.mem_addrs[addr as usize] + pub(crate) fn resolve_mem_addr(&self, addr: MemAddr) -> MemAddr { + self.0.mem_addrs[addr as usize] } // resolve a data address to the global store address #[inline] - pub(crate) fn resolve_data_addr(&self, addr: DataAddr) -> &DataAddr { - &self.0.data_addrs[addr as usize] + pub(crate) fn resolve_data_addr(&self, addr: DataAddr) -> DataAddr { + self.0.data_addrs[addr as usize] } // resolve a memory address to the global store address #[inline] - pub(crate) fn resolve_elem_addr(&self, addr: ElemAddr) -> &ElemAddr { - &self.0.elem_addrs[addr as usize] + pub(crate) fn resolve_elem_addr(&self, addr: ElemAddr) -> ElemAddr { + self.0.elem_addrs[addr as usize] } // resolve a global address to the global store address #[inline] - pub(crate) fn resolve_global_addr(&self, addr: GlobalAddr) -> &GlobalAddr { - &self.0.global_addrs[addr as usize] + pub(crate) fn resolve_global_addr(&self, addr: GlobalAddr) -> GlobalAddr { + self.0.global_addrs[addr as usize] } /// Get an exported function by name @@ -169,12 +169,12 @@ impl ModuleInstance { return Err(Error::InvalidStore); } - let export = self.export_addr(name).ok_or_else(|| Error::Other(format!("Export not found: {}", name)))?; + let export = self.export_addr(name).ok_or_else(|| Error::Other(format!("Export not found: {name}")))?; let ExternVal::Func(func_addr) = export else { - return Err(Error::Other(format!("Export is not a function: {}", name))); + return Err(Error::Other(format!("Export is not a function: {name}"))); }; - let ty = store.get_func(&func_addr).func.ty(); + let ty = store.get_func(func_addr).func.ty(); Ok(FuncHandle { addr: func_addr, module_addr: self.id(), name: Some(name.to_string()), ty: ty.clone() }) } @@ -190,7 +190,7 @@ impl ModuleInstance { /// Get an exported memory by name pub fn exported_memory<'a>(&self, store: &'a mut Store, name: &str) -> Result<MemoryRef<'a>> { - let export = self.export_addr(name).ok_or_else(|| Error::Other(format!("Export not found: {}", name)))?; + let export = self.export_addr(name).ok_or_else(|| Error::Other(format!("Export not found: {name}")))?; let ExternVal::Memory(mem_addr) = export else { return Err(Error::Other(format!("Export is not a memory: {}", name))); }; @@ -200,7 +200,7 @@ impl ModuleInstance { /// Get an exported memory by name pub fn exported_memory_mut<'a>(&self, store: &'a mut Store, name: &str) -> Result<MemoryRefMut<'a>> { - let export = self.export_addr(name).ok_or_else(|| Error::Other(format!("Export not found: {}", name)))?; + let export = self.export_addr(name).ok_or_else(|| Error::Other(format!("Export not found: {name}")))?; let ExternVal::Memory(mem_addr) = export else { return Err(Error::Other(format!("Export is not a memory: {}", name))); }; @@ -247,7 +247,7 @@ impl ModuleInstance { let func_inst = store.get_func(func_addr); let ty = func_inst.func.ty(); - Ok(Some(FuncHandle { module_addr: self.id(), addr: *func_addr, ty: ty.clone(), name: None })) + Ok(Some(FuncHandle { module_addr: self.id(), addr: func_addr, ty: ty.clone(), name: None })) } /// Invoke the start function of the module diff --git a/crates/tinywasm/src/interpreter/executor.rs b/crates/tinywasm/src/interpreter/executor.rs index a9516f0..39fcbd4 100644 --- a/crates/tinywasm/src/interpreter/executor.rs +++ b/crates/tinywasm/src/interpreter/executor.rs @@ -42,7 +42,7 @@ impl<'store, 'stack> Executor<'store, 'stack> { fn exec_next(&mut self) -> ControlFlow<Option<Error>> { use tinywasm_types::Instruction::*; match self.cf.fetch_instr() { - Nop => self.exec_noop(), + Nop | BrLabel(_) | I32ReinterpretF32 | I64ReinterpretF64 | F32ReinterpretI32 | F64ReinterpretI64 => {} Unreachable => self.exec_unreachable()?, Drop32 => self.stack.values.drop::<Value32>(), @@ -58,20 +58,19 @@ impl<'store, 'stack> Executor<'store, 'stack> { Call(v) => return self.exec_call_direct(*v), CallIndirect(ty, table) => return self.exec_call_indirect(*ty, *table), - If(end, el) => self.exec_if(*end, *el, (Default::default(), Default::default())), - IfWithType(ty, end, el) => self.exec_if(*end, *el, (Default::default(), (*ty).into())), + If(end, el) => self.exec_if(*end, *el, (StackHeight::default(), StackHeight::default())), + IfWithType(ty, end, el) => self.exec_if(*end, *el, (StackHeight::default(), (*ty).into())), IfWithFuncType(ty, end, el) => self.exec_if(*end, *el, self.resolve_functype(*ty)), Else(end_offset) => self.exec_else(*end_offset), - Loop(end) => self.enter_block(*end, BlockType::Loop, (Default::default(), Default::default())), - LoopWithType(ty, end) => self.enter_block(*end, BlockType::Loop, (Default::default(), (*ty).into())), + Loop(end) => self.enter_block(*end, BlockType::Loop, (StackHeight::default(), StackHeight::default())), + LoopWithType(ty, end) => self.enter_block(*end, BlockType::Loop, (StackHeight::default(), (*ty).into())), LoopWithFuncType(ty, end) => self.enter_block(*end, BlockType::Loop, self.resolve_functype(*ty)), - Block(end) => self.enter_block(*end, BlockType::Block, (Default::default(), Default::default())), - BlockWithType(ty, end) => self.enter_block(*end, BlockType::Block, (Default::default(), (*ty).into())), + Block(end) => self.enter_block(*end, BlockType::Block, (StackHeight::default(), StackHeight::default())), + BlockWithType(ty, end) => self.enter_block(*end, BlockType::Block, (StackHeight::default(), (*ty).into())), BlockWithFuncType(ty, end) => self.enter_block(*end, BlockType::Block, self.resolve_functype(*ty)), Br(v) => return self.exec_br(*v), BrIf(v) => return self.exec_br_if(*v), BrTable(default, len) => return self.exec_brtable(*default, *len), - BrLabel(_) => {} Return => return self.exec_return(), EndBlockFrame => self.exec_end_block(), @@ -140,45 +139,45 @@ impl<'store, 'stack> Executor<'store, 'stack> { I64Load32S { mem_addr, offset } => self.exec_mem_load::<i32, 4, _>(*mem_addr, *offset, |v| v as i64)?, I64Load32U { mem_addr, offset } => self.exec_mem_load::<u32, 4, _>(*mem_addr, *offset, |v| v as i64)?, - I64Eqz => self.stack.values.replace_top::<i64, _>(|v| Ok((v == 0) as i32)).to_cf()?, - I32Eqz => self.stack.values.replace_top_same::<i32>(|v| Ok((v == 0) as i32)).to_cf()?, - I32Eq => self.stack.values.calculate_same::<i32>(|a, b| Ok((a == b) as i32)).to_cf()?, - I64Eq => self.stack.values.calculate::<i64, _>(|a, b| Ok((a == b) as i32)).to_cf()?, - F32Eq => self.stack.values.calculate::<f32, _>(|a, b| Ok((a == b) as i32)).to_cf()?, - F64Eq => self.stack.values.calculate::<f64, _>(|a, b| Ok((a == b) as i32)).to_cf()?, + I64Eqz => self.stack.values.replace_top::<i64, _>(|v| Ok(i32::from(v == 0))).to_cf()?, + I32Eqz => self.stack.values.replace_top_same::<i32>(|v| Ok(i32::from(v == 0))).to_cf()?, + I32Eq => self.stack.values.calculate_same::<i32>(|a, b| Ok(i32::from(a == b))).to_cf()?, + I64Eq => self.stack.values.calculate::<i64, _>(|a, b| Ok(i32::from(a == b))).to_cf()?, + F32Eq => self.stack.values.calculate::<f32, _>(|a, b| Ok(i32::from(a == b))).to_cf()?, + F64Eq => self.stack.values.calculate::<f64, _>(|a, b| Ok(i32::from(a == b))).to_cf()?, - I32Ne => self.stack.values.calculate_same::<i32>(|a, b| Ok((a != b) as i32)).to_cf()?, - I64Ne => self.stack.values.calculate::<i64, _>(|a, b| Ok((a != b) as i32)).to_cf()?, - F32Ne => self.stack.values.calculate::<f32, _>(|a, b| Ok((a != b) as i32)).to_cf()?, - F64Ne => self.stack.values.calculate::<f64, _>(|a, b| Ok((a != b) as i32)).to_cf()?, + I32Ne => self.stack.values.calculate_same::<i32>(|a, b| Ok(i32::from(a != b))).to_cf()?, + I64Ne => self.stack.values.calculate::<i64, _>(|a, b| Ok(i32::from(a != b))).to_cf()?, + F32Ne => self.stack.values.calculate::<f32, _>(|a, b| Ok(i32::from(a != b))).to_cf()?, + F64Ne => self.stack.values.calculate::<f64, _>(|a, b| Ok(i32::from(a != b))).to_cf()?, - I32LtS => self.stack.values.calculate_same::<i32>(|a, b| Ok((a < b) as i32)).to_cf()?, - I64LtS => self.stack.values.calculate::<i64, _>(|a, b| Ok((a < b) as i32)).to_cf()?, - I32LtU => self.stack.values.calculate::<u32, _>(|a, b| Ok((a < b) as i32)).to_cf()?, - I64LtU => self.stack.values.calculate::<u64, _>(|a, b| Ok((a < b) as i32)).to_cf()?, - F32Lt => self.stack.values.calculate::<f32, _>(|a, b| Ok((a < b) as i32)).to_cf()?, - F64Lt => self.stack.values.calculate::<f64, _>(|a, b| Ok((a < b) as i32)).to_cf()?, + I32LtS => self.stack.values.calculate_same::<i32>(|a, b| Ok(i32::from(a < b))).to_cf()?, + I64LtS => self.stack.values.calculate::<i64, _>(|a, b| Ok(i32::from(a < b))).to_cf()?, + I32LtU => self.stack.values.calculate::<u32, _>(|a, b| Ok(i32::from(a < b))).to_cf()?, + I64LtU => self.stack.values.calculate::<u64, _>(|a, b| Ok(i32::from(a < b))).to_cf()?, + F32Lt => self.stack.values.calculate::<f32, _>(|a, b| Ok(i32::from(a < b))).to_cf()?, + F64Lt => self.stack.values.calculate::<f64, _>(|a, b| Ok(i32::from(a < b))).to_cf()?, - I32LeS => self.stack.values.calculate_same::<i32>(|a, b| Ok((a <= b) as i32)).to_cf()?, - I64LeS => self.stack.values.calculate::<i64, _>(|a, b| Ok((a <= b) as i32)).to_cf()?, - I32LeU => self.stack.values.calculate::<u32, _>(|a, b| Ok((a <= b) as i32)).to_cf()?, - I64LeU => self.stack.values.calculate::<u64, _>(|a, b| Ok((a <= b) as i32)).to_cf()?, - F32Le => self.stack.values.calculate::<f32, _>(|a, b| Ok((a <= b) as i32)).to_cf()?, - F64Le => self.stack.values.calculate::<f64, _>(|a, b| Ok((a <= b) as i32)).to_cf()?, + I32LeS => self.stack.values.calculate_same::<i32>(|a, b| Ok(i32::from(a <= b))).to_cf()?, + I64LeS => self.stack.values.calculate::<i64, _>(|a, b| Ok(i32::from(a <= b))).to_cf()?, + I32LeU => self.stack.values.calculate::<u32, _>(|a, b| Ok(i32::from(a <= b))).to_cf()?, + I64LeU => self.stack.values.calculate::<u64, _>(|a, b| Ok(i32::from(a <= b))).to_cf()?, + F32Le => self.stack.values.calculate::<f32, _>(|a, b| Ok(i32::from(a <= b))).to_cf()?, + F64Le => self.stack.values.calculate::<f64, _>(|a, b| Ok(i32::from(a <= b))).to_cf()?, - I32GeS => self.stack.values.calculate_same::<i32>(|a, b| Ok((a >= b) as i32)).to_cf()?, - I64GeS => self.stack.values.calculate::<i64, _>(|a, b| Ok((a >= b) as i32)).to_cf()?, - I32GeU => self.stack.values.calculate::<u32, _>(|a, b| Ok((a >= b) as i32)).to_cf()?, - I64GeU => self.stack.values.calculate::<u64, _>(|a, b| Ok((a >= b) as i32)).to_cf()?, - F32Ge => self.stack.values.calculate::<f32, _>(|a, b| Ok((a >= b) as i32)).to_cf()?, - F64Ge => self.stack.values.calculate::<f64, _>(|a, b| Ok((a >= b) as i32)).to_cf()?, + I32GeS => self.stack.values.calculate_same::<i32>(|a, b| Ok(i32::from(a >= b))).to_cf()?, + I64GeS => self.stack.values.calculate::<i64, _>(|a, b| Ok(i32::from(a >= b))).to_cf()?, + I32GeU => self.stack.values.calculate::<u32, _>(|a, b| Ok(i32::from(a >= b))).to_cf()?, + I64GeU => self.stack.values.calculate::<u64, _>(|a, b| Ok(i32::from(a >= b))).to_cf()?, + F32Ge => self.stack.values.calculate::<f32, _>(|a, b| Ok(i32::from(a >= b))).to_cf()?, + F64Ge => self.stack.values.calculate::<f64, _>(|a, b| Ok(i32::from(a >= b))).to_cf()?, - I32GtS => self.stack.values.calculate_same::<i32>(|a, b| Ok((a > b) as i32)).to_cf()?, - I64GtS => self.stack.values.calculate::<i64, _>(|a, b| Ok((a > b) as i32)).to_cf()?, - I32GtU => self.stack.values.calculate::<u32, _>(|a, b| Ok((a > b) as i32)).to_cf()?, - I64GtU => self.stack.values.calculate::<u64, _>(|a, b| Ok((a > b) as i32)).to_cf()?, - F32Gt => self.stack.values.calculate::<f32, _>(|a, b| Ok((a > b) as i32)).to_cf()?, - F64Gt => self.stack.values.calculate::<f64, _>(|a, b| Ok((a > b) as i32)).to_cf()?, + I32GtS => self.stack.values.calculate_same::<i32>(|a, b| Ok(i32::from(a > b))).to_cf()?, + I64GtS => self.stack.values.calculate::<i64, _>(|a, b| Ok(i32::from(a > b))).to_cf()?, + I32GtU => self.stack.values.calculate::<u32, _>(|a, b| Ok(i32::from(a > b))).to_cf()?, + I64GtU => self.stack.values.calculate::<u64, _>(|a, b| Ok(i32::from(a > b))).to_cf()?, + F32Gt => self.stack.values.calculate::<f32, _>(|a, b| Ok(i32::from(a > b))).to_cf()?, + F64Gt => self.stack.values.calculate::<f64, _>(|a, b| Ok(i32::from(a > b))).to_cf()?, I32Add => self.stack.values.calculate_same::<i32>(|a, b| Ok(a.wrapping_add(b))).to_cf()?, I64Add => self.stack.values.calculate_same::<i64>(|a, b| Ok(a.wrapping_add(b))).to_cf()?, @@ -273,9 +272,6 @@ impl<'store, 'stack> Executor<'store, 'stack> { F32Copysign => self.stack.values.calculate_same::<f32>(|a, b| Ok(a.copysign(b))).to_cf()?, F64Copysign => self.stack.values.calculate_same::<f64>(|a, b| Ok(a.copysign(b))).to_cf()?, - // no-op instructions since types are erased at runtime - I32ReinterpretF32 | I64ReinterpretF64 | F32ReinterpretI32 | F64ReinterpretI64 => {} - I32TruncF32S => checked_conv_float!(f32, i32, self), I32TruncF64S => checked_conv_float!(f64, i32, self), I32TruncF32U => checked_conv_float!(f32, u32, i32, self), @@ -315,14 +311,13 @@ impl<'store, 'stack> Executor<'store, 'stack> { ControlFlow::Continue(()) } - fn exec_noop(&self) {} #[cold] fn exec_unreachable(&self) -> ControlFlow<Option<Error>> { ControlFlow::Break(Some(Trap::Unreachable.into())) } fn exec_call(&mut self, wasm_func: Rc<WasmFunction>, owner: ModuleInstanceAddr) -> ControlFlow<Option<Error>> { - let locals = self.stack.values.pop_locals(&wasm_func.params, &wasm_func.locals); + let locals = self.stack.values.pop_locals(wasm_func.params, wasm_func.locals); let new_call_frame = CallFrame::new_raw(wasm_func, owner, locals, self.stack.blocks.len() as u32); self.cf.incr_instr_ptr(); // skip the call instruction self.stack.call_stack.push(core::mem::replace(&mut self.cf, new_call_frame))?; @@ -344,7 +339,7 @@ impl<'store, 'stack> Executor<'store, 'stack> { } }; - self.exec_call(wasm_func.clone(), func_inst._owner) + self.exec_call(wasm_func.clone(), func_inst.owner) } fn exec_call_indirect(&mut self, type_addr: u32, table_addr: u32) -> ControlFlow<Option<Error>> { // verify that the table is of the right type, this should be validated by the parser already @@ -361,7 +356,7 @@ impl<'store, 'stack> Executor<'store, 'stack> { .to_cf()? }; - let func_inst = self.store.get_func(&func_ref); + let func_inst = self.store.get_func(func_ref); let call_ty = self.module.func_ty(type_addr); let wasm_func = match &func_inst.func { crate::Function::Wasm(f) => f, @@ -393,7 +388,7 @@ impl<'store, 'stack> Executor<'store, 'stack> { )); } - self.exec_call(wasm_func.clone(), func_inst._owner) + self.exec_call(wasm_func.clone(), func_inst.owner) } fn exec_if(&mut self, else_offset: u32, end_offset: u32, (params, results): (StackHeight, StackHeight)) { @@ -488,7 +483,7 @@ impl<'store, 'stack> Executor<'store, 'stack> { } fn exec_end_block(&mut self) { let block = self.stack.blocks.pop(); - self.stack.values.truncate_keep(&block.stack_ptr, &block.results); + self.stack.values.truncate_keep(block.stack_ptr, block.results); } fn exec_local_get<T: InternalValue>(&mut self, local_index: u16) { let v = self.cf.locals.get::<T>(local_index); @@ -566,17 +561,17 @@ impl<'store, 'stack> Executor<'store, 'stack> { .store .data .datas - .get(*self.module.resolve_data_addr(data_index) as usize) + .get(self.module.resolve_data_addr(data_index) as usize) .ok_or_else(|| Error::Other("data not found".to_string()))?; let mem = self .store .data .memories - .get_mut(*self.module.resolve_mem_addr(mem_index) as usize) + .get_mut(self.module.resolve_mem_addr(mem_index) as usize) .ok_or_else(|| Error::Other("memory not found".to_string()))?; - let data_len = data.data.as_ref().map(|d| d.len()).unwrap_or(0); + let data_len = data.data.as_ref().map_or(0, |d| d.len()); if unlikely(((size + offset) as usize > data_len) || ((dst + size) as usize > mem.len())) { return Err(Trap::MemoryOutOfBounds { offset: offset as usize, len: size as usize, max: data_len }.into()); @@ -586,11 +581,7 @@ impl<'store, 'stack> Executor<'store, 'stack> { return Ok(()); } - let data = match &data.data { - Some(data) => data, - None => return Err(Trap::MemoryOutOfBounds { offset: 0, len: 0, max: 0 }.into()), - }; - + let Some(data) = &data.data else { return Err(Trap::MemoryOutOfBounds { offset: 0, len: 0, max: 0 }.into()) }; mem.store(dst as usize, size as usize, &data[offset as usize..((offset + size) as usize)]) } fn exec_data_drop(&mut self, data_index: u32) { @@ -628,7 +619,7 @@ impl<'store, 'stack> Executor<'store, 'stack> { ) -> ControlFlow<Option<Error>> { let mem = self.store.get_mem(self.module.resolve_mem_addr(mem_addr)); let val = self.stack.values.pop::<i32>() as u64; - let Some(Ok(addr)) = offset.checked_add(val).map(|a| a.try_into()) else { + let Some(Ok(addr)) = offset.checked_add(val).map(TryInto::try_into) else { cold(); return ControlFlow::Break(Some(Error::Trap(Trap::MemoryOutOfBounds { offset: val as usize, @@ -679,17 +670,17 @@ impl<'store, 'stack> Executor<'store, 'stack> { .store .data .elements - .get(*self.module.resolve_elem_addr(elem_index) as usize) + .get(self.module.resolve_elem_addr(elem_index) as usize) .ok_or_else(|| Error::Other("element not found".to_string()))?; let table = self .store .data .tables - .get_mut(*self.module.resolve_table_addr(table_index) as usize) + .get_mut(self.module.resolve_table_addr(table_index) as usize) .ok_or_else(|| Error::Other("table not found".to_string()))?; - let elem_len = elem.items.as_ref().map(|items| items.len()).unwrap_or(0); + let elem_len = elem.items.as_ref().map_or(0, alloc::vec::Vec::len); let table_len = table.size(); let size: i32 = self.stack.values.pop(); // n diff --git a/crates/tinywasm/src/interpreter/mod.rs b/crates/tinywasm/src/interpreter/mod.rs index 0299cb1..0b7df2f 100644 --- a/crates/tinywasm/src/interpreter/mod.rs +++ b/crates/tinywasm/src/interpreter/mod.rs @@ -9,9 +9,9 @@ mod no_std_floats; use crate::{Result, Store}; pub use values::*; -/// The main TinyWasm runtime. +/// The main `TinyWasm` runtime. /// -/// This is the default runtime used by TinyWasm. +/// This is the default runtime used by `TinyWasm`. #[derive(Debug, Default)] pub struct InterpreterRuntime {} diff --git a/crates/tinywasm/src/interpreter/num_helpers.rs b/crates/tinywasm/src/interpreter/num_helpers.rs index 89a8002..02fbc24 100644 --- a/crates/tinywasm/src/interpreter/num_helpers.rs +++ b/crates/tinywasm/src/interpreter/num_helpers.rs @@ -10,7 +10,7 @@ where /// we need to check for overflow. This macro generates the min/max values /// for a specific conversion, which are then used in the actual conversion. /// Rust sadly doesn't have wrapping casts for floats yet, maybe never. -/// Alternatively, https://crates.io/crates/az could be used for this but +/// Alternatively, <https://crates.io/crates/az> could be used for this but /// it's not worth the dependency. #[rustfmt::skip] macro_rules! float_min_max { diff --git a/crates/tinywasm/src/interpreter/stack/call_stack.rs b/crates/tinywasm/src/interpreter/stack/call_stack.rs index 03885f9..7c2be9c 100644 --- a/crates/tinywasm/src/interpreter/stack/call_stack.rs +++ b/crates/tinywasm/src/interpreter/stack/call_stack.rs @@ -114,7 +114,7 @@ impl CallFrame { self.instr_ptr = break_to.instr_ptr; // We also want to push the params to the stack - values.truncate_keep(&break_to.stack_ptr, &break_to.params); + values.truncate_keep(break_to.stack_ptr, break_to.params); // check if we're breaking to the loop if break_to_relative != 0 { @@ -127,7 +127,7 @@ impl CallFrame { BlockType::Block | BlockType::If | BlockType::Else => { // this is a block, so we want to jump to the next instruction after the block ends // We also want to push the block's results to the stack - values.truncate_keep(&break_to.stack_ptr, &break_to.results); + values.truncate_keep(break_to.stack_ptr, break_to.results); // (the inst_ptr will be incremented by 1 before the next instruction is executed) self.instr_ptr = break_to.instr_ptr + break_to.end_instr_offset as usize; diff --git a/crates/tinywasm/src/interpreter/stack/value_stack.rs b/crates/tinywasm/src/interpreter/stack/value_stack.rs index 178c9ec..03c676e 100644 --- a/crates/tinywasm/src/interpreter/stack/value_stack.rs +++ b/crates/tinywasm/src/interpreter/stack/value_stack.rs @@ -102,7 +102,7 @@ impl ValueStack { } #[inline] - pub(crate) fn pop_locals(&mut self, pc: &ValueCountsSmall, lc: &ValueCounts) -> Locals { + pub(crate) fn pop_locals(&mut self, pc: ValueCountsSmall, lc: ValueCounts) -> Locals { Locals { locals_32: { let mut locals_32 = { alloc::vec![Value32::default(); lc.c32 as usize].into_boxed_slice() }; @@ -135,7 +135,7 @@ impl ValueStack { } } - pub(crate) fn truncate_keep(&mut self, to: &StackLocation, keep: &StackHeight) { + pub(crate) fn truncate_keep(&mut self, to: StackLocation, keep: StackHeight) { #[inline(always)] fn truncate_keep<T: Copy + Default>(data: &mut Vec<T>, n: u32, end_keep: u32) { let len = data.len() as u32; @@ -145,10 +145,10 @@ impl ValueStack { data.drain((n as usize)..(len - end_keep) as usize); } - truncate_keep(&mut self.stack_32, to.s32, keep.s32 as u32); - truncate_keep(&mut self.stack_64, to.s64, keep.s64 as u32); - truncate_keep(&mut self.stack_128, to.s128, keep.s128 as u32); - truncate_keep(&mut self.stack_ref, to.sref, keep.sref as u32); + truncate_keep(&mut self.stack_32, to.s32, u32::from(keep.s32)); + truncate_keep(&mut self.stack_64, to.s64, u32::from(keep.s64)); + truncate_keep(&mut self.stack_128, to.s128, u32::from(keep.s128)); + truncate_keep(&mut self.stack_ref, to.sref, u32::from(keep.sref)); } pub(crate) fn push_dyn(&mut self, value: TinyWasmValue) { @@ -179,7 +179,7 @@ impl ValueStack { } pub(crate) fn extend_from_wasmvalues(&mut self, values: &[WasmValue]) { - for value in values.iter() { + for value in values { self.push_dyn(value.into()) } } diff --git a/crates/tinywasm/src/interpreter/values.rs b/crates/tinywasm/src/interpreter/values.rs index b35f481..7b363a8 100644 --- a/crates/tinywasm/src/interpreter/values.rs +++ b/crates/tinywasm/src/interpreter/values.rs @@ -54,7 +54,7 @@ impl From<&[ValType]> for StackHeight { let mut s64 = 0; let mut s128 = 0; let mut sref = 0; - for val_type in value.iter() { + for val_type in value { match val_type { ValType::I32 | ValType::F32 => s32 += 1, ValType::I64 | ValType::F64 => s64 += 1, @@ -127,8 +127,7 @@ impl From<&WasmValue> for TinyWasmValue { WasmValue::V128(v) => TinyWasmValue::Value128(*v), WasmValue::F32(v) => TinyWasmValue::Value32(v.to_bits()), WasmValue::F64(v) => TinyWasmValue::Value64(v.to_bits()), - WasmValue::RefFunc(v) => TinyWasmValue::ValueRef(Some(*v)), - WasmValue::RefExtern(v) => TinyWasmValue::ValueRef(Some(*v)), + WasmValue::RefFunc(v) | WasmValue::RefExtern(v) => TinyWasmValue::ValueRef(Some(*v)), WasmValue::RefNull(_) => TinyWasmValue::ValueRef(None), } } diff --git a/crates/tinywasm/src/lib.rs b/crates/tinywasm/src/lib.rs index f53f4c6..7038dd6 100644 --- a/crates/tinywasm/src/lib.rs +++ b/crates/tinywasm/src/lib.rs @@ -9,7 +9,7 @@ //! A tiny WebAssembly Runtime written in Rust //! -//! TinyWasm provides a minimal WebAssembly runtime for executing WebAssembly modules. +//! `TinyWasm` provides a minimal WebAssembly runtime for executing WebAssembly modules. //! It currently supports all features of the WebAssembly MVP specification and is //! designed to be easy to use and integrate in other projects. //! @@ -23,8 +23,8 @@ //!- **`archive`**\ //! Enables pre-parsing of archives. This is enabled by default. //! -//! With all these features disabled, TinyWasm only depends on `core`, `alloc` and `libm`. -//! By disabling `std`, you can use TinyWasm in `no_std` environments. This requires +//! With all these features disabled, `TinyWasm` only depends on `core`, `alloc` and `libm`. +//! By disabling `std`, you can use `TinyWasm` in `no_std` environments. This requires //! a custom allocator and removes support for parsing from files and streams, but otherwise the API is the same. //! Additionally, to have proper error types in `no_std`, you currently need a `nightly` compiler to use the unstable error trait in `core`. //! @@ -127,7 +127,7 @@ pub(crate) fn cold() {} pub(crate) fn unlikely(b: bool) -> bool { if b { - cold() + cold(); }; b } diff --git a/crates/tinywasm/src/reference.rs b/crates/tinywasm/src/reference.rs index b9d65bc..3765098 100644 --- a/crates/tinywasm/src/reference.rs +++ b/crates/tinywasm/src/reference.rs @@ -38,7 +38,7 @@ impl MemoryRef<'_> { /// Load a slice of memory as a vector pub fn load_vec(&self, offset: usize, len: usize) -> Result<Vec<u8>> { - self.load(offset, len).map(|x| x.to_vec()) + self.load(offset, len).map(<[u8]>::to_vec) } } @@ -50,7 +50,7 @@ impl MemoryRefMut<'_> { /// Load a slice of memory as a vector pub fn load_vec(&self, offset: usize, len: usize) -> Result<Vec<u8>> { - self.load(offset, len).map(|x| x.to_vec()) + self.load(offset, len).map(<[u8]>::to_vec) } /// Grow the memory by the given number of pages @@ -83,7 +83,7 @@ impl MemoryRefMut<'_> { pub trait MemoryRefLoad { fn load(&self, offset: usize, len: usize) -> Result<&[u8]>; fn load_vec(&self, offset: usize, len: usize) -> Result<Vec<u8>> { - self.load(offset, len).map(|x| x.to_vec()) + self.load(offset, len).map(<[u8]>::to_vec) } } @@ -124,7 +124,7 @@ pub trait MemoryStringExt: MemoryRefLoad { for i in 0..(len / 2) { let c = u16::from_le_bytes([bytes[i * 2], bytes[i * 2 + 1]]); string.push( - char::from_u32(c as u32).ok_or_else(|| crate::Error::Other("Invalid UTF-16 string".to_string()))?, + char::from_u32(u32::from(c)).ok_or_else(|| crate::Error::Other("Invalid UTF-16 string".to_string()))?, ); } Ok(string) diff --git a/crates/tinywasm/src/store/function.rs b/crates/tinywasm/src/store/function.rs index f3f1df0..ef370c2 100644 --- a/crates/tinywasm/src/store/function.rs +++ b/crates/tinywasm/src/store/function.rs @@ -8,11 +8,11 @@ use tinywasm_types::*; /// See <https://webassembly.github.io/spec/core/exec/runtime.html#function-instances> pub(crate) struct FunctionInstance { pub(crate) func: Function, - pub(crate) _owner: ModuleInstanceAddr, // index into store.module_instances, none for host functions + pub(crate) owner: ModuleInstanceAddr, // index into store.module_instances, none for host functions } impl FunctionInstance { pub(crate) fn new_wasm(func: WasmFunction, owner: ModuleInstanceAddr) -> Self { - Self { func: Function::Wasm(Rc::new(func)), _owner: owner } + Self { func: Function::Wasm(Rc::new(func)), owner } } } diff --git a/crates/tinywasm/src/store/mod.rs b/crates/tinywasm/src/store/mod.rs index bc4055d..bc3360a 100644 --- a/crates/tinywasm/src/store/mod.rs +++ b/crates/tinywasm/src/store/mod.rs @@ -41,6 +41,7 @@ impl Debug for Store { .field("id", &self.id) .field("module_instances", &self.module_instances) .field("data", &"...") + .field("runtime", &self.runtime) .finish() } } @@ -117,35 +118,35 @@ impl Store { #[cold] fn not_found_error(name: &str) -> Error { - Error::Other(format!("{} not found", name)) + Error::Other(format!("{name} not found")) } /// Get the function at the actual index in the store #[inline] - pub(crate) fn get_func(&self, addr: &FuncAddr) -> &FunctionInstance { - &self.data.funcs[*addr as usize] + pub(crate) fn get_func(&self, addr: FuncAddr) -> &FunctionInstance { + &self.data.funcs[addr as usize] } /// Get the memory at the actual index in the store #[inline] - pub(crate) fn get_mem(&self, addr: &MemAddr) -> &MemoryInstance { - &self.data.memories[*addr as usize] + pub(crate) fn get_mem(&self, addr: MemAddr) -> &MemoryInstance { + &self.data.memories[addr as usize] } /// Get the memory at the actual index in the store #[inline(always)] - pub(crate) fn get_mem_mut(&mut self, addr: &MemAddr) -> &mut MemoryInstance { - &mut self.data.memories[*addr as usize] + pub(crate) fn get_mem_mut(&mut self, addr: MemAddr) -> &mut MemoryInstance { + &mut self.data.memories[addr as usize] } /// Get the memory at the actual index in the store #[inline(always)] pub(crate) fn get_mems_mut( &mut self, - addr: &MemAddr, - addr2: &MemAddr, + addr: MemAddr, + addr2: MemAddr, ) -> Result<(&mut MemoryInstance, &mut MemoryInstance)> { - match get_pair_mut(&mut self.data.memories, *addr as usize, *addr2 as usize) { + match get_pair_mut(&mut self.data.memories, addr as usize, addr2 as usize) { Some(mems) => Ok(mems), None => { cold(); @@ -156,24 +157,24 @@ impl Store { /// Get the table at the actual index in the store #[inline] - pub(crate) fn get_table(&self, addr: &TableAddr) -> &TableInstance { - &self.data.tables[*addr as usize] + pub(crate) fn get_table(&self, addr: TableAddr) -> &TableInstance { + &self.data.tables[addr as usize] } /// Get the table at the actual index in the store #[inline] - pub(crate) fn get_table_mut(&mut self, addr: &TableAddr) -> &mut TableInstance { - &mut self.data.tables[*addr as usize] + pub(crate) fn get_table_mut(&mut self, addr: TableAddr) -> &mut TableInstance { + &mut self.data.tables[addr as usize] } /// Get two mutable tables at the actual index in the store #[inline] pub(crate) fn get_tables_mut( &mut self, - addr: &TableAddr, - addr2: &TableAddr, + addr: TableAddr, + addr2: TableAddr, ) -> Result<(&mut TableInstance, &mut TableInstance)> { - match get_pair_mut(&mut self.data.tables, *addr as usize, *addr2 as usize) { + match get_pair_mut(&mut self.data.tables, addr as usize, addr2 as usize) { Some(tables) => Ok(tables), None => { cold(); @@ -184,32 +185,32 @@ impl Store { /// Get the data at the actual index in the store #[inline] - pub(crate) fn get_data_mut(&mut self, addr: &DataAddr) -> &mut DataInstance { - &mut self.data.datas[*addr as usize] + pub(crate) fn get_data_mut(&mut self, addr: DataAddr) -> &mut DataInstance { + &mut self.data.datas[addr as usize] } /// Get the element at the actual index in the store #[inline] - pub(crate) fn get_elem_mut(&mut self, addr: &ElemAddr) -> &mut ElementInstance { - &mut self.data.elements[*addr as usize] + pub(crate) fn get_elem_mut(&mut self, addr: ElemAddr) -> &mut ElementInstance { + &mut self.data.elements[addr as usize] } /// Get the global at the actual index in the store #[inline] - pub(crate) fn get_global(&self, addr: &GlobalAddr) -> &GlobalInstance { - &self.data.globals[*addr as usize] + pub(crate) fn get_global(&self, addr: GlobalAddr) -> &GlobalInstance { + &self.data.globals[addr as usize] } /// Get the global at the actual index in the store #[doc(hidden)] - pub fn get_global_val(&self, addr: &MemAddr) -> TinyWasmValue { - self.data.globals[*addr as usize].value.get() + pub fn get_global_val(&self, addr: MemAddr) -> TinyWasmValue { + self.data.globals[addr as usize].value.get() } /// Set the global at the actual index in the store #[doc(hidden)] - pub fn set_global_val(&mut self, addr: &MemAddr, value: TinyWasmValue) { - self.data.globals[*addr as usize].value.set(value); + pub fn set_global_val(&mut self, addr: MemAddr, value: TinyWasmValue) { + self.data.globals[addr as usize].value.set(value); } } @@ -279,17 +280,17 @@ impl Store { let res = match item { ElementItem::Func(addr) | ElementItem::Expr(ConstInstruction::RefFunc(addr)) => { Some(funcs.get(*addr as usize).copied().ok_or_else(|| { - Error::Other(format!("function {} not found. This should have been caught by the validator", addr)) + Error::Other(format!("function {addr} not found. This should have been caught by the validator")) })?) } ElementItem::Expr(ConstInstruction::RefNull(_ty)) => None, ElementItem::Expr(ConstInstruction::GlobalGet(addr)) => { let addr = globals.get(*addr as usize).copied().ok_or_else(|| { - Error::Other(format!("global {} not found. This should have been caught by the validator", addr)) + Error::Other(format!("global {addr} not found. This should have been caught by the validator")) })?; self.data.globals[addr as usize].value.get().unwrap_ref() } - _ => return Err(Error::UnsupportedFeature(format!("const expression other than ref: {:?}", item))), + _ => return Err(Error::UnsupportedFeature(format!("const expression other than ref: {item:?}"))), }; Ok(res) @@ -323,14 +324,14 @@ impl Store { // this one is active, so we need to initialize it (essentially a `table.init` instruction) ElementKind::Active { offset, table } => { - let offset = self.eval_i32_const(&offset)?; + let offset = self.eval_i32_const(offset)?; let table_addr = table_addrs .get(table as usize) .copied() - .ok_or_else(|| Error::Other(format!("table {} not found for element {}", table, i)))?; + .ok_or_else(|| Error::Other(format!("table {table} not found for element {i}")))?; let Some(table) = self.data.tables.get_mut(table_addr as usize) else { - return Err(Error::Other(format!("table {} not found for element {}", table, i))); + return Err(Error::Other(format!("table {table} not found for element {i}"))); }; // In wasm 2.0, it's possible to call a function that hasn't been instantiated yet, @@ -373,12 +374,12 @@ impl Store { } let Some(mem_addr) = mem_addrs.get(mem_addr as usize) else { - return Err(Error::Other(format!("memory {} not found for data segment {}", mem_addr, i))); + return Err(Error::Other(format!("memory {mem_addr} not found for data segment {i}"))); }; - let offset = self.eval_i32_const(&offset)?; + let offset = self.eval_i32_const(offset)?; let Some(mem) = self.data.memories.get_mut(*mem_addr as usize) else { - return Err(Error::Other(format!("memory {} not found for data segment {}", mem_addr, i))); + return Err(Error::Other(format!("memory {mem_addr} not found for data segment {i}"))); }; match mem.store(offset as usize, data.data.len(), &data.data) { @@ -417,16 +418,16 @@ impl Store { } pub(crate) fn add_func(&mut self, func: Function, idx: ModuleInstanceAddr) -> Result<FuncAddr> { - self.data.funcs.push(FunctionInstance { func, _owner: idx }); + self.data.funcs.push(FunctionInstance { func, owner: idx }); Ok(self.data.funcs.len() as FuncAddr - 1) } /// Evaluate a constant expression, only supporting i32 globals and i32.const - pub(crate) fn eval_i32_const(&self, const_instr: &tinywasm_types::ConstInstruction) -> Result<i32> { + pub(crate) fn eval_i32_const(&self, const_instr: tinywasm_types::ConstInstruction) -> Result<i32> { use tinywasm_types::ConstInstruction::*; let val = match const_instr { - I32Const(i) => *i, - GlobalGet(addr) => self.data.globals[*addr as usize].value.get().unwrap_32() as i32, + I32Const(i) => i, + GlobalGet(addr) => self.data.globals[addr as usize].value.get().unwrap_32() as i32, _ => return Err(Error::Other("expected i32".to_string())), }; Ok(val) @@ -447,7 +448,7 @@ impl Store { I64Const(i) => (*i).into(), GlobalGet(addr) => { let addr = module_global_addrs.get(*addr as usize).ok_or_else(|| { - Error::Other(format!("global {} not found. This should have been caught by the validator", addr)) + Error::Other(format!("global {addr} not found. This should have been caught by the validator")) })?; let global = @@ -456,7 +457,7 @@ impl Store { } RefNull(t) => t.default_value().into(), RefFunc(idx) => TinyWasmValue::ValueRef(Some(*module_func_addrs.get(*idx as usize).ok_or_else(|| { - Error::Other(format!("function {} not found. This should have been caught by the validator", idx)) + Error::Other(format!("function {idx} not found. This should have been caught by the validator")) })?)), }; Ok(val) diff --git a/crates/tinywasm/src/store/table.rs b/crates/tinywasm/src/store/table.rs index 4dee122..02225d8 100644 --- a/crates/tinywasm/src/store/table.rs +++ b/crates/tinywasm/src/store/table.rs @@ -3,7 +3,7 @@ use crate::{Error, Result, Trap}; use alloc::{vec, vec::Vec}; use tinywasm_types::*; -const MAX_TABLE_SIZE: u32 = 10000000; +const MAX_TABLE_SIZE: u32 = 10_000_000; /// A WebAssembly Table Instance /// @@ -30,8 +30,8 @@ impl TableInstance { let val = self.get(addr)?.addr(); Ok(match self.kind.element_type { - ValType::RefFunc => val.map(WasmValue::RefFunc).unwrap_or(WasmValue::RefNull(ValType::RefFunc)), - ValType::RefExtern => val.map(WasmValue::RefExtern).unwrap_or(WasmValue::RefNull(ValType::RefExtern)), + ValType::RefFunc => val.map_or(WasmValue::RefNull(ValType::RefFunc), WasmValue::RefFunc), + ValType::RefExtern => val.map_or(WasmValue::RefNull(ValType::RefExtern), WasmValue::RefExtern), _ => Err(Error::UnsupportedFeature("non-ref table".into()))?, }) } diff --git a/crates/tinywasm/tests/test-mvp.rs b/crates/tinywasm/tests/test-mvp.rs index 445b7fa..0e5b7dd 100644 --- a/crates/tinywasm/tests/test-mvp.rs +++ b/crates/tinywasm/tests/test-mvp.rs @@ -23,7 +23,7 @@ fn test_mvp() -> Result<()> { println!(); Err(eyre!(format!("{}:\n{:#?}", "failed one or more tests".red().bold(), test_suite,))) } else { - println!("\n\npassed all tests:\n{:#?}", test_suite); + println!("\n\npassed all tests:\n{test_suite:#?}"); Ok(()) } } diff --git a/crates/tinywasm/tests/test-two.rs b/crates/tinywasm/tests/test-two.rs index e710d1a..cb974ef 100644 --- a/crates/tinywasm/tests/test-two.rs +++ b/crates/tinywasm/tests/test-two.rs @@ -23,7 +23,7 @@ fn test_2() -> Result<()> { println!(); Err(eyre!(format!("{}:\n{:#?}", "failed one or more tests".red().bold(), test_suite,))) } else { - println!("\n\npassed all tests:\n{:#?}", test_suite); + println!("\n\npassed all tests:\n{test_suite:#?}"); Ok(()) } } diff --git a/crates/tinywasm/tests/test-wast.rs b/crates/tinywasm/tests/test-wast.rs index 1d3fbe3..98302f9 100644 --- a/crates/tinywasm/tests/test-wast.rs +++ b/crates/tinywasm/tests/test-wast.rs @@ -33,10 +33,10 @@ fn test_wast(wast_file: &str) -> Result<()> { TestSuite::set_log_level(log::LevelFilter::Debug); let args = std::env::args().collect::<Vec<_>>(); - println!("args: {:?}", args); + println!("args: {args:?}"); let mut test_suite = TestSuite::new(); - println!("running wast file: {}", wast_file); + println!("running wast file: {wast_file}"); test_suite.run_paths(&[wast_file])?; @@ -46,7 +46,7 @@ fn test_wast(wast_file: &str) -> Result<()> { println!(); Err(eyre!(format!("{}:\n{:#?}", "failed one or more tests".red().bold(), test_suite,))) } else { - println!("\n\npassed all tests:\n{:#?}", test_suite); + println!("\n\npassed all tests:\n{test_suite:#?}"); Ok(()) } } diff --git a/crates/tinywasm/tests/testsuite/mod.rs b/crates/tinywasm/tests/testsuite/mod.rs index 350a1b9..b9cf233 100644 --- a/crates/tinywasm/tests/testsuite/mod.rs +++ b/crates/tinywasm/tests/testsuite/mod.rs @@ -30,7 +30,7 @@ pub struct TestSuite(BTreeMap<String, TestGroup>, Vec<String>); impl TestSuite { pub fn skip(&mut self, groups: &[&str]) { - self.1.extend(groups.iter().map(|s| s.to_string())); + self.1.extend(groups.iter().map(|s| (*s).to_string())); } pub fn set_log_level(level: log::LevelFilter) { @@ -89,7 +89,7 @@ impl TestSuite { let mut failed = 0; let mut groups = Vec::new(); - for (name, group) in self.0.iter() { + for (name, group) in &self.0 { let (group_passed, group_failed) = group.stats(); passed += group_passed; failed += group_failed; @@ -98,7 +98,7 @@ impl TestSuite { } let groups = serde_json::to_string(&groups)?; - let line = format!("{},{},{},{}\n", version, passed, failed, groups); + let line = format!("{version},{passed},{failed},{groups}\n"); file.write_all(line.as_bytes()).expect("failed to write to csv file"); Ok(()) @@ -108,10 +108,10 @@ impl TestSuite { fn link(name: &str, file: &str, line: Option<usize>) -> String { let (path, name) = match line { None => (file.to_string(), name.to_owned()), - Some(line) => (format!("{}:{}:0", file, line), (format!("{}:{}", name, line))), + Some(line) => (format!("{file}:{line}:0"), (format!("{name}:{line}"))), }; - format!("\x1b]8;;file://{}\x1b\\{}\x1b]8;;\x1b\\", path, name) + format!("\x1b]8;;file://{path}\x1b\\{name}\x1b]8;;\x1b\\") } impl Debug for TestSuite { diff --git a/crates/tinywasm/tests/testsuite/run.rs b/crates/tinywasm/tests/testsuite/run.rs index 0c5f3ff..0086b4b 100644 --- a/crates/tinywasm/tests/testsuite/run.rs +++ b/crates/tinywasm/tests/testsuite/run.rs @@ -1,4 +1,3 @@ -/// Here be dragons (this file is in need of a big refactor) use crate::testsuite::util::*; use std::{borrow::Cow, collections::HashMap}; @@ -71,11 +70,11 @@ impl RegisteredModules { impl TestSuite { pub fn run_paths(&mut self, tests: &[&str]) -> Result<()> { - tests.iter().for_each(|group| { + for group in tests { let group_wast = std::fs::read(group).expect("failed to read test wast"); let group_wast = Cow::Owned(group_wast); self.run_group(group, group_wast).expect("failed to run group"); - }); + } Ok(()) } @@ -86,7 +85,7 @@ impl TestSuite { let table = Extern::table(TableType::new(ValType::RefFunc, 10, Some(20)), WasmValue::default_for(ValType::RefFunc)); - let print = Extern::typed_func(|_ctx: tinywasm::FuncContext, _: ()| { + let print = Extern::typed_func(|_ctx: tinywasm::FuncContext, (): ()| { log::debug!("print"); Ok(()) }); @@ -147,9 +146,9 @@ impl TestSuite { pub fn run_spec_group(&mut self, tests: &[&str]) -> Result<()> { tests.iter().for_each(|group| { let group_wast = wasm_testsuite::get_test_wast(group).expect("failed to get test wast"); - if self.1.contains(&group.to_string()) { + if self.1.contains(&(*group).to_string()) { info!("skipping group: {}", group); - self.test_group(&format!("{} (skipped)", group), group); + self.test_group(&format!("{group} (skipped)"), group); return; } @@ -177,20 +176,23 @@ impl TestSuite { println!("running {} tests for group: {}", wast_data.directives.len(), group_name); for (i, directive) in wast_data.directives.into_iter().enumerate() { let span = directive.span(); - use wast::WastDirective::*; + use wast::WastDirective::{ + AssertExhaustion, AssertInvalid, AssertMalformed, AssertReturn, AssertTrap, AssertUnlinkable, Invoke, + Register, Wat, + }; match directive { Register { span, name, .. } => { let Some(last) = registered_modules.last(&store) else { test_group.add_result( - &format!("Register({})", i), + &format!("Register({i})"), span.linecol_in(wast), Err(eyre!("no module to register")), ); continue; }; registered_modules.register(name.to_string(), last.id()); - test_group.add_result(&format!("Register({})", i), span.linecol_in(wast), Ok(())); + test_group.add_result(&format!("Register({i})"), span.linecol_in(wast), Ok(())); } Wat(module) => { @@ -212,12 +214,12 @@ impl TestSuite { Ok((name, module)) => registered_modules.update_last_module(module.id(), name.clone()), }; - test_group.add_result(&format!("Wat({})", i), span.linecol_in(wast), result.map(|_| ())); + test_group.add_result(&format!("Wat({i})"), span.linecol_in(wast), result.map(|_| ())); } AssertMalformed { span, mut module, message } => { let Ok(module) = module.encode() else { - test_group.add_result(&format!("AssertMalformed({})", i), span.linecol_in(wast), Ok(())); + test_group.add_result(&format!("AssertMalformed({i})"), span.linecol_in(wast), Ok(())); continue; }; @@ -226,7 +228,7 @@ impl TestSuite { .and_then(|res| res); test_group.add_result( - &format!("AssertMalformed({})", i), + &format!("AssertMalformed({i})"), span.linecol_in(wast), match res { Ok(_) => { @@ -249,7 +251,7 @@ impl TestSuite { .and_then(|res| res); test_group.add_result( - &format!("AssertInvalid({})", i), + &format!("AssertInvalid({i})"), span.linecol_in(wast), match res { Ok(_) => Err(eyre!("expected module to be invalid")), @@ -266,7 +268,7 @@ impl TestSuite { let Ok(Err(tinywasm::Error::Trap(trap))) = res else { test_group.add_result( - &format!("AssertExhaustion({})", i), + &format!("AssertExhaustion({i})"), span.linecol_in(wast), Err(eyre!("expected trap")), ); @@ -275,14 +277,14 @@ impl TestSuite { if !message.starts_with(trap.message()) { test_group.add_result( - &format!("AssertExhaustion({})", i), + &format!("AssertExhaustion({i})"), span.linecol_in(wast), Err(eyre!("expected trap: {}, got: {}", message, trap.message())), ); continue; } - test_group.add_result(&format!("AssertExhaustion({})", i), span.linecol_in(wast), Ok(())); + test_group.add_result(&format!("AssertExhaustion({i})"), span.linecol_in(wast), Ok(())); } AssertTrap { exec, message, span } => { @@ -311,29 +313,29 @@ impl TestSuite { match res { Err(err) => test_group.add_result( - &format!("AssertTrap({})", i), + &format!("AssertTrap({i})"), span.linecol_in(wast), Err(eyre!("test panicked: {:?}", try_downcast_panic(err))), ), Ok(Err(tinywasm::Error::Trap(trap))) => { if !message.starts_with(trap.message()) { test_group.add_result( - &format!("AssertTrap({})", i), + &format!("AssertTrap({i})"), span.linecol_in(wast), Err(eyre!("expected trap: {}, got: {}", message, trap.message())), ); continue; } - test_group.add_result(&format!("AssertTrap({})", i), span.linecol_in(wast), Ok(())) + test_group.add_result(&format!("AssertTrap({i})"), span.linecol_in(wast), Ok(())); } Ok(Err(err)) => test_group.add_result( - &format!("AssertTrap({})", i), + &format!("AssertTrap({i})"), span.linecol_in(wast), Err(eyre!("expected trap, {}, got: {:?}", message, err)), ), Ok(Ok(())) => test_group.add_result( - &format!("AssertTrap({})", i), + &format!("AssertTrap({i})"), span.linecol_in(wast), Err(eyre!("expected trap {}, got Ok", message)), ), @@ -350,29 +352,29 @@ impl TestSuite { match res { Err(err) => test_group.add_result( - &format!("AssertUnlinkable({})", i), + &format!("AssertUnlinkable({i})"), span.linecol_in(wast), Err(eyre!("test panicked: {:?}", try_downcast_panic(err))), ), Ok(Err(tinywasm::Error::Linker(err))) => { if err.message() != message { test_group.add_result( - &format!("AssertUnlinkable({})", i), + &format!("AssertUnlinkable({i})"), span.linecol_in(wast), Err(eyre!("expected linker error: {}, got: {}", message, err.message())), ); continue; } - test_group.add_result(&format!("AssertUnlinkable({})", i), span.linecol_in(wast), Ok(())) + test_group.add_result(&format!("AssertUnlinkable({i})"), span.linecol_in(wast), Ok(())); } Ok(Err(err)) => test_group.add_result( - &format!("AssertUnlinkable({})", i), + &format!("AssertUnlinkable({i})"), span.linecol_in(wast), Err(eyre!("expected linker error, {}, got: {:?}", message, err)), ), Ok(Ok(_)) => test_group.add_result( - &format!("AssertUnlinkable({})", i), + &format!("AssertUnlinkable({i})"), span.linecol_in(wast), Err(eyre!("expected linker error {}, got Ok", message)), ), @@ -393,7 +395,7 @@ impl TestSuite { }); let res = res.map_err(|e| eyre!("test panicked: {:?}", try_downcast_panic(e))).and_then(|r| r); - test_group.add_result(&format!("Invoke({}-{})", name, i), span.linecol_in(wast), res); + test_group.add_result(&format!("Invoke({name}-{i})"), span.linecol_in(wast), res); } AssertReturn { span, exec, results } => { @@ -406,7 +408,7 @@ impl TestSuite { let module = registered_modules.get(module_id, &store); let Some(module) = module else { test_group.add_result( - &format!("AssertReturn(unsupported-{})", i), + &format!("AssertReturn(unsupported-{i})"), span.linecol_in(wast), Err(eyre!("no module to get global from")), ); @@ -414,13 +416,13 @@ impl TestSuite { }; let module_global = match match module.export_addr(global) { - Some(ExternVal::Global(addr)) => Ok(store.get_global_val(&addr)), + Some(ExternVal::Global(addr)) => Ok(store.get_global_val(addr)), _ => Err(eyre!("no module to get global from")), } { Ok(module_global) => module_global, Err(err) => { test_group.add_result( - &format!("AssertReturn(unsupported-{})", i), + &format!("AssertReturn(unsupported-{i})"), span.linecol_in(wast), Err(eyre!("failed to get global: {:?}", err)), ); @@ -432,7 +434,7 @@ impl TestSuite { if !module_global.eq_loose(expected) { test_group.add_result( - &format!("AssertReturn(unsupported-{})", i), + &format!("AssertReturn(unsupported-{i})"), span.linecol_in(wast), Err(eyre!("global value did not match: {:?} != {:?}", module_global, expected)), ); @@ -440,7 +442,7 @@ impl TestSuite { } test_group.add_result( - &format!("AssertReturn({}-{})", global, i), + &format!("AssertReturn({global}-{i})"), span.linecol_in(wast), Ok(()), ); @@ -453,7 +455,7 @@ impl TestSuite { Ok(invoke) => invoke, Err(err) => { test_group.add_result( - &format!("AssertReturn(unsupported-{})", i), + &format!("AssertReturn(unsupported-{i})"), span.linecol_in(wast), Err(eyre!("unsupported directive: {:?}", err)), ); @@ -488,10 +490,10 @@ impl TestSuite { }); let res = res.map_err(|e| eyre!("test panicked: {:?}", try_downcast_panic(e))).and_then(|r| r); - test_group.add_result(&format!("AssertReturn({}-{})", invoke_name, i), span.linecol_in(wast), res); + test_group.add_result(&format!("AssertReturn({invoke_name}-{i})"), span.linecol_in(wast), res); } _ => test_group.add_result( - &format!("Unknown({})", i), + &format!("Unknown({i})"), span.linecol_in(wast), Err(eyre!("unsupported directive")), ), diff --git a/crates/tinywasm/tests/testsuite/util.rs b/crates/tinywasm/tests/testsuite/util.rs index c54dfc1..e238f72 100644 --- a/crates/tinywasm/tests/testsuite/util.rs +++ b/crates/tinywasm/tests/testsuite/util.rs @@ -5,7 +5,7 @@ use tinywasm_types::{ModuleInstanceAddr, TinyWasmModule, ValType, WasmValue}; use wast::{core::AbstractHeapType, QuoteWat}; pub fn try_downcast_panic(panic: Box<dyn std::any::Any + Send>) -> String { - let info = panic.downcast_ref::<panic::PanicHookInfo>().or(None).map(|p| p.to_string()).clone(); + let info = panic.downcast_ref::<panic::PanicHookInfo>().or(None).map(ToString::to_string).clone(); let info_string = panic.downcast_ref::<String>().cloned(); let info_str = panic.downcast::<&str>().ok().map(|s| *s); @@ -96,7 +96,7 @@ fn wastarg2tinywasmvalue(arg: wast::WastArg) -> Result<tinywasm_types::WasmValue return Err(eyre!("unsupported arg type: Component")); }; - use wast::core::WastArgCore::*; + use wast::core::WastArgCore::{RefExtern, RefNull, F32, F64, I32, I64}; Ok(match arg { F32(f) => WasmValue::F32(f32::from_bits(f.bits)), F64(f) => WasmValue::F64(f64::from_bits(f.bits)), @@ -121,7 +121,7 @@ fn wastret2tinywasmvalue(ret: wast::WastRet) -> Result<tinywasm_types::WasmValue return Err(eyre!("unsupported arg type")); }; - use wast::core::WastRetCore::*; + use wast::core::WastRetCore::{RefExtern, RefFunc, RefNull, F32, F64, I32, I64}; Ok(match ret { F32(f) => nanpattern2tinywasmvalue(f)?, F64(f) => nanpattern2tinywasmvalue(f)?, @@ -194,7 +194,7 @@ fn nanpattern2tinywasmvalue<T>(arg: wast::core::NanPattern<T>) -> Result<tinywas where T: FloatToken, { - use wast::core::NanPattern::*; + use wast::core::NanPattern::{ArithmeticNan, CanonicalNan, Value}; Ok(match arg { CanonicalNan => T::canonical_nan(), ArithmeticNan => T::arithmetic_nan(), diff --git a/crates/types/src/archive.rs b/crates/types/src/archive.rs index 0a57f4c..398b616 100644 --- a/crates/types/src/archive.rs +++ b/crates/types/src/archive.rs @@ -54,16 +54,16 @@ extern crate std; impl std::error::Error for TwasmError {} impl TinyWasmModule { - /// Creates a TinyWasmModule from a slice of bytes. + /// Creates a `TinyWasmModule` from a slice of bytes. pub fn from_twasm(wasm: &[u8]) -> Result<TinyWasmModule, TwasmError> { let len = validate_magic(wasm)?; let root = check_archived_root::<Self>(&wasm[len..]).map_err(|_e| TwasmError::InvalidArchive)?; Ok(root.deserialize(&mut rkyv::Infallible).unwrap()) } - /// Serializes the TinyWasmModule into a vector of bytes. - /// AlignedVec can be deferenced as a slice of bytes and - /// implements io::Write when the `std` feature is enabled. + /// Serializes the `TinyWasmModule` into a vector of bytes. + /// `AlignedVec` can be deferenced as a slice of bytes and + /// implements `io::Write` when the `std` feature is enabled. pub fn serialize_twasm(&self) -> rkyv::AlignedVec { let mut serializer = AllocSerializer::<0>::default(); serializer.pad(TWASM_MAGIC.len()).unwrap(); diff --git a/crates/types/src/lib.rs b/crates/types/src/lib.rs index a4029e2..94dc94d 100644 --- a/crates/types/src/lib.rs +++ b/crates/types/src/lib.rs @@ -37,11 +37,11 @@ pub use value::*; #[cfg(feature = "archive")] pub mod archive; -/// A TinyWasm WebAssembly Module +/// A `TinyWasm` WebAssembly Module /// -/// This is the internal representation of a WebAssembly module in TinyWasm. -/// TinyWasmModules are validated before being created, so they are guaranteed to be valid (as long as they were created by TinyWasm). -/// This means you should not trust a TinyWasmModule created by a third party to be valid. +/// This is the internal representation of a WebAssembly module in `TinyWasm`. +/// `TinyWasmModules` are validated before being created, so they are guaranteed to be valid (as long as they were created by `TinyWasm`). +/// This means you should not trust a `TinyWasmModule` created by a third party to be valid. #[derive(Debug, Clone, Default, PartialEq)] #[cfg_attr(feature = "archive", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize), archive(check_bytes))] pub struct TinyWasmModule { diff --git a/crates/types/src/value.rs b/crates/types/src/value.rs index c418338..416f678 100644 --- a/crates/types/src/value.rs +++ b/crates/types/src/value.rs @@ -87,14 +87,14 @@ fn cold() {} impl Debug for WasmValue { fn fmt(&self, f: &mut alloc::fmt::Formatter<'_>) -> alloc::fmt::Result { match self { - WasmValue::I32(i) => write!(f, "i32({})", i), - WasmValue::I64(i) => write!(f, "i64({})", i), - WasmValue::F32(i) => write!(f, "f32({})", i), - WasmValue::F64(i) => write!(f, "f64({})", i), - WasmValue::V128(i) => write!(f, "v128({:?})", i), - WasmValue::RefExtern(addr) => write!(f, "ref.extern({:?})", addr), - WasmValue::RefFunc(addr) => write!(f, "ref.func({:?})", addr), - WasmValue::RefNull(ty) => write!(f, "ref.null({:?})", ty), + WasmValue::I32(i) => write!(f, "i32({i})"), + WasmValue::I64(i) => write!(f, "i64({i})"), + WasmValue::F32(i) => write!(f, "f32({i})"), + WasmValue::F64(i) => write!(f, "f64({i})"), + WasmValue::V128(i) => write!(f, "v128({i:?})"), + WasmValue::RefExtern(addr) => write!(f, "ref.extern({addr:?})"), + WasmValue::RefFunc(addr) => write!(f, "ref.func({addr:?})"), + WasmValue::RefNull(ty) => write!(f, "ref.null({ty:?})"), } } } diff --git a/crates/wasm-testsuite/lib.rs b/crates/wasm-testsuite/lib.rs index 466f7d2..93f750c 100644 --- a/crates/wasm-testsuite/lib.rs +++ b/crates/wasm-testsuite/lib.rs @@ -66,12 +66,10 @@ pub fn get_tests(include_proposals: &[String]) -> impl Iterator<Item = String> { /// Get the WAST file as a byte slice. pub fn get_test_wast(name: &str) -> Option<Cow<'static, [u8]>> { - if !name.ends_with(".wast") { - panic!("Expected .wast file. Got: {}", name); - } + assert!(name.ends_with(".wast"), "Expected .wast file. Got: {name}"); match name.contains('/') { - true => Asset::get(&format!("proposals/{}", name)).map(|x| x.data), + true => Asset::get(&format!("proposals/{name}")).map(|x| x.data), false => Asset::get(name).map(|x| x.data), } } |
