diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index baf0eebbaf..b96cb0478f 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -2,9 +2,9 @@ name: Rust - Continuous Integration on: push: - branches: [ casper-main ] + branches: [ main ] pull_request: - branches: [ casper-main ] + branches: [ main ] jobs: check: @@ -184,10 +184,10 @@ jobs: with: version: '0.18.0' args: --workspace - - name: Upload to codecov.io - uses: codecov/codecov-action@v1.0.2 - with: - token: ${{secrets.CODECOV_TOKEN}} +# - name: Upload to codecov.io +# uses: codecov/codecov-action@v1.0.2 +# with: +# token: ${{secrets.CODECOV_TOKEN}} - name: Archive code coverage results uses: actions/upload-artifact@v1 with: diff --git a/.gitignore b/.gitignore index 62707ec5c7..500f4a3fc6 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ Cargo.lock spec/target .idea +.direnv diff --git a/Cargo.toml b/Cargo.toml index 05bacdf95d..03aa1b7f7e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,6 +49,8 @@ virtual_memory = ["casper-wasmi-core/virtual_memory", "std"] reduced-stack-buffer = [ "casper-wasm/reduced-stack-buffer" ] +sign_ext = ["casper-wasm/sign_ext", "validation/sign_ext" ] + [workspace] members = ["validation", "core", "wasmi_v1", "cli"] exclude = [] diff --git a/benches/benches.rs b/benches/benches.rs index 19415820d9..60c6cdbe4b 100644 --- a/benches/benches.rs +++ b/benches/benches.rs @@ -898,7 +898,7 @@ fn bench_execute_memory_fill_v1(c: &mut Criterion) { }); assert!(mem.data(&store)[ptr..(ptr + len)] .iter() - .all(|byte| (*byte as u8) == value)); + .all(|byte| { *byte } == value)); }); } diff --git a/cli/src/main.rs b/cli/src/main.rs index 7629fdcad9..a5a83104dd 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -9,7 +9,7 @@ use casper_wasmi::{ use clap::Parser; use core::fmt::Write; use std::fs; -use wasmi_v1 as wasmi; +use wasmi_v1 as casper_wasmi; /// Simple program to greet a person #[derive(Parser, Debug)] @@ -53,7 +53,7 @@ fn main() -> Result<()> { /// Converts the given `.wat` into `.wasm`. fn wat2wasm(wat: &str) -> Result, wat::Error> { - wat::parse_str(&wat) + wat::parse_str(wat) } /// Returns the contents of the given `.wasm` or `.wat` file. @@ -63,7 +63,7 @@ fn wat2wasm(wat: &str) -> Result, wat::Error> { /// If `wasm_file` is not a valid `.wasm` or `.wat` file. fn read_wasm_or_wat(wasm_file: &str) -> Result> { let mut file_contents = - fs::read(&wasm_file).map_err(|_| anyhow!("failed to read Wasm file {wasm_file}"))?; + fs::read(wasm_file).map_err(|_| anyhow!("failed to read Wasm file {wasm_file}"))?; if wasm_file.ends_with(".wat") { let wat = String::from_utf8(file_contents) .map_err(|error| anyhow!("failed to read UTF-8 file {wasm_file}: {error}"))?; @@ -87,12 +87,12 @@ fn load_wasm_func( wasm_bytes: &[u8], func_name: &str, ) -> Result<(Func, Store<()>)> { - let engine = wasmi::Engine::default(); - let mut store = wasmi::Store::new(&engine, ()); - let module = wasmi::Module::new(&engine, &mut &wasm_bytes[..]).map_err(|error| { + let engine = casper_wasmi::Engine::default(); + let mut store = casper_wasmi::Store::new(&engine, ()); + let module = casper_wasmi::Module::new(&engine, &mut &wasm_bytes[..]).map_err(|error| { anyhow!("failed to parse and validate Wasm module {wasm_file}: {error}") })?; - let mut linker = >::new(); + let mut linker = >::new(); let instance = linker .instantiate(&mut store, &module) .and_then(|pre| pre.start(&mut store)) @@ -113,8 +113,8 @@ fn load_wasm_func( /// Returns a [`Vec`] of `(&str, FuncType)` describing the exported functions of the [`Module`]. /// -/// [`Module`]: [`wasmi::Module`] -fn exported_funcs(module: &wasmi::Module) -> Vec<(&str, FuncType)> { +/// [`Module`]: [`casper_wasmi::Module`] +fn exported_funcs(module: &casper_wasmi::Module) -> Vec<(&str, FuncType)> { module .exports() .filter_map(|export| { @@ -129,8 +129,8 @@ fn exported_funcs(module: &wasmi::Module) -> Vec<(&str, FuncType)> { /// Returns a [`String`] displaying a list of exported functions from the [`Module`]. /// -/// [`Module`]: [`wasmi::Module`] -fn display_exported_funcs(module: &wasmi::Module) -> String { +/// [`Module`]: [`casper_wasmi::Module`] +fn display_exported_funcs(module: &casper_wasmi::Module) -> String { let exported_funcs = exported_funcs(module) .into_iter() .map(|(name, func_type)| display_exported_func(name, &func_type)); @@ -241,7 +241,7 @@ fn print_execution_start(wasm_file: &str, func_name: &str, func_args: &[Value]) println!(") ..."); } -/// Prints the results of the Wasm computation in a human readable form. +/// Prints the results of the Wasm computation in a human-readable form. fn print_pretty_results(results: &[Value]) { let pretty_results = results .iter() diff --git a/core/src/value.rs b/core/src/value.rs index 6911e14b60..ee6465408c 100644 --- a/core/src/value.rs +++ b/core/src/value.rs @@ -2,7 +2,7 @@ use crate::{ nan_preserving_float::{F32, F64}, TrapCode, }; -use core::{f32, fmt, fmt::Display, i32, i64, u32, u64}; +use core::{f32, fmt, fmt::Display}; /// Type of a value. /// @@ -400,8 +400,8 @@ impl FromValue for bool { impl FromValue for i8 { #[inline] fn from_value(val: Value) -> Option { - let min = i8::min_value() as i32; - let max = i8::max_value() as i32; + let min = i8::MIN as i32; + let max = i8::MAX as i32; match val { Value::I32(val) if min <= val && val <= max => Some(val as i8), _ => None, @@ -415,8 +415,8 @@ impl FromValue for i8 { impl FromValue for i16 { #[inline] fn from_value(val: Value) -> Option { - let min = i16::min_value() as i32; - let max = i16::max_value() as i32; + let min = i16::MIN as i32; + let max = i16::MAX as i32; match val { Value::I32(val) if min <= val && val <= max => Some(val as i16), _ => None, @@ -430,8 +430,8 @@ impl FromValue for i16 { impl FromValue for u8 { #[inline] fn from_value(val: Value) -> Option { - let min = u8::min_value() as i32; - let max = u8::max_value() as i32; + let min = u8::MIN as i32; + let max = u8::MAX as i32; match val { Value::I32(val) if min <= val && val <= max => Some(val as u8), _ => None, @@ -445,8 +445,8 @@ impl FromValue for u8 { impl FromValue for u16 { #[inline] fn from_value(val: Value) -> Option { - let min = u16::min_value() as i32; - let max = u16::max_value() as i32; + let min = u16::MIN as i32; + let max = u16::MAX as i32; match val { Value::I32(val) if min <= val && val <= max => Some(val as u16), _ => None, diff --git a/core/src/vmem.rs b/core/src/vmem.rs index 7995d2a5a9..3a7a69909c 100644 --- a/core/src/vmem.rs +++ b/core/src/vmem.rs @@ -75,7 +75,7 @@ impl VirtualMemory { /// /// # Errors /// - /// - If `len` should not exceed `isize::max_value()` + /// - If `len` should not exceed `isize::MAX` /// - If `len` should be greater than 0. /// - If the operating system returns an error upon virtual memory allocation. pub fn new(len: usize) -> Result { diff --git a/examples/tictactoe.rs b/examples/tictactoe.rs index dfafd2a651..b398a47e32 100644 --- a/examples/tictactoe.rs +++ b/examples/tictactoe.rs @@ -79,7 +79,7 @@ mod tictactoe { if !(0..9).contains(&idx) { return Err(Error::OutOfRange); } - if self.board[idx as usize] != None { + if self.board[idx as usize].is_some() { return Err(Error::AlreadyOccupied); } self.board[idx as usize] = Some(player); diff --git a/src/isa.rs b/src/isa.rs index 7481f7a3a9..d500ade69f 100644 --- a/src/isa.rs +++ b/src/isa.rs @@ -338,6 +338,17 @@ pub enum Instruction<'a> { I64ReinterpretF64, F32ReinterpretI32, F64ReinterpretI64, + + #[cfg(feature = "sign_ext")] + I32Extend8S, + #[cfg(feature = "sign_ext")] + I32Extend16S, + #[cfg(feature = "sign_ext")] + I64Extend8S, + #[cfg(feature = "sign_ext")] + I64Extend16S, + #[cfg(feature = "sign_ext")] + I64Extend32S, } /// The internally-stored instruction type. This differs from `Instruction` in that the `BrTable` @@ -356,7 +367,9 @@ pub(crate) enum InstructionInternal { Br(Target), BrIfEqz(Target), BrIfNez(Target), - BrTable { count: u32 }, + BrTable { + count: u32, + }, BrTableTarget(Target), Unreachable, @@ -533,6 +546,17 @@ pub(crate) enum InstructionInternal { I64ReinterpretF64, F32ReinterpretI32, F64ReinterpretI64, + + #[cfg(feature = "sign_ext")] + I32Extend8S, + #[cfg(feature = "sign_ext")] + I32Extend16S, + #[cfg(feature = "sign_ext")] + I64Extend8S, + #[cfg(feature = "sign_ext")] + I64Extend16S, + #[cfg(feature = "sign_ext")] + I64Extend32S, } #[derive(Debug, Clone)] @@ -789,6 +813,17 @@ impl<'a> Iterator for InstructionIter<'a> { InstructionInternal::I64ReinterpretF64 => Instruction::I64ReinterpretF64, InstructionInternal::F32ReinterpretI32 => Instruction::F32ReinterpretI32, InstructionInternal::F64ReinterpretI64 => Instruction::F64ReinterpretI64, + + #[cfg(feature = "sign_ext")] + InstructionInternal::I32Extend8S => Instruction::I32Extend8S, + #[cfg(feature = "sign_ext")] + InstructionInternal::I32Extend16S => Instruction::I32Extend16S, + #[cfg(feature = "sign_ext")] + InstructionInternal::I64Extend8S => Instruction::I64Extend8S, + #[cfg(feature = "sign_ext")] + InstructionInternal::I64Extend16S => Instruction::I64Extend16S, + #[cfg(feature = "sign_ext")] + InstructionInternal::I64Extend32S => Instruction::I64Extend32S, }; self.position += 1; diff --git a/src/lib.rs b/src/lib.rs index 0e5ad574c7..894abcf91e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -303,8 +303,6 @@ pub(crate) mod value { LittleEndianConvert, TransmuteInto, TryTruncateInto, - Value as RuntimeValue, - ValueType, WrapInto, }; } diff --git a/src/memory/mmap_bytebuf.rs b/src/memory/mmap_bytebuf.rs index 0c092e82f6..6118b9fa49 100644 --- a/src/memory/mmap_bytebuf.rs +++ b/src/memory/mmap_bytebuf.rs @@ -28,8 +28,8 @@ impl ByteBuf { /// Creates a new byte buffer with the given initial length. pub fn new(len: usize) -> Result { - if len > isize::max_value() as usize { - return Err("`len` should not exceed `isize::max_value()`".into()); + if len > isize::MAX as usize { + return Err("`len` should not exceed `isize::MAX`".into()); } let mem = VirtualMemory::new(Self::ALLOCATION_SIZE).map_err(|error| error.to_string())?; Ok(Self { mem, len }) diff --git a/src/memory/mod.rs b/src/memory/mod.rs index 9f85a14f78..be2a03d72c 100644 --- a/src/memory/mod.rs +++ b/src/memory/mod.rs @@ -10,7 +10,6 @@ use core::{ cmp, fmt, ops::Range, - u32, }; #[cfg(all(feature = "virtual_memory", target_pointer_width = "64"))] diff --git a/src/module.rs b/src/module.rs index 4539c964c2..93a3fae00b 100644 --- a/src/module.rs +++ b/src/module.rs @@ -241,7 +241,7 @@ impl ModuleInstance { let module = loaded_module.module(); let instance = ModuleRef(Rc::new(ModuleInstance::default())); - for &Type::Function(ref ty) in module.type_section().map(|ts| ts.types()).unwrap_or(&[]) { + for Type::Function(ty) in module.type_section().map(|ts| ts.types()).unwrap_or(&[]) { let signature = Rc::new(Signature::from_elements(ty)); instance.push_signature(signature); } @@ -268,7 +268,7 @@ impl ModuleInstance { }; match (import.external(), extern_val) { - (&External::Function(fn_type_idx), &ExternVal::Func(ref func)) => { + (&External::Function(fn_type_idx), ExternVal::Func(func)) => { let expected_fn_type = instance .signature_by_index(fn_type_idx) .expect("Due to validation function type should exists"); @@ -283,15 +283,15 @@ impl ModuleInstance { } instance.push_func(func.clone()) } - (&External::Table(ref tt), &ExternVal::Table(ref table)) => { + (External::Table(tt), ExternVal::Table(table)) => { match_limits(table.limits(), tt.limits())?; instance.push_table(table.clone()); } - (&External::Memory(ref mt), &ExternVal::Memory(ref memory)) => { + (External::Memory(mt), ExternVal::Memory(memory)) => { match_limits(memory.limits(), mt.limits())?; instance.push_memory(memory.clone()); } - (&External::Global(ref gl), &ExternVal::Global(ref global)) => { + (External::Global(gl), ExternVal::Global(global)) => { if gl.content_type() != global.elements_value_type() { return Err(Error::Instantiation(format!( "Expect global with {:?} type, but provided global with {:?} type", @@ -554,7 +554,7 @@ impl ModuleInstance { let extern_val = match *import_entry.external() { External::Function(fn_ty_idx) => { let types = module.type_section().map(|s| s.types()).unwrap_or(&[]); - let &Type::Function(ref func_type) = types + let Type::Function(func_type) = types .get(fn_ty_idx as usize) .expect("Due to validation functions should have valid types"); let signature = Signature::from_elements(func_type); diff --git a/src/prepare/compile.rs b/src/prepare/compile.rs index 42d6b54fe9..8fec469111 100644 --- a/src/prepare/compile.rs +++ b/src/prepare/compile.rs @@ -1,5 +1,7 @@ use alloc::{string::String, vec::Vec}; +#[cfg(feature = "sign_ext")] +use casper_wasm::elements::SignExtInstruction; use casper_wasm::elements::{BlockType, FuncBody, Instruction}; use crate::isa; @@ -111,7 +113,7 @@ impl Compiler { ) -> Result<(), Error> { use self::Instruction::*; - match *instruction { + match instruction { Unreachable => { self.sink.emit(isa::InstructionInternal::Unreachable); context.step(instruction)?; @@ -226,7 +228,7 @@ impl Compiler { } Br(depth) => { let target = require_target( - depth, + *depth, context.value_stack.len(), &context.frame_stack, &self.label_stack, @@ -246,7 +248,7 @@ impl Compiler { context.step(instruction)?; let target = require_target( - depth, + *depth, context.value_stack.len(), &context.frame_stack, &self.label_stack, @@ -312,12 +314,12 @@ impl Compiler { } Call(index) => { context.step(instruction)?; - self.sink.emit(isa::InstructionInternal::Call(index)); + self.sink.emit(isa::InstructionInternal::Call(*index)); } CallIndirect(index, _reserved) => { context.step(instruction)?; self.sink - .emit(isa::InstructionInternal::CallIndirect(index)); + .emit(isa::InstructionInternal::CallIndirect(*index)); } Drop => { @@ -332,121 +334,130 @@ impl Compiler { GetLocal(index) => { // We need to calculate relative depth before validation since // it will change the value stack size. - let depth = relative_local_depth(index, &context.locals, &context.value_stack)?; + let depth = relative_local_depth(*index, &context.locals, &context.value_stack)?; context.step(instruction)?; self.sink.emit(isa::InstructionInternal::GetLocal(depth)); } SetLocal(index) => { context.step(instruction)?; - let depth = relative_local_depth(index, &context.locals, &context.value_stack)?; + let depth = relative_local_depth(*index, &context.locals, &context.value_stack)?; self.sink.emit(isa::InstructionInternal::SetLocal(depth)); } TeeLocal(index) => { context.step(instruction)?; - let depth = relative_local_depth(index, &context.locals, &context.value_stack)?; + let depth = relative_local_depth(*index, &context.locals, &context.value_stack)?; self.sink.emit(isa::InstructionInternal::TeeLocal(depth)); } GetGlobal(index) => { context.step(instruction)?; - self.sink.emit(isa::InstructionInternal::GetGlobal(index)); + self.sink.emit(isa::InstructionInternal::GetGlobal(*index)); } SetGlobal(index) => { context.step(instruction)?; - self.sink.emit(isa::InstructionInternal::SetGlobal(index)); + self.sink.emit(isa::InstructionInternal::SetGlobal(*index)); } I32Load(_, offset) => { context.step(instruction)?; - self.sink.emit(isa::InstructionInternal::I32Load(offset)); + self.sink.emit(isa::InstructionInternal::I32Load(*offset)); } I64Load(_, offset) => { context.step(instruction)?; - self.sink.emit(isa::InstructionInternal::I64Load(offset)); + self.sink.emit(isa::InstructionInternal::I64Load(*offset)); } F32Load(_, offset) => { context.step(instruction)?; - self.sink.emit(isa::InstructionInternal::F32Load(offset)); + self.sink.emit(isa::InstructionInternal::F32Load(*offset)); } F64Load(_, offset) => { context.step(instruction)?; - self.sink.emit(isa::InstructionInternal::F64Load(offset)); + self.sink.emit(isa::InstructionInternal::F64Load(*offset)); } I32Load8S(_, offset) => { context.step(instruction)?; - self.sink.emit(isa::InstructionInternal::I32Load8S(offset)); + self.sink.emit(isa::InstructionInternal::I32Load8S(*offset)); } I32Load8U(_, offset) => { context.step(instruction)?; - self.sink.emit(isa::InstructionInternal::I32Load8U(offset)); + self.sink.emit(isa::InstructionInternal::I32Load8U(*offset)); } I32Load16S(_, offset) => { context.step(instruction)?; - self.sink.emit(isa::InstructionInternal::I32Load16S(offset)); + self.sink + .emit(isa::InstructionInternal::I32Load16S(*offset)); } I32Load16U(_, offset) => { context.step(instruction)?; - self.sink.emit(isa::InstructionInternal::I32Load16U(offset)); + self.sink + .emit(isa::InstructionInternal::I32Load16U(*offset)); } I64Load8S(_, offset) => { context.step(instruction)?; - self.sink.emit(isa::InstructionInternal::I64Load8S(offset)); + self.sink.emit(isa::InstructionInternal::I64Load8S(*offset)); } I64Load8U(_, offset) => { context.step(instruction)?; - self.sink.emit(isa::InstructionInternal::I64Load8U(offset)); + self.sink.emit(isa::InstructionInternal::I64Load8U(*offset)); } I64Load16S(_, offset) => { context.step(instruction)?; - self.sink.emit(isa::InstructionInternal::I64Load16S(offset)); + self.sink + .emit(isa::InstructionInternal::I64Load16S(*offset)); } I64Load16U(_, offset) => { context.step(instruction)?; - self.sink.emit(isa::InstructionInternal::I64Load16U(offset)); + self.sink + .emit(isa::InstructionInternal::I64Load16U(*offset)); } I64Load32S(_, offset) => { context.step(instruction)?; - self.sink.emit(isa::InstructionInternal::I64Load32S(offset)); + self.sink + .emit(isa::InstructionInternal::I64Load32S(*offset)); } I64Load32U(_, offset) => { context.step(instruction)?; - self.sink.emit(isa::InstructionInternal::I64Load32U(offset)); + self.sink + .emit(isa::InstructionInternal::I64Load32U(*offset)); } I32Store(_, offset) => { context.step(instruction)?; - self.sink.emit(isa::InstructionInternal::I32Store(offset)); + self.sink.emit(isa::InstructionInternal::I32Store(*offset)); } I64Store(_, offset) => { context.step(instruction)?; - self.sink.emit(isa::InstructionInternal::I64Store(offset)); + self.sink.emit(isa::InstructionInternal::I64Store(*offset)); } F32Store(_, offset) => { context.step(instruction)?; - self.sink.emit(isa::InstructionInternal::F32Store(offset)); + self.sink.emit(isa::InstructionInternal::F32Store(*offset)); } F64Store(_, offset) => { context.step(instruction)?; - self.sink.emit(isa::InstructionInternal::F64Store(offset)); + self.sink.emit(isa::InstructionInternal::F64Store(*offset)); } I32Store8(_, offset) => { context.step(instruction)?; - self.sink.emit(isa::InstructionInternal::I32Store8(offset)); + self.sink.emit(isa::InstructionInternal::I32Store8(*offset)); } I32Store16(_, offset) => { context.step(instruction)?; - self.sink.emit(isa::InstructionInternal::I32Store16(offset)); + self.sink + .emit(isa::InstructionInternal::I32Store16(*offset)); } I64Store8(_, offset) => { context.step(instruction)?; - self.sink.emit(isa::InstructionInternal::I64Store8(offset)); + self.sink.emit(isa::InstructionInternal::I64Store8(*offset)); } I64Store16(_, offset) => { context.step(instruction)?; - self.sink.emit(isa::InstructionInternal::I64Store16(offset)); + self.sink + .emit(isa::InstructionInternal::I64Store16(*offset)); } I64Store32(_, offset) => { context.step(instruction)?; - self.sink.emit(isa::InstructionInternal::I64Store32(offset)); + self.sink + .emit(isa::InstructionInternal::I64Store32(*offset)); } CurrentMemory(_) => { @@ -460,19 +471,19 @@ impl Compiler { I32Const(v) => { context.step(instruction)?; - self.sink.emit(isa::InstructionInternal::I32Const(v)); + self.sink.emit(isa::InstructionInternal::I32Const(*v)); } I64Const(v) => { context.step(instruction)?; - self.sink.emit(isa::InstructionInternal::I64Const(v)); + self.sink.emit(isa::InstructionInternal::I64Const(*v)); } F32Const(v) => { context.step(instruction)?; - self.sink.emit(isa::InstructionInternal::F32Const(v)); + self.sink.emit(isa::InstructionInternal::F32Const(*v)); } F64Const(v) => { context.step(instruction)?; - self.sink.emit(isa::InstructionInternal::F64Const(v)); + self.sink.emit(isa::InstructionInternal::F64Const(*v)); } I32Eqz => { @@ -976,6 +987,31 @@ impl Compiler { context.step(instruction)?; self.sink.emit(isa::InstructionInternal::F64ReinterpretI64); } + + #[cfg(feature = "sign_ext")] + SignExt(sign_ext_instruction) => match sign_ext_instruction { + SignExtInstruction::I32Extend8S => { + context.step(instruction)?; + self.sink.emit(isa::InstructionInternal::I32Extend8S); + } + SignExtInstruction::I32Extend16S => { + context.step(instruction)?; + self.sink.emit(isa::InstructionInternal::I32Extend16S); + } + SignExtInstruction::I64Extend8S => { + context.step(instruction)?; + self.sink.emit(isa::InstructionInternal::I64Extend8S); + } + SignExtInstruction::I64Extend16S => { + context.step(instruction)?; + self.sink.emit(isa::InstructionInternal::I64Extend16S); + } + SignExtInstruction::I64Extend32S => { + context.step(instruction)?; + self.sink.emit(isa::InstructionInternal::I64Extend32S); + } + }, + _ => { context.step(instruction)?; } @@ -1173,7 +1209,7 @@ impl Sink { (Label::Resolved(dst_pc), _) => dst_pc, (Label::NotResolved, ref mut unresolved) => { unresolved.push(reloc_creator()); - u32::max_value() + u32::MAX } } } diff --git a/src/runner.rs b/src/runner.rs index 5baaee9331..0321776550 100644 --- a/src/runner.rs +++ b/src/runner.rs @@ -24,7 +24,9 @@ use crate::{ }; use alloc::{boxed::Box, vec::Vec}; use casper_wasm::elements::Local; -use core::{fmt, ops, u32, usize}; +#[cfg(feature = "sign_ext")] +use casper_wasmi_core::SignExtendFrom; +use core::{fmt, ops}; use validation::{DEFAULT_MEMORY_INDEX, DEFAULT_TABLE_INDEX}; /// Maximum number of bytes on the value stack. @@ -603,6 +605,17 @@ impl Interpreter { isa::Instruction::I64ReinterpretF64 => self.run_reinterpret::(), isa::Instruction::F32ReinterpretI32 => self.run_reinterpret::(), isa::Instruction::F64ReinterpretI64 => self.run_reinterpret::(), + + #[cfg(feature = "sign_ext")] + isa::Instruction::I32Extend8S => self.run_iextend::(), + #[cfg(feature = "sign_ext")] + isa::Instruction::I32Extend16S => self.run_iextend::(), + #[cfg(feature = "sign_ext")] + isa::Instruction::I64Extend8S => self.run_iextend::(), + #[cfg(feature = "sign_ext")] + isa::Instruction::I64Extend16S => self.run_iextend::(), + #[cfg(feature = "sign_ext")] + isa::Instruction::I64Extend32S => self.run_iextend::(), } } @@ -1263,6 +1276,20 @@ impl Interpreter { Ok(InstructionOutcome::RunNextInstruction) } + + #[cfg(feature = "sign_ext")] + fn run_iextend(&mut self) -> Result + where + ValueInternal: From, + U: SignExtendFrom + FromValueInternal, + { + let v = self.value_stack.pop_as::(); + + let v = v.sign_extend_from(); + self.value_stack.push(v.into())?; + + Ok(InstructionOutcome::RunNextInstruction) + } } /// Function execution context. diff --git a/src/table.rs b/src/table.rs index 5cb9d13820..010ee22251 100644 --- a/src/table.rs +++ b/src/table.rs @@ -1,7 +1,7 @@ use crate::{func::FuncRef, module::check_limits, Error}; use alloc::{rc::Rc, vec::Vec}; use casper_wasm::elements::ResizableLimits; -use core::{cell::RefCell, fmt, u32}; +use core::{cell::RefCell, fmt}; /// Reference to a table (See [`TableInstance`] for details). /// diff --git a/tests/e2e/v0/host.rs b/tests/e2e/v0/host.rs index a9acdf2649..1a0878abce 100644 --- a/tests/e2e/v0/host.rs +++ b/tests/e2e/v0/host.rs @@ -305,7 +305,7 @@ fn resume_call_host_func() { let export = instance.export_by_name("test").unwrap(); let func_instance = export.as_func().unwrap(); - let mut invocation = FuncInstance::invoke_resumable(&func_instance, &[][..]).unwrap(); + let mut invocation = FuncInstance::invoke_resumable(func_instance, &[][..]).unwrap(); let result = invocation.start_execution(&mut env); match result { Err(ResumableError::Trap(_)) => {} @@ -350,7 +350,7 @@ fn resume_call_host_func_type_mismatch() { let export = instance.export_by_name("test").unwrap(); let func_instance = export.as_func().unwrap(); - let mut invocation = FuncInstance::invoke_resumable(&func_instance, &[][..]).unwrap(); + let mut invocation = FuncInstance::invoke_resumable(func_instance, &[][..]).unwrap(); let result = invocation.start_execution(&mut env); match result { Err(ResumableError::Trap(_)) => {} @@ -565,7 +565,7 @@ fn defer_providing_externals() { field_name ))); } - if signature.params() != [ValueType::I32] || signature.return_type() != None { + if signature.params() != [ValueType::I32] || signature.return_type().is_some() { return Err(Error::Instantiation(format!( "Export `{}` doesnt match expected type {:?}", field_name, signature @@ -851,7 +851,7 @@ fn dynamically_add_host_func() { (module (type $t0 (func (result i32))) (import "env" "add_func" (func $add_func (result i32))) - (import "env" "table" (table 10 anyfunc)) + (import "env" "table" (table 10 funcref)) (func (export "test") (result i32) ;; Call add_func but discard the result call $add_func diff --git a/tests/e2e/v0/mod.rs b/tests/e2e/v0/mod.rs index fb68257feb..7ca8e68d7c 100644 --- a/tests/e2e/v0/mod.rs +++ b/tests/e2e/v0/mod.rs @@ -25,13 +25,13 @@ fn assert_error_properties() { fn unsigned_to_value() { use casper_wasmi::RuntimeValue; - let overflow_i32: u32 = ::core::i32::MAX as u32 + 1; + let overflow_i32: u32 = i32::MAX as u32 + 1; assert_eq!( RuntimeValue::from(overflow_i32).try_into::().unwrap(), overflow_i32 ); - let overflow_i64: u64 = ::core::i64::MAX as u64 + 1; + let overflow_i64: u64 = i64::MAX as u64 + 1; assert_eq!( RuntimeValue::from(overflow_i64).try_into::().unwrap(), overflow_i64 diff --git a/tests/e2e/v0/wasm.rs b/tests/e2e/v0/wasm.rs index a6e508ac7e..2e73c068ca 100644 --- a/tests/e2e/v0/wasm.rs +++ b/tests/e2e/v0/wasm.rs @@ -107,7 +107,7 @@ fn interpreter_inc_i32() { // Name of function contained in WASM file (note the leading underline) const FUNCTION_NAME: &str = "_inc_i32"; // The WASM file containing the module and function - const WASM_FILE: &str = &"tests/e2e/wat/inc_i32.wast"; + const WASM_FILE: &str = "tests/e2e/wat/inc_i32.wast"; let module = load_from_file(WASM_FILE); @@ -133,7 +133,7 @@ fn interpreter_accumulate_u8() { // Name of function contained in WASM file (note the leading underline) const FUNCTION_NAME: &str = "_accumulate_u8"; // The WASM file containing the module and function - const WASM_FILE: &str = &"tests/e2e/wat/accumulate_u8.wast"; + const WASM_FILE: &str = "tests/e2e/wat/accumulate_u8.wast"; // The octet sequence being accumulated const BUF: &[u8] = &[9, 8, 7, 6, 5, 4, 3, 2, 1]; diff --git a/tests/e2e/v1/func.rs b/tests/e2e/v1/func.rs index 21c0580c17..6a9c7feb3f 100644 --- a/tests/e2e/v1/func.rs +++ b/tests/e2e/v1/func.rs @@ -199,7 +199,7 @@ fn static_many_params_works() { fn setup_many_results() -> (Store<()>, Func) { let mut store = test_setup(); // Function taking 16 arguments (maximum) and doing nothing. - let func = Func::wrap(&mut store, || ascending_tuple()); + let func = Func::wrap(&mut store, ascending_tuple); (store, func) } diff --git a/tests/e2e/wat/accumulate_u8.wast b/tests/e2e/wat/accumulate_u8.wast index f401204567..a8475633fe 100644 --- a/tests/e2e/wat/accumulate_u8.wast +++ b/tests/e2e/wat/accumulate_u8.wast @@ -16,7 +16,7 @@ (type $1 (func)) (import "env" "memoryBase" (global $import$0 i32)) (import "env" "memory" (memory $0 256)) - (import "env" "table" (table 0 anyfunc)) + (import "env" "table" (table 0 funcref)) (import "env" "tableBase" (global $import$3 i32)) (global $global$0 (mut i32) (i32.const 0)) (global $global$1 (mut i32) (i32.const 0)) diff --git a/tests/e2e/wat/inc_i32.wast b/tests/e2e/wat/inc_i32.wast index da0ee0a79f..c250d2eb7b 100644 --- a/tests/e2e/wat/inc_i32.wast +++ b/tests/e2e/wat/inc_i32.wast @@ -11,7 +11,7 @@ (type $1 (func)) (import "env" "memoryBase" (global $import$0 i32)) (import "env" "memory" (memory $0 256)) - (import "env" "table" (table 0 anyfunc)) + (import "env" "table" (table 0 funcref)) (import "env" "tableBase" (global $import$3 i32)) (global $global$0 (mut i32) (i32.const 0)) (global $global$1 (mut i32) (i32.const 0)) diff --git a/tests/spec/v0/mod.rs b/tests/spec/v0/mod.rs index 9d1568744d..0a96378ff7 100644 --- a/tests/spec/v0/mod.rs +++ b/tests/spec/v0/mod.rs @@ -9,6 +9,15 @@ macro_rules! run_test { }; } +macro_rules! run_proposal_test { + ($proposal: expr, $label: expr, $test_name: ident) => { + #[test] + fn $test_name() { + self::run::proposal_spec($proposal, $label) + } + }; +} + run_test!("address", wasm_address); run_test!("align", wasm_align); run_test!("binary", wasm_binary); @@ -81,3 +90,15 @@ run_test!("utf8-custom-section-id", wasm_utf8_custom_section_id); run_test!("utf8-import-field", wasm_utf8_import_field); run_test!("utf8-import-module", wasm_utf8_import_module); run_test!("utf8-invalid-encoding", wasm_utf8_invalid_encoding); +#[cfg(feature = "sign_ext")] +run_proposal_test!( + "sign-extension-ops", + "i32", + wasm_proposal_sign_extension_i32 +); +#[cfg(feature = "sign_ext")] +run_proposal_test!( + "sign-extension-ops", + "i64", + wasm_proposal_sign_extension_i64 +); diff --git a/tests/spec/v0/run.rs b/tests/spec/v0/run.rs index 4835e5e3a4..6996f5ba04 100644 --- a/tests/spec/v0/run.rs +++ b/tests/spec/v0/run.rs @@ -1,6 +1,7 @@ #![cfg(test)] use std::{collections::HashMap, fs::File}; +use wabt::Features; use casper_wasmi::{ memory_units::Pages, @@ -42,9 +43,13 @@ fn spec_to_value(val: WabtValue) -> RuntimeValue { #[derive(Debug)] enum Error { + #[allow(dead_code)] Load(String), + #[allow(dead_code)] Start(Trap), + #[allow(dead_code)] Script(script::Error), + #[allow(dead_code)] Interpreter(InterpreterError), } @@ -332,7 +337,7 @@ fn run_action( .module_or_last(module.as_ref().map(|x| x.as_ref())) .unwrap_or_else(|_| panic!("Expected program to have loaded module {:?}", module)); let global = module - .export_by_name(&field) + .export_by_name(field) .ok_or_else(|| { InterpreterError::Global(format!("Expected to have export with name {}", field)) })? @@ -347,13 +352,25 @@ fn run_action( } pub fn spec(name: &str) { - println!("running test: {}", name); - try_spec(name).expect("Failed to run spec"); + let script_dir_path = "tests/spec/testsuite"; + println!("running spec test: {name}"); + try_spec(name, script_dir_path, Features::new()).expect("Failed to run spec"); } -fn try_spec(name: &str) -> Result<(), Error> { +pub fn proposal_spec(proposal: &str, name: &str) { + let script_dir_path = format!("tests/spec/testsuite/proposals/{proposal}"); + println!("running proposal spec test: {proposal}/{name}"); + let mut features = Features::new(); + match proposal { + "sign-extension-ops" => features.enable_sign_extension(), + _ => panic!("unsupported proposal {proposal}"), + } + try_spec(name, &script_dir_path, features).expect("Failed to run spec"); +} + +fn try_spec(name: &str, script_dir_path: &str, features: Features) -> Result<(), Error> { let mut spec_driver = SpecDriver::new(); - let spec_script_path = format!("tests/spec/testsuite/{}.wast", name); + let spec_script_path = format!("{script_dir_path}/{name}.wast"); use std::io::Read; let mut spec_source = Vec::new(); @@ -362,8 +379,12 @@ fn try_spec(name: &str) -> Result<(), Error> { .read_to_end(&mut spec_source) .expect("Can't read file"); - let mut parser = ScriptParser::from_source_and_name(&spec_source, &format!("{}.wast", name)) - .expect("Can't read spec script"); + let mut parser = ScriptParser::from_source_and_name_with_features( + &spec_source, + &format!("{}.wast", name), + features, + ) + .expect("Can't read spec script"); let mut errors = vec![]; while let Some(Command { kind, line }) = parser.next()? { diff --git a/tests/spec/v1/context.rs b/tests/spec/v1/context.rs index 05d3f529ee..5c42b97cbf 100644 --- a/tests/spec/v1/context.rs +++ b/tests/spec/v1/context.rs @@ -185,7 +185,7 @@ impl TestContext<'_> { /// Registers the given [`Instance`] with the given `name` and sets it as the last instance. pub fn register_instance(&mut self, name: &str, instance: Instance) { - if self.instances.get(name).is_some() { + if self.instances.contains_key(name) { // Already registered the instance. return; } diff --git a/tests/spec/v1/run.rs b/tests/spec/v1/run.rs index f2ccad8176..aef635eaa7 100644 --- a/tests/spec/v1/run.rs +++ b/tests/spec/v1/run.rs @@ -145,7 +145,7 @@ fn execute_directives(wast: Wast, test_context: &mut TestContext) -> Result<()> error ) }); - assert_results(&test_context, span, &results, &expected); + assert_results(test_context, span, &results, &expected); } WastDirective::AssertExhaustion { span, @@ -178,13 +178,12 @@ fn execute_directives(wast: Wast, test_context: &mut TestContext) -> Result<()> } WastDirective::AssertException { span, exec } => { test_context.profile().bump_assert_exception(); - match execute_wast_execute(test_context, span, exec) { - Ok(results) => panic!( + if let Ok(results) = execute_wast_execute(test_context, span, exec) { + panic!( "{}: expected to fail due to exception but succeeded with: {:?}", test_context.spanned(span), results - ), - Err(_) => {} + ) } } } diff --git a/validation/Cargo.toml b/validation/Cargo.toml index 04c011c93a..dbf305eba5 100644 --- a/validation/Cargo.toml +++ b/validation/Cargo.toml @@ -16,3 +16,4 @@ assert_matches = "1.1" [features] default = ["std"] std = ["casper-wasm/std"] +sign_ext = ["casper-wasm/sign_ext"] diff --git a/validation/src/func.rs b/validation/src/func.rs index ca1a18a952..e478d87a68 100644 --- a/validation/src/func.rs +++ b/validation/src/func.rs @@ -9,7 +9,9 @@ use crate::{ }; use casper_wasm::elements::{BlockType, Func, FuncBody, Instruction, TableElementType, ValueType}; -use core::u32; + +#[cfg(feature = "sign_ext")] +use casper_wasm::elements::SignExtInstruction; /// Maximum number of entries in value stack per function. const DEFAULT_VALUE_STACK_LIMIT: usize = 16384; @@ -171,7 +173,7 @@ impl<'a> FunctionValidationContext<'a> { pub fn step(&mut self, instruction: &Instruction) -> Result<(), Error> { use self::Instruction::*; - match *instruction { + match instruction { // Nop instruction doesn't do anything. It is safe to just skip it. Nop => {} @@ -182,7 +184,7 @@ impl<'a> FunctionValidationContext<'a> { Block(block_type) => { push_label( StartedWith::Block, - block_type, + *block_type, &self.value_stack, &mut self.frame_stack, )?; @@ -190,7 +192,7 @@ impl<'a> FunctionValidationContext<'a> { Loop(block_type) => { push_label( StartedWith::Loop, - block_type, + *block_type, &self.value_stack, &mut self.frame_stack, )?; @@ -203,7 +205,7 @@ impl<'a> FunctionValidationContext<'a> { )?; push_label( StartedWith::If, - block_type, + *block_type, &self.value_stack, &mut self.frame_stack, )?; @@ -267,11 +269,11 @@ impl<'a> FunctionValidationContext<'a> { } } Br(depth) => { - self.validate_br(depth)?; + self.validate_br(*depth)?; make_top_frame_polymorphic(&mut self.value_stack, &mut self.frame_stack); } BrIf(depth) => { - self.validate_br_if(depth)?; + self.validate_br_if(*depth)?; } BrTable(ref br_table_data) => { self.validate_br_table(&br_table_data.table, br_table_data.default)?; @@ -285,10 +287,10 @@ impl<'a> FunctionValidationContext<'a> { } Call(index) => { - self.validate_call(index)?; + self.validate_call(*index)?; } CallIndirect(index, _reserved) => { - self.validate_call_indirect(index)?; + self.validate_call_indirect(*index)?; } Drop => { @@ -299,90 +301,90 @@ impl<'a> FunctionValidationContext<'a> { } GetLocal(index) => { - self.validate_get_local(index)?; + self.validate_get_local(*index)?; } SetLocal(index) => { - self.validate_set_local(index)?; + self.validate_set_local(*index)?; } TeeLocal(index) => { - self.validate_tee_local(index)?; + self.validate_tee_local(*index)?; } GetGlobal(index) => { - self.validate_get_global(index)?; + self.validate_get_global(*index)?; } SetGlobal(index) => { - self.validate_set_global(index)?; + self.validate_set_global(*index)?; } I32Load(align, _) => { - self.validate_load(align, 4, ValueType::I32)?; + self.validate_load(*align, 4, ValueType::I32)?; } I64Load(align, _) => { - self.validate_load(align, 8, ValueType::I64)?; + self.validate_load(*align, 8, ValueType::I64)?; } F32Load(align, _) => { - self.validate_load(align, 4, ValueType::F32)?; + self.validate_load(*align, 4, ValueType::F32)?; } F64Load(align, _) => { - self.validate_load(align, 8, ValueType::F64)?; + self.validate_load(*align, 8, ValueType::F64)?; } I32Load8S(align, _) => { - self.validate_load(align, 1, ValueType::I32)?; + self.validate_load(*align, 1, ValueType::I32)?; } I32Load8U(align, _) => { - self.validate_load(align, 1, ValueType::I32)?; + self.validate_load(*align, 1, ValueType::I32)?; } I32Load16S(align, _) => { - self.validate_load(align, 2, ValueType::I32)?; + self.validate_load(*align, 2, ValueType::I32)?; } I32Load16U(align, _) => { - self.validate_load(align, 2, ValueType::I32)?; + self.validate_load(*align, 2, ValueType::I32)?; } I64Load8S(align, _) => { - self.validate_load(align, 1, ValueType::I64)?; + self.validate_load(*align, 1, ValueType::I64)?; } I64Load8U(align, _) => { - self.validate_load(align, 1, ValueType::I64)?; + self.validate_load(*align, 1, ValueType::I64)?; } I64Load16S(align, _) => { - self.validate_load(align, 2, ValueType::I64)?; + self.validate_load(*align, 2, ValueType::I64)?; } I64Load16U(align, _) => { - self.validate_load(align, 2, ValueType::I64)?; + self.validate_load(*align, 2, ValueType::I64)?; } I64Load32S(align, _) => { - self.validate_load(align, 4, ValueType::I64)?; + self.validate_load(*align, 4, ValueType::I64)?; } I64Load32U(align, _) => { - self.validate_load(align, 4, ValueType::I64)?; + self.validate_load(*align, 4, ValueType::I64)?; } I32Store(align, _) => { - self.validate_store(align, 4, ValueType::I32)?; + self.validate_store(*align, 4, ValueType::I32)?; } I64Store(align, _) => { - self.validate_store(align, 8, ValueType::I64)?; + self.validate_store(*align, 8, ValueType::I64)?; } F32Store(align, _) => { - self.validate_store(align, 4, ValueType::F32)?; + self.validate_store(*align, 4, ValueType::F32)?; } F64Store(align, _) => { - self.validate_store(align, 8, ValueType::F64)?; + self.validate_store(*align, 8, ValueType::F64)?; } I32Store8(align, _) => { - self.validate_store(align, 1, ValueType::I32)?; + self.validate_store(*align, 1, ValueType::I32)?; } I32Store16(align, _) => { - self.validate_store(align, 2, ValueType::I32)?; + self.validate_store(*align, 2, ValueType::I32)?; } I64Store8(align, _) => { - self.validate_store(align, 1, ValueType::I64)?; + self.validate_store(*align, 1, ValueType::I64)?; } I64Store16(align, _) => { - self.validate_store(align, 2, ValueType::I64)?; + self.validate_store(*align, 2, ValueType::I64)?; } I64Store32(align, _) => { - self.validate_store(align, 4, ValueType::I64)?; + self.validate_store(*align, 4, ValueType::I64)?; } CurrentMemory(_) => { @@ -783,6 +785,15 @@ impl<'a> FunctionValidationContext<'a> { F64ReinterpretI64 => { self.validate_cvtop(ValueType::I64, ValueType::F64)?; } + + #[cfg(feature = "sign_ext")] + SignExt(instruction) => match instruction { + SignExtInstruction::I32Extend8S => self.validate_unop(ValueType::I32)?, + SignExtInstruction::I32Extend16S => self.validate_unop(ValueType::I32)?, + SignExtInstruction::I64Extend8S => self.validate_unop(ValueType::I64)?, + SignExtInstruction::I64Extend16S => self.validate_unop(ValueType::I64)?, + SignExtInstruction::I64Extend32S => self.validate_unop(ValueType::I64)?, + }, } Ok(()) diff --git a/validation/src/lib.rs b/validation/src/lib.rs index afe389159c..197641d1ff 100644 --- a/validation/src/lib.rs +++ b/validation/src/lib.rs @@ -168,7 +168,7 @@ pub fn validate_module( .map(|ts| { ts.types() .iter() - .map(|&Type::Function(ref ty)| ty) + .map(|Type::Function(ty)| ty) .cloned() .collect() }) @@ -244,7 +244,7 @@ pub fn validate_module( for (index, function) in function_section.entries().iter().enumerate() { let function_body = code_section .bodies() - .get(index as usize) + .get(index) .ok_or_else(|| Error(format!("Missing body for function {}", index)))?; let func_validator_input = validation.func_validator_input(); let output = func::drive::( diff --git a/validation/src/util.rs b/validation/src/util.rs index e83788d63c..2c075d04ce 100644 --- a/validation/src/util.rs +++ b/validation/src/util.rs @@ -120,7 +120,7 @@ mod tests { #[test] fn locals_u32_overflow() { let local_groups = vec![ - Local::new(u32::max_value(), ValueType::I32), + Local::new(u32::MAX, ValueType::I32), Local::new(1, ValueType::I64), ]; assert_matches!(Locals::new(&[], &local_groups), Err(_)); diff --git a/wasmi_v1/src/arena/tests.rs b/wasmi_v1/src/arena/tests.rs index 727113458c..c7fb416d62 100644 --- a/wasmi_v1/src/arena/tests.rs +++ b/wasmi_v1/src/arena/tests.rs @@ -10,7 +10,7 @@ impl Index for usize { } } -const TEST_ENTITIES: &[&'static str] = &["a", "b", "c", "d"]; +const TEST_ENTITIES: &[&str] = &["a", "b", "c", "d"]; mod arena { use super::*; diff --git a/wasmi_v1/src/engine/exec_context.rs b/wasmi_v1/src/engine/exec_context.rs index 34a14ee1d3..2a9d0b744f 100644 --- a/wasmi_v1/src/engine/exec_context.rs +++ b/wasmi_v1/src/engine/exec_context.rs @@ -260,6 +260,7 @@ impl<'engine, 'func> FunctionExecutor<'engine, 'func> { Instr::I64Extend16S => { exec_ctx.visit_i64_sign_extend16()?; } Instr::I64Extend32S => { exec_ctx.visit_i64_sign_extend32()?; } Instr::FuncBodyStart { .. } | Instruction::FuncBodyEnd => { + #[allow(unexpected_cfgs)] if cfg!(debug) { unreachable!( "expected start of a new instruction \ @@ -519,6 +520,7 @@ where self.next_instr() } + #[allow(clippy::extra_unused_type_parameters)] fn execute_reinterpret(&mut self) -> Result<(), Trap> where UntypedValue: From, @@ -562,7 +564,7 @@ where Ctx: AsContextMut, { fn visit_unreachable(&mut self) -> Result<(), Trap> { - Err(TrapCode::Unreachable).map_err(Into::into) + Err(Into::into(TrapCode::Unreachable)) } fn visit_br(&mut self, target: Target) -> Result<(), Trap> { @@ -680,7 +682,7 @@ where ) }); if actual_signature != expected_signature { - return Err(TrapCode::UnexpectedSignature).map_err(Into::into); + return Err(Into::into(TrapCode::UnexpectedSignature)); } self.call_func(func) } diff --git a/wasmi_v1/src/engine/func_builder/locals_registry.rs b/wasmi_v1/src/engine/func_builder/locals_registry.rs index bd14254477..f37e79781d 100644 --- a/wasmi_v1/src/engine/func_builder/locals_registry.rs +++ b/wasmi_v1/src/engine/func_builder/locals_registry.rs @@ -166,7 +166,7 @@ mod tests { registry.register_locals(ValueType::F32, 1); registry.register_locals(ValueType::F64, 1); fn assert_valid_accesses(registry: &mut LocalsRegistry, offset: u32) { - assert_eq!(registry.resolve_local(offset + 0), Some(ValueType::I32)); + assert_eq!(registry.resolve_local(offset), Some(ValueType::I32)); assert_eq!(registry.resolve_local(offset + 1), Some(ValueType::I64)); assert_eq!(registry.resolve_local(offset + 2), Some(ValueType::F32)); assert_eq!(registry.resolve_local(offset + 3), Some(ValueType::F64)); diff --git a/wasmi_v1/src/engine/mod.rs b/wasmi_v1/src/engine/mod.rs index 43948c25b5..d0441c8b63 100644 --- a/wasmi_v1/src/engine/mod.rs +++ b/wasmi_v1/src/engine/mod.rs @@ -22,7 +22,7 @@ use self::{ pub use self::{ bytecode::{DropKeep, Target}, code_map::FuncBody, - func_builder::{FunctionBuilder, InstructionIdx, LabelIdx, RelativeDepth, Reloc}, + func_builder::{FunctionBuilder, InstructionIdx, LabelIdx, RelativeDepth}, traits::{CallParams, CallResults}, }; use super::{func::FuncEntityInternal, AsContext, AsContextMut, Func}; @@ -303,7 +303,7 @@ impl Engine { .code_map .resolve(func_body) .get(index) - .map(Clone::clone) + .copied() } /// Executes the given [`Func`] using the given arguments `params` and stores the result into `results`. diff --git a/wasmi_v1/src/engine/traits.rs b/wasmi_v1/src/engine/traits.rs index 6c907c63fd..fa33c57cd9 100644 --- a/wasmi_v1/src/engine/traits.rs +++ b/wasmi_v1/src/engine/traits.rs @@ -21,6 +21,7 @@ pub trait CallParams { /// Used by the [`Engine`] to determine how many parameters are received. /// /// [`Engine`]: [`crate::Engine`] + #[allow(dead_code)] fn len_params(&self) -> usize; /// Feeds the parameter values from the caller. diff --git a/wasmi_v1/src/func/mod.rs b/wasmi_v1/src/func/mod.rs index 1ef32f612c..bd19370de1 100644 --- a/wasmi_v1/src/func/mod.rs +++ b/wasmi_v1/src/func/mod.rs @@ -298,10 +298,10 @@ impl Func { let (expected_inputs, expected_outputs) = func_type.params_results(); let actual_inputs = inputs.iter().map(|value| value.value_type()); if expected_inputs.iter().copied().ne(actual_inputs) { - return Err(FuncError::MismatchingParameters { func: *self }).map_err(Into::into); + return Err(Into::into(FuncError::MismatchingParameters { func: *self })); } if expected_outputs.len() != outputs.len() { - return Err(FuncError::MismatchingResults { func: *self }).map_err(Into::into); + return Err(Into::into(FuncError::MismatchingResults { func: *self })); } // Note: Cloning an [`Engine`] is intentionally a cheap operation. ctx.as_context().store.engine().clone().execute_func( diff --git a/wasmi_v1/src/func/typed_func.rs b/wasmi_v1/src/func/typed_func.rs index 948097ae20..cce03c43de 100644 --- a/wasmi_v1/src/func/typed_func.rs +++ b/wasmi_v1/src/func/typed_func.rs @@ -143,9 +143,7 @@ impl Default for CallResultsTuple { impl Copy for CallResultsTuple {} impl Clone for CallResultsTuple { fn clone(&self) -> Self { - Self { - _marker: PhantomData, - } + *self } } diff --git a/wasmi_v1/src/linker.rs b/wasmi_v1/src/linker.rs index 9638faae32..7f9870d8bf 100644 --- a/wasmi_v1/src/linker.rs +++ b/wasmi_v1/src/linker.rs @@ -369,7 +369,7 @@ impl Linker { .ok_or_else(|| LinkerError::cannot_find_definition_of_import(&import))?; let actual_func_type = func.signature(&context); if &actual_func_type != expected_func_type { - return Err(LinkerError::FuncTypeMismatch { + return Err(Into::into(LinkerError::FuncTypeMismatch { name: import.name().clone(), expected: context .as_context() @@ -379,8 +379,7 @@ impl Linker { .as_context() .store .resolve_func_type(actual_func_type), - }) - .map_err(Into::into); + })); } Extern::Func(func) } @@ -409,12 +408,11 @@ impl Linker { .ok_or_else(|| LinkerError::cannot_find_definition_of_import(&import))?; let actual_global_type = global.global_type(context.as_context()); if &actual_global_type != expected_global_type { - return Err(LinkerError::GlobalTypeMismatch { + return Err(Into::into(LinkerError::GlobalTypeMismatch { name: import.name().clone(), expected: *expected_global_type, actual: actual_global_type, - }) - .map_err(Into::into); + })); } Extern::Global(global) } diff --git a/wasmi_v1/src/module/instantiate/mod.rs b/wasmi_v1/src/module/instantiate/mod.rs index 613d1c1f17..fe518fbbbb 100644 --- a/wasmi_v1/src/module/instantiate/mod.rs +++ b/wasmi_v1/src/module/instantiate/mod.rs @@ -347,12 +347,11 @@ impl Module { let len_table = table.len(&context); let len_items = element_segment.items().len(); if offset + len_items > len_table { - return Err(InstantiationError::ElementSegmentDoesNotFit { + return Err(Into::into(InstantiationError::ElementSegmentDoesNotFit { table, offset, amount: len_items, - }) - .map_err(Into::into); + })); } // Finally do the actual initialization of the table elements. for (i, func_index) in element_segment.items().iter().enumerate() {