From 2824b8438139ff526ba79397862498dbf5fb8e4d Mon Sep 17 00:00:00 2001 From: Andrew Dirksen Date: Tue, 13 Nov 2018 16:51:35 -0800 Subject: [PATCH] run 'cargo fmt' again --- examples/invoke.rs | 10 +- examples/tictactoe.rs | 22 +-- src/bin/instantiate.rs | 24 +-- src/func.rs | 21 +-- src/global.rs | 4 +- src/host.rs | 12 +- src/imports.rs | 88 ++-------- src/isa.rs | 10 +- src/memory.rs | 69 ++------ src/module.rs | 68 ++------ src/nan_preserving_float.rs | 12 +- src/runner.rs | 230 +++++++----------------- src/table.rs | 9 +- src/tests/host.rs | 124 +++---------- src/tests/wasm.rs | 33 +--- src/types.rs | 9 +- src/validation/context.rs | 9 +- src/validation/func.rs | 337 ++++++++---------------------------- src/validation/mod.rs | 51 ++---- src/validation/tests.rs | 23 +-- src/value.rs | 5 +- tests/spec/run.rs | 139 ++++----------- 22 files changed, 307 insertions(+), 1002 deletions(-) diff --git a/examples/invoke.rs b/examples/invoke.rs index f7beb98..39d3d20 100644 --- a/examples/invoke.rs +++ b/examples/invoke.rs @@ -22,9 +22,7 @@ fn main() { // Export section has an entry with a func_name with an index inside a module let export_section = module.export_section().expect("No export section found"); // It's a section with function declarations (which are references to the type section entries) - let function_section = module - .function_section() - .expect("No function section found"); + let function_section = module.function_section().expect("No function section found"); // Type section stores function types which are referenced by function_section entries let type_section = module.type_section().expect("No type section found"); @@ -59,8 +57,7 @@ fn main() { let function_index_in_section = function_index - import_section_len; // Getting a type reference from a function section entry - let func_type_ref: usize = - function_section.entries()[function_index_in_section].type_ref() as usize; + let func_type_ref: usize = function_section.entries()[function_index_in_section].type_ref() as usize; // Use the reference to get an actual function type let function_type: &FunctionType = match &type_section.types()[func_type_ref] { @@ -112,7 +109,6 @@ fn main() { println!( "Result: {:?}", - main.invoke_export(func_name, &args, &mut NopExternals) - .expect("") + main.invoke_export(func_name, &args, &mut NopExternals).expect("") ); } diff --git a/examples/tictactoe.rs b/examples/tictactoe.rs index 0223a6d..cf079bb 100644 --- a/examples/tictactoe.rs +++ b/examples/tictactoe.rs @@ -5,9 +5,8 @@ use std::env; use std::fmt; use std::fs::File; use wasmi::{ - Error as InterpreterError, Externals, FuncInstance, FuncRef, HostError, ImportsBuilder, - ModuleImportResolver, ModuleInstance, ModuleRef, RuntimeArgs, RuntimeValue, Signature, Trap, - ValueType, + Error as InterpreterError, Externals, FuncInstance, FuncRef, HostError, ImportsBuilder, ModuleImportResolver, + ModuleInstance, ModuleRef, RuntimeArgs, RuntimeValue, Signature, Trap, ValueType, }; #[derive(Debug)] @@ -140,11 +139,7 @@ const SET_FUNC_INDEX: usize = 0; const GET_FUNC_INDEX: usize = 1; impl<'a> Externals for Runtime<'a> { - fn invoke_index( - &mut self, - index: usize, - args: RuntimeArgs, - ) -> Result, Trap> { + fn invoke_index(&mut self, index: usize, args: RuntimeArgs) -> Result, Trap> { match index { SET_FUNC_INDEX => { let idx: i32 = args.nth(0); @@ -164,16 +159,9 @@ impl<'a> Externals for Runtime<'a> { struct RuntimeModuleImportResolver; impl<'a> ModuleImportResolver for RuntimeModuleImportResolver { - fn resolve_func( - &self, - field_name: &str, - _signature: &Signature, - ) -> Result { + fn resolve_func(&self, field_name: &str, _signature: &Signature) -> Result { let func_ref = match field_name { - "set" => FuncInstance::alloc_host( - Signature::new(&[ValueType::I32][..], None), - SET_FUNC_INDEX, - ), + "set" => FuncInstance::alloc_host(Signature::new(&[ValueType::I32][..], None), SET_FUNC_INDEX), "get" => FuncInstance::alloc_host( Signature::new(&[ValueType::I32][..], Some(ValueType::I32)), GET_FUNC_INDEX, diff --git a/src/bin/instantiate.rs b/src/bin/instantiate.rs index 6d92fc3..cf61367 100644 --- a/src/bin/instantiate.rs +++ b/src/bin/instantiate.rs @@ -7,9 +7,9 @@ use std::env::args; use std::fs::File; use wasmi::memory_units::*; use wasmi::{ - Error, FuncInstance, FuncRef, GlobalDescriptor, GlobalInstance, GlobalRef, ImportsBuilder, - MemoryDescriptor, MemoryInstance, MemoryRef, Module, ModuleImportResolver, ModuleInstance, - NopExternals, RuntimeValue, Signature, TableDescriptor, TableInstance, TableRef, + Error, FuncInstance, FuncRef, GlobalDescriptor, GlobalInstance, GlobalRef, ImportsBuilder, MemoryDescriptor, + MemoryInstance, MemoryRef, Module, ModuleImportResolver, ModuleInstance, NopExternals, RuntimeValue, Signature, + TableDescriptor, TableInstance, TableRef, }; fn load_from_file(filename: &str) -> Module { @@ -27,33 +27,21 @@ impl ModuleImportResolver for ResolveAll { Ok(FuncInstance::alloc_host(signature.clone(), 0)) } - fn resolve_global( - &self, - _field_name: &str, - global_type: &GlobalDescriptor, - ) -> Result { + fn resolve_global(&self, _field_name: &str, global_type: &GlobalDescriptor) -> Result { Ok(GlobalInstance::alloc( RuntimeValue::default(global_type.value_type()), global_type.is_mutable(), )) } - fn resolve_memory( - &self, - _field_name: &str, - memory_type: &MemoryDescriptor, - ) -> Result { + fn resolve_memory(&self, _field_name: &str, memory_type: &MemoryDescriptor) -> Result { Ok(MemoryInstance::alloc( Pages(memory_type.initial() as usize), memory_type.maximum().map(|m| Pages(m as usize)), ).unwrap()) } - fn resolve_table( - &self, - _field_name: &str, - table_type: &TableDescriptor, - ) -> Result { + fn resolve_table(&self, _field_name: &str, table_type: &TableDescriptor) -> Result { Ok(TableInstance::alloc(table_type.initial(), table_type.maximum()).unwrap()) } } diff --git a/src/func.rs b/src/func.rs index 3344d5c..dda1a4c 100644 --- a/src/func.rs +++ b/src/func.rs @@ -63,9 +63,7 @@ impl fmt::Debug for FuncInstance { // debug string for function instances and this will lead to infinite loop. write!(f, "Internal {{ signature={:?} }}", signature,) } - &FuncInstanceInternal::Host { ref signature, .. } => { - write!(f, "Host {{ signature={:?} }}", signature) - } + &FuncInstanceInternal::Host { ref signature, .. } => write!(f, "Host {{ signature={:?} }}", signature), } } } @@ -103,11 +101,7 @@ impl FuncInstance { &self.0 } - pub(crate) fn alloc_internal( - module: Weak, - signature: Rc, - body: FuncBody, - ) -> FuncRef { + pub(crate) fn alloc_internal(module: Weak, signature: Rc, body: FuncBody) -> FuncRef { let func = FuncInstanceInternal::Internal { signature, module: module, @@ -144,8 +138,7 @@ impl FuncInstance { interpreter.start_execution(externals) } FuncInstanceInternal::Host { - ref host_func_index, - .. + ref host_func_index, .. } => externals.invoke_index(*host_func_index, args.into()), } } @@ -164,10 +157,7 @@ impl FuncInstance { /// [`Trap`]: #enum.Trap.html /// [`start_execution`]: struct.FuncInvocation.html#method.start_execution /// [`resume_execution`]: struct.FuncInvocation.html#method.resume_execution - pub fn invoke_resumable<'args>( - func: &FuncRef, - args: &'args [RuntimeValue], - ) -> Result, Trap> { + pub fn invoke_resumable<'args>(func: &FuncRef, args: &'args [RuntimeValue]) -> Result, Trap> { check_function_args(func.signature(), &args)?; match *func.as_internal() { FuncInstanceInternal::Internal { .. } => { @@ -177,8 +167,7 @@ impl FuncInstance { }) } FuncInstanceInternal::Host { - ref host_func_index, - .. + ref host_func_index, .. } => Ok(FuncInvocation { kind: FuncInvocationKind::Host { args, diff --git a/src/global.rs b/src/global.rs index 9d408c6..e6ecbac 100644 --- a/src/global.rs +++ b/src/global.rs @@ -57,9 +57,7 @@ impl GlobalInstance { /// type of `val` doesn't match global's type. pub fn set(&self, val: RuntimeValue) -> Result<(), Error> { if !self.mutable { - return Err(Error::Global( - "Attempt to change an immutable variable".into(), - )); + return Err(Error::Global("Attempt to change an immutable variable".into())); } if self.value_type() != val.value_type() { return Err(Error::Global("Attempt to change variable type".into())); diff --git a/src/host.rs b/src/host.rs index 0501389..ee8044c 100644 --- a/src/host.rs +++ b/src/host.rs @@ -208,11 +208,7 @@ impl HostError { /// ``` pub trait Externals { /// Perform invoke of a host function by specified `index`. - fn invoke_index( - &mut self, - index: usize, - args: RuntimeArgs, - ) -> Result, Trap>; + fn invoke_index(&mut self, index: usize, args: RuntimeArgs) -> Result, Trap>; } /// Implementation of [`Externals`] that just traps on [`invoke_index`]. @@ -222,11 +218,7 @@ pub trait Externals { pub struct NopExternals; impl Externals for NopExternals { - fn invoke_index( - &mut self, - _index: usize, - _args: RuntimeArgs, - ) -> Result, Trap> { + fn invoke_index(&mut self, _index: usize, _args: RuntimeArgs) -> Result, Trap> { Err(TrapKind::Unreachable.into()) } } diff --git a/src/imports.rs b/src/imports.rs index fce2906..43e0ed3 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -30,12 +30,7 @@ pub trait ImportResolver { /// /// Returned function should match given `signature`, i.e. all parameter types and return value should have exact match. /// Otherwise, link-time error will occur. - fn resolve_func( - &self, - _module_name: &str, - field_name: &str, - _signature: &Signature, - ) -> Result; + fn resolve_func(&self, _module_name: &str, field_name: &str, _signature: &Signature) -> Result; /// Resolve a global variable. /// @@ -124,11 +119,7 @@ impl<'a> ImportsBuilder<'a> { } /// Register an resolver by a name. - pub fn with_resolver>( - mut self, - name: N, - resolver: &'a ModuleImportResolver, - ) -> Self { + pub fn with_resolver>(mut self, name: N, resolver: &'a ModuleImportResolver) -> Self { self.modules.insert(name.into(), resolver); self } @@ -146,12 +137,7 @@ impl<'a> ImportsBuilder<'a> { } impl<'a> ImportResolver for ImportsBuilder<'a> { - fn resolve_func( - &self, - module_name: &str, - field_name: &str, - signature: &Signature, - ) -> Result { + fn resolve_func(&self, module_name: &str, field_name: &str, signature: &Signature) -> Result { self.resolver(module_name) .ok_or_else(|| Error::Instantiation(format!("Module {} not found", module_name)))? .resolve_func(field_name, signature) @@ -201,10 +187,7 @@ pub trait ModuleImportResolver { /// /// [`ImportResolver::resolve_func`]: trait.ImportResolver.html#tymethod.resolve_func fn resolve_func(&self, field_name: &str, _signature: &Signature) -> Result { - Err(Error::Instantiation(format!( - "Export {} not found", - field_name - ))) + Err(Error::Instantiation(format!("Export {} not found", field_name))) } /// Resolve a global variable. @@ -212,15 +195,8 @@ pub trait ModuleImportResolver { /// See [`ImportResolver::resolve_global`] for details. /// /// [`ImportResolver::resolve_global`]: trait.ImportResolver.html#tymethod.resolve_global - fn resolve_global( - &self, - field_name: &str, - _global_type: &GlobalDescriptor, - ) -> Result { - Err(Error::Instantiation(format!( - "Export {} not found", - field_name - ))) + fn resolve_global(&self, field_name: &str, _global_type: &GlobalDescriptor) -> Result { + Err(Error::Instantiation(format!("Export {} not found", field_name))) } /// Resolve a memory. @@ -228,15 +204,8 @@ pub trait ModuleImportResolver { /// See [`ImportResolver::resolve_memory`] for details. /// /// [`ImportResolver::resolve_memory`]: trait.ImportResolver.html#tymethod.resolve_memory - fn resolve_memory( - &self, - field_name: &str, - _memory_type: &MemoryDescriptor, - ) -> Result { - Err(Error::Instantiation(format!( - "Export {} not found", - field_name - ))) + fn resolve_memory(&self, field_name: &str, _memory_type: &MemoryDescriptor) -> Result { + Err(Error::Instantiation(format!("Export {} not found", field_name))) } /// Resolve a table. @@ -244,15 +213,8 @@ pub trait ModuleImportResolver { /// See [`ImportResolver::resolve_table`] for details. /// /// [`ImportResolver::resolve_table`]: trait.ImportResolver.html#tymethod.resolve_table - fn resolve_table( - &self, - field_name: &str, - _table_type: &TableDescriptor, - ) -> Result { - Err(Error::Instantiation(format!( - "Export {} not found", - field_name - ))) + fn resolve_table(&self, field_name: &str, _table_type: &TableDescriptor) -> Result { + Err(Error::Instantiation(format!("Export {} not found", field_name))) } } @@ -263,46 +225,28 @@ impl ModuleImportResolver for ModuleRef { .ok_or_else(|| Error::Instantiation(format!("Export {} not found", field_name)))? .as_func() .cloned() - .ok_or_else(|| { - Error::Instantiation(format!("Export {} is not a function", field_name)) - })?) + .ok_or_else(|| Error::Instantiation(format!("Export {} is not a function", field_name)))?) } - fn resolve_global( - &self, - field_name: &str, - _global_type: &GlobalDescriptor, - ) -> Result { + fn resolve_global(&self, field_name: &str, _global_type: &GlobalDescriptor) -> Result { Ok(self .export_by_name(field_name) .ok_or_else(|| Error::Instantiation(format!("Export {} not found", field_name)))? .as_global() .cloned() - .ok_or_else(|| { - Error::Instantiation(format!("Export {} is not a global", field_name)) - })?) + .ok_or_else(|| Error::Instantiation(format!("Export {} is not a global", field_name)))?) } - fn resolve_memory( - &self, - field_name: &str, - _memory_type: &MemoryDescriptor, - ) -> Result { + fn resolve_memory(&self, field_name: &str, _memory_type: &MemoryDescriptor) -> Result { Ok(self .export_by_name(field_name) .ok_or_else(|| Error::Instantiation(format!("Export {} not found", field_name)))? .as_memory() .cloned() - .ok_or_else(|| { - Error::Instantiation(format!("Export {} is not a memory", field_name)) - })?) + .ok_or_else(|| Error::Instantiation(format!("Export {} is not a memory", field_name)))?) } - fn resolve_table( - &self, - field_name: &str, - _table_type: &TableDescriptor, - ) -> Result { + fn resolve_table(&self, field_name: &str, _table_type: &TableDescriptor) -> Result { Ok(self .export_by_name(field_name) .ok_or_else(|| Error::Instantiation(format!("Export {} not found", field_name)))? diff --git a/src/isa.rs b/src/isa.rs index e9a7caf..327b3ae 100644 --- a/src/isa.rs +++ b/src/isa.rs @@ -371,11 +371,9 @@ impl<'a> Iterator for InstructionIter<'a> { #[inline] fn next(&mut self) -> Option<::Item> { - self.instructions - .get(self.position as usize) - .map(|instruction| { - self.position += 1; - instruction - }) + self.instructions.get(self.position as usize).map(|instruction| { + self.position += 1; + instruction + }) } } diff --git a/src/memory.rs b/src/memory.rs index 82fabca..2a6dfc7 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -174,8 +174,7 @@ impl MemoryInstance { /// Get value from memory at given offset. pub fn get_value(&self, offset: u32) -> Result { let mut buffer = self.buffer.borrow_mut(); - let region = - self.checked_region(&mut buffer, offset as usize, ::core::mem::size_of::())?; + let region = self.checked_region(&mut buffer, offset as usize, ::core::mem::size_of::())?; Ok(T::from_little_endian(&buffer[region.range()]).expect("Slice size is checked")) } @@ -209,9 +208,7 @@ impl MemoryInstance { /// Copy data in the memory at given offset. pub fn set(&self, offset: u32, value: &[u8]) -> Result<(), Error> { let mut buffer = self.buffer.borrow_mut(); - let range = self - .checked_region(&mut buffer, offset as usize, value.len())? - .range(); + let range = self.checked_region(&mut buffer, offset as usize, value.len())?.range(); buffer[range].copy_from_slice(value); @@ -241,9 +238,7 @@ impl MemoryInstance { return Ok(size_before_grow); } if additional > Pages(65536) { - return Err(Error::Memory(format!( - "Trying to grow memory by more than 65536 pages" - ))); + return Err(Error::Memory(format!("Trying to grow memory by more than 65536 pages"))); } let new_size: Pages = size_before_grow + additional; @@ -260,12 +255,7 @@ impl MemoryInstance { Ok(size_before_grow) } - fn checked_region( - &self, - buffer: &mut B, - offset: usize, - size: usize, - ) -> Result + fn checked_region(&self, buffer: &mut B, offset: usize, size: usize) -> Result where B: ::core::ops::DerefMut>, { @@ -365,8 +355,7 @@ impl MemoryInstance { pub fn copy(&self, src_offset: usize, dst_offset: usize, len: usize) -> Result<(), Error> { let mut buffer = self.buffer.borrow_mut(); - let (read_region, write_region) = - self.checked_region_pair(&mut buffer, src_offset, len, dst_offset, len)?; + let (read_region, write_region) = self.checked_region_pair(&mut buffer, src_offset, len, dst_offset, len)?; unsafe { ::core::ptr::copy( @@ -390,16 +379,10 @@ impl MemoryInstance { /// /// - either of specified regions is out of bounds, /// - these regions overlaps. - pub fn copy_nonoverlapping( - &self, - src_offset: usize, - dst_offset: usize, - len: usize, - ) -> Result<(), Error> { + pub fn copy_nonoverlapping(&self, src_offset: usize, dst_offset: usize, len: usize) -> Result<(), Error> { let mut buffer = self.buffer.borrow_mut(); - let (read_region, write_region) = - self.checked_region_pair(&mut buffer, src_offset, len, dst_offset, len)?; + let (read_region, write_region) = self.checked_region_pair(&mut buffer, src_offset, len, dst_offset, len)?; if read_region.intersects(&write_region) { return Err(Error::Memory(format!( @@ -439,12 +422,8 @@ impl MemoryInstance { let mut src_buffer = src.buffer.borrow_mut(); let mut dst_buffer = dst.buffer.borrow_mut(); - let src_range = src - .checked_region(&mut src_buffer, src_offset, len)? - .range(); - let dst_range = dst - .checked_region(&mut dst_buffer, dst_offset, len)? - .range(); + let src_range = src.checked_region(&mut src_buffer, src_offset, len)?.range(); + let dst_range = dst.checked_region(&mut dst_buffer, dst_offset, len)?.range(); dst_buffer[dst_range].copy_from_slice(&src_buffer[src_range]); @@ -588,8 +567,7 @@ mod tests { fn create_memory(initial_content: &[u8]) -> MemoryInstance { let mem = MemoryInstance::new(Pages(1), Some(Pages(1))); - mem.set(0, initial_content) - .expect("Successful initialize the memory"); + mem.set(0, initial_content).expect("Successful initialize the memory"); mem } @@ -641,17 +619,12 @@ mod tests { #[test] fn transfer_works() { let src = MemoryRef(Rc::new(create_memory(&[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))); - let dst = MemoryRef(Rc::new(create_memory(&[ - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - ]))); + let dst = MemoryRef(Rc::new(create_memory(&[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]))); MemoryInstance::transfer(&src, 4, &dst, 0, 3).unwrap(); assert_eq!(src.get(0, 10).unwrap(), &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); - assert_eq!( - dst.get(0, 10).unwrap(), - &[4, 5, 6, 13, 14, 15, 16, 17, 18, 19] - ); + assert_eq!(dst.get(0, 10).unwrap(), &[4, 5, 6, 13, 14, 15, 16, 17, 18, 19]); } #[test] @@ -675,25 +648,19 @@ mod tests { #[test] fn transfer_oob_errors() { let src = MemoryRef(Rc::new(create_memory(&[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))); - let dst = MemoryRef(Rc::new(create_memory(&[ - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - ]))); + let dst = MemoryRef(Rc::new(create_memory(&[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]))); assert!(MemoryInstance::transfer(&src, 65535, &dst, 0, 3).is_err()); // Check that memories content left untouched assert_eq!(src.get(0, 10).unwrap(), &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); - assert_eq!( - dst.get(0, 10).unwrap(), - &[10, 11, 12, 13, 14, 15, 16, 17, 18, 19] - ); + assert_eq!(dst.get(0, 10).unwrap(), &[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]); } #[test] fn clear() { let mem = create_memory(&[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); - mem.clear(0, 0x4A, 10) - .expect("To successfully clear the memory"); + mem.clear(0, 0x4A, 10).expect("To successfully clear the memory"); let result = mem.get(0, 10).expect("To successfully retrieve the result"); assert_eq!(result, &[0x4A; 10]); } @@ -701,12 +668,10 @@ mod tests { #[test] fn get_into() { let mem = MemoryInstance::new(Pages(1), None); - mem.set(6, &[13, 17, 129]) - .expect("memory set should not fail"); + mem.set(6, &[13, 17, 129]).expect("memory set should not fail"); let mut data = [0u8; 2]; - mem.get_into(7, &mut data[..]) - .expect("get_into should not fail"); + mem.get_into(7, &mut data[..]).expect("get_into should not fail"); assert_eq!(data, [17, 129]); } diff --git a/src/module.rs b/src/module.rs index 6a5f241..3951c33 100644 --- a/src/module.rs +++ b/src/module.rs @@ -298,46 +298,36 @@ impl ModuleInstance { let code = loaded_module.code(); { - let funcs = module - .function_section() - .map(|fs| fs.entries()) - .unwrap_or(&[]); + let funcs = module.function_section().map(|fs| fs.entries()).unwrap_or(&[]); let bodies = module.code_section().map(|cs| cs.bodies()).unwrap_or(&[]); debug_assert!( funcs.len() == bodies.len(), "Due to validation func and body counts must match" ); - for (index, (ty, body)) in - Iterator::zip(funcs.into_iter(), bodies.into_iter()).enumerate() - { + for (index, (ty, body)) in Iterator::zip(funcs.into_iter(), bodies.into_iter()).enumerate() { let signature = instance .signature_by_index(ty.type_ref()) .expect("Due to validation type should exists"); - let code = code.get(index).expect( - "At func validation time labels are collected; Collected labels are added by index; qed", - ).clone(); + let code = code + .get(index) + .expect("At func validation time labels are collected; Collected labels are added by index; qed") + .clone(); let func_body = FuncBody { locals: body.locals().to_vec(), code: code, }; - let func_instance = - FuncInstance::alloc_internal(Rc::downgrade(&instance.0), signature, func_body); + let func_instance = FuncInstance::alloc_internal(Rc::downgrade(&instance.0), signature, func_body); instance.push_func(func_instance); } } for table_type in module.table_section().map(|ts| ts.entries()).unwrap_or(&[]) { - let table = - TableInstance::alloc(table_type.limits().initial(), table_type.limits().maximum())?; + let table = TableInstance::alloc(table_type.limits().initial(), table_type.limits().maximum())?; instance.push_table(table); } - for memory_type in module - .memory_section() - .map(|ms| ms.entries()) - .unwrap_or(&[]) - { + for memory_type in module.memory_section().map(|ms| ms.entries()).unwrap_or(&[]) { let initial: Pages = Pages(memory_type.limits().initial() as usize); let maximum: Option = memory_type.limits().maximum().map(|m| Pages(m as usize)); @@ -346,21 +336,13 @@ impl ModuleInstance { instance.push_memory(memory); } - for global_entry in module - .global_section() - .map(|gs| gs.entries()) - .unwrap_or(&[]) - { + for global_entry in module.global_section().map(|gs| gs.entries()).unwrap_or(&[]) { let init_val = eval_init_expr(global_entry.init_expr(), &*instance); let global = GlobalInstance::alloc(init_val, global_entry.global_type().is_mutable()); instance.push_global(global); } - for export in module - .export_section() - .map(|es| es.entries()) - .unwrap_or(&[]) - { + for export in module.export_section().map(|es| es.entries()).unwrap_or(&[]) { let field = export.field(); let extern_val: ExternVal = match *export.internal() { Internal::Function(idx) => { @@ -408,11 +390,7 @@ impl ModuleInstance { let module_ref = ModuleInstance::alloc_module(loaded_module, extern_vals)?; - for element_segment in module - .elements_section() - .map(|es| es.entries()) - .unwrap_or(&[]) - { + for element_segment in module.elements_section().map(|es| es.entries()).unwrap_or(&[]) { let offset_val = match eval_init_expr(element_segment.offset(), &module_ref) { RuntimeValue::I32(v) => v as u32, _ => panic!("Due to validation elem segment offset should evaluate to i32"), @@ -424,12 +402,8 @@ impl ModuleInstance { // This check is not only for bailing out early, but also to check the case when // segment consist of 0 members. - if offset_val as u64 + element_segment.members().len() as u64 - > table_inst.current_size() as u64 - { - return Err(Error::Instantiation( - "elements segment does not fit".to_string(), - )); + if offset_val as u64 + element_segment.members().len() as u64 > table_inst.current_size() as u64 { + return Err(Error::Instantiation("elements segment does not fit".to_string())); } for (j, func_idx) in element_segment.members().into_iter().enumerate() { @@ -541,20 +515,17 @@ impl ModuleInstance { } External::Table(ref table_type) => { let table_descriptor = TableDescriptor::from_elements(table_type); - let table = - imports.resolve_table(module_name, field_name, &table_descriptor)?; + let table = imports.resolve_table(module_name, field_name, &table_descriptor)?; ExternVal::Table(table) } External::Memory(ref memory_type) => { let memory_descriptor = MemoryDescriptor::from_elements(memory_type); - let memory = - imports.resolve_memory(module_name, field_name, &memory_descriptor)?; + let memory = imports.resolve_memory(module_name, field_name, &memory_descriptor)?; ExternVal::Memory(memory) } External::Global(ref global_type) => { let global_descriptor = GlobalDescriptor::from_elements(global_type); - let global = - imports.resolve_global(module_name, field_name, &global_descriptor)?; + let global = imports.resolve_global(module_name, field_name, &global_descriptor)?; ExternVal::Global(global) } }; @@ -711,10 +682,7 @@ impl<'a> NotStartedModuleRef<'a> { fn eval_init_expr(init_expr: &InitExpr, module: &ModuleInstance) -> RuntimeValue { let code = init_expr.code(); - debug_assert!( - code.len() == 2, - "Due to validation `code`.len() should be 2" - ); + debug_assert!(code.len() == 2, "Due to validation `code`.len() should be 2"); match code[0] { Instruction::I32Const(v) => v.into(), Instruction::I64Const(v) => v.into(), diff --git a/src/nan_preserving_float.rs b/src/nan_preserving_float.rs index cb40c6d..254e929 100644 --- a/src/nan_preserving_float.rs +++ b/src/nan_preserving_float.rs @@ -12,10 +12,7 @@ macro_rules! impl_binop { type Output = Self; fn $func_name(self, other: T) -> Self { - $for( - $op::$func_name($is::from_bits(self.0), $is::from_bits(other.into().0)) - .to_bits(), - ) + $for($op::$func_name($is::from_bits(self.0), $is::from_bits(other.into().0)).to_bits()) } } }; @@ -23,12 +20,7 @@ macro_rules! impl_binop { macro_rules! float { ($for:ident, $rep:ident, $is:ident) => { - float!( - $for, - $rep, - $is, - 1 << (::core::mem::size_of::<$is>() * 8 - 1) - ); + float!($for, $rep, $is, 1 << (::core::mem::size_of::<$is>() * 8 - 1)); }; ($for:ident, $rep:ident, $is:ident, $sign_bit:expr) => { #[derive(Copy, Clone)] diff --git a/src/runner.rs b/src/runner.rs index 64c464d..d854421 100644 --- a/src/runner.rs +++ b/src/runner.rs @@ -13,8 +13,8 @@ use module::ModuleRef; use nan_preserving_float::{F32, F64}; use parity_wasm::elements::Local; use value::{ - ArithmeticOps, ExtendInto, Float, Integer, LittleEndianConvert, RuntimeValue, TransmuteInto, - TryTruncateInto, WrapInto, + ArithmeticOps, ExtendInto, Float, Integer, LittleEndianConvert, RuntimeValue, TransmuteInto, TryTruncateInto, + WrapInto, }; use {Signature, Trap, TrapKind, ValueType}; @@ -211,9 +211,7 @@ impl Interpreter { self.state = InterpreterState::Started; self.run_interpreter_loop(externals)?; - let opt_return_value = self - .return_type - .map(|vt| self.value_stack.pop().with_type(vt)); + let opt_return_value = self.return_type.map(|vt| self.value_stack.pop().with_type(vt)); // Ensure that stack is empty after the execution. This is guaranteed by the validation properties. assert!(self.value_stack.len() == 0); @@ -235,16 +233,12 @@ impl Interpreter { swap(&mut self.state, &mut resumable_state); if let Some(return_val) = return_val { - self.value_stack - .push(return_val.into()) - .map_err(Trap::new)?; + self.value_stack.push(return_val.into()).map_err(Trap::new)?; } self.run_interpreter_loop(externals)?; - let opt_return_value = self - .return_type - .map(|vt| self.value_stack.pop().with_type(vt)); + let opt_return_value = self.return_type.map(|vt| self.value_stack.pop().with_type(vt)); // Ensure that stack is empty after the execution. This is guaranteed by the validation properties. assert!(self.value_stack.len() == 0); @@ -252,20 +246,16 @@ impl Interpreter { Ok(opt_return_value) } - fn run_interpreter_loop<'a, E: Externals + 'a>( - &mut self, - externals: &'a mut E, - ) -> Result<(), Trap> { + fn run_interpreter_loop<'a, E: Externals + 'a>(&mut self, externals: &'a mut E) -> Result<(), Trap> { loop { - let mut function_context = self.call_stack.pop().expect( - "on loop entry - not empty; on loop continue - checking for emptiness; qed", - ); + let mut function_context = self + .call_stack + .pop() + .expect("on loop entry - not empty; on loop continue - checking for emptiness; qed"); let function_ref = function_context.function.clone(); let function_body = function_ref .body() - .expect( - "Host functions checked in function_return below; Internal functions always have a body; qed" - ); + .expect("Host functions checked in function_return below; Internal functions always have a body; qed"); if !function_context.is_initialized() { // Initialize stack frame for the function call. @@ -300,18 +290,15 @@ impl Interpreter { // We push the function context first. If the VM is not resumable, it does no harm. If it is, we then save the context here. self.call_stack.push(function_context); - let return_val = - match FuncInstance::invoke(&nested_func, &args, externals) { - Ok(val) => val, - Err(trap) => { - if trap.kind().is_host() { - self.state = InterpreterState::Resumable( - nested_func.signature().return_type(), - ); - } - return Err(trap); + let return_val = match FuncInstance::invoke(&nested_func, &args, externals) { + Ok(val) => val, + Err(trap) => { + if trap.kind().is_host() { + self.state = InterpreterState::Resumable(nested_func.signature().return_type()); } - }; + return Err(trap); + } + }; // Check if `return_val` matches the signature. let value_ty = return_val.as_ref().map(|val| val.value_type()); @@ -321,9 +308,7 @@ impl Interpreter { } if let Some(return_val) = return_val { - self.value_stack - .push(return_val.into()) - .map_err(Trap::new)?; + self.value_stack.push(return_val.into()).map_err(Trap::new)?; } } } @@ -392,52 +377,26 @@ impl Interpreter { &isa::Instruction::I64Load(offset) => self.run_load::(context, offset), &isa::Instruction::F32Load(offset) => self.run_load::(context, offset), &isa::Instruction::F64Load(offset) => self.run_load::(context, offset), - &isa::Instruction::I32Load8S(offset) => { - self.run_load_extend::(context, offset) - } - &isa::Instruction::I32Load8U(offset) => { - self.run_load_extend::(context, offset) - } - &isa::Instruction::I32Load16S(offset) => { - self.run_load_extend::(context, offset) - } - &isa::Instruction::I32Load16U(offset) => { - self.run_load_extend::(context, offset) - } - &isa::Instruction::I64Load8S(offset) => { - self.run_load_extend::(context, offset) - } - &isa::Instruction::I64Load8U(offset) => { - self.run_load_extend::(context, offset) - } - &isa::Instruction::I64Load16S(offset) => { - self.run_load_extend::(context, offset) - } - &isa::Instruction::I64Load16U(offset) => { - self.run_load_extend::(context, offset) - } - &isa::Instruction::I64Load32S(offset) => { - self.run_load_extend::(context, offset) - } - &isa::Instruction::I64Load32U(offset) => { - self.run_load_extend::(context, offset) - } + &isa::Instruction::I32Load8S(offset) => self.run_load_extend::(context, offset), + &isa::Instruction::I32Load8U(offset) => self.run_load_extend::(context, offset), + &isa::Instruction::I32Load16S(offset) => self.run_load_extend::(context, offset), + &isa::Instruction::I32Load16U(offset) => self.run_load_extend::(context, offset), + &isa::Instruction::I64Load8S(offset) => self.run_load_extend::(context, offset), + &isa::Instruction::I64Load8U(offset) => self.run_load_extend::(context, offset), + &isa::Instruction::I64Load16S(offset) => self.run_load_extend::(context, offset), + &isa::Instruction::I64Load16U(offset) => self.run_load_extend::(context, offset), + &isa::Instruction::I64Load32S(offset) => self.run_load_extend::(context, offset), + &isa::Instruction::I64Load32U(offset) => self.run_load_extend::(context, offset), &isa::Instruction::I32Store(offset) => self.run_store::(context, offset), &isa::Instruction::I64Store(offset) => self.run_store::(context, offset), &isa::Instruction::F32Store(offset) => self.run_store::(context, offset), &isa::Instruction::F64Store(offset) => self.run_store::(context, offset), &isa::Instruction::I32Store8(offset) => self.run_store_wrap::(context, offset), - &isa::Instruction::I32Store16(offset) => { - self.run_store_wrap::(context, offset) - } + &isa::Instruction::I32Store16(offset) => self.run_store_wrap::(context, offset), &isa::Instruction::I64Store8(offset) => self.run_store_wrap::(context, offset), - &isa::Instruction::I64Store16(offset) => { - self.run_store_wrap::(context, offset) - } - &isa::Instruction::I64Store32(offset) => { - self.run_store_wrap::(context, offset) - } + &isa::Instruction::I64Store16(offset) => self.run_store_wrap::(context, offset), + &isa::Instruction::I64Store32(offset) => self.run_store_wrap::(context, offset), &isa::Instruction::CurrentMemory => self.run_current_memory(context), &isa::Instruction::GrowMemory => self.run_grow_memory(context), @@ -582,18 +541,11 @@ impl Interpreter { } } - fn run_unreachable( - &mut self, - _context: &mut FunctionContext, - ) -> Result { + fn run_unreachable(&mut self, _context: &mut FunctionContext) -> Result { Err(TrapKind::Unreachable) } - fn run_br( - &mut self, - _context: &mut FunctionContext, - target: isa::Target, - ) -> Result { + fn run_br(&mut self, _context: &mut FunctionContext, target: isa::Target) -> Result { Ok(InstructionOutcome::Branch(target)) } @@ -633,11 +585,7 @@ impl Interpreter { Ok(InstructionOutcome::Return(drop_keep)) } - fn run_call( - &mut self, - context: &mut FunctionContext, - func_idx: u32, - ) -> Result { + fn run_call(&mut self, context: &mut FunctionContext, func_idx: u32) -> Result { let func = context .module() .func_by_index(func_idx) @@ -707,11 +655,7 @@ impl Interpreter { Ok(InstructionOutcome::RunNextInstruction) } - fn run_get_global( - &mut self, - context: &mut FunctionContext, - index: u32, - ) -> Result { + fn run_get_global(&mut self, context: &mut FunctionContext, index: u32) -> Result { let global = context .module() .global_by_index(index) @@ -721,11 +665,7 @@ impl Interpreter { Ok(InstructionOutcome::RunNextInstruction) } - fn run_set_global( - &mut self, - context: &mut FunctionContext, - index: u32, - ) -> Result { + fn run_set_global(&mut self, context: &mut FunctionContext, index: u32) -> Result { let val = self.value_stack.pop(); let global = context .module() @@ -737,23 +677,15 @@ impl Interpreter { Ok(InstructionOutcome::RunNextInstruction) } - fn run_load( - &mut self, - context: &mut FunctionContext, - offset: u32, - ) -> Result + fn run_load(&mut self, context: &mut FunctionContext, offset: u32) -> Result where RuntimeValueInternal: From, T: LittleEndianConvert, { let raw_address = self.value_stack.pop_as(); let address = effective_address(offset, raw_address)?; - let m = context - .memory() - .expect("Due to validation memory should exists"); - let n: T = m - .get_value(address) - .map_err(|_| TrapKind::MemoryAccessOutOfBounds)?; + let m = context.memory().expect("Due to validation memory should exists"); + let n: T = m.get_value(address).map_err(|_| TrapKind::MemoryAccessOutOfBounds)?; self.value_stack.push(n.into())?; Ok(InstructionOutcome::RunNextInstruction) } @@ -770,12 +702,8 @@ impl Interpreter { { let raw_address = self.value_stack.pop_as(); let address = effective_address(offset, raw_address)?; - let m = context - .memory() - .expect("Due to validation memory should exists"); - let v: T = m - .get_value(address) - .map_err(|_| TrapKind::MemoryAccessOutOfBounds)?; + let m = context.memory().expect("Due to validation memory should exists"); + let v: T = m.get_value(address).map_err(|_| TrapKind::MemoryAccessOutOfBounds)?; let stack_value: U = v.extend_into(); self.value_stack .push(stack_value.into()) @@ -783,11 +711,7 @@ impl Interpreter { .map(|_| InstructionOutcome::RunNextInstruction) } - fn run_store( - &mut self, - context: &mut FunctionContext, - offset: u32, - ) -> Result + fn run_store(&mut self, context: &mut FunctionContext, offset: u32) -> Result where T: FromRuntimeValueInternal, T: LittleEndianConvert, @@ -796,9 +720,7 @@ impl Interpreter { let raw_address = self.value_stack.pop_as::(); let address = effective_address(offset, raw_address)?; - let m = context - .memory() - .expect("Due to validation memory should exists"); + let m = context.memory().expect("Due to validation memory should exists"); m.set_value(address, stack_value) .map_err(|_| TrapKind::MemoryAccessOutOfBounds)?; Ok(InstructionOutcome::RunNextInstruction) @@ -818,34 +740,22 @@ impl Interpreter { let stack_value = stack_value.wrap_into(); let raw_address = self.value_stack.pop_as::(); let address = effective_address(offset, raw_address)?; - let m = context - .memory() - .expect("Due to validation memory should exists"); + let m = context.memory().expect("Due to validation memory should exists"); m.set_value(address, stack_value) .map_err(|_| TrapKind::MemoryAccessOutOfBounds)?; Ok(InstructionOutcome::RunNextInstruction) } - fn run_current_memory( - &mut self, - context: &mut FunctionContext, - ) -> Result { - let m = context - .memory() - .expect("Due to validation memory should exists"); + fn run_current_memory(&mut self, context: &mut FunctionContext) -> Result { + let m = context.memory().expect("Due to validation memory should exists"); let s = m.current_size().0; self.value_stack.push(RuntimeValueInternal(s as _))?; Ok(InstructionOutcome::RunNextInstruction) } - fn run_grow_memory( - &mut self, - context: &mut FunctionContext, - ) -> Result { + fn run_grow_memory(&mut self, context: &mut FunctionContext) -> Result { let pages: u32 = self.value_stack.pop_as(); - let m = context - .memory() - .expect("Due to validation memory should exists"); + let m = context.memory().expect("Due to validation memory should exists"); let m = match m.grow(Pages(pages as usize)) { Ok(Pages(new_size)) => new_size as u32, Err(_) => u32::MAX, // Returns -1 (or 0xFFFFFFFF) in case of error. @@ -1279,11 +1189,7 @@ impl FunctionContext { self.is_initialized } - pub fn initialize( - &mut self, - locals: &[Local], - value_stack: &mut ValueStack, - ) -> Result<(), TrapKind> { + pub fn initialize(&mut self, locals: &[Local], value_stack: &mut ValueStack) -> Result<(), TrapKind> { debug_assert!(!self.is_initialized); let num_locals = locals.iter().map(|l| l.count() as usize).sum(); @@ -1291,9 +1197,7 @@ impl FunctionContext { // TODO: Replace with extend. for local in locals { - value_stack - .push(local) - .map_err(|_| TrapKind::StackOverflow)?; + value_stack.push(local).map_err(|_| TrapKind::StackOverflow)?; } self.is_initialized = true; @@ -1322,10 +1226,7 @@ fn effective_address(address: u32, offset: u32) -> Result { } } -fn prepare_function_args( - signature: &Signature, - caller_stack: &mut ValueStack, -) -> Vec { +fn prepare_function_args(signature: &Signature, caller_stack: &mut ValueStack) -> Vec { let mut out = signature .params() .iter() @@ -1341,14 +1242,10 @@ pub fn check_function_args(signature: &Signature, args: &[RuntimeValue]) -> Resu return Err(TrapKind::UnexpectedSignature.into()); } - if signature - .params() - .iter() - .zip(args) - .any(|(expected_type, param_value)| { - let actual_type = param_value.value_type(); - &actual_type != expected_type - }) { + if signature.params().iter().zip(args).any(|(expected_type, param_value)| { + let actual_type = param_value.value_type(); + &actual_type != expected_type + }) { return Err(TrapKind::UnexpectedSignature.into()); } @@ -1405,13 +1302,7 @@ impl ValueStack { } #[inline] - fn pop_triple( - &mut self, - ) -> ( - RuntimeValueInternal, - RuntimeValueInternal, - RuntimeValueInternal, - ) { + fn pop_triple(&mut self) -> (RuntimeValueInternal, RuntimeValueInternal, RuntimeValueInternal) { let right = self.pop(); let mid = self.pop(); let left = self.pop(); @@ -1440,10 +1331,7 @@ impl ValueStack { #[inline] fn push(&mut self, value: RuntimeValueInternal) -> Result<(), TrapKind> { - let cell = self - .buf - .get_mut(self.sp) - .ok_or_else(|| TrapKind::StackOverflow)?; + let cell = self.buf.get_mut(self.sp).ok_or_else(|| TrapKind::StackOverflow)?; *cell = value; self.sp += 1; Ok(()) diff --git a/src/table.rs b/src/table.rs index c60af42..7247e12 100644 --- a/src/table.rs +++ b/src/table.rs @@ -109,13 +109,8 @@ impl TableInstance { let new_size = self .current_size() .checked_add(by) - .and_then(|new_size| { - if maximum_size < new_size { - None - } else { - Some(new_size) - } - }).ok_or_else(|| { + .and_then(|new_size| if maximum_size < new_size { None } else { Some(new_size) }) + .ok_or_else(|| { Error::Table(format!( "Trying to grow table by {} items when there are already {} items", by, diff --git a/src/tests/host.rs b/src/tests/host.rs index f217f91..e10e713 100644 --- a/src/tests/host.rs +++ b/src/tests/host.rs @@ -2,9 +2,9 @@ use super::parse_wat; use memory_units::Pages; use types::ValueType; use { - Error, Externals, FuncInstance, FuncRef, HostError, ImportsBuilder, MemoryDescriptor, - MemoryInstance, MemoryRef, ModuleImportResolver, ModuleInstance, ModuleRef, ResumableError, - RuntimeArgs, RuntimeValue, Signature, TableDescriptor, TableInstance, TableRef, Trap, TrapKind, + Error, Externals, FuncInstance, FuncRef, HostError, ImportsBuilder, MemoryDescriptor, MemoryInstance, MemoryRef, + ModuleImportResolver, ModuleInstance, ModuleRef, ResumableError, RuntimeArgs, RuntimeValue, Signature, + TableDescriptor, TableInstance, TableRef, Trap, TrapKind, }; #[derive(Debug, Clone, PartialEq)] @@ -85,11 +85,7 @@ const RECURSE_FUNC_INDEX: usize = 4; const TRAP_SUB_FUNC_INDEX: usize = 5; impl Externals for TestHost { - fn invoke_index( - &mut self, - index: usize, - args: RuntimeArgs, - ) -> Result, Trap> { + fn invoke_index(&mut self, index: usize, args: RuntimeArgs) -> Result, Trap> { match index { SUB_FUNC_INDEX => { let a: i32 = args.nth(0); @@ -131,9 +127,7 @@ impl Externals for TestHost { Ok(Some(RuntimeValue::I32(buf[0] as i32))) } RECURSE_FUNC_INDEX => { - let val = args - .nth_value_checked(0) - .expect("Exactly one argument expected"); + let val = args.nth_value_checked(0).expect("Exactly one argument expected"); let instance = self .instance @@ -146,9 +140,7 @@ impl Externals for TestHost { .expect("expected to be Some"); if val.value_type() != result.value_type() { - return Err( - TrapKind::Host(Box::new(HostErrorWithCode { error_code: 123 })).into(), - ); + return Err(TrapKind::Host(Box::new(HostErrorWithCode { error_code: 123 })).into()); } Ok(Some(result)) } @@ -198,12 +190,7 @@ impl ModuleImportResolver for TestHost { "get_mem" => GET_MEM_FUNC_INDEX, "recurse" => RECURSE_FUNC_INDEX, "trap_sub" => TRAP_SUB_FUNC_INDEX, - _ => { - return Err(Error::Instantiation(format!( - "Export {} not found", - field_name - ))) - } + _ => return Err(Error::Instantiation(format!("Export {} not found", field_name))), }; if !self.check_signature(index, signature) { @@ -216,15 +203,8 @@ impl ModuleImportResolver for TestHost { Ok(FuncInstance::alloc_host(signature.clone(), index)) } - fn resolve_memory( - &self, - field_name: &str, - _memory_type: &MemoryDescriptor, - ) -> Result { - Err(Error::Instantiation(format!( - "Export {} not found", - field_name - ))) + fn resolve_memory(&self, field_name: &str, _memory_type: &MemoryDescriptor) -> Result { + Err(Error::Instantiation(format!("Export {} not found", field_name))) } } @@ -484,10 +464,7 @@ fn defer_providing_externals() { impl ModuleImportResolver for HostImportResolver { fn resolve_func(&self, field_name: &str, signature: &Signature) -> Result { if field_name != "inc" { - return Err(Error::Instantiation(format!( - "Export {} not found", - field_name - ))); + return Err(Error::Instantiation(format!("Export {} not found", field_name))); } if signature.params() != &[ValueType::I32] || signature.return_type() != None { return Err(Error::Instantiation(format!( @@ -499,18 +476,11 @@ fn defer_providing_externals() { Ok(FuncInstance::alloc_host(signature.clone(), INC_FUNC_INDEX)) } - fn resolve_memory( - &self, - field_name: &str, - _memory_type: &MemoryDescriptor, - ) -> Result { + fn resolve_memory(&self, field_name: &str, _memory_type: &MemoryDescriptor) -> Result { if field_name == "mem" { Ok(self.mem.clone()) } else { - Err(Error::Instantiation(format!( - "Export {} not found", - field_name - ))) + Err(Error::Instantiation(format!("Export {} not found", field_name))) } } } @@ -522,11 +492,7 @@ fn defer_providing_externals() { } impl<'a> Externals for HostExternals<'a> { - fn invoke_index( - &mut self, - index: usize, - args: RuntimeArgs, - ) -> Result, Trap> { + fn invoke_index(&mut self, index: usize, args: RuntimeArgs) -> Result, Trap> { match index { INC_FUNC_INDEX => { let a = args.nth::(0); @@ -569,12 +535,8 @@ fn defer_providing_externals() { { let mut host_externals = HostExternals { acc: &mut acc }; - instance - .invoke_export("test", &[], &mut host_externals) - .unwrap(); // acc += 1; - instance - .invoke_export("test", &[], &mut host_externals) - .unwrap(); // acc += 1; + instance.invoke_export("test", &[], &mut host_externals).unwrap(); // acc += 1; + instance.invoke_export("test", &[], &mut host_externals).unwrap(); // acc += 1; } assert_eq!(acc, 91); } @@ -587,11 +549,7 @@ fn two_envs_one_externals() { struct HostExternals; impl Externals for HostExternals { - fn invoke_index( - &mut self, - index: usize, - _args: RuntimeArgs, - ) -> Result, Trap> { + fn invoke_index(&mut self, index: usize, _args: RuntimeArgs) -> Result, Trap> { match index { PRIVILEGED_FUNC_INDEX => { println!("privileged!"); @@ -611,12 +569,7 @@ fn two_envs_one_externals() { let index = match field_name { "ordinary" => ORDINARY_FUNC_INDEX, "privileged" => PRIVILEGED_FUNC_INDEX, - _ => { - return Err(Error::Instantiation(format!( - "Export {} not found", - field_name - ))) - } + _ => return Err(Error::Instantiation(format!("Export {} not found", field_name))), }; Ok(FuncInstance::alloc_host(signature.clone(), index)) @@ -632,12 +585,7 @@ fn two_envs_one_externals() { "'priveleged' can be imported only in privileged context".into(), )) } - _ => { - return Err(Error::Instantiation(format!( - "Export {} not found", - field_name - ))) - } + _ => return Err(Error::Instantiation(format!("Export {} not found", field_name))), }; Ok(FuncInstance::alloc_host(signature.clone(), index)) @@ -701,11 +649,7 @@ fn dynamically_add_host_func() { } impl Externals for HostExternals { - fn invoke_index( - &mut self, - index: usize, - _args: RuntimeArgs, - ) -> Result, Trap> { + fn invoke_index(&mut self, index: usize, _args: RuntimeArgs) -> Result, Trap> { match index { ADD_FUNC_FUNC_INDEX => { // Allocate indicies for the new function. @@ -724,9 +668,7 @@ fn dynamically_add_host_func() { Ok(Some(RuntimeValue::I32(table_index as i32))) } - index if index as u32 <= self.added_funcs => { - Ok(Some(RuntimeValue::I32(index as i32))) - } + index if index as u32 <= self.added_funcs => Ok(Some(RuntimeValue::I32(index as i32))), _ => panic!("'env' module doesn't provide function at index {}", index), } } @@ -736,28 +678,16 @@ fn dynamically_add_host_func() { fn resolve_func(&self, field_name: &str, signature: &Signature) -> Result { let index = match field_name { "add_func" => ADD_FUNC_FUNC_INDEX, - _ => { - return Err(Error::Instantiation(format!( - "Export {} not found", - field_name - ))) - } + _ => return Err(Error::Instantiation(format!("Export {} not found", field_name))), }; Ok(FuncInstance::alloc_host(signature.clone(), index)) } - fn resolve_table( - &self, - field_name: &str, - _table_type: &TableDescriptor, - ) -> Result { + fn resolve_table(&self, field_name: &str, _table_type: &TableDescriptor) -> Result { if field_name == "table" { Ok(self.table.clone()) } else { - Err(Error::Instantiation(format!( - "Export {} not found", - field_name - ))) + Err(Error::Instantiation(format!("Export {} not found", field_name))) } } } @@ -786,11 +716,9 @@ fn dynamically_add_host_func() { "#, ); - let instance = ModuleInstance::new( - &module, - &ImportsBuilder::new().with_resolver("env", &host_externals), - ).expect("Failed to instantiate module") - .assert_no_start(); + let instance = ModuleInstance::new(&module, &ImportsBuilder::new().with_resolver("env", &host_externals)) + .expect("Failed to instantiate module") + .assert_no_start(); assert_eq!( instance diff --git a/src/tests/wasm.rs b/src/tests/wasm.rs index c9b2d25..afe5a10 100644 --- a/src/tests/wasm.rs +++ b/src/tests/wasm.rs @@ -1,9 +1,9 @@ use memory_units::Pages; use std::fs::File; use { - Error, FuncRef, GlobalDescriptor, GlobalInstance, GlobalRef, ImportsBuilder, MemoryDescriptor, - MemoryInstance, MemoryRef, Module, ModuleImportResolver, ModuleInstance, NopExternals, - RuntimeValue, Signature, TableDescriptor, TableInstance, TableRef, + Error, FuncRef, GlobalDescriptor, GlobalInstance, GlobalRef, ImportsBuilder, MemoryDescriptor, MemoryInstance, + MemoryRef, Module, ModuleImportResolver, ModuleInstance, NopExternals, RuntimeValue, Signature, TableDescriptor, + TableInstance, TableRef, }; struct Env { @@ -26,16 +26,10 @@ impl Env { impl ModuleImportResolver for Env { fn resolve_func(&self, _field_name: &str, _func_type: &Signature) -> Result { - Err(Error::Instantiation( - "env module doesn't provide any functions".into(), - )) + Err(Error::Instantiation("env module doesn't provide any functions".into())) } - fn resolve_global( - &self, - field_name: &str, - _global_type: &GlobalDescriptor, - ) -> Result { + fn resolve_global(&self, field_name: &str, _global_type: &GlobalDescriptor) -> Result { match field_name { "tableBase" => Ok(self.table_base.clone()), "memoryBase" => Ok(self.memory_base.clone()), @@ -46,11 +40,7 @@ impl ModuleImportResolver for Env { } } - fn resolve_memory( - &self, - field_name: &str, - _memory_type: &MemoryDescriptor, - ) -> Result { + fn resolve_memory(&self, field_name: &str, _memory_type: &MemoryDescriptor) -> Result { match field_name { "memory" => Ok(self.memory.clone()), _ => Err(Error::Instantiation(format!( @@ -60,11 +50,7 @@ impl ModuleImportResolver for Env { } } - fn resolve_table( - &self, - field_name: &str, - _table_type: &TableDescriptor, - ) -> Result { + fn resolve_table(&self, field_name: &str, _table_type: &TableDescriptor) -> Result { match field_name { "table" => Ok(self.table.clone()), _ => Err(Error::Instantiation(format!( @@ -134,10 +120,7 @@ fn interpreter_accumulate_u8() { let _ = env_memory.set(offset, BUF); // Set up the function argument list and invoke the function - let args = &[ - RuntimeValue::I32(BUF.len() as i32), - RuntimeValue::I32(offset as i32), - ]; + let args = &[RuntimeValue::I32(BUF.len() as i32), RuntimeValue::I32(offset as i32)]; let retval = instance .invoke_export(FUNCTION_NAME, args, &mut NopExternals) .expect("Failed to execute function"); diff --git a/src/types.rs b/src/types.rs index 0509bc3..a2e32a7 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,8 +1,6 @@ use alloc::borrow::Cow; -use parity_wasm::elements::{ - FunctionType, GlobalType, MemoryType, TableType, ValueType as EValueType, -}; +use parity_wasm::elements::{FunctionType, GlobalType, MemoryType, TableType, ValueType as EValueType}; /// Signature of a [function]. /// @@ -37,10 +35,7 @@ impl Signature { /// let dynamic_params = vec![ValueType::I64]; /// let s3 = Signature::new(dynamic_params, None); /// ``` - pub fn new>>( - params: C, - return_type: Option, - ) -> Signature { + pub fn new>>(params: C, return_type: Option) -> Signature { Signature { params: params.into(), return_type: return_type, diff --git a/src/validation/context.rs b/src/validation/context.rs index c54923c..8e71c88 100644 --- a/src/validation/context.rs +++ b/src/validation/context.rs @@ -1,8 +1,6 @@ #[allow(unused_imports)] use alloc::prelude::*; -use parity_wasm::elements::{ - BlockType, FunctionType, GlobalType, MemoryType, TableType, ValueType, -}; +use parity_wasm::elements::{BlockType, FunctionType, GlobalType, MemoryType, TableType, ValueType}; use validation::Error; #[derive(Default, Debug)] @@ -63,10 +61,7 @@ impl ModuleContext { .ok_or_else(|| Error(format!("Type at index {} doesn't exists", idx)))?; let params = ty.params(); - let return_ty = ty - .return_type() - .map(BlockType::Value) - .unwrap_or(BlockType::NoResult); + let return_ty = ty.return_type().map(BlockType::Value).unwrap_or(BlockType::NoResult); Ok((params, return_ty)) } diff --git a/src/validation/func.rs b/src/validation/func.rs index c30f900..51bd899 100644 --- a/src/validation/func.rs +++ b/src/validation/func.rs @@ -158,11 +158,7 @@ enum Outcome { pub struct FunctionReader; impl FunctionReader { - pub fn read_function( - module: &ModuleContext, - func: &Func, - body: &FuncBody, - ) -> Result { + pub fn read_function(module: &ModuleContext, func: &Func, body: &FuncBody) -> Result { let (params, result_ty) = module.require_function_type(func.type_ref())?; let ins_size_estimate = body.code().elements().len(); @@ -190,10 +186,7 @@ impl FunctionReader { Ok(context.into_code()) } - fn read_function_body( - context: &mut FunctionValidationContext, - body: &[Instruction], - ) -> Result<(), Error> { + fn read_function_body(context: &mut FunctionValidationContext, body: &[Instruction]) -> Result<(), Error> { let body_len = body.len(); if body_len == 0 { return Err(Error("Non-empty function body expected".into())); @@ -202,19 +195,16 @@ impl FunctionReader { loop { let instruction = &body[context.position]; - let outcome = - FunctionReader::read_instruction(context, instruction).map_err(|err| { - Error(format!( - "At instruction {:?}(@{}): {}", - instruction, context.position, err - )) - })?; + let outcome = FunctionReader::read_instruction(context, instruction).map_err(|err| { + Error(format!( + "At instruction {:?}(@{}): {}", + instruction, context.position, err + )) + })?; match outcome { Outcome::NextInstruction => (), - Outcome::Unreachable => { - make_top_frame_polymorphic(&mut context.value_stack, &mut context.frame_stack) - } + Outcome::Unreachable => make_top_frame_polymorphic(&mut context.value_stack, &mut context.frame_stack), } context.position += 1; @@ -224,10 +214,7 @@ impl FunctionReader { } } - fn read_instruction( - context: &mut FunctionValidationContext, - instruction: &Instruction, - ) -> Result { + fn read_instruction(context: &mut FunctionValidationContext, instruction: &Instruction) -> Result { use self::Instruction::*; match *instruction { // Nop instruction doesn't do anything. It is safe to just skip it. @@ -267,11 +254,7 @@ impl FunctionReader { let if_not = context.sink.new_label(); let end_label = context.sink.new_label(); - pop_value( - &mut context.value_stack, - &context.frame_stack, - ValueType::I32.into(), - )?; + pop_value(&mut context.value_stack, &context.frame_stack, ValueType::I32.into())?; push_label( BlockFrameType::IfTrue { if_not, end_label }, block_type, @@ -334,9 +317,9 @@ impl FunctionReader { // A `if` without an `else` can't return a result. if block_type != BlockType::NoResult { return Err(Error(format!( - "If block without else required to have NoResult block type. But it has {:?} type", - block_type - ))); + "If block without else required to have NoResult block type. But it has {:?} type", + block_type + ))); } // Resolve `if_not` label. If the `if's` condition doesn't hold the control will jump @@ -356,19 +339,11 @@ impl FunctionReader { // Check the return type. if let BlockType::Value(value_type) = context.return_type()? { - tee_value( - &mut context.value_stack, - &context.frame_stack, - value_type.into(), - )?; + tee_value(&mut context.value_stack, &context.frame_stack, value_type.into())?; } // Emit the return instruction. - let drop_keep = drop_keep_return( - &context.locals, - &context.value_stack, - &context.frame_stack, - ); + let drop_keep = drop_keep_return(&context.locals, &context.value_stack, &context.frame_stack); context.sink.emit(isa::Instruction::Return(drop_keep)); } @@ -401,23 +376,17 @@ impl FunctionReader { let target = require_target(*depth, &context.value_stack, &context.frame_stack); targets.push(target); } - let default_target = - require_target(default, &context.value_stack, &context.frame_stack); + let default_target = require_target(default, &context.value_stack, &context.frame_stack); context.sink.emit_br_table(&targets, default_target); return Ok(Outcome::Unreachable); } Return => { if let BlockType::Value(value_type) = context.return_type()? { - tee_value( - &mut context.value_stack, - &context.frame_stack, - value_type.into(), - )?; + tee_value(&mut context.value_stack, &context.frame_stack, value_type.into())?; } - let drop_keep = - drop_keep_return(&context.locals, &context.value_stack, &context.frame_stack); + let drop_keep = drop_keep_return(&context.locals, &context.value_stack, &context.frame_stack); context.sink.emit(isa::Instruction::Return(drop_keep)); return Ok(Outcome::Unreachable); @@ -1098,72 +1067,33 @@ impl FunctionReader { struct Validator; impl Validator { - fn validate_const( - context: &mut FunctionValidationContext, - value_type: ValueType, - ) -> Result<(), Error> { + fn validate_const(context: &mut FunctionValidationContext, value_type: ValueType) -> Result<(), Error> { push_value(&mut context.value_stack, value_type.into())?; Ok(()) } - fn validate_unop( - context: &mut FunctionValidationContext, - value_type: ValueType, - ) -> Result<(), Error> { - pop_value( - &mut context.value_stack, - &context.frame_stack, - value_type.into(), - )?; + fn validate_unop(context: &mut FunctionValidationContext, value_type: ValueType) -> Result<(), Error> { + pop_value(&mut context.value_stack, &context.frame_stack, value_type.into())?; push_value(&mut context.value_stack, value_type.into())?; Ok(()) } - fn validate_binop( - context: &mut FunctionValidationContext, - value_type: ValueType, - ) -> Result<(), Error> { - pop_value( - &mut context.value_stack, - &context.frame_stack, - value_type.into(), - )?; - pop_value( - &mut context.value_stack, - &context.frame_stack, - value_type.into(), - )?; + fn validate_binop(context: &mut FunctionValidationContext, value_type: ValueType) -> Result<(), Error> { + pop_value(&mut context.value_stack, &context.frame_stack, value_type.into())?; + pop_value(&mut context.value_stack, &context.frame_stack, value_type.into())?; push_value(&mut context.value_stack, value_type.into())?; Ok(()) } - fn validate_testop( - context: &mut FunctionValidationContext, - value_type: ValueType, - ) -> Result<(), Error> { - pop_value( - &mut context.value_stack, - &context.frame_stack, - value_type.into(), - )?; + fn validate_testop(context: &mut FunctionValidationContext, value_type: ValueType) -> Result<(), Error> { + pop_value(&mut context.value_stack, &context.frame_stack, value_type.into())?; push_value(&mut context.value_stack, ValueType::I32.into())?; Ok(()) } - fn validate_relop( - context: &mut FunctionValidationContext, - value_type: ValueType, - ) -> Result<(), Error> { - pop_value( - &mut context.value_stack, - &context.frame_stack, - value_type.into(), - )?; - pop_value( - &mut context.value_stack, - &context.frame_stack, - value_type.into(), - )?; + fn validate_relop(context: &mut FunctionValidationContext, value_type: ValueType) -> Result<(), Error> { + pop_value(&mut context.value_stack, &context.frame_stack, value_type.into())?; + pop_value(&mut context.value_stack, &context.frame_stack, value_type.into())?; push_value(&mut context.value_stack, ValueType::I32.into())?; Ok(()) } @@ -1173,59 +1103,33 @@ impl Validator { value_type1: ValueType, value_type2: ValueType, ) -> Result<(), Error> { - pop_value( - &mut context.value_stack, - &context.frame_stack, - value_type1.into(), - )?; + pop_value(&mut context.value_stack, &context.frame_stack, value_type1.into())?; push_value(&mut context.value_stack, value_type2.into())?; Ok(()) } fn validate_drop(context: &mut FunctionValidationContext) -> Result<(), Error> { - pop_value( - &mut context.value_stack, - &context.frame_stack, - StackValueType::Any, - )?; + pop_value(&mut context.value_stack, &context.frame_stack, StackValueType::Any)?; Ok(()) } fn validate_select(context: &mut FunctionValidationContext) -> Result<(), Error> { - pop_value( - &mut context.value_stack, - &context.frame_stack, - ValueType::I32.into(), - )?; - let select_type = pop_value( - &mut context.value_stack, - &context.frame_stack, - StackValueType::Any, - )?; + pop_value(&mut context.value_stack, &context.frame_stack, ValueType::I32.into())?; + let select_type = pop_value(&mut context.value_stack, &context.frame_stack, StackValueType::Any)?; pop_value(&mut context.value_stack, &context.frame_stack, select_type)?; push_value(&mut context.value_stack, select_type)?; Ok(()) } - fn validate_get_local( - context: &mut FunctionValidationContext, - index: u32, - ) -> Result<(), Error> { + fn validate_get_local(context: &mut FunctionValidationContext, index: u32) -> Result<(), Error> { let local_type = require_local(&context.locals, index)?; push_value(&mut context.value_stack, local_type.into())?; Ok(()) } - fn validate_set_local( - context: &mut FunctionValidationContext, - index: u32, - ) -> Result<(), Error> { + fn validate_set_local(context: &mut FunctionValidationContext, index: u32) -> Result<(), Error> { let local_type = require_local(&context.locals, index)?; - let value_type = pop_value( - &mut context.value_stack, - &context.frame_stack, - StackValueType::Any, - )?; + let value_type = pop_value(&mut context.value_stack, &context.frame_stack, StackValueType::Any)?; if StackValueType::from(local_type) != value_type { return Err(Error(format!( "Trying to update local {} of type {:?} with value of type {:?}", @@ -1235,23 +1139,13 @@ impl Validator { Ok(()) } - fn validate_tee_local( - context: &mut FunctionValidationContext, - index: u32, - ) -> Result<(), Error> { + fn validate_tee_local(context: &mut FunctionValidationContext, index: u32) -> Result<(), Error> { let local_type = require_local(&context.locals, index)?; - tee_value( - &mut context.value_stack, - &context.frame_stack, - local_type.into(), - )?; + tee_value(&mut context.value_stack, &context.frame_stack, local_type.into())?; Ok(()) } - fn validate_get_global( - context: &mut FunctionValidationContext, - index: u32, - ) -> Result<(), Error> { + fn validate_get_global(context: &mut FunctionValidationContext, index: u32) -> Result<(), Error> { let global_type: StackValueType = { let global = context.module.require_global(index, None)?; global.content_type().into() @@ -1260,19 +1154,12 @@ impl Validator { Ok(()) } - fn validate_set_global( - context: &mut FunctionValidationContext, - index: u32, - ) -> Result<(), Error> { + fn validate_set_global(context: &mut FunctionValidationContext, index: u32) -> Result<(), Error> { let global_type: StackValueType = { let global = context.module.require_global(index, Some(true))?; global.content_type().into() }; - let value_type = pop_value( - &mut context.value_stack, - &context.frame_stack, - StackValueType::Any, - )?; + let value_type = pop_value(&mut context.value_stack, &context.frame_stack, StackValueType::Any)?; if global_type != value_type { return Err(Error(format!( "Trying to update global {} of type {:?} with value of type {:?}", @@ -1295,11 +1182,7 @@ impl Validator { ))); } - pop_value( - &mut context.value_stack, - &context.frame_stack, - ValueType::I32.into(), - )?; + pop_value(&mut context.value_stack, &context.frame_stack, ValueType::I32.into())?; context.module.require_memory(DEFAULT_MEMORY_INDEX)?; push_value(&mut context.value_stack, value_type.into())?; Ok(()) @@ -1319,16 +1202,8 @@ impl Validator { } context.module.require_memory(DEFAULT_MEMORY_INDEX)?; - pop_value( - &mut context.value_stack, - &context.frame_stack, - value_type.into(), - )?; - pop_value( - &mut context.value_stack, - &context.frame_stack, - ValueType::I32.into(), - )?; + pop_value(&mut context.value_stack, &context.frame_stack, value_type.into())?; + pop_value(&mut context.value_stack, &context.frame_stack, ValueType::I32.into())?; Ok(()) } @@ -1339,22 +1214,14 @@ impl Validator { }; if !frame_type.is_loop() { if let BlockType::Value(value_type) = frame_block_type { - tee_value( - &mut context.value_stack, - &context.frame_stack, - value_type.into(), - )?; + tee_value(&mut context.value_stack, &context.frame_stack, value_type.into())?; } } Ok(()) } fn validate_br_if(context: &mut FunctionValidationContext, depth: u32) -> Result<(), Error> { - pop_value( - &mut context.value_stack, - &context.frame_stack, - ValueType::I32.into(), - )?; + pop_value(&mut context.value_stack, &context.frame_stack, ValueType::I32.into())?; let (frame_type, frame_block_type) = { let frame = require_label(depth, &context.frame_stack)?; @@ -1362,21 +1229,13 @@ impl Validator { }; if !frame_type.is_loop() { if let BlockType::Value(value_type) = frame_block_type { - tee_value( - &mut context.value_stack, - &context.frame_stack, - value_type.into(), - )?; + tee_value(&mut context.value_stack, &context.frame_stack, value_type.into())?; } } Ok(()) } - fn validate_br_table( - context: &mut FunctionValidationContext, - table: &[u32], - default: u32, - ) -> Result<(), Error> { + fn validate_br_table(context: &mut FunctionValidationContext, table: &[u32], default: u32) -> Result<(), Error> { let required_block_type: BlockType = { let default_block = require_label(default, &context.frame_stack)?; let required_block_type = if !default_block.frame_type.is_loop() { @@ -1402,17 +1261,9 @@ impl Validator { required_block_type }; - pop_value( - &mut context.value_stack, - &context.frame_stack, - ValueType::I32.into(), - )?; + pop_value(&mut context.value_stack, &context.frame_stack, ValueType::I32.into())?; if let BlockType::Value(value_type) = required_block_type { - tee_value( - &mut context.value_stack, - &context.frame_stack, - value_type.into(), - )?; + tee_value(&mut context.value_stack, &context.frame_stack, value_type.into())?; } Ok(()) @@ -1421,11 +1272,7 @@ impl Validator { fn validate_call(context: &mut FunctionValidationContext, idx: u32) -> Result<(), Error> { let (argument_types, return_type) = context.module.require_function(idx)?; for argument_type in argument_types.iter().rev() { - pop_value( - &mut context.value_stack, - &context.frame_stack, - (*argument_type).into(), - )?; + pop_value(&mut context.value_stack, &context.frame_stack, (*argument_type).into())?; } if let BlockType::Value(value_type) = return_type { push_value(&mut context.value_stack, value_type.into())?; @@ -1433,10 +1280,7 @@ impl Validator { Ok(()) } - fn validate_call_indirect( - context: &mut FunctionValidationContext, - idx: u32, - ) -> Result<(), Error> { + fn validate_call_indirect(context: &mut FunctionValidationContext, idx: u32) -> Result<(), Error> { { let table = context.module.require_table(DEFAULT_TABLE_INDEX)?; if table.elem_type() != TableElementType::AnyFunc { @@ -1448,18 +1292,10 @@ impl Validator { } } - pop_value( - &mut context.value_stack, - &context.frame_stack, - ValueType::I32.into(), - )?; + pop_value(&mut context.value_stack, &context.frame_stack, ValueType::I32.into())?; let (argument_types, return_type) = context.module.require_function_type(idx)?; for argument_type in argument_types.iter().rev() { - pop_value( - &mut context.value_stack, - &context.frame_stack, - (*argument_type).into(), - )?; + pop_value(&mut context.value_stack, &context.frame_stack, (*argument_type).into())?; } if let BlockType::Value(value_type) = return_type { push_value(&mut context.value_stack, value_type.into())?; @@ -1475,11 +1311,7 @@ impl Validator { fn validate_grow_memory(context: &mut FunctionValidationContext) -> Result<(), Error> { context.module.require_memory(DEFAULT_MEMORY_INDEX)?; - pop_value( - &mut context.value_stack, - &context.frame_stack, - ValueType::I32.into(), - )?; + pop_value(&mut context.value_stack, &context.frame_stack, ValueType::I32.into())?; push_value(&mut context.value_stack, ValueType::I32.into())?; Ok(()) } @@ -1543,10 +1375,7 @@ fn make_top_frame_polymorphic( frame.polymorphic_stack = true; } -fn push_value( - value_stack: &mut StackWithLimit, - value_type: StackValueType, -) -> Result<(), Error> { +fn push_value(value_stack: &mut StackWithLimit, value_type: StackValueType) -> Result<(), Error> { Ok(value_stack.push(value_type.into())?) } @@ -1564,19 +1393,14 @@ fn pop_value( let actual_value = if stack_is_empty && is_stack_polymorphic { StackValueType::Any } else { - let value_stack_min = frame_stack - .top() - .expect("at least 1 topmost block") - .value_stack_len; + let value_stack_min = frame_stack.top().expect("at least 1 topmost block").value_stack_len; if value_stack.len() <= value_stack_min { return Err(Error("Trying to access parent frame stack values.".into())); } value_stack.pop()? }; match actual_value { - StackValueType::Specific(stack_value_type) if stack_value_type == value_type => { - Ok(actual_value) - } + StackValueType::Specific(stack_value_type) if stack_value_type == value_type => Ok(actual_value), StackValueType::Any => Ok(actual_value), stack_value_type @ _ => Err(Error(format!( "Expected value of type {:?} on top of stack. Got {:?}", @@ -1623,11 +1447,7 @@ fn pop_label( match block_type { BlockType::NoResult => (), BlockType::Value(required_value_type) => { - let _ = pop_value( - value_stack, - frame_stack, - StackValueType::Specific(required_value_type), - )?; + let _ = pop_value(value_stack, frame_stack, StackValueType::Specific(required_value_type))?; } } @@ -1649,10 +1469,7 @@ fn top_label(frame_stack: &StackWithLimit) -> &BlockFrame { .expect("this function can't be called with empty frame stack") } -fn require_label( - depth: u32, - frame_stack: &StackWithLimit, -) -> Result<&BlockFrame, Error> { +fn require_label(depth: u32, frame_stack: &StackWithLimit) -> Result<&BlockFrame, Error> { Ok(frame_stack.get(depth as usize)?) } @@ -1662,8 +1479,7 @@ fn require_target( frame_stack: &StackWithLimit, ) -> Target { let is_stack_polymorphic = top_label(frame_stack).polymorphic_stack; - let frame = - require_label(depth, frame_stack).expect("require_target called with a bogus depth"); + let frame = require_label(depth, frame_stack).expect("require_target called with a bogus depth"); // Find out how many values we need to keep (copy to the new stack location after the drop). let keep: isa::Keep = match (frame.frame_type, frame.block_type) { @@ -1727,11 +1543,7 @@ fn require_local(locals: &Locals, idx: u32) -> Result { } /// See stack layout definition in mod isa. -fn relative_local_depth( - idx: u32, - locals: &Locals, - value_stack: &StackWithLimit, -) -> Result { +fn relative_local_depth(idx: u32, locals: &Locals, value_stack: &StackWithLimit) -> Result { let value_stack_height = value_stack.len() as u32; let locals_and_params_count = locals.count(); @@ -1779,11 +1591,7 @@ impl Sink { self.ins.current_pc() } - fn pc_or_placeholder isa::Reloc>( - &mut self, - label: LabelId, - reloc_creator: F, - ) -> u32 { + fn pc_or_placeholder isa::Reloc>(&mut self, label: LabelId, reloc_creator: F) -> u32 { match self.labels[label.0] { (Label::Resolved(dst_pc), _) => dst_pc, (Label::NotResolved, ref mut unresolved) => { @@ -1832,17 +1640,14 @@ impl Sink { let pc = self.cur_pc(); let mut isa_targets = Vec::new(); - for (idx, &Target { label, drop_keep }) in - targets.iter().chain(iter::once(&default)).enumerate() - { + for (idx, &Target { label, drop_keep }) in targets.iter().chain(iter::once(&default)).enumerate() { let dst_pc = self.pc_or_placeholder(label, || isa::Reloc::BrTable { pc, idx }); isa_targets.push(isa::Target { dst_pc, drop_keep: drop_keep.into(), }); } - self.ins - .push(isa::Instruction::BrTable(isa_targets.into_boxed_slice())); + self.ins.push(isa::Instruction::BrTable(isa_targets.into_boxed_slice())); } /// Create a new unresolved label. @@ -1879,12 +1684,10 @@ impl Sink { // At this moment all labels should be resolved. assert!( { - self.labels - .iter() - .all(|(state, unresolved)| match (state, unresolved) { - (Label::Resolved(_), unresolved) if unresolved.is_empty() => true, - _ => false, - }) + self.labels.iter().all(|(state, unresolved)| match (state, unresolved) { + (Label::Resolved(_), unresolved) if unresolved.is_empty() => true, + _ => false, + }) }, "there are unresolved labels left: {:?}", self.labels diff --git a/src/validation/mod.rs b/src/validation/mod.rs index 26ed7a3..598c28a 100644 --- a/src/validation/mod.rs +++ b/src/validation/mod.rs @@ -15,8 +15,8 @@ use common::stack; use isa; use memory_units::Pages; use parity_wasm::elements::{ - BlockType, External, GlobalEntry, GlobalType, InitExpr, Instruction, Internal, MemoryType, - Module, ResizableLimits, TableType, Type, ValueType, + BlockType, External, GlobalEntry, GlobalType, InitExpr, Instruction, Internal, MemoryType, Module, ResizableLimits, + TableType, Type, ValueType, }; mod context; @@ -194,11 +194,7 @@ pub fn validate_module(module: Module) -> Result { ); // Fill elements with imported values. - for import_entry in module - .import_section() - .map(|i| i.entries()) - .unwrap_or_default() - { + for import_entry in module.import_section().map(|i| i.entries()).unwrap_or_default() { match *import_entry.external() { External::Function(idx) => context_builder.push_func_type_index(idx), External::Table(ref table) => context_builder.push_table(table.clone()), @@ -237,10 +233,7 @@ pub fn validate_module(module: Module) -> Result { let context = context_builder.build(); - let function_section_len = module - .function_section() - .map(|s| s.entries().len()) - .unwrap_or(0); + let function_section_len = module.function_section().map(|s| s.entries().len()).unwrap_or(0); let code_section_len = module.code_section().map(|s| s.bodies().len()).unwrap_or(0); if function_section_len != code_section_len { return Err(Error(format!( @@ -252,9 +245,7 @@ pub fn validate_module(module: Module) -> Result { // validate every function body in user modules if function_section_len != 0 { // tests use invalid code - let function_section = module - .function_section() - .expect("function_section_len != 0; qed"); + let function_section = module.function_section().expect("function_section_len != 0; qed"); let code_section = module .code_section() .expect("function_section_len != 0; function_section_len == code_section_len; qed"); @@ -264,14 +255,10 @@ pub fn validate_module(module: Module) -> Result { .bodies() .get(index as usize) .ok_or(Error(format!("Missing body for function {}", index)))?; - let code = - FunctionReader::read_function(&context, function, function_body).map_err(|e| { - let Error(ref msg) = e; - Error(format!( - "Function #{} reading/validation error: {}", - index, msg - )) - })?; + let code = FunctionReader::read_function(&context, function, function_body).map_err(|e| { + let Error(ref msg) = e; + Error(format!("Function #{} reading/validation error: {}", index, msg)) + })?; code_map.push(code); } } @@ -280,9 +267,7 @@ pub fn validate_module(module: Module) -> Result { if let Some(start_fn_idx) = module.start_section() { let (params, return_ty) = context.require_function(start_fn_idx)?; if return_ty != BlockType::NoResult || params.len() != 0 { - return Err(Error( - "start function expected to have type [] -> []".into(), - )); + return Err(Error("start function expected to have type [] -> []".into())); } } @@ -321,10 +306,7 @@ pub fn validate_module(module: Module) -> Result { } External::Global(ref global_type) => { if global_type.is_mutable() { - return Err(Error(format!( - "trying to import mutable global {}", - import.field() - ))); + return Err(Error(format!("trying to import mutable global {}", import.field()))); } } External::Memory(ref memory_type) => { @@ -423,9 +405,7 @@ fn validate_global_entry(global_entry: &GlobalEntry, globals: &[GlobalType]) -> fn expr_const_type(init_expr: &InitExpr, globals: &[GlobalType]) -> Result { let code = init_expr.code(); if code.len() != 2 { - return Err(Error( - "Init expression should always be with length 2".into(), - )); + return Err(Error("Init expression should always be with length 2".into())); } let expr_ty: ValueType = match code[0] { Instruction::I32Const(_) => ValueType::I32, @@ -439,12 +419,7 @@ fn expr_const_type(init_expr: &InitExpr, globals: &[GlobalType]) -> Result { - return Err(Error(format!( - "Global {} doesn't exists or not yet defined", - idx - ))) - } + None => return Err(Error(format!("Global {} doesn't exists or not yet defined", idx))), }, _ => return Err(Error("Non constant opcode in init expr".into())), }; diff --git a/src/validation/tests.rs b/src/validation/tests.rs index 08b270c..9610400 100644 --- a/src/validation/tests.rs +++ b/src/validation/tests.rs @@ -2,8 +2,8 @@ use super::{validate_module, ValidatedModule}; use isa; use parity_wasm::builder::module; use parity_wasm::elements::{ - deserialize_buffer, BlockType, External, GlobalEntry, GlobalType, ImportEntry, InitExpr, - Instruction, Instructions, MemoryType, Module, TableType, ValueType, + deserialize_buffer, BlockType, External, GlobalEntry, GlobalType, ImportEntry, InitExpr, Instruction, Instructions, + MemoryType, Module, TableType, ValueType, }; use wabt; @@ -39,12 +39,7 @@ fn limits() { assert_eq!(validate_module(m).is_ok(), is_valid); // defined memory - let m = module() - .memory() - .with_min(min) - .with_max(max) - .build() - .build(); + let m = module().memory().with_min(min).with_max(max).build().build(); assert_eq!(validate_module(m).is_ok(), is_valid); // imported table @@ -185,10 +180,8 @@ fn funcs() { .i32() .build() .body() - .with_instructions(Instructions::new(vec![ - Instruction::Call(1), - Instruction::End, - ])).build() + .with_instructions(Instructions::new(vec![Instruction::Call(1), Instruction::End])) + .build() .build() .function() .signature() @@ -196,10 +189,8 @@ fn funcs() { .i32() .build() .body() - .with_instructions(Instructions::new(vec![ - Instruction::Call(0), - Instruction::End, - ])).build() + .with_instructions(Instructions::new(vec![Instruction::Call(0), Instruction::End])) + .build() .build() .build(); assert!(validate_module(m).is_ok()); diff --git a/src/value.rs b/src/value.rs index bacc991..29cda8d 100644 --- a/src/value.rs +++ b/src/value.rs @@ -590,10 +590,7 @@ impl LittleEndianConvert for u8 { } fn from_little_endian(buffer: &[u8]) -> Result { - buffer - .get(0) - .cloned() - .ok_or_else(|| Error::InvalidLittleEndianBuffer) + buffer.get(0).cloned().ok_or_else(|| Error::InvalidLittleEndianBuffer) } } diff --git a/tests/spec/run.rs b/tests/spec/run.rs index f7baa76..2c04679 100644 --- a/tests/spec/run.rs +++ b/tests/spec/run.rs @@ -6,10 +6,9 @@ use std::fs::File; use wabt::script::{self, Action, Command, CommandKind, ScriptParser, Value}; use wasmi::memory_units::Pages; use wasmi::{ - Error as InterpreterError, Externals, FuncInstance, FuncRef, GlobalDescriptor, GlobalInstance, - GlobalRef, ImportResolver, ImportsBuilder, MemoryDescriptor, MemoryInstance, MemoryRef, Module, - ModuleImportResolver, ModuleInstance, ModuleRef, RuntimeArgs, RuntimeValue, Signature, - TableDescriptor, TableInstance, TableRef, Trap, + Error as InterpreterError, Externals, FuncInstance, FuncRef, GlobalDescriptor, GlobalInstance, GlobalRef, + ImportResolver, ImportsBuilder, MemoryDescriptor, MemoryInstance, MemoryRef, Module, ModuleImportResolver, + ModuleInstance, ModuleRef, RuntimeArgs, RuntimeValue, Signature, TableDescriptor, TableInstance, TableRef, Trap, }; fn spec_to_runtime_value(val: Value) -> RuntimeValue { @@ -64,11 +63,7 @@ impl SpecModule { const PRINT_FUNC_INDEX: usize = 0; impl Externals for SpecModule { - fn invoke_index( - &mut self, - index: usize, - args: RuntimeArgs, - ) -> Result, Trap> { + fn invoke_index(&mut self, index: usize, args: RuntimeArgs) -> Result, Trap> { match index { PRINT_FUNC_INDEX => { println!("print: {:?}", args); @@ -80,11 +75,7 @@ impl Externals for SpecModule { } impl ModuleImportResolver for SpecModule { - fn resolve_func( - &self, - field_name: &str, - func_type: &Signature, - ) -> Result { + fn resolve_func(&self, field_name: &str, func_type: &Signature) -> Result { let index = match field_name { "print" => PRINT_FUNC_INDEX, "print_i32" => PRINT_FUNC_INDEX, @@ -110,11 +101,7 @@ impl ModuleImportResolver for SpecModule { return Ok(func); } - fn resolve_global( - &self, - field_name: &str, - _global_type: &GlobalDescriptor, - ) -> Result { + fn resolve_global(&self, field_name: &str, _global_type: &GlobalDescriptor) -> Result { match field_name { "global_i32" => Ok(self.global_i32.clone()), "global_f32" => Ok(self.global_f32.clone()), @@ -126,11 +113,7 @@ impl ModuleImportResolver for SpecModule { } } - fn resolve_memory( - &self, - field_name: &str, - _memory_type: &MemoryDescriptor, - ) -> Result { + fn resolve_memory(&self, field_name: &str, _memory_type: &MemoryDescriptor) -> Result { if field_name == "memory" { return Ok(self.memory.clone()); } @@ -141,11 +124,7 @@ impl ModuleImportResolver for SpecModule { ))) } - fn resolve_table( - &self, - field_name: &str, - _table_type: &TableDescriptor, - ) -> Result { + fn resolve_table(&self, field_name: &str, _table_type: &TableDescriptor) -> Result { if field_name == "table" { return Ok(self.table.clone()); } @@ -184,9 +163,10 @@ impl SpecDriver { } fn module(&self, name: &str) -> Result { - self.instances.get(name).cloned().ok_or_else(|| { - InterpreterError::Instantiation(format!("Module not registered {}", name)) - }) + self.instances + .get(name) + .cloned() + .ok_or_else(|| InterpreterError::Instantiation(format!("Module not registered {}", name))) } fn module_or_last(&self, name: Option<&str>) -> Result { @@ -210,8 +190,7 @@ impl ImportResolver for SpecDriver { if module_name == "spectest" { self.spec_module.resolve_func(field_name, func_type) } else { - self.module(module_name)? - .resolve_func(field_name, func_type) + self.module(module_name)?.resolve_func(field_name, func_type) } } @@ -224,8 +203,7 @@ impl ImportResolver for SpecDriver { if module_name == "spectest" { self.spec_module.resolve_global(field_name, global_type) } else { - self.module(module_name)? - .resolve_global(field_name, global_type) + self.module(module_name)?.resolve_global(field_name, global_type) } } @@ -238,8 +216,7 @@ impl ImportResolver for SpecDriver { if module_name == "spectest" { self.spec_module.resolve_memory(field_name, memory_type) } else { - self.module(module_name)? - .resolve_memory(field_name, memory_type) + self.module(module_name)?.resolve_memory(field_name, memory_type) } } @@ -252,8 +229,7 @@ impl ImportResolver for SpecDriver { if module_name == "spectest" { self.spec_module.resolve_table(field_name, table_type) } else { - self.module(module_name)? - .resolve_table(field_name, table_type) + self.module(module_name)?.resolve_table(field_name, table_type) } } } @@ -271,11 +247,7 @@ fn try_load(wasm: &[u8], spec_driver: &mut SpecDriver) -> Result<(), Error> { Ok(()) } -fn load_module( - wasm: &[u8], - name: &Option, - spec_driver: &mut SpecDriver, -) -> Result { +fn load_module(wasm: &[u8], name: &Option, spec_driver: &mut SpecDriver) -> Result { let module = try_load_module(wasm)?; let instance = ModuleInstance::new(&module, spec_driver) .map_err(|e| Error::Load(e.to_string()))? @@ -288,10 +260,7 @@ fn load_module( Ok(instance) } -fn run_action( - program: &mut SpecDriver, - action: &Action, -) -> Result, InterpreterError> { +fn run_action(program: &mut SpecDriver, action: &Action) -> Result, InterpreterError> { match *action { Action::Invoke { ref module, @@ -300,37 +269,22 @@ fn run_action( } => { let module = program .module_or_last(module.as_ref().map(|x| x.as_ref())) - .expect(&format!( - "Expected program to have loaded module {:?}", - module - )); - let vec_args = args - .iter() - .cloned() - .map(spec_to_runtime_value) - .collect::>(); + .expect(&format!("Expected program to have loaded module {:?}", module)); + let vec_args = args.iter().cloned().map(spec_to_runtime_value).collect::>(); module.invoke_export(field, &vec_args, program.spec_module()) } Action::Get { - ref module, - ref field, - .. + ref module, ref field, .. } => { let module = program .module_or_last(module.as_ref().map(|x| x.as_ref())) - .expect(&format!( - "Expected program to have loaded module {:?}", - module - )); + .expect(&format!("Expected program to have loaded module {:?}", module)); let global = module .export_by_name(&field) - .ok_or_else(|| { - InterpreterError::Global(format!("Expected to have export with name {}", field)) - })?.as_global() + .ok_or_else(|| InterpreterError::Global(format!("Expected to have export with name {}", field)))? + .as_global() .cloned() - .ok_or_else(|| { - InterpreterError::Global(format!("Expected export {} to be a global", field)) - })?; + .ok_or_else(|| InterpreterError::Global(format!("Expected export {} to be a global", field)))?; Ok(Some(global.get())) } } @@ -348,12 +302,10 @@ fn try_spec(name: &str) -> Result<(), Error> { use std::io::Read; let mut spec_source = Vec::new(); let mut spec_file = File::open(&spec_script_path).expect("Can't open file"); - spec_file - .read_to_end(&mut spec_source) - .expect("Can't read file"); + spec_file.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(&spec_source, &format!("{}.wast", name)).expect("Can't read spec script"); let mut errors = vec![]; while let Some(Command { kind, line }) = parser.next()? { @@ -377,22 +329,15 @@ fn try_spec(name: &str) -> Result<(), Error> { match kind { CommandKind::Module { name, module, .. } => { - load_module(&module.into_vec(), &name, &mut spec_driver) - .expect("Failed to load module"); + load_module(&module.into_vec(), &name, &mut spec_driver).expect("Failed to load module"); } CommandKind::AssertReturn { action, expected } => { let result = run_action(&mut spec_driver, &action); match result { Ok(result) => { - let spec_expected = expected - .iter() - .cloned() - .map(spec_to_runtime_value) - .collect::>(); + let spec_expected = expected.iter().cloned().map(spec_to_runtime_value).collect::>(); let actual_result = result.into_iter().collect::>(); - for (actual_result, spec_expected) in - actual_result.iter().zip(spec_expected.iter()) - { + for (actual_result, spec_expected) in actual_result.iter().zip(spec_expected.iter()) { assert_eq!(actual_result.value_type(), spec_expected.value_type()); // f32::NAN != f32::NAN match spec_expected { @@ -413,8 +358,7 @@ fn try_spec(name: &str) -> Result<(), Error> { } } } - CommandKind::AssertReturnCanonicalNan { action } - | CommandKind::AssertReturnArithmeticNan { action } => { + CommandKind::AssertReturnCanonicalNan { action } | CommandKind::AssertReturnArithmeticNan { action } => { let result = run_action(&mut spec_driver, &action); match result { Ok(result) => { @@ -426,9 +370,7 @@ fn try_spec(name: &str) -> Result<(), Error> { RuntimeValue::F64(val) => if !val.is_nan() { panic!("Expected nan value, got {:?}", val) }, - val @ _ => { - panic!("Expected action to return float value, got {:?}", val) - } + val @ _ => panic!("Expected action to return float value, got {:?}", val), } } } @@ -448,10 +390,7 @@ fn try_spec(name: &str) -> Result<(), Error> { let result = run_action(&mut spec_driver, &action); match result { Ok(result) => { - panic!( - "Expected action to result in a trap, got result: {:?}", - result - ); + panic!("Expected action to result in a trap, got result: {:?}", result); } Err(_e) => {} } @@ -465,12 +404,10 @@ fn try_spec(name: &str) -> Result<(), Error> { Err(_e) => {} } } - CommandKind::AssertUninstantiable { module, .. } => { - match try_load(&module.into_vec(), &mut spec_driver) { - Ok(_) => panic!("Expected error running start function at line {}", line), - Err(_e) => {} - } - } + CommandKind::AssertUninstantiable { module, .. } => match try_load(&module.into_vec(), &mut spec_driver) { + Ok(_) => panic!("Expected error running start function at line {}", line), + Err(_e) => {} + }, CommandKind::Register { name, as_name, .. } => { let module = match spec_driver.module_or_last(name.as_ref().map(|x| x.as_ref())) { Ok(module) => module,