From 5c15ff9673c2459dc31623cf997b527ea1108a28 Mon Sep 17 00:00:00 2001 From: losfair Date: Thu, 9 Jan 2020 01:42:21 +0800 Subject: [PATCH 01/46] `ExceptionCode` and `ExceptionTable`. --- lib/runtime-core/src/backend.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/lib/runtime-core/src/backend.rs b/lib/runtime-core/src/backend.rs index 19995f3a7a8..96e6eb30a9c 100644 --- a/lib/runtime-core/src/backend.rs +++ b/lib/runtime-core/src/backend.rs @@ -183,6 +183,26 @@ pub struct CompilerConfig { pub backend_specific_config: Option, } +/// An exception table for a `RunnableModule`. +#[derive(Clone, Debug, Default)] +pub struct ExceptionTable { + /// Mappings from offsets in generated machine code to the corresponding exception code. + pub offset_to_code: HashMap, +} + +/// The code of an exception. +#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] +pub enum ExceptionCode { + /// An `unreachable` opcode was executed. + Unreachable, + + /// An arithmetic exception, e.g. divided by zero. + Arithmetic, + + /// Memory access exception, e.g. misaligned/out-of-bound read/write. + Memory, +} + pub trait Compiler { /// Compiles a `Module` from WebAssembly binary format. /// The `CompileToken` parameter ensures that this can only @@ -214,6 +234,10 @@ pub trait RunnableModule: Send + Sync { None } + fn get_exception_table(&self) -> Option<&ExceptionTable> { + None + } + unsafe fn patch_local_function(&self, _idx: usize, _target_address: usize) -> bool { false } From f44517b9fb5bb123a91f0801c9eca4272860feda Mon Sep 17 00:00:00 2001 From: losfair Date: Thu, 9 Jan 2020 01:42:50 +0800 Subject: [PATCH 02/46] Look up exception tables in trap handler. --- lib/runtime-core/src/fault.rs | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/lib/runtime-core/src/fault.rs b/lib/runtime-core/src/fault.rs index 2628e5df5c4..d30578624f6 100644 --- a/lib/runtime-core/src/fault.rs +++ b/lib/runtime-core/src/fault.rs @@ -375,15 +375,23 @@ extern "C" fn signal_trap_handler( _ => {} } + // Now we have looked up all possible handler tables but failed to find a handler + // for this exception that allows a normal return. + // + // So here we check whether this exception is caused by a suspend signal, return the + // state image if so, or throw the exception out otherwise. + let ctx: &mut vm::Ctx = &mut **CURRENT_CTX.with(|x| x.get()); let es_image = fault .read_stack(None) .expect("fault.read_stack() failed. Broken invariants?"); if is_suspend_signal { + // If this is a suspend signal, we parse the runtime state and return the resulting image. let image = build_instance_image(ctx, es_image); unwind_result = Box::new(image); } else { + // Otherwise, this is a real exception and we just throw it to the caller. if es_image.frames.len() > 0 { eprintln!( "\n{}", @@ -391,7 +399,26 @@ extern "C" fn signal_trap_handler( ); es_image.print_backtrace_if_needed(); } - // Just let the error propagate otherwise + + // Look up the exception tables and try to find an exception code. + let exc_code = CURRENT_CODE_VERSIONS.with(|versions| { + let versions = versions.borrow(); + for v in versions.iter() { + if let Some(table) = v.runnable_module.get_exception_table() { + let ip = fault.ip.get(); + let end = v.base + v.msm.total_size; + if ip >= v.base && ip < end { + if let Some(exc_code) = table.offset_to_code.get(&(ip - v.base)) { + return Some(*exc_code); + } + } + } + } + None + }); + if let Some(code) = exc_code { + unwind_result = Box::new(code); + } } true From 4b5b8976e9616084dbd088123236253ebd452055 Mon Sep 17 00:00:00 2001 From: losfair Date: Fri, 10 Jan 2020 02:53:08 +0800 Subject: [PATCH 03/46] Serialize/deserialize exception codes. --- lib/runtime-core/src/backend.rs | 10 ++++++++-- lib/runtime-core/src/error.rs | 3 +++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/runtime-core/src/backend.rs b/lib/runtime-core/src/backend.rs index 96e6eb30a9c..aceb752a755 100644 --- a/lib/runtime-core/src/backend.rs +++ b/lib/runtime-core/src/backend.rs @@ -184,14 +184,20 @@ pub struct CompilerConfig { } /// An exception table for a `RunnableModule`. -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug, Default, Serialize, Deserialize)] pub struct ExceptionTable { /// Mappings from offsets in generated machine code to the corresponding exception code. pub offset_to_code: HashMap, } +impl ExceptionTable { + pub fn new() -> Self { + Self::default() + } +} + /// The code of an exception. -#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)] pub enum ExceptionCode { /// An `unreachable` opcode was executed. Unreachable, diff --git a/lib/runtime-core/src/error.rs b/lib/runtime-core/src/error.rs index 391386e3b4f..fad87600549 100644 --- a/lib/runtime-core/src/error.rs +++ b/lib/runtime-core/src/error.rs @@ -1,6 +1,7 @@ //! The error module contains the data structures and helper functions used to implement errors that //! are produced and returned from the wasmer runtime core. use crate::types::{FuncSig, GlobalDescriptor, MemoryDescriptor, TableDescriptor, Type}; +use crate::backend::ExceptionCode; use core::borrow::Borrow; use std::any::Any; @@ -208,6 +209,8 @@ impl std::fmt::Display for RuntimeError { write!(f, "\"{}\"", s) } else if let Some(s) = data.downcast_ref::<&str>() { write!(f, "\"{}\"", s) + } else if let Some(exc_code) = data.downcast_ref::() { + write!(f, "\"{:?}\"", exc_code) } else { write!(f, "unknown error") } From 8bf0c1966cf6dc698d6554db03b0ca5b47320df0 Mon Sep 17 00:00:00 2001 From: losfair Date: Fri, 10 Jan 2020 02:53:31 +0800 Subject: [PATCH 04/46] Push code version for non-WASI entrypoints. --- src/bin/wasmer.rs | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/bin/wasmer.rs b/src/bin/wasmer.rs index 04ef6d3a2f3..cf33d2e5bab 100644 --- a/src/bin/wasmer.rs +++ b/src/bin/wasmer.rs @@ -41,6 +41,11 @@ use wasmer_runtime_core::{ loader::{Instance as LoadedInstance, LocalLoader}, Module, }; +#[cfg(unix)] +use wasmer_runtime_core::{ + fault::{pop_code_version, push_code_version}, + state::CodeVersion, +}; #[cfg(feature = "wasi")] use wasmer_wasi; @@ -472,12 +477,6 @@ fn execute_wasi( #[cfg(not(feature = "managed"))] { use wasmer_runtime::error::RuntimeError; - #[cfg(unix)] - use wasmer_runtime_core::{ - fault::{pop_code_version, push_code_version}, - state::CodeVersion, - }; - let result; #[cfg(unix)] @@ -849,11 +848,32 @@ fn execute_wasm(options: &Run) -> Result<(), String> { }; let args = options.parse_args(&module, invoke_fn)?; + #[cfg(unix)] + let cv_pushed = if let Some(msm) = instance.module.runnable_module.get_module_state_map() { + push_code_version(CodeVersion { + baseline: true, + msm: msm, + base: instance.module.runnable_module.get_code().unwrap().as_ptr() as usize, + backend: options.backend, + runnable_module: instance.module.runnable_module.clone(), + }); + true + } else { + false + }; + let result = instance .dyn_func(&invoke_fn) .map_err(|e| format!("{:?}", e))? .call(&args) .map_err(|e| format!("{:?}", e))?; + + #[cfg(unix)] + { + if cv_pushed { + pop_code_version().unwrap(); + } + } println!("{}({:?}) returned {:?}", invoke_fn, args, result); } } From 0a23327401801873c9c135ad92db814fec044d5c Mon Sep 17 00:00:00 2001 From: losfair Date: Fri, 10 Jan 2020 02:54:23 +0800 Subject: [PATCH 05/46] Emit exception table in singlepass. --- lib/singlepass-backend/src/codegen_x64.rs | 162 ++++++++++++++++++++-- 1 file changed, 154 insertions(+), 8 deletions(-) diff --git a/lib/singlepass-backend/src/codegen_x64.rs b/lib/singlepass-backend/src/codegen_x64.rs index ccc1089931b..c39fab5a5ea 100644 --- a/lib/singlepass-backend/src/codegen_x64.rs +++ b/lib/singlepass-backend/src/codegen_x64.rs @@ -25,6 +25,7 @@ use wasmer_runtime_core::{ sys::{Memory, Protect}, Architecture, Backend, CacheGen, CompilerConfig, InlineBreakpoint, InlineBreakpointType, MemoryBoundCheckMode, RunnableModule, Token, + ExceptionTable, ExceptionCode, }, cache::{Artifact, Error as CacheError}, codegen::*, @@ -224,6 +225,8 @@ pub struct X64FunctionCode { unreachable_depth: usize, config: Arc, + + exception_table: Option, } enum FuncPtrInner {} @@ -242,6 +245,7 @@ pub struct X64ExecutionContext { breakpoints: BreakpointMap, func_import_count: usize, msm: ModuleStateMap, + exception_table: ExceptionTable, } /// On-disk cache format. @@ -264,6 +268,9 @@ pub struct CacheImage { /// Module state map. msm: ModuleStateMap, + + /// An exception table that maps instruction offsets to exception codes. + exception_table: ExceptionTable, } #[derive(Debug)] @@ -322,6 +329,10 @@ impl RunnableModule for X64ExecutionContext { Some(self.breakpoints.clone()) } + fn get_exception_table(&self) -> Option<&ExceptionTable> { + Some(&self.exception_table) + } + unsafe fn patch_local_function(&self, idx: usize, target_address: usize) -> bool { /* 0: 48 b8 42 42 42 42 42 42 42 42 movabsq $4774451407313060418, %rax @@ -662,16 +673,18 @@ impl ModuleCodeGenerator &mut self, _module_info: Arc>, ) -> Result<&mut X64FunctionCode, CodegenError> { - let (mut assembler, mut function_labels, breakpoints) = match self.functions.last_mut() { + let (mut assembler, mut function_labels, breakpoints, exception_table) = match self.functions.last_mut() { Some(x) => ( x.assembler.take().unwrap(), x.function_labels.take().unwrap(), x.breakpoints.take().unwrap(), + x.exception_table.take().unwrap(), ), None => ( self.assembler.take().unwrap(), self.function_labels.take().unwrap(), HashMap::new(), + ExceptionTable::new(), ), }; @@ -707,6 +720,7 @@ impl ModuleCodeGenerator machine, unreachable_depth: 0, config: self.config.as_ref().unwrap().clone(), + exception_table: Some(exception_table), }; self.functions.push(code); Ok(self.functions.last_mut().unwrap()) @@ -716,16 +730,18 @@ impl ModuleCodeGenerator mut self, _: &ModuleInfo, ) -> Result<(X64ExecutionContext, Box), CodegenError> { - let (assembler, function_labels, breakpoints) = match self.functions.last_mut() { + let (assembler, function_labels, breakpoints, exception_table) = match self.functions.last_mut() { Some(x) => ( x.assembler.take().unwrap(), x.function_labels.take().unwrap(), x.breakpoints.take().unwrap(), + x.exception_table.take().unwrap(), ), None => ( self.assembler.take().unwrap(), self.function_labels.take().unwrap(), HashMap::new(), + ExceptionTable::new(), ), }; @@ -797,6 +813,7 @@ impl ModuleCodeGenerator function_offsets: out_offsets.iter().map(|x| x.0 as usize).collect(), func_import_count: self.func_import_count, msm: msm.clone(), + exception_table: exception_table.clone(), }; let cache = SinglepassCache { @@ -812,6 +829,7 @@ impl ModuleCodeGenerator function_pointers: out_labels, function_offsets: out_offsets, msm: msm, + exception_table, }, Box::new(cache), )) @@ -915,6 +933,7 @@ impl ModuleCodeGenerator breakpoints: Arc::new(HashMap::new()), func_import_count: cache_image.func_import_count, msm: cache_image.msm, + exception_table: cache_image.exception_table, }; Ok(ModuleInner { runnable_module: Arc::new(Box::new(ec)), @@ -947,10 +966,22 @@ impl X64FunctionCode { .insert(m.state.wasm_inst_offset, SuspendOffset::Trappable(offset)); } + /// Marks each address in the code range emitted by `f` with the exception code `code`. + fn mark_range_with_exception_code R, R>(a: &mut Assembler, etable: &mut ExceptionTable, code: ExceptionCode, f: F) -> R { + let begin = a.get_offset().0; + let ret = f(a); + let end = a.get_offset().0; + for i in begin..end { + etable.offset_to_code.insert(i, code); + } + ret + } + /// Moves `loc` to a valid location for `div`/`idiv`. fn emit_relaxed_xdiv( a: &mut Assembler, m: &mut Machine, + etable: &mut ExceptionTable, op: fn(&mut Assembler, Size, Location), sz: Size, loc: Location, @@ -962,10 +993,12 @@ impl X64FunctionCode { Location::Imm64(_) | Location::Imm32(_) => { a.emit_mov(sz, loc, Location::GPR(GPR::RCX)); // must not be used during div (rax, rdx) Self::mark_trappable(a, m, fsm, control_stack); + etable.offset_to_code.insert(a.get_offset().0, ExceptionCode::Arithmetic); op(a, sz, Location::GPR(GPR::RCX)); } _ => { Self::mark_trappable(a, m, fsm, control_stack); + etable.offset_to_code.insert(a.get_offset().0, ExceptionCode::Arithmetic); op(a, sz, loc); } } @@ -1876,6 +1909,7 @@ impl X64FunctionCode { config: &CodegenConfig, a: &mut Assembler, m: &mut Machine, + etable: &mut ExceptionTable, addr: Location, memarg: &MemoryImmediate, check_alignment: bool, @@ -1949,7 +1983,8 @@ impl X64FunctionCode { // Trap if the end address of the requested area is above that of the linear memory. a.emit_add(Size::S64, Location::GPR(tmp_base), Location::GPR(tmp_addr)); a.emit_cmp(Size::S64, Location::GPR(tmp_bound), Location::GPR(tmp_addr)); - a.emit_conditional_trap(Condition::Above); + + Self::mark_range_with_exception_code(a, etable, ExceptionCode::Memory, |a| a.emit_conditional_trap(Condition::Above)); m.release_temp_gpr(tmp_bound); } @@ -1989,11 +2024,13 @@ impl X64FunctionCode { Location::Imm32(align - 1), Location::GPR(tmp_aligncheck), ); - a.emit_conditional_trap(Condition::NotEqual); + Self::mark_range_with_exception_code(a, etable, ExceptionCode::Memory, |a| a.emit_conditional_trap(Condition::NotEqual)); m.release_temp_gpr(tmp_aligncheck); } - cb(a, m, tmp_addr)?; + Self::mark_range_with_exception_code(a, etable, ExceptionCode::Memory, |a| { + cb(a, m, tmp_addr) + })?; m.release_temp_gpr(tmp_addr); Ok(()) @@ -2005,6 +2042,7 @@ impl X64FunctionCode { config: &CodegenConfig, a: &mut Assembler, m: &mut Machine, + etable: &mut ExceptionTable, loc: Location, target: Location, ret: Location, @@ -2038,6 +2076,7 @@ impl X64FunctionCode { config, a, m, + etable, target, memarg, true, @@ -2108,6 +2147,7 @@ impl X64FunctionCode { fn emit_f32_int_conv_check_trap( a: &mut Assembler, m: &mut Machine, + etable: &mut ExceptionTable, reg: XMM, lower_bound: f32, upper_bound: f32, @@ -2117,6 +2157,7 @@ impl X64FunctionCode { Self::emit_f32_int_conv_check(a, m, reg, lower_bound, upper_bound, trap, trap, trap, end); a.emit_label(trap); + etable.offset_to_code.insert(a.get_offset().0, ExceptionCode::Arithmetic); a.emit_ud2(); a.emit_label(end); } @@ -2232,6 +2273,7 @@ impl X64FunctionCode { fn emit_f64_int_conv_check_trap( a: &mut Assembler, m: &mut Machine, + etable: &mut ExceptionTable, reg: XMM, lower_bound: f64, upper_bound: f64, @@ -2241,6 +2283,7 @@ impl X64FunctionCode { Self::emit_f64_int_conv_check(a, m, reg, lower_bound, upper_bound, trap, trap, trap, end); a.emit_label(trap); + etable.offset_to_code.insert(a.get_offset().0, ExceptionCode::Arithmetic); a.emit_ud2(); a.emit_label(end); } @@ -2365,7 +2408,7 @@ impl FunctionCodeGenerator for X64FunctionCode { ), Location::GPR(GPR::RSP), ); - a.emit_conditional_trap(Condition::Below); + Self::mark_range_with_exception_code(a, self.exception_table.as_mut().unwrap(), ExceptionCode::Memory, |a| a.emit_conditional_trap(Condition::Below)); } self.locals = self @@ -2788,6 +2831,7 @@ impl FunctionCodeGenerator for X64FunctionCode { Self::emit_relaxed_xdiv( a, &mut self.machine, + self.exception_table.as_mut().unwrap(), Assembler::emit_div, Size::S32, loc_b, @@ -2813,6 +2857,7 @@ impl FunctionCodeGenerator for X64FunctionCode { Self::emit_relaxed_xdiv( a, &mut self.machine, + self.exception_table.as_mut().unwrap(), Assembler::emit_idiv, Size::S32, loc_b, @@ -2838,6 +2883,7 @@ impl FunctionCodeGenerator for X64FunctionCode { Self::emit_relaxed_xdiv( a, &mut self.machine, + self.exception_table.as_mut().unwrap(), Assembler::emit_div, Size::S32, loc_b, @@ -2889,6 +2935,7 @@ impl FunctionCodeGenerator for X64FunctionCode { Self::emit_relaxed_xdiv( a, &mut self.machine, + self.exception_table.as_mut().unwrap(), Assembler::emit_idiv, Size::S32, loc_b, @@ -3187,6 +3234,7 @@ impl FunctionCodeGenerator for X64FunctionCode { Self::emit_relaxed_xdiv( a, &mut self.machine, + self.exception_table.as_mut().unwrap(), Assembler::emit_div, Size::S64, loc_b, @@ -3212,6 +3260,7 @@ impl FunctionCodeGenerator for X64FunctionCode { Self::emit_relaxed_xdiv( a, &mut self.machine, + self.exception_table.as_mut().unwrap(), Assembler::emit_idiv, Size::S64, loc_b, @@ -3237,6 +3286,7 @@ impl FunctionCodeGenerator for X64FunctionCode { Self::emit_relaxed_xdiv( a, &mut self.machine, + self.exception_table.as_mut().unwrap(), Assembler::emit_div, Size::S64, loc_b, @@ -3296,6 +3346,7 @@ impl FunctionCodeGenerator for X64FunctionCode { Self::emit_relaxed_xdiv( a, &mut self.machine, + self.exception_table.as_mut().unwrap(), Assembler::emit_idiv, Size::S64, loc_b, @@ -4748,6 +4799,7 @@ impl FunctionCodeGenerator for X64FunctionCode { Self::emit_f32_int_conv_check_trap( a, &mut self.machine, + self.exception_table.as_mut().unwrap(), tmp_in, GEF32_LT_U32_MIN, LEF32_GT_U32_MAX, @@ -4859,6 +4911,7 @@ impl FunctionCodeGenerator for X64FunctionCode { Self::emit_f32_int_conv_check_trap( a, &mut self.machine, + self.exception_table.as_mut().unwrap(), tmp_in, GEF32_LT_I32_MIN, LEF32_GT_I32_MAX, @@ -4976,6 +5029,7 @@ impl FunctionCodeGenerator for X64FunctionCode { Self::emit_f32_int_conv_check_trap( a, &mut self.machine, + self.exception_table.as_mut().unwrap(), tmp_in, GEF32_LT_I64_MIN, LEF32_GT_I64_MAX, @@ -5093,6 +5147,7 @@ impl FunctionCodeGenerator for X64FunctionCode { Self::emit_f32_int_conv_check_trap( a, &mut self.machine, + self.exception_table.as_mut().unwrap(), tmp_in, GEF32_LT_U64_MIN, LEF32_GT_U64_MAX, @@ -5253,6 +5308,7 @@ impl FunctionCodeGenerator for X64FunctionCode { Self::emit_f64_int_conv_check_trap( a, &mut self.machine, + self.exception_table.as_mut().unwrap(), tmp_in, GEF64_LT_U32_MIN, LEF64_GT_U32_MAX, @@ -5370,6 +5426,7 @@ impl FunctionCodeGenerator for X64FunctionCode { Self::emit_f64_int_conv_check_trap( a, &mut self.machine, + self.exception_table.as_mut().unwrap(), real_in, GEF64_LT_I32_MIN, LEF64_GT_I32_MAX, @@ -5493,6 +5550,7 @@ impl FunctionCodeGenerator for X64FunctionCode { Self::emit_f64_int_conv_check_trap( a, &mut self.machine, + self.exception_table.as_mut().unwrap(), tmp_in, GEF64_LT_I64_MIN, LEF64_GT_I64_MAX, @@ -5611,6 +5669,7 @@ impl FunctionCodeGenerator for X64FunctionCode { Self::emit_f64_int_conv_check_trap( a, &mut self.machine, + self.exception_table.as_mut().unwrap(), tmp_in, GEF64_LT_U64_MIN, LEF64_GT_U64_MAX, @@ -6210,7 +6269,7 @@ impl FunctionCodeGenerator for X64FunctionCode { Location::GPR(table_base), ); a.emit_cmp(Size::S32, func_index, Location::GPR(table_count)); - a.emit_conditional_trap(Condition::BelowEqual); + Self::mark_range_with_exception_code(a, self.exception_table.as_mut().unwrap(), ExceptionCode::Memory, |a| a.emit_conditional_trap(Condition::BelowEqual)); a.emit_mov(Size::S64, func_index, Location::GPR(table_count)); a.emit_imul_imm32_gpr64(vm::Anyfunc::size() as u32, table_count); a.emit_add( @@ -6236,7 +6295,7 @@ impl FunctionCodeGenerator for X64FunctionCode { Location::GPR(sigidx), Location::Memory(table_count, (vm::Anyfunc::offset_sig_id() as usize) as i32), ); - a.emit_conditional_trap(Condition::NotEqual); + Self::mark_range_with_exception_code(a, self.exception_table.as_mut().unwrap(), ExceptionCode::Memory, |a| a.emit_conditional_trap(Condition::NotEqual)); self.machine.release_temp_gpr(sigidx); self.machine.release_temp_gpr(table_count); @@ -6587,6 +6646,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, false, @@ -6619,6 +6679,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, false, @@ -6651,6 +6712,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, false, @@ -6684,6 +6746,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, false, @@ -6717,6 +6780,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, false, @@ -6750,6 +6814,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, false, @@ -6779,6 +6844,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target_addr, memarg, false, @@ -6807,6 +6873,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target_addr, memarg, false, @@ -6835,6 +6902,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target_addr, memarg, false, @@ -6863,6 +6931,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target_addr, memarg, false, @@ -6895,6 +6964,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, false, @@ -6927,6 +6997,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, false, @@ -6959,6 +7030,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, false, @@ -6992,6 +7064,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, false, @@ -7025,6 +7098,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, false, @@ -7058,6 +7132,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, false, @@ -7091,6 +7166,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, false, @@ -7138,6 +7214,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, false, @@ -7167,6 +7244,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target_addr, memarg, false, @@ -7195,6 +7273,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target_addr, memarg, false, @@ -7223,6 +7302,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target_addr, memarg, false, @@ -7251,6 +7331,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target_addr, memarg, false, @@ -7279,6 +7360,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target_addr, memarg, false, @@ -7298,6 +7380,7 @@ impl FunctionCodeGenerator for X64FunctionCode { } Operator::Unreachable => { Self::mark_trappable(a, &self.machine, &mut self.fsm, &mut self.control_stack); + self.exception_table.as_mut().unwrap().offset_to_code.insert(a.get_offset().0, ExceptionCode::Unreachable); a.emit_ud2(); self.unreachable_depth = 1; } @@ -7526,6 +7609,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, @@ -7558,6 +7642,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, @@ -7591,6 +7676,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, @@ -7620,6 +7706,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target_addr, memarg, true, @@ -7648,6 +7735,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target_addr, memarg, true, @@ -7676,6 +7764,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target_addr, memarg, true, @@ -7708,6 +7797,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, @@ -7740,6 +7830,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, @@ -7773,6 +7864,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, @@ -7806,6 +7898,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, @@ -7849,6 +7942,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target_addr, memarg, true, @@ -7877,6 +7971,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target_addr, memarg, true, @@ -7905,6 +8000,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target_addr, memarg, true, @@ -7933,6 +8029,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target_addr, memarg, true, @@ -7969,6 +8066,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, @@ -8004,6 +8102,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, @@ -8039,6 +8138,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, @@ -8070,6 +8170,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, @@ -8105,6 +8206,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, @@ -8136,6 +8238,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, @@ -8171,6 +8274,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, @@ -8207,6 +8311,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, @@ -8243,6 +8348,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, @@ -8279,6 +8385,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, @@ -8311,6 +8418,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, @@ -8347,6 +8455,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, @@ -8379,6 +8488,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, @@ -8415,6 +8525,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, @@ -8448,6 +8559,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), loc, target, ret, @@ -8477,6 +8589,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), loc, target, ret, @@ -8506,6 +8619,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), loc, target, ret, @@ -8535,6 +8649,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), loc, target, ret, @@ -8564,6 +8679,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), loc, target, ret, @@ -8593,6 +8709,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), loc, target, ret, @@ -8622,6 +8739,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), loc, target, ret, @@ -8651,6 +8769,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), loc, target, ret, @@ -8680,6 +8799,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), loc, target, ret, @@ -8709,6 +8829,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), loc, target, ret, @@ -8738,6 +8859,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), loc, target, ret, @@ -8767,6 +8889,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), loc, target, ret, @@ -8796,6 +8919,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), loc, target, ret, @@ -8825,6 +8949,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), loc, target, ret, @@ -8854,6 +8979,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), loc, target, ret, @@ -8883,6 +9009,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), loc, target, ret, @@ -8912,6 +9039,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), loc, target, ret, @@ -8941,6 +9069,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), loc, target, ret, @@ -8970,6 +9099,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), loc, target, ret, @@ -8999,6 +9129,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), loc, target, ret, @@ -9028,6 +9159,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), loc, target, ret, @@ -9059,6 +9191,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, @@ -9090,6 +9223,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, @@ -9121,6 +9255,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, @@ -9152,6 +9287,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, @@ -9183,6 +9319,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, @@ -9214,6 +9351,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, @@ -9245,6 +9383,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, @@ -9290,6 +9429,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, @@ -9340,6 +9480,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, @@ -9390,6 +9531,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, @@ -9440,6 +9582,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, @@ -9490,6 +9633,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, @@ -9540,6 +9684,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, @@ -9590,6 +9735,7 @@ impl FunctionCodeGenerator for X64FunctionCode { &self.config, a, &mut self.machine, + self.exception_table.as_mut().unwrap(), target, memarg, true, From 9e2080def1328f3b08e770a0d13fd8fa2a2f03c0 Mon Sep 17 00:00:00 2001 From: losfair Date: Fri, 10 Jan 2020 02:54:50 +0800 Subject: [PATCH 06/46] Run cargo fmt. --- lib/runtime-core/src/error.rs | 2 +- lib/singlepass-backend/src/codegen_x64.rs | 121 ++++++++++++++-------- src/bin/wasmer.rs | 25 ++--- 3 files changed, 93 insertions(+), 55 deletions(-) diff --git a/lib/runtime-core/src/error.rs b/lib/runtime-core/src/error.rs index fad87600549..94abce06d5a 100644 --- a/lib/runtime-core/src/error.rs +++ b/lib/runtime-core/src/error.rs @@ -1,7 +1,7 @@ //! The error module contains the data structures and helper functions used to implement errors that //! are produced and returned from the wasmer runtime core. -use crate::types::{FuncSig, GlobalDescriptor, MemoryDescriptor, TableDescriptor, Type}; use crate::backend::ExceptionCode; +use crate::types::{FuncSig, GlobalDescriptor, MemoryDescriptor, TableDescriptor, Type}; use core::borrow::Borrow; use std::any::Any; diff --git a/lib/singlepass-backend/src/codegen_x64.rs b/lib/singlepass-backend/src/codegen_x64.rs index c39fab5a5ea..bcf2acb25cd 100644 --- a/lib/singlepass-backend/src/codegen_x64.rs +++ b/lib/singlepass-backend/src/codegen_x64.rs @@ -23,9 +23,8 @@ use std::{ use wasmer_runtime_core::{ backend::{ sys::{Memory, Protect}, - Architecture, Backend, CacheGen, CompilerConfig, InlineBreakpoint, InlineBreakpointType, - MemoryBoundCheckMode, RunnableModule, Token, - ExceptionTable, ExceptionCode, + Architecture, Backend, CacheGen, CompilerConfig, ExceptionCode, ExceptionTable, + InlineBreakpoint, InlineBreakpointType, MemoryBoundCheckMode, RunnableModule, Token, }, cache::{Artifact, Error as CacheError}, codegen::*, @@ -673,20 +672,21 @@ impl ModuleCodeGenerator &mut self, _module_info: Arc>, ) -> Result<&mut X64FunctionCode, CodegenError> { - let (mut assembler, mut function_labels, breakpoints, exception_table) = match self.functions.last_mut() { - Some(x) => ( - x.assembler.take().unwrap(), - x.function_labels.take().unwrap(), - x.breakpoints.take().unwrap(), - x.exception_table.take().unwrap(), - ), - None => ( - self.assembler.take().unwrap(), - self.function_labels.take().unwrap(), - HashMap::new(), - ExceptionTable::new(), - ), - }; + let (mut assembler, mut function_labels, breakpoints, exception_table) = + match self.functions.last_mut() { + Some(x) => ( + x.assembler.take().unwrap(), + x.function_labels.take().unwrap(), + x.breakpoints.take().unwrap(), + x.exception_table.take().unwrap(), + ), + None => ( + self.assembler.take().unwrap(), + self.function_labels.take().unwrap(), + HashMap::new(), + ExceptionTable::new(), + ), + }; let begin_offset = assembler.offset(); let begin_label_info = function_labels @@ -730,20 +730,21 @@ impl ModuleCodeGenerator mut self, _: &ModuleInfo, ) -> Result<(X64ExecutionContext, Box), CodegenError> { - let (assembler, function_labels, breakpoints, exception_table) = match self.functions.last_mut() { - Some(x) => ( - x.assembler.take().unwrap(), - x.function_labels.take().unwrap(), - x.breakpoints.take().unwrap(), - x.exception_table.take().unwrap(), - ), - None => ( - self.assembler.take().unwrap(), - self.function_labels.take().unwrap(), - HashMap::new(), - ExceptionTable::new(), - ), - }; + let (assembler, function_labels, breakpoints, exception_table) = + match self.functions.last_mut() { + Some(x) => ( + x.assembler.take().unwrap(), + x.function_labels.take().unwrap(), + x.breakpoints.take().unwrap(), + x.exception_table.take().unwrap(), + ), + None => ( + self.assembler.take().unwrap(), + self.function_labels.take().unwrap(), + HashMap::new(), + ExceptionTable::new(), + ), + }; let total_size = assembler.get_offset().0; let _output = assembler.finalize().unwrap(); @@ -967,7 +968,12 @@ impl X64FunctionCode { } /// Marks each address in the code range emitted by `f` with the exception code `code`. - fn mark_range_with_exception_code R, R>(a: &mut Assembler, etable: &mut ExceptionTable, code: ExceptionCode, f: F) -> R { + fn mark_range_with_exception_code R, R>( + a: &mut Assembler, + etable: &mut ExceptionTable, + code: ExceptionCode, + f: F, + ) -> R { let begin = a.get_offset().0; let ret = f(a); let end = a.get_offset().0; @@ -993,12 +999,16 @@ impl X64FunctionCode { Location::Imm64(_) | Location::Imm32(_) => { a.emit_mov(sz, loc, Location::GPR(GPR::RCX)); // must not be used during div (rax, rdx) Self::mark_trappable(a, m, fsm, control_stack); - etable.offset_to_code.insert(a.get_offset().0, ExceptionCode::Arithmetic); + etable + .offset_to_code + .insert(a.get_offset().0, ExceptionCode::Arithmetic); op(a, sz, Location::GPR(GPR::RCX)); } _ => { Self::mark_trappable(a, m, fsm, control_stack); - etable.offset_to_code.insert(a.get_offset().0, ExceptionCode::Arithmetic); + etable + .offset_to_code + .insert(a.get_offset().0, ExceptionCode::Arithmetic); op(a, sz, loc); } } @@ -1984,7 +1994,9 @@ impl X64FunctionCode { a.emit_add(Size::S64, Location::GPR(tmp_base), Location::GPR(tmp_addr)); a.emit_cmp(Size::S64, Location::GPR(tmp_bound), Location::GPR(tmp_addr)); - Self::mark_range_with_exception_code(a, etable, ExceptionCode::Memory, |a| a.emit_conditional_trap(Condition::Above)); + Self::mark_range_with_exception_code(a, etable, ExceptionCode::Memory, |a| { + a.emit_conditional_trap(Condition::Above) + }); m.release_temp_gpr(tmp_bound); } @@ -2024,7 +2036,9 @@ impl X64FunctionCode { Location::Imm32(align - 1), Location::GPR(tmp_aligncheck), ); - Self::mark_range_with_exception_code(a, etable, ExceptionCode::Memory, |a| a.emit_conditional_trap(Condition::NotEqual)); + Self::mark_range_with_exception_code(a, etable, ExceptionCode::Memory, |a| { + a.emit_conditional_trap(Condition::NotEqual) + }); m.release_temp_gpr(tmp_aligncheck); } @@ -2157,7 +2171,9 @@ impl X64FunctionCode { Self::emit_f32_int_conv_check(a, m, reg, lower_bound, upper_bound, trap, trap, trap, end); a.emit_label(trap); - etable.offset_to_code.insert(a.get_offset().0, ExceptionCode::Arithmetic); + etable + .offset_to_code + .insert(a.get_offset().0, ExceptionCode::Arithmetic); a.emit_ud2(); a.emit_label(end); } @@ -2283,7 +2299,9 @@ impl X64FunctionCode { Self::emit_f64_int_conv_check(a, m, reg, lower_bound, upper_bound, trap, trap, trap, end); a.emit_label(trap); - etable.offset_to_code.insert(a.get_offset().0, ExceptionCode::Arithmetic); + etable + .offset_to_code + .insert(a.get_offset().0, ExceptionCode::Arithmetic); a.emit_ud2(); a.emit_label(end); } @@ -2408,7 +2426,12 @@ impl FunctionCodeGenerator for X64FunctionCode { ), Location::GPR(GPR::RSP), ); - Self::mark_range_with_exception_code(a, self.exception_table.as_mut().unwrap(), ExceptionCode::Memory, |a| a.emit_conditional_trap(Condition::Below)); + Self::mark_range_with_exception_code( + a, + self.exception_table.as_mut().unwrap(), + ExceptionCode::Memory, + |a| a.emit_conditional_trap(Condition::Below), + ); } self.locals = self @@ -6269,7 +6292,12 @@ impl FunctionCodeGenerator for X64FunctionCode { Location::GPR(table_base), ); a.emit_cmp(Size::S32, func_index, Location::GPR(table_count)); - Self::mark_range_with_exception_code(a, self.exception_table.as_mut().unwrap(), ExceptionCode::Memory, |a| a.emit_conditional_trap(Condition::BelowEqual)); + Self::mark_range_with_exception_code( + a, + self.exception_table.as_mut().unwrap(), + ExceptionCode::Memory, + |a| a.emit_conditional_trap(Condition::BelowEqual), + ); a.emit_mov(Size::S64, func_index, Location::GPR(table_count)); a.emit_imul_imm32_gpr64(vm::Anyfunc::size() as u32, table_count); a.emit_add( @@ -6295,7 +6323,12 @@ impl FunctionCodeGenerator for X64FunctionCode { Location::GPR(sigidx), Location::Memory(table_count, (vm::Anyfunc::offset_sig_id() as usize) as i32), ); - Self::mark_range_with_exception_code(a, self.exception_table.as_mut().unwrap(), ExceptionCode::Memory, |a| a.emit_conditional_trap(Condition::NotEqual)); + Self::mark_range_with_exception_code( + a, + self.exception_table.as_mut().unwrap(), + ExceptionCode::Memory, + |a| a.emit_conditional_trap(Condition::NotEqual), + ); self.machine.release_temp_gpr(sigidx); self.machine.release_temp_gpr(table_count); @@ -7380,7 +7413,11 @@ impl FunctionCodeGenerator for X64FunctionCode { } Operator::Unreachable => { Self::mark_trappable(a, &self.machine, &mut self.fsm, &mut self.control_stack); - self.exception_table.as_mut().unwrap().offset_to_code.insert(a.get_offset().0, ExceptionCode::Unreachable); + self.exception_table + .as_mut() + .unwrap() + .offset_to_code + .insert(a.get_offset().0, ExceptionCode::Unreachable); a.emit_ud2(); self.unreachable_depth = 1; } diff --git a/src/bin/wasmer.rs b/src/bin/wasmer.rs index cf33d2e5bab..1f62182adaf 100644 --- a/src/bin/wasmer.rs +++ b/src/bin/wasmer.rs @@ -849,18 +849,19 @@ fn execute_wasm(options: &Run) -> Result<(), String> { let args = options.parse_args(&module, invoke_fn)?; #[cfg(unix)] - let cv_pushed = if let Some(msm) = instance.module.runnable_module.get_module_state_map() { - push_code_version(CodeVersion { - baseline: true, - msm: msm, - base: instance.module.runnable_module.get_code().unwrap().as_ptr() as usize, - backend: options.backend, - runnable_module: instance.module.runnable_module.clone(), - }); - true - } else { - false - }; + let cv_pushed = + if let Some(msm) = instance.module.runnable_module.get_module_state_map() { + push_code_version(CodeVersion { + baseline: true, + msm: msm, + base: instance.module.runnable_module.get_code().unwrap().as_ptr() as usize, + backend: options.backend, + runnable_module: instance.module.runnable_module.clone(), + }); + true + } else { + false + }; let result = instance .dyn_func(&invoke_fn) From 661df38cf24b8e97aefce9f9fdea5c1e1a359d2d Mon Sep 17 00:00:00 2001 From: Syrus Date: Mon, 13 Jan 2020 11:58:31 +0100 Subject: [PATCH 07/46] Use blake3 instead of blake2_simd --- Cargo.lock | 14 ++++++++------ lib/runtime-core/Cargo.toml | 10 +++++----- lib/runtime-core/build.rs | 8 ++++---- lib/runtime-core/src/cache.rs | 10 +++++----- 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0718cf6f673..d6d4ed440be 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -63,13 +63,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] -name = "blake2b_simd" -version = "0.5.10" +name = "blake3" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a" +checksum = "b8c90bf4a07dd0b816948d0915ba1b110e7ce54169797feb5b39d6139a0a81ca" dependencies = [ "arrayref", "arrayvec", + "cc", + "cfg-if", "constant_time_eq", ] @@ -534,9 +536,9 @@ dependencies = [ [[package]] name = "hex" -version = "0.3.2" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" +checksum = "023b39be39e3a2da62a94feb433e91e8bcd37676fbc8bea371daf52b7a769a3e" [[package]] name = "indexmap" @@ -1788,7 +1790,7 @@ name = "wasmer-runtime-core" version = "0.12.0" dependencies = [ "bincode", - "blake2b_simd", + "blake3", "cc", "digest", "errno", diff --git a/lib/runtime-core/Cargo.toml b/lib/runtime-core/Cargo.toml index c4cd63baa99..c8b908894d7 100644 --- a/lib/runtime-core/Cargo.toml +++ b/lib/runtime-core/Cargo.toml @@ -13,11 +13,11 @@ edition = "2018" nix = "0.15" page_size = "0.4" wasmparser = "0.45.0" -parking_lot = "0.9" +parking_lot = "0.10.0" lazy_static = "1.4" errno = "0.2" libc = "0.2.60" -hex = "0.3" +hex = "0.4" smallvec = "0.6" bincode = "1.1" @@ -36,8 +36,8 @@ version = "1.0" version = "0.11" [dependencies.serde-bench] version = "0.0.7" -[dependencies.blake2b_simd] -version = "0.5" +[dependencies.blake3] +version = "0.1.0" [dependencies.digest] version = "0.8" @@ -45,7 +45,7 @@ version = "0.8" winapi = { version = "0.3", features = ["memoryapi"] } [build-dependencies] -blake2b_simd = "0.5" +blake3 = "0.1.0" rustc_version = "0.2" cc = "1.0" diff --git a/lib/runtime-core/build.rs b/lib/runtime-core/build.rs index 3a549e45fd4..9fd1ea457c0 100644 --- a/lib/runtime-core/build.rs +++ b/lib/runtime-core/build.rs @@ -1,13 +1,13 @@ -use blake2b_simd::blake2bp; +use blake3; use std::{env, fs, io::Write, path::PathBuf}; const WASMER_VERSION: &'static str = env!("CARGO_PKG_VERSION"); fn main() { - let mut state = blake2bp::State::new(); - state.update(WASMER_VERSION.as_bytes()); + let mut hasher = blake3::Hasher::new(); + hasher.update(WASMER_VERSION.as_bytes()); - let hasher = state.finalize(); + let hasher = hasher.finalize(); let hash_string = hasher.to_hex().as_str().to_owned(); let crate_dir = env::var("OUT_DIR").unwrap(); diff --git a/lib/runtime-core/src/cache.rs b/lib/runtime-core/src/cache.rs index e924cd9f5dd..dc88e99779e 100644 --- a/lib/runtime-core/src/cache.rs +++ b/lib/runtime-core/src/cache.rs @@ -7,7 +7,7 @@ use crate::{ module::{Module, ModuleInfo}, sys::Memory, }; -use blake2b_simd::blake2bp; +use blake3; use std::{fmt, io, mem, slice}; /// Indicates the invalid type of invalid cache file @@ -65,11 +65,11 @@ impl WasmHash { let mut first_part = [0u8; 32]; let mut second_part = [0u8; 32]; - let mut state = blake2bp::State::new(); - state.update(wasm); + let mut hasher = blake3::Hasher::new(); + hasher.update(wasm); - let hasher = state.finalize(); - let generic_array = hasher.as_bytes(); + let hash = hasher.finalize(); + let generic_array = hash.as_bytes(); first_part.copy_from_slice(&generic_array[0..32]); second_part.copy_from_slice(&generic_array[32..64]); From 6c0568798fb65b0fa78bb5e5cfc5d318bc9d5db5 Mon Sep 17 00:00:00 2001 From: Syrus Date: Mon, 13 Jan 2020 12:02:07 +0100 Subject: [PATCH 08/46] Added Blake3 changes into changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fe82692b441..2f7515991a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## **[Unreleased]** +- [#1140](https://github.com/wasmerio/wasmer/pull/1140) Use [`blake3`](https://github.com/BLAKE3-team/BLAKE3) as default hashing algorithm for caching. - [#1128](https://github.com/wasmerio/wasmer/pull/1128) Fix a crash when a host function is missing and the `allow_missing_functions` flag is enabled - [#1097](https://github.com/wasmerio/wasmer/pull/1097) Move inline breakpoint outside of runtime backend - [#1095](https://github.com/wasmerio/wasmer/pull/1095) Update to cranelift 0.52. From c45819de324fe824fa66aed69e877f2f6a907068 Mon Sep 17 00:00:00 2001 From: Syrus Date: Mon, 13 Jan 2020 14:59:50 +0100 Subject: [PATCH 09/46] Remove unnecessary import --- lib/runtime-core/build.rs | 1 - lib/runtime-core/src/cache.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/lib/runtime-core/build.rs b/lib/runtime-core/build.rs index 9fd1ea457c0..6187b4fd15a 100644 --- a/lib/runtime-core/build.rs +++ b/lib/runtime-core/build.rs @@ -1,4 +1,3 @@ -use blake3; use std::{env, fs, io::Write, path::PathBuf}; const WASMER_VERSION: &'static str = env!("CARGO_PKG_VERSION"); diff --git a/lib/runtime-core/src/cache.rs b/lib/runtime-core/src/cache.rs index c3a5f50a4bd..f95bba614ec 100644 --- a/lib/runtime-core/src/cache.rs +++ b/lib/runtime-core/src/cache.rs @@ -3,7 +3,6 @@ //! and loaded to allow skipping compilation and fast startup. use crate::{module::ModuleInfo, sys::Memory}; -use blake3; use std::{io, mem, slice}; /// Indicates the invalid type of invalid cache file From fcb158b24355c76b80c3e7237d8e2848598cafaf Mon Sep 17 00:00:00 2001 From: Syrus Date: Mon, 13 Jan 2020 15:11:02 +0100 Subject: [PATCH 10/46] Fixed cache --- lib/runtime-core/src/cache.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/runtime-core/src/cache.rs b/lib/runtime-core/src/cache.rs index f95bba614ec..127d110332b 100644 --- a/lib/runtime-core/src/cache.rs +++ b/lib/runtime-core/src/cache.rs @@ -58,7 +58,8 @@ impl WasmHash { /// is, in fact, a wasm module. pub fn generate(wasm: &[u8]) -> Self { let mut first_part = [0u8; 32]; - let mut second_part = [0u8; 32]; + // We don't use the second part for now, since the blake3 hash is 32 byte array + let second_part = [0u8; 32]; let mut hasher = blake3::Hasher::new(); hasher.update(wasm); @@ -67,7 +68,6 @@ impl WasmHash { let generic_array = hash.as_bytes(); first_part.copy_from_slice(&generic_array[0..32]); - second_part.copy_from_slice(&generic_array[32..64]); WasmHash(first_part, second_part) } From f4fb1077c95310feaf991c37dc9dbf4d2e7672f2 Mon Sep 17 00:00:00 2001 From: losfair Date: Mon, 13 Jan 2020 22:39:04 +0800 Subject: [PATCH 11/46] Fix type of `backend` passed to `push_code_version`. --- src/bin/wasmer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/wasmer.rs b/src/bin/wasmer.rs index 5c7f1669706..b4a58ee054c 100644 --- a/src/bin/wasmer.rs +++ b/src/bin/wasmer.rs @@ -862,7 +862,7 @@ fn execute_wasm(options: &Run) -> Result<(), String> { baseline: true, msm: msm, base: instance.module.runnable_module.get_code().unwrap().as_ptr() as usize, - backend: options.backend, + backend: options.backend.to_string().to_owned(), runnable_module: instance.module.runnable_module.clone(), }); true From 1cd198a5a5e7b06875f280a44f5d6c37be9d423f Mon Sep 17 00:00:00 2001 From: Syrus Date: Tue, 14 Jan 2020 10:32:32 +0100 Subject: [PATCH 12/46] Use a 32 byte array instead of 64 one --- lib/runtime-core/src/cache.rs | 34 +++++++++------------------------- 1 file changed, 9 insertions(+), 25 deletions(-) diff --git a/lib/runtime-core/src/cache.rs b/lib/runtime-core/src/cache.rs index 127d110332b..b5aa8ccfc27 100644 --- a/lib/runtime-core/src/cache.rs +++ b/lib/runtime-core/src/cache.rs @@ -45,10 +45,8 @@ impl From for Error { /// /// [`Cache`]: trait.Cache.html #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] -// WasmHash is made up of two 32 byte arrays instead of a 64 byte array -// because derive only works on fixed sized arrays size 32 or below -// TODO: fix this when this gets fixed by improved const generics -pub struct WasmHash([u8; 32], [u8; 32]); +// WasmHash is made up of a 32 byte array +pub struct WasmHash([u8; 32]); impl WasmHash { /// Hash a wasm module. @@ -57,18 +55,8 @@ impl WasmHash { /// This does no verification that the supplied data /// is, in fact, a wasm module. pub fn generate(wasm: &[u8]) -> Self { - let mut first_part = [0u8; 32]; - // We don't use the second part for now, since the blake3 hash is 32 byte array - let second_part = [0u8; 32]; - - let mut hasher = blake3::Hasher::new(); - hasher.update(wasm); - - let hash = hasher.finalize(); - let generic_array = hash.as_bytes(); - - first_part.copy_from_slice(&generic_array[0..32]); - WasmHash(first_part, second_part) + let hash = blake3::hash(wasm); + WasmHash(hash.into()) } /// Create the hexadecimal representation of the @@ -85,26 +73,22 @@ impl WasmHash { e )) })?; - if bytes.len() != 64 { + if bytes.len() != 32 { return Err(Error::DeserializeError( - "Prehashed keys must deserialze into exactly 64 bytes".to_string(), + "Prehashed keys must deserialze into exactly 32 bytes".to_string(), )); } use std::convert::TryInto; Ok(WasmHash( bytes[0..32].try_into().map_err(|e| { Error::DeserializeError(format!("Could not get first 32 bytes: {}", e)) - })?, - bytes[32..64].try_into().map_err(|e| { - Error::DeserializeError(format!("Could not get last 32 bytes: {}", e)) - })?, + })? )) } - pub(crate) fn into_array(self) -> [u8; 64] { - let mut total = [0u8; 64]; + pub(crate) fn into_array(self) -> [u8; 32] { + let mut total = [0u8; 32]; total[0..32].copy_from_slice(&self.0); - total[32..64].copy_from_slice(&self.1); total } } From 6dfd5916c27e2a869946ab02bdc0340cde894824 Mon Sep 17 00:00:00 2001 From: losfair Date: Tue, 14 Jan 2020 20:56:34 +0800 Subject: [PATCH 13/46] Improve error message on exception. --- lib/runtime-core/src/error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/runtime-core/src/error.rs b/lib/runtime-core/src/error.rs index 94abce06d5a..266bd444e27 100644 --- a/lib/runtime-core/src/error.rs +++ b/lib/runtime-core/src/error.rs @@ -210,7 +210,7 @@ impl std::fmt::Display for RuntimeError { } else if let Some(s) = data.downcast_ref::<&str>() { write!(f, "\"{}\"", s) } else if let Some(exc_code) = data.downcast_ref::() { - write!(f, "\"{:?}\"", exc_code) + write!(f, "Caught exception of type \"{:?}\".", exc_code) } else { write!(f, "unknown error") } From 35870b33e5f4dcbfe17866bdf8927ed3f3e4ab49 Mon Sep 17 00:00:00 2001 From: losfair Date: Thu, 16 Jan 2020 02:59:27 +0800 Subject: [PATCH 14/46] Update spectests to test singlepass traps. --- lib/runtime/src/lib.rs | 8 +- lib/spectests/tests/excludes.txt | 467 ------------------------------- lib/spectests/tests/spectest.rs | 75 ++++- 3 files changed, 67 insertions(+), 483 deletions(-) diff --git a/lib/runtime/src/lib.rs b/lib/runtime/src/lib.rs index a4913896d4b..b26dc50e9b1 100644 --- a/lib/runtime/src/lib.rs +++ b/lib/runtime/src/lib.rs @@ -94,7 +94,7 @@ #[macro_use] extern crate serde_derive; -pub use wasmer_runtime_core::backend::Features; +pub use wasmer_runtime_core::backend::{ExceptionCode, Features}; pub use wasmer_runtime_core::codegen::{MiddlewareChain, StreamingCompiler}; pub use wasmer_runtime_core::export::Export; pub use wasmer_runtime_core::global::Global; @@ -111,6 +111,12 @@ pub use wasmer_runtime_core::Func; pub use wasmer_runtime_core::{compile_with, validate}; pub use wasmer_runtime_core::{func, imports}; +#[cfg(unix)] +pub use wasmer_runtime_core::{ + fault::{pop_code_version, push_code_version}, + state::CodeVersion, +}; + pub mod memory { //! The memory module contains the implementation data structures and helper functions used to //! manipulate and access wasm memory. diff --git a/lib/spectests/tests/excludes.txt b/lib/spectests/tests/excludes.txt index 4919f9338b3..b1c6e5dc8d7 100644 --- a/lib/spectests/tests/excludes.txt +++ b/lib/spectests/tests/excludes.txt @@ -312,7 +312,6 @@ singlepass:skip:simd_binaryen.wast:* # SIMD not implemented singlepass:skip:atomic.wast:*:*:aarch64 # Threads not yet supported on singlepass -singlepass:fail:address.wast:192 # AssertTrap - expected trap, got Runtime:Error unknown error singlepass:fail:address.wast:194 # AssertTrap - expected trap, got [] singlepass:fail:address.wast:195 # AssertTrap - expected trap, got [] singlepass:fail:address.wast:196 # AssertTrap - expected trap, got [] @@ -323,7 +322,6 @@ singlepass:fail:address.wast:201 # AssertTrap - expected trap, got [] singlepass:fail:address.wast:202 # AssertTrap - expected trap, got [] singlepass:fail:address.wast:203 # AssertTrap - expected trap, got [] singlepass:fail:address.wast:204 # AssertTrap - expected trap, got [] -singlepass:fail:address.wast:479 # AssertTrap - expected trap, got Runtime:Error unknown error singlepass:fail:address.wast:481 # AssertTrap - expected trap, got [] singlepass:fail:address.wast:482 # AssertTrap - expected trap, got [] singlepass:fail:address.wast:483 # AssertTrap - expected trap, got [] @@ -338,486 +336,21 @@ singlepass:fail:address.wast:492 # AssertTrap - expected trap, got [] singlepass:fail:address.wast:493 # AssertTrap - expected trap, got [] singlepass:fail:address.wast:494 # AssertTrap - expected trap, got [] singlepass:fail:address.wast:495 # AssertTrap - expected trap, got [] -singlepass:fail:address.wast:539 # AssertTrap - expected trap, got Runtime:Error unknown error singlepass:fail:address.wast:541 # AssertTrap - expected trap, got [] singlepass:fail:address.wast:542 # AssertTrap - expected trap, got [] -singlepass:fail:address.wast:586 # AssertTrap - expected trap, got Runtime:Error unknown error singlepass:fail:address.wast:588 # AssertTrap - expected trap, got [] singlepass:fail:address.wast:589 # AssertTrap - expected trap, got [] -singlepass:fail:align.wast:864 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:380 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:381 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:382 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:383 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:384 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:385 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:386 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:387 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:388 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:389 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:390 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:391 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:392 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:393 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:394 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:395 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:396 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:397 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:398 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:399 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:400 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:401 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:402 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:403 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:404 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:405 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:406 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:407 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:408 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:409 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:410 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:411 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:412 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:413 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:414 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:415 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:416 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:417 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:418 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:419 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:420 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:421 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:422 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:423 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:atomic.wast:424 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:call.wast:289 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:call_indirect.wast:469 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:call_indirect.wast:470 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:call_indirect.wast:471 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:call_indirect.wast:472 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:call_indirect.wast:473 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:call_indirect.wast:479 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:call_indirect.wast:480 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:call_indirect.wast:486 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:call_indirect.wast:487 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:call_indirect.wast:493 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:call_indirect.wast:494 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:call_indirect.wast:500 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:call_indirect.wast:501 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:83 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:84 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:85 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:86 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:87 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:88 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:89 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:90 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:105 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:106 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:107 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:108 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:109 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:110 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:111 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:112 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:128 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:129 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:130 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:131 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:132 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:133 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:134 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:135 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:151 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:152 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:153 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:154 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:155 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:156 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:157 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:158 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:159 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:160 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:161 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:179 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:180 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:181 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:182 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:183 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:184 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:185 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:186 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:199 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:200 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:201 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:202 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:203 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:204 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:205 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:206 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:224 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:225 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:226 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:227 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:228 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:229 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:230 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:231 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:248 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:249 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:250 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:251 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:252 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:253 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:254 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:conversions.wast:255 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:elem.wast:353 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:func_ptrs.wast:78 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:func_ptrs.wast:79 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:func_ptrs.wast:80 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:func_ptrs.wast:89 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:func_ptrs.wast:90 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:func_ptrs.wast:91 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:globals.wast:221 # AssertTrap - expected trap, got Runtime:Error unknown error singlepass:fail:globals.wast:243 # AssertInvalid - Should be invalid -singlepass:fail:i32.wast:62 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:i32.wast:63 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:i32.wast:64 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:i32.wast:82 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:i32.wast:83 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:i32.wast:99 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:i32.wast:100 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:i32.wast:120 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:i32.wast:121 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:i64.wast:62 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:i64.wast:63 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:i64.wast:64 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:i64.wast:82 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:i64.wast:83 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:i64.wast:99 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:i64.wast:100 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:i64.wast:120 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:i64.wast:121 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:if.wast:440 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:imports.wast:283 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:imports.wast:286 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:imports.wast:287 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:imports.wast:302 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:imports.wast:305 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:imports.wast:306 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:imports.wast:391 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:imports.wast:402 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:int_exprs.wast:113 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:int_exprs.wast:114 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:int_exprs.wast:115 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:int_exprs.wast:116 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:int_exprs.wast:132 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:int_exprs.wast:133 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:int_exprs.wast:134 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:int_exprs.wast:135 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:int_exprs.wast:196 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:int_exprs.wast:197 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:int_exprs.wast:198 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:int_exprs.wast:199 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:int_exprs.wast:349 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:int_exprs.wast:350 # AssertTrap - expected trap, got Runtime:Error unknown error singlepass:fail:linking.wast:134 # AssertReturn - Call failed RuntimeError: unknown error -singlepass:fail:linking.wast:136 # AssertTrap - expected trap, got Runtime:Error unknown error singlepass:fail:linking.wast:137 # AssertTrap - expected trap, got Runtime:Error unknown error singlepass:fail:linking.wast:139 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:linking.wast:141 # AssertTrap - expected trap, got Runtime:Error unknown error singlepass:fail:linking.wast:142 # AssertTrap - expected trap, got Runtime:Error unknown error singlepass:fail:linking.wast:144 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:linking.wast:146 # AssertTrap - expected trap, got Runtime:Error unknown error singlepass:fail:linking.wast:147 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:linking.wast:148 # AssertTrap - expected trap, got Runtime:Error unknown error singlepass:fail:linking.wast:149 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:linking.wast:152 # AssertTrap - expected trap, got Runtime:Error unknown error singlepass:fail:linking.wast:169 # AssertReturn - Call failed RuntimeError: unknown error singlepass:fail:linking.wast:175 # AssertReturn - Call failed RuntimeError: unknown error singlepass:fail:linking.wast:181 # AssertReturn - Call failed RuntimeError: unknown error -singlepass:fail:linking.wast:184 # AssertTrap - expected trap, got Runtime:Error unknown error singlepass:fail:linking.wast:185 # AssertTrap - expected trap, got Runtime:Error unknown error singlepass:fail:linking.wast:187 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:linking.wast:188 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:linking.wast:190 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:linking.wast:225 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:linking.wast:236 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:linking.wast:248 # AssertTrap - expected trap, got Runtime:Error unknown error singlepass:fail:linking.wast:388 # AssertReturn - Call failed RuntimeError: unknown error -singlepass:fail:memory_grow.wast:15 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_grow.wast:16 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_grow.wast:17 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_grow.wast:18 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_grow.wast:24 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_grow.wast:25 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_grow.wast:286 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:23 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:24 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:25 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:26 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:27 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:28 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:29 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:30 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:31 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:32 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:111 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:112 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:113 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:114 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:115 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:116 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:117 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:118 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:119 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:120 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:121 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:122 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:123 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:124 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:125 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:126 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:127 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:128 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:129 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:130 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:131 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:132 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:133 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:134 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:135 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:136 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:137 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:138 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:139 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:140 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:141 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:142 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:143 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:144 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:145 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:146 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:147 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:148 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:149 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:150 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:151 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:152 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:153 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:154 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:155 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:156 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:157 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:158 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:159 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:160 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:161 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:162 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:163 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:164 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:165 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:166 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:167 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:168 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:169 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:170 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:171 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:172 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:173 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:174 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:175 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:176 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:177 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:178 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:179 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:180 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:181 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:182 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:183 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:184 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:185 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:186 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:187 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:188 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:189 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:190 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:191 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:192 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:193 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:194 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:195 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:196 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:197 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:198 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:199 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:200 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:201 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:202 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:203 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:204 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:205 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:206 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:207 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:208 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:209 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:210 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:211 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:212 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:213 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:214 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:215 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:216 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:217 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:218 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:219 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:220 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:221 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:222 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:223 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:224 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:225 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:226 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:227 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:228 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:229 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:230 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:231 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:232 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:233 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:234 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:235 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:236 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:237 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:238 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:239 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:240 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:241 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:242 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:243 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:244 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:245 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:246 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:247 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:248 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:249 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:250 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:251 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:252 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:253 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:254 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:255 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:256 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:257 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:258 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:259 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:260 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:261 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:262 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:263 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:264 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:265 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:memory_trap.wast:266 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:select.wast:208 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:select.wast:209 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:select.wast:210 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:select.wast:211 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:select.wast:248 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:select.wast:249 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:traps.wast:16 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:traps.wast:17 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:traps.wast:18 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:traps.wast:19 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:traps.wast:20 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:traps.wast:21 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:traps.wast:34 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:traps.wast:35 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:traps.wast:36 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:traps.wast:37 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:traps.wast:50 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:traps.wast:51 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:traps.wast:52 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:traps.wast:53 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:traps.wast:54 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:traps.wast:55 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:traps.wast:56 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:traps.wast:57 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:traps.wast:78 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:traps.wast:79 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:traps.wast:80 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:traps.wast:81 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:traps.wast:82 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:traps.wast:83 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:traps.wast:84 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:traps.wast:85 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:traps.wast:86 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:traps.wast:87 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:traps.wast:88 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:traps.wast:89 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:traps.wast:90 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:traps.wast:91 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:218 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:219 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:220 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:221 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:223 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:224 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:225 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:226 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:228 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:229 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:230 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:231 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:234 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:235 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:236 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:239 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:241 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:242 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:243 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:245 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:246 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:247 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:248 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:249 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:251 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:253 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:254 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:256 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:259 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:260 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:261 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:262 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:263 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:265 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:266 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:267 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:269 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:270 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:271 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:272 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:274 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:275 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:276 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:278 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:279 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:281 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:282 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:283 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:284 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:286 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:288 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:289 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:291 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:293 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:294 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:296 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unreachable.wast:298 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unwind.wast:212 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unwind.wast:221 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unwind.wast:230 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unwind.wast:239 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unwind.wast:245 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unwind.wast:251 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unwind.wast:257 # AssertTrap - expected trap, got Runtime:Error unknown error -singlepass:fail:unwind.wast:263 # AssertTrap - expected trap, got Runtime:Error unknown error diff --git a/lib/spectests/tests/spectest.rs b/lib/spectests/tests/spectest.rs index 518e545d6bc..9c255740e12 100644 --- a/lib/spectests/tests/spectest.rs +++ b/lib/spectests/tests/spectest.rs @@ -616,9 +616,47 @@ mod tests { } => { let maybe_call_result = with_instance(instance.clone(), &named_modules, &module, |instance| { + #[cfg(unix)] + use wasmer_runtime::{ + pop_code_version, push_code_version, CodeVersion, + }; + + // Manually push code version before calling WebAssembly function, as a hack. + // + // This should eventually be fixed by doing push/pop code version in the function invocation + // logic itself. + + #[cfg(unix)] + let cv_pushed = if let Some(msm) = + instance.module.runnable_module.get_module_state_map() + { + push_code_version(CodeVersion { + baseline: true, + msm: msm, + base: instance + .module + .runnable_module + .get_code() + .unwrap() + .as_ptr() + as usize, + backend: backend.into(), + runnable_module: instance.module.runnable_module.clone(), + }); + true + } else { + false + }; let params: Vec = args.iter().cloned().map(convert_value).collect(); - instance.call(&field, ¶ms[..]) + let ret = instance.call(&field, ¶ms[..]); + #[cfg(unix)] + { + if cv_pushed { + pop_code_version().unwrap(); + } + } + ret }); if maybe_call_result.is_none() { test_report.add_failure( @@ -657,21 +695,28 @@ mod tests { // TODO assert message? test_report.count_passed() } - RuntimeError::Error { .. } => { - test_report.add_failure( - SpecFailure { - file: filename.to_string(), + RuntimeError::Error { ref data } => { + use wasmer_runtime::ExceptionCode; + if let Some(_) = + data.downcast_ref::() + { + test_report.count_passed(); + } else { + test_report.add_failure( + SpecFailure { + file: filename.to_string(), + line, + kind: format!("{}", "AssertTrap"), + message: format!( + "expected trap, got Runtime:Error {:?}", + r + ), + }, + &test_key, + excludes, line, - kind: format!("{}", "AssertTrap"), - message: format!( - "expected trap, got Runtime:Error {:?}", - r - ), - }, - &test_key, - excludes, - line, - ); + ); + } } } } From 1b682bf35335d09b4efc9f62438f48a0ada95d75 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Fri, 17 Jan 2020 14:31:00 -0800 Subject: [PATCH 15/46] Delete runtime-core::mono_vec --- lib/runtime-core/src/structures/mono_vec.rs | 85 --------------------- 1 file changed, 85 deletions(-) delete mode 100644 lib/runtime-core/src/structures/mono_vec.rs diff --git a/lib/runtime-core/src/structures/mono_vec.rs b/lib/runtime-core/src/structures/mono_vec.rs deleted file mode 100644 index fe19d2510d0..00000000000 --- a/lib/runtime-core/src/structures/mono_vec.rs +++ /dev/null @@ -1,85 +0,0 @@ -#[derive(Debug, Clone)] -enum MonoVecInner { - None, - Inline(T), - Heap(Vec), -} - -/// A type that can hold zero items, -/// one item, or many items. -#[derive(Debug, Clone)] -pub struct MonoVec { - inner: MonoVecInner, -} - -impl MonoVec { - pub fn new() -> Self { - Self { - inner: MonoVecInner::None, - } - } - - pub fn new_inline(item: T) -> Self { - Self { - inner: MonoVecInner::Inline(item), - } - } - - pub fn with_capacity(capacity: usize) -> Self { - match capacity { - 0 | 1 => Self::new(), - _ => Self { - inner: MonoVecInner::Heap(Vec::with_capacity(capacity)), - }, - } - } - - pub fn push(&mut self, item: T) { - let uninit = MonoVecInner::None; - let prev = mem::replace(&mut self.inner, uninit); - let next = match prev { - MonoVecInner::None => MonoVecInner::Inline(item), - MonoVecInner::Inline(previous_item) => MonoVecInner::Heap(vec![previous_item, item]), - MonoVecInner::Heap(mut v) => { - v.push(item); - MonoVecInner::Heap(v) - } - }; - let uninit = mem::replace(&mut self.inner, next); - mem::forget(uninit); - } - - pub fn pop(&mut self) -> Option { - match self.inner { - MonoVecInner::None => None, - MonoVecInner::Inline(ref mut item) => { - let uninit = unsafe { mem::zeroed() }; - let item = mem::replace(item, uninit); - let uninit = mem::replace(&mut self.inner, MonoVecInner::None); - mem::forget(uninit); - Some(item) - } - MonoVecInner::Heap(ref mut v) => v.pop(), - } - } - - pub fn as_slice(&self) -> &[T] { - match self.inner { - MonoVecInner::None => unsafe { - slice::from_raw_parts(mem::align_of::() as *const T, 0) - }, - MonoVecInner::Inline(ref item) => slice::from_ref(item), - MonoVecInner::Heap(ref v) => &v[..], - } - } - - pub fn as_slice_mut(&mut self) -> &mut [T] { - match self.inner { - MonoVecInner::None => unsafe { - slice::from_raw_parts_mut(mem::align_of::() as *mut T, 0) - }, - MonoVecInner::Inline(ref mut item) => slice::from_mut(item), - MonoVecInner::Heap(ref mut v) => &mut v[..], - } - } -} From c187d1656eeadd525fe373c960d107da968cf9b0 Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Fri, 17 Jan 2020 14:31:10 -0800 Subject: [PATCH 16/46] Add misc doc improvements to runtime-core --- lib/runtime-core/src/backend.rs | 9 +++++++++ lib/runtime-core/src/lib.rs | 2 +- lib/runtime-core/src/vm.rs | 11 +++++++---- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/lib/runtime-core/src/backend.rs b/lib/runtime-core/src/backend.rs index 607e72ee3b0..4bfb25c1587 100644 --- a/lib/runtime-core/src/backend.rs +++ b/lib/runtime-core/src/backend.rs @@ -76,9 +76,18 @@ impl Default for MemoryBoundCheckMode { } /// Controls which experimental features will be enabled. +/// Features usually have a corresponding [WebAssembly proposal][wasm-props]. +/// +/// [wasm-props]: https://github.com/WebAssembly/proposals #[derive(Debug, Default)] pub struct Features { + /// Whether support for the [SIMD proposal][simd-prop] is enabled. + /// + /// [simd-prop]: https://github.com/webassembly/simd pub simd: bool, + /// Whether support for the [threads proposal][threads-prop] is enabled. + /// + /// [threads-prop]: https://github.com/webassembly/threads pub threads: bool, } diff --git a/lib/runtime-core/src/lib.rs b/lib/runtime-core/src/lib.rs index 4e7cdcee3ad..f211e80dbe6 100644 --- a/lib/runtime-core/src/lib.rs +++ b/lib/runtime-core/src/lib.rs @@ -173,7 +173,7 @@ pub fn validate_and_report_errors_with_features( } } -/// Creates a new module from the given cache `Artifact` for the specified compiler backend +/// Creates a new module from the given cache [`Artifact`] for the specified compiler backend pub unsafe fn load_cache_with( cache: Artifact, compiler: &dyn backend::Compiler, diff --git a/lib/runtime-core/src/vm.rs b/lib/runtime-core/src/vm.rs index 2864bf8ed64..ca7032c8770 100644 --- a/lib/runtime-core/src/vm.rs +++ b/lib/runtime-core/src/vm.rs @@ -54,11 +54,14 @@ pub struct Ctx { /// This is intended to be user-supplied, per-instance /// contextual data. There are currently some issue with it, /// notably that it cannot be set before running the `start` - /// function in a WebAssembly module. + /// function in a WebAssembly module. Additionally, the `data` + /// field may be taken by another ABI implementation that the user + /// wishes to use in addition to their own, such as WASI. This issue is + /// being discussed at [#1111](https://github.com/wasmerio/wasmer/pull/1111). /// - /// [#219](https://github.com/wasmerio/wasmer/pull/219) fixes that - /// issue, as well as allowing the user to have *per-function* - /// context, instead of just per-instance. + /// Alternatively, per-function data can be used if the function in the + /// [`ImportObject`] is a closure. This cannot duplicate data though, + /// so if data may be shared if the [`ImportObject`] is reused. pub data: *mut c_void, /// If there's a function set in this field, it gets called From e5ffac08b5ce56984985f00e9290920db559a794 Mon Sep 17 00:00:00 2001 From: Brandon Fish Date: Fri, 17 Jan 2020 17:15:00 -0600 Subject: [PATCH 17/46] Update CODEOWNERS --- .github/CODEOWNERS | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 847de4fd8cc..63b28eaec9c 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -3,15 +3,15 @@ src/ @syrusakbary @MarkMcCaskey # Backends lib/singlepass-backend @losfair @nlewycky -lib/clif-backend @nlewycky @bjfish +lib/clif-backend @nlewycky lib/llvm-backend @nlewycky @losfair # Runtime -lib/runtime-core @Hywan @bjfish -lib/runtime @MarkMcCaskey @Hywan @bjfish -lib/runtime-c-api @bjfish @Hywan -lib/win-exception-handler @bjfish @losfair -lib/middleware-common @bjfish @losfair +lib/runtime-core @Hywan +lib/runtime @MarkMcCaskey @Hywan +lib/runtime-c-api @Hywan +lib/win-exception-handler @losfair +lib/middleware-common @losfair # Frontend integrations From 5931944a21d586fb89e8b6f8c23aad03aa2b5f7a Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Fri, 17 Jan 2020 15:47:45 -0800 Subject: [PATCH 18/46] Add clippy error checking in lint step --- azure-pipelines.yml | 2 +- lib/llvm-backend/src/intrinsics.rs | 7 ++++--- lib/runtime-c-api/src/export.rs | 2 +- lib/runtime-core/src/state.rs | 2 ++ lib/runtime-core/src/vm.rs | 1 + lib/wasi/src/syscalls/mod.rs | 16 ++++++++-------- 6 files changed, 17 insertions(+), 13 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 82e6a8f2c25..96968baeb60 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -19,7 +19,7 @@ jobs: rustup component add rustfmt rustup component add clippy || cargo install --git https://github.com/rust-lang/rust-clippy/ --force clippy displayName: Lint dependencies - - script: cargo fmt --all -- --check + - script: cargo fmt --all -- --check && cargo clippy --workspace displayName: Lint variables: rust_toolchain: '1.39.0' diff --git a/lib/llvm-backend/src/intrinsics.rs b/lib/llvm-backend/src/intrinsics.rs index c983e41752a..f4a48ad600d 100644 --- a/lib/llvm-backend/src/intrinsics.rs +++ b/lib/llvm-backend/src/intrinsics.rs @@ -1171,9 +1171,10 @@ pub fn tbaa_label<'ctx>( // TODO: ContextRef can't return us the lifetime from module through Deref. // This could be fixed once generic_associated_types is stable. - let context2 = &*context; - let context = unsafe { std::mem::transmute::<&Context, &'ctx Context>(context2) }; - std::mem::forget(context2); + let context = { + let context2 = &*context; + unsafe { std::mem::transmute::<&Context, &'ctx Context>(context2) } + }; // `!wasmer_tbaa_root = {}`, the TBAA root node for wasmer. let tbaa_root = module diff --git a/lib/runtime-c-api/src/export.rs b/lib/runtime-c-api/src/export.rs index 5f33748ce3b..57d958abb3f 100644 --- a/lib/runtime-c-api/src/export.rs +++ b/lib/runtime-c-api/src/export.rs @@ -439,7 +439,7 @@ pub unsafe extern "C" fn wasmer_export_func_call( } let params: Vec = { - if params_len <= 0 { + if params_len == 0 { vec![] } else { slice::from_raw_parts::(params, params_len as usize) diff --git a/lib/runtime-core/src/state.rs b/lib/runtime-core/src/state.rs index f7e9cc791b3..2bd72282c23 100644 --- a/lib/runtime-core/src/state.rs +++ b/lib/runtime-core/src/state.rs @@ -627,9 +627,11 @@ pub mod x64 { use crate::vm::Ctx; use std::any::Any; + #[allow(clippy::cast_ptr_alignment)] unsafe fn compute_vmctx_deref(vmctx: *const Ctx, seq: &[usize]) -> u64 { let mut ptr = &vmctx as *const *const Ctx as *const u8; for x in seq { + debug_assert!(ptr.align_offset(std::mem::align_of::<*const u8>()) == 0); ptr = (*(ptr as *const *const u8)).offset(*x as isize); } ptr as usize as u64 diff --git a/lib/runtime-core/src/vm.rs b/lib/runtime-core/src/vm.rs index ca7032c8770..d7b32c94aa3 100644 --- a/lib/runtime-core/src/vm.rs +++ b/lib/runtime-core/src/vm.rs @@ -570,6 +570,7 @@ pub struct FuncCtx { impl FuncCtx { /// Offset to the `vmctx` field. + #[allow(clippy::erasing_op)] pub const fn offset_vmctx() -> u8 { 0 * (mem::size_of::() as u8) } diff --git a/lib/wasi/src/syscalls/mod.rs b/lib/wasi/src/syscalls/mod.rs index 5a243c5d56f..204649c8dc4 100644 --- a/lib/wasi/src/syscalls/mod.rs +++ b/lib/wasi/src/syscalls/mod.rs @@ -1,4 +1,4 @@ -#![allow(unused)] +#![allow(unused, clippy::too_many_arguments)] pub mod types; #[cfg(any(target_os = "linux", target_os = "macos"))] pub mod unix; @@ -331,7 +331,7 @@ pub fn fd_allocate( ) -> __wasi_errno_t { debug!("wasi::fd_allocate"); let (memory, state) = get_memory_and_wasi_state(ctx, 0); - let fd_entry = wasi_try!(state.fs.get_fd(fd)).clone(); + let fd_entry = wasi_try!(state.fs.get_fd(fd)); let inode = fd_entry.inode; if !has_rights(fd_entry.rights, __WASI_RIGHT_FD_ALLOCATE) { @@ -374,7 +374,7 @@ pub fn fd_close(ctx: &mut Ctx, fd: __wasi_fd_t) -> __wasi_errno_t { debug!("=> fd={}", fd); let (memory, state) = get_memory_and_wasi_state(ctx, 0); - let fd_entry = wasi_try!(state.fs.get_fd(fd)).clone(); + let fd_entry = wasi_try!(state.fs.get_fd(fd)); wasi_try!(state.fs.close_fd(fd)); @@ -389,7 +389,7 @@ pub fn fd_close(ctx: &mut Ctx, fd: __wasi_fd_t) -> __wasi_errno_t { pub fn fd_datasync(ctx: &mut Ctx, fd: __wasi_fd_t) -> __wasi_errno_t { debug!("wasi::fd_datasync"); let (memory, state) = get_memory_and_wasi_state(ctx, 0); - let fd_entry = wasi_try!(state.fs.get_fd(fd)).clone(); + let fd_entry = wasi_try!(state.fs.get_fd(fd)); if !has_rights(fd_entry.rights, __WASI_RIGHT_FD_DATASYNC) { return __WASI_EACCES; } @@ -420,7 +420,7 @@ pub fn fd_fdstat_get( buf_ptr.offset() ); let (memory, state) = get_memory_and_wasi_state(ctx, 0); - let fd_entry = wasi_try!(state.fs.get_fd(fd)).clone(); + let fd_entry = wasi_try!(state.fs.get_fd(fd)); let stat = wasi_try!(state.fs.fdstat(fd)); let buf = wasi_try!(buf_ptr.deref(memory)); @@ -528,7 +528,7 @@ pub fn fd_filestat_set_size( ) -> __wasi_errno_t { debug!("wasi::fd_filestat_set_size"); let (memory, state) = get_memory_and_wasi_state(ctx, 0); - let fd_entry = wasi_try!(state.fs.get_fd(fd)).clone(); + let fd_entry = wasi_try!(state.fs.get_fd(fd)); let inode = fd_entry.inode; if !has_rights(fd_entry.rights, __WASI_RIGHT_FD_FILESTAT_SET_SIZE) { @@ -1309,7 +1309,7 @@ pub fn path_create_directory( debug!("wasi::path_create_directory"); let (memory, state) = get_memory_and_wasi_state(ctx, 0); - let working_dir = wasi_try!(state.fs.get_fd(fd)).clone(); + let working_dir = wasi_try!(state.fs.get_fd(fd)); if let Kind::Root { .. } = &state.fs.inodes[working_dir.inode].kind { return __WASI_EACCES; } @@ -1468,7 +1468,7 @@ pub fn path_filestat_set_times( ) -> __wasi_errno_t { debug!("wasi::path_filestat_set_times"); let (memory, state) = get_memory_and_wasi_state(ctx, 0); - let fd_entry = wasi_try!(state.fs.get_fd(fd)).clone(); + let fd_entry = wasi_try!(state.fs.get_fd(fd)); let fd_inode = fd_entry.inode; if !has_rights(fd_entry.rights, __WASI_RIGHT_PATH_FILESTAT_SET_TIMES) { return __WASI_EACCES; From d1f049916bd9af8c66aef92b4041ca2a0985fb8f Mon Sep 17 00:00:00 2001 From: Mark McCaskey Date: Fri, 17 Jan 2020 15:56:25 -0800 Subject: [PATCH 19/46] Make Clippy Lint a separate step; upgrade all Ubuntu to 18.04 --- azure-pipelines.yml | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 96968baeb60..2b60d744e89 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -17,18 +17,36 @@ jobs: - template: .azure/install-rust.yml - script: | rustup component add rustfmt - rustup component add clippy || cargo install --git https://github.com/rust-lang/rust-clippy/ --force clippy displayName: Lint dependencies - - script: cargo fmt --all -- --check && cargo clippy --workspace + - script: cargo fmt --all -- --check displayName: Lint variables: rust_toolchain: '1.39.0' + - job: clippy_lint + pool: + vmImage: "ubuntu-18.04" + steps: + - checkout: self + submodules: true + - template: .azure/install-rust.yml + - template: .azure/install-llvm.yml + - template: .azure/install-sccache.yml + - template: .azure/install-cmake.yml + - script: | + rustup component add rustfmt + rustup component add clippy || cargo install --git https://github.com/rust-lang/rust-clippy/ --force clippy + displayName: Lint dependencies with clippy + - script: cargo clippy --workspace + displayName: Clippy Lint + variables: + rust_toolchain: nightly-2019-12-19 + - job: Test strategy: matrix: linux: - imageName: "ubuntu-16.04" + imageName: "ubuntu-18.04" rust_toolchain: nightly-2019-12-19 mac: imageName: "macos-10.14" @@ -73,7 +91,7 @@ jobs: - job: Check pool: - vmImage: "ubuntu-16.04" + vmImage: "ubuntu-18.04" variables: rust_toolchain: nightly-2019-12-19 condition: in(variables['Build.SourceBranch'], 'refs/heads/master', 'refs/heads/staging', 'refs/heads/trying') @@ -92,7 +110,7 @@ jobs: strategy: matrix: linux: - imageName: "ubuntu-16.04" + imageName: "ubuntu-18.04" rust_toolchain: nightly-2019-12-19 mac: imageName: "macos-10.14" @@ -159,7 +177,7 @@ jobs: strategy: matrix: linux: - imageName: "ubuntu-16.04" + imageName: "ubuntu-18.04" rust_toolchain: nightly-2019-12-19 mac: imageName: "macos-10.14" @@ -212,7 +230,7 @@ jobs: - job: Build_Docs pool: - vmImage: "ubuntu-16.04" + vmImage: "ubuntu-18.04" variables: rust_toolchain: nightly-2019-08-15 condition: in(variables['Build.SourceBranch'], 'refs/heads/master', 'refs/heads/staging', 'refs/heads/trying') @@ -287,7 +305,7 @@ jobs: - Build_Docs displayName: Deploy API Documentation to GitHub pool: - vmImage: "ubuntu-16.04" + vmImage: "ubuntu-18.04" condition: in(variables['Build.SourceBranch'], 'refs/heads/master') steps: - checkout: self From 8721f6c17b22d2298facafeb07b79ab244ff4ed7 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 20 Jan 2020 07:58:42 +0000 Subject: [PATCH 20/46] Bump smallvec from 0.6.13 to 1.1.0 Bumps [smallvec](https://github.com/servo/rust-smallvec) from 0.6.13 to 1.1.0. - [Release notes](https://github.com/servo/rust-smallvec/releases) - [Commits](https://github.com/servo/rust-smallvec/compare/v0.6.13...v1.1.0) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b80f6e4fb2f..9627483c096 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1790,7 +1790,7 @@ dependencies = [ "regex", "rustc_version", "semver", - "smallvec 0.6.13", + "smallvec 1.1.0", "wabt", "wasmer-runtime-core", "wasmparser", @@ -1877,7 +1877,7 @@ dependencies = [ "serde-bench", "serde_bytes", "serde_derive", - "smallvec 0.6.13", + "smallvec 1.1.0", "wasmparser", "winapi", ] @@ -1906,7 +1906,7 @@ dependencies = [ "nix", "serde", "serde_derive", - "smallvec 0.6.13", + "smallvec 1.1.0", "wasmer-runtime-core", ] From aff8256eb94ad093c2bf89dd0f18ca0f3ab75333 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 20 Jan 2020 07:59:18 +0000 Subject: [PATCH 21/46] Bump structopt from 0.3.7 to 0.3.8 Bumps [structopt](https://github.com/TeXitoi/structopt) from 0.3.7 to 0.3.8. - [Release notes](https://github.com/TeXitoi/structopt/releases) - [Changelog](https://github.com/TeXitoi/structopt/blob/master/CHANGELOG.md) - [Commits](https://github.com/TeXitoi/structopt/compare/v0.3.7...v0.3.8) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b80f6e4fb2f..ee746e7492b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1405,19 +1405,20 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "structopt" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "884ae79d6aad1e738f4a70dff314203fd498490a63ebc4d03ea83323c40b7b72" +checksum = "df136b42d76b1fbea72e2ab3057343977b04b4a2e00836c3c7c0673829572713" dependencies = [ "clap", + "lazy_static", "structopt-derive", ] [[package]] name = "structopt-derive" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a97f829a34a0a9d5b353a881025a23b8c9fd09d46be6045df6b22920dbd7a93" +checksum = "fd50a87d2f7b8958055f3e73a963d78feaccca3836767a9069844e34b5b03c0a" dependencies = [ "heck", "proc-macro-error", From 1b806c4b2aaca1544b6cc3c5bd3e69eb8e7e2ca9 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 20 Jan 2020 08:00:06 +0000 Subject: [PATCH 22/46] Bump indexmap from 1.3.0 to 1.3.1 Bumps [indexmap](https://github.com/bluss/indexmap) from 1.3.0 to 1.3.1. - [Release notes](https://github.com/bluss/indexmap/releases) - [Commits](https://github.com/bluss/indexmap/compare/1.3.0...1.3.1) Signed-off-by: dependabot-preview[bot] --- Cargo.lock | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b80f6e4fb2f..61f9cb97e52 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -46,6 +46,12 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" +[[package]] +name = "autocfg" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" + [[package]] name = "bincode" version = "1.2.1" @@ -312,7 +318,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac" dependencies = [ - "autocfg", + "autocfg 0.1.7", "cfg-if", "crossbeam-utils", "lazy_static", @@ -335,7 +341,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4" dependencies = [ - "autocfg", + "autocfg 0.1.7", "cfg-if", "lazy_static", ] @@ -555,11 +561,11 @@ checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" [[package]] name = "indexmap" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712d7b3ea5827fcb9d4fda14bf4da5f136f0db2ae9c8f4bd4e2d1c6fde4e6db2" +checksum = "0b54058f0a6ff80b6803da8faf8997cde53872b38f4023728f6830b06cd3c0dc" dependencies = [ - "autocfg", + "autocfg 1.0.0", "serde", ] @@ -755,7 +761,7 @@ version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09" dependencies = [ - "autocfg", + "autocfg 0.1.7", "num-traits", ] @@ -765,7 +771,7 @@ version = "0.1.39" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76bd5272412d173d6bf9afdf98db8612bbabc9a7a830b7bfc9c188911716132e" dependencies = [ - "autocfg", + "autocfg 0.1.7", "num-integer", "num-traits", ] @@ -776,7 +782,7 @@ version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4c81ffc11c212fa327657cb19dd85eb7419e163b5b076bede2bdb5c974c07e4" dependencies = [ - "autocfg", + "autocfg 0.1.7", ] [[package]] @@ -982,7 +988,7 @@ version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" dependencies = [ - "autocfg", + "autocfg 0.1.7", "libc", "rand_chacha 0.1.1", "rand_core 0.4.2", @@ -1014,7 +1020,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" dependencies = [ - "autocfg", + "autocfg 0.1.7", "rand_core 0.3.1", ] @@ -1110,7 +1116,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" dependencies = [ - "autocfg", + "autocfg 0.1.7", "rand_core 0.4.2", ] From 384c501c934bf90a6a9a28f7c1459817bda056de Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 20 Jan 2020 14:23:52 +0100 Subject: [PATCH 23/46] doc(runtime-c-api) Improve error functions' documentations. --- lib/runtime-c-api/src/error.rs | 42 +++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/lib/runtime-c-api/src/error.rs b/lib/runtime-c-api/src/error.rs index 444bf61eea6..8c224930585 100644 --- a/lib/runtime-c-api/src/error.rs +++ b/lib/runtime-c-api/src/error.rs @@ -22,16 +22,12 @@ pub(crate) fn take_last_error() -> Option> { LAST_ERROR.with(|prev| prev.borrow_mut().take()) } -/// Gets the length in bytes of the last error. +/// Gets the length in bytes of the last error if any. +/// /// This can be used to dynamically allocate a buffer with the correct number of /// bytes needed to store a message. /// -/// # Example -/// -/// ```c -/// int error_len = wasmer_last_error_length(); -/// char *error_str = malloc(error_len); -/// ``` +/// See `wasmer_last_error_message()` to get a full example. #[no_mangle] pub extern "C" fn wasmer_last_error_length() -> c_int { LAST_ERROR.with(|prev| match *prev.borrow() { @@ -40,19 +36,33 @@ pub extern "C" fn wasmer_last_error_length() -> c_int { }) } -/// Stores the last error message into the provided buffer up to the given `length`. -/// The `length` parameter must be large enough to store the last error message. +/// Gets the last error message if any into the provided buffer +/// `buffer` up to the given `length`. /// -/// Returns the length of the string in bytes. -/// Returns `-1` if an error occurs. +/// The `length` parameter must be large enough to store the last +/// error message. Ideally, the value should come from +/// `wasmer_last_error_length()`. /// -/// # Example +/// The function returns the length of the string in bytes, `-1` if an +/// error occurs. Potential errors are: +/// +/// * The buffer is a null pointer, +/// * The buffer is too smal to hold the error message. +/// +/// Note: The error message always has a trailing null character. +/// +/// Example: /// /// ```c -/// int error_len = wasmer_last_error_length(); -/// char *error_str = malloc(error_len); -/// wasmer_last_error_message(error_str, error_len); -/// printf("Error str: `%s`\n", error_str); +/// int error_length = wasmer_last_error_length(); +/// +/// if (error_length > 0) { +/// char *error_message = malloc(error_length); +/// wasmer_last_error_message(error_message, error_length); +/// printf("Error message: `%s`\n", error_message); +/// } else { +/// printf("No error message\n"); +/// } /// ``` #[no_mangle] pub unsafe extern "C" fn wasmer_last_error_message(buffer: *mut c_char, length: c_int) -> c_int { From cd3a1064f904ee1512d98e231c91a9f273c63d2f Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 20 Jan 2020 14:25:13 +0100 Subject: [PATCH 24/46] chore(runtime-c-api) Move `wasmer_module_import_instantiate` to the `module` module. --- lib/runtime-c-api/src/instance.rs | 26 -------------------------- lib/runtime-c-api/src/module.rs | 26 ++++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/lib/runtime-c-api/src/instance.rs b/lib/runtime-c-api/src/instance.rs index 5ca72725b9c..89a5443e683 100644 --- a/lib/runtime-c-api/src/instance.rs +++ b/lib/runtime-c-api/src/instance.rs @@ -171,32 +171,6 @@ pub unsafe extern "C" fn wasmer_instantiate( wasmer_result_t::WASMER_OK } -/// Given: -/// * A prepared `wasmer` import-object -/// * A compiled wasmer module -/// -/// Instantiates a wasmer instance -#[no_mangle] -pub unsafe extern "C" fn wasmer_module_import_instantiate( - instance: *mut *mut wasmer_instance_t, - module: *const wasmer_module_t, - import_object: *const wasmer_import_object_t, -) -> wasmer_result_t { - let import_object: &ImportObject = &*(import_object as *const ImportObject); - let module: &Module = &*(module as *const Module); - - let new_instance: Instance = match module.instantiate(import_object) { - Ok(instance) => instance, - Err(error) => { - update_last_error(error); - return wasmer_result_t::WASMER_ERROR; - } - }; - *instance = Box::into_raw(Box::new(new_instance)) as *mut wasmer_instance_t; - - return wasmer_result_t::WASMER_OK; -} - /// Extracts the instance's context and returns it. #[allow(clippy::cast_ptr_alignment)] #[no_mangle] diff --git a/lib/runtime-c-api/src/module.rs b/lib/runtime-c-api/src/module.rs index 20de1e66d17..6b03b9ccfda 100644 --- a/lib/runtime-c-api/src/module.rs +++ b/lib/runtime-c-api/src/module.rs @@ -151,6 +151,32 @@ pub unsafe extern "C" fn wasmer_module_instantiate( wasmer_result_t::WASMER_OK } +/// Given: +/// * A prepared `wasmer` import-object +/// * A compiled wasmer module +/// +/// Instantiates a wasmer instance +#[no_mangle] +pub unsafe extern "C" fn wasmer_module_import_instantiate( + instance: *mut *mut wasmer_instance_t, + module: *const wasmer_module_t, + import_object: *const wasmer_import_object_t, +) -> wasmer_result_t { + let import_object: &ImportObject = &*(import_object as *const ImportObject); + let module: &Module = &*(module as *const Module); + + let new_instance: Instance = match module.instantiate(import_object) { + Ok(instance) => instance, + Err(error) => { + update_last_error(error); + return wasmer_result_t::WASMER_ERROR; + } + }; + *instance = Box::into_raw(Box::new(new_instance)) as *mut wasmer_instance_t; + + return wasmer_result_t::WASMER_OK; +} + /// Serialize the given Module. /// /// The caller owns the object and should call `wasmer_serialized_module_destroy` to free it. From 77ba77446d639546be14f3ac8f4d901ffa307117 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 20 Jan 2020 14:36:11 +0100 Subject: [PATCH 25/46] doc(runtime-c-api) Improve documentation of `wasmer_instance_context_get`. --- lib/runtime-c-api/src/instance.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/runtime-c-api/src/instance.rs b/lib/runtime-c-api/src/instance.rs index 89a5443e683..86a65415c26 100644 --- a/lib/runtime-c-api/src/instance.rs +++ b/lib/runtime-c-api/src/instance.rs @@ -171,7 +171,20 @@ pub unsafe extern "C" fn wasmer_instantiate( wasmer_result_t::WASMER_OK } -/// Extracts the instance's context and returns it. +/// Returns the instance context. Learn more by looking at the +/// `wasmer_instance_context_t` struct. +/// +/// This function returns `null` if `instance` is a null pointer. +/// +/// Example: +/// +/// ```c +/// const wasmer_instance_context_get *context = wasmer_instance_context_get(instance); +/// my_data *data = (my_data *) wasmer_instance_context_data_get(context); +/// // Do something with `my_data`. +/// ``` +/// +/// It is often useful with `wasmer_instance_context_data_set()`. #[allow(clippy::cast_ptr_alignment)] #[no_mangle] pub unsafe extern "C" fn wasmer_instance_context_get( From 585f5615cfbfc4a9b746f813b4bdcd7677a16a6f Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 20 Jan 2020 14:36:45 +0100 Subject: [PATCH 26/46] fix(runtime-c-api) Fix imports, and check for null pointer. --- lib/runtime-c-api/src/instance.rs | 18 ++++++++++-------- lib/runtime-c-api/src/module.rs | 6 ++++-- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/lib/runtime-c-api/src/instance.rs b/lib/runtime-c-api/src/instance.rs index 86a65415c26..689a5c4ba81 100644 --- a/lib/runtime-c-api/src/instance.rs +++ b/lib/runtime-c-api/src/instance.rs @@ -3,15 +3,14 @@ use crate::{ error::{update_last_error, CApiError}, export::{wasmer_exports_t, wasmer_import_export_kind, NamedExport, NamedExports}, - import::{wasmer_import_object_t, wasmer_import_t}, + import::wasmer_import_t, memory::wasmer_memory_t, - module::wasmer_module_t, value::{wasmer_value, wasmer_value_t, wasmer_value_tag}, wasmer_result_t, }; use libc::{c_char, c_int, c_void}; -use std::{collections::HashMap, ffi::CStr, slice}; -use wasmer_runtime::{Ctx, Global, Instance, Memory, Module, Table, Value}; +use std::{collections::HashMap, ffi::CStr, ptr, slice}; +use wasmer_runtime::{Ctx, Global, Instance, Memory, Table, Value}; use wasmer_runtime_core::{ export::Export, import::{ImportObject, Namespace}, @@ -187,14 +186,17 @@ pub unsafe extern "C" fn wasmer_instantiate( /// It is often useful with `wasmer_instance_context_data_set()`. #[allow(clippy::cast_ptr_alignment)] #[no_mangle] -pub unsafe extern "C" fn wasmer_instance_context_get( +pub extern "C" fn wasmer_instance_context_get( instance: *mut wasmer_instance_t, ) -> *const wasmer_instance_context_t { - let instance_ref = &*(instance as *const Instance); + if instance.is_null() { + return ptr::null() as _; + } - let ctx: *const Ctx = instance_ref.context() as *const _; + let instance = unsafe { &*(instance as *const Instance) }; + let context: *const Ctx = instance.context() as *const _; - ctx as *const wasmer_instance_context_t + context as *const wasmer_instance_context_t } /// Calls an instances exported function by `name` with the provided parameters. diff --git a/lib/runtime-c-api/src/module.rs b/lib/runtime-c-api/src/module.rs index 6b03b9ccfda..d3e51f9b5a6 100644 --- a/lib/runtime-c-api/src/module.rs +++ b/lib/runtime-c-api/src/module.rs @@ -3,13 +3,15 @@ use crate::{ error::{update_last_error, CApiError}, export::wasmer_import_export_kind, - import::wasmer_import_t, + import::{wasmer_import_object_t, wasmer_import_t}, instance::wasmer_instance_t, wasmer_byte_array, wasmer_result_t, }; use libc::c_int; use std::{collections::HashMap, slice}; -use wasmer_runtime::{compile, default_compiler, Global, ImportObject, Memory, Module, Table}; +use wasmer_runtime::{ + compile, default_compiler, Global, ImportObject, Instance, Memory, Module, Table, +}; use wasmer_runtime_core::{cache::Artifact, export::Export, import::Namespace, load_cache_with}; #[repr(C)] From ee424bbadf3021247515d829376d34580244b0e2 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 20 Jan 2020 15:26:52 +0100 Subject: [PATCH 27/46] doc(runtime-c-api) Improve documentation of `wasmer_result_t`. --- lib/runtime-c-api/src/lib.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/runtime-c-api/src/lib.rs b/lib/runtime-c-api/src/lib.rs index f0464075467..2acc4c94ad0 100644 --- a/lib/runtime-c-api/src/lib.rs +++ b/lib/runtime-c-api/src/lib.rs @@ -107,10 +107,15 @@ pub mod table; pub mod trampoline; pub mod value; +/// The `wasmer_result_t` struct is a type that represents either a +/// success, or a failure. #[allow(non_camel_case_types)] #[repr(C)] pub enum wasmer_result_t { + /// Represents a success. WASMER_OK = 1, + + /// Represents a failure. WASMER_ERROR = 2, } From 97c25f78624a450bc76028819da49c11c73a940c Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 20 Jan 2020 15:27:50 +0100 Subject: [PATCH 28/46] doc(runtime-c-api) Improve documentation of `wasmer_exports_t`. --- lib/runtime-c-api/src/export.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/runtime-c-api/src/export.rs b/lib/runtime-c-api/src/export.rs index 57d958abb3f..dd13688da4d 100644 --- a/lib/runtime-c-api/src/export.rs +++ b/lib/runtime-c-api/src/export.rs @@ -43,7 +43,11 @@ pub struct wasmer_export_func_t; /// exposed to C. pub(crate) struct NamedExports(pub Vec); -/// Opaque pointer to `NamedExports`. +/// Opaque pointer to the opaque structure `crate::NamedExports`, +/// which is a wrapper around a vector of the opaque structure +/// `crate::NamedExport`. +/// +/// Check the `wasmer_instance_exports()` function to learn more. #[repr(C)] #[derive(Clone)] pub struct wasmer_exports_t; From 3022a16ec3c1dcc29b3a6e5e9384b8df741562f0 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 20 Jan 2020 15:28:13 +0100 Subject: [PATCH 29/46] doc(runtime-c-api) Improve documentation of `wasmer_import_export_value`. --- lib/runtime-c-api/src/export.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/runtime-c-api/src/export.rs b/lib/runtime-c-api/src/export.rs index dd13688da4d..a786f99573f 100644 --- a/lib/runtime-c-api/src/export.rs +++ b/lib/runtime-c-api/src/export.rs @@ -95,9 +95,16 @@ pub union wasmer_import_export_value { // ================ // Do not modify these values without updating the `TryFrom` implementation below pub enum wasmer_import_export_kind { + /// The export/import is a function. WASM_FUNCTION = 0, + + /// The export/import is a global. WASM_GLOBAL = 1, + + /// The export/import is a memory. WASM_MEMORY = 2, + + /// The export/import is a table. WASM_TABLE = 3, } From 076931de91f926a360871ccd958162d0c73aefc3 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 20 Jan 2020 15:28:30 +0100 Subject: [PATCH 30/46] doc(runtime-c-api) Improve documentation of `wasmer_exports_destroy`. --- lib/runtime-c-api/src/export.rs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/runtime-c-api/src/export.rs b/lib/runtime-c-api/src/export.rs index a786f99573f..26c501c747a 100644 --- a/lib/runtime-c-api/src/export.rs +++ b/lib/runtime-c-api/src/export.rs @@ -212,7 +212,23 @@ pub unsafe extern "C" fn wasmer_export_descriptor_kind( named_export_descriptor.kind.clone() } -/// Frees the memory for the given exports +/// Frees the memory for the given exports. +/// +/// Check the `wasmer_instance_exports` function to get a complete +/// example. +/// +/// If `exports` is a null pointer, this function does nothing. +/// +/// Example: +/// +/// ```c +/// // Get some exports. +/// wasmer_exports_t *exports = NULL; +/// wasmer_instance_exports(instance, &exports); +/// +/// // Destroy the exports. +/// wasmer_exports_destroy(exports); +/// ``` #[allow(clippy::cast_ptr_alignment)] #[no_mangle] pub extern "C" fn wasmer_exports_destroy(exports: *mut wasmer_exports_t) { From 3efd7d1232acd6b095ae4830c050987f4c612367 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 20 Jan 2020 15:29:04 +0100 Subject: [PATCH 31/46] doc(runtime-c-api) Improve documentation of `wasmer_instance_call`. --- lib/runtime-c-api/src/instance.rs | 57 ++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 5 deletions(-) diff --git a/lib/runtime-c-api/src/instance.rs b/lib/runtime-c-api/src/instance.rs index 689a5c4ba81..09046c7c308 100644 --- a/lib/runtime-c-api/src/instance.rs +++ b/lib/runtime-c-api/src/instance.rs @@ -199,13 +199,55 @@ pub extern "C" fn wasmer_instance_context_get( context as *const wasmer_instance_context_t } -/// Calls an instances exported function by `name` with the provided parameters. -/// Results are set using the provided `results` pointer. +/// Calls an exported function of a WebAssembly instance by `name` +/// with the provided parameters. The exported function results are +/// stored on the provided `results` pointer. /// -/// Returns `wasmer_result_t::WASMER_OK` upon success. +/// This function returns `wasmer_result_t::WASMER_OK` upon success, +/// `wasmer_result_t::WASMER_ERROR` otherwise. You can use +/// `wasmer_last_error_message()` to get the generated error message. /// -/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` -/// and `wasmer_last_error_message` to get an error message. +/// Potential errors are the following: +/// +/// * `instance` is a null pointer, +/// * `name` is a null pointer, +/// * `params` is a null pointer. +/// +/// Example of calling an exported function that needs two parameters, and returns one value: +/// +/// ```c +/// // First argument. +/// wasmer_value_t argument_one = { +/// .tag = WASM_I32, +/// .value.I32 = 3, +/// }; +/// +/// // Second argument. +/// wasmer_value_t argument_two = { +/// .tag = WASM_I32, +/// .value.I32 = 4, +/// }; +/// +/// // First result. +/// wasmer_value_t result_one; +/// +/// // All arguments and results. +/// wasmer_value_t arguments[] = {argument_one, argument_two}; +/// wasmer_value_t results[] = {result_one}; +/// +/// wasmer_result_t call_result = wasmer_instance_call( +/// instance, // instance pointer +/// "sum", // the exported function name +/// arguments, // the arguments +/// 2, // the number of arguments +/// results, // the results +/// 1 // the number of results +/// ); +/// +/// if (call_result == WASMER_OK) { +/// printf("Result is: %d\n", results[0].value.I32); +/// } +/// ``` #[allow(clippy::cast_ptr_alignment)] #[no_mangle] pub unsafe extern "C" fn wasmer_instance_call( @@ -220,18 +262,23 @@ pub unsafe extern "C" fn wasmer_instance_call( update_last_error(CApiError { msg: "instance ptr is null".to_string(), }); + return wasmer_result_t::WASMER_ERROR; } + if name.is_null() { update_last_error(CApiError { msg: "name ptr is null".to_string(), }); + return wasmer_result_t::WASMER_ERROR; } + if params.is_null() { update_last_error(CApiError { msg: "params ptr is null".to_string(), }); + return wasmer_result_t::WASMER_ERROR; } From 19627bdb8bb14fb1c5454527210315a60eee9d4b Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 20 Jan 2020 15:29:35 +0100 Subject: [PATCH 32/46] doc(runtime-c-api) Improve documentation of `wasmer_instance_exports`. --- lib/runtime-c-api/src/instance.rs | 46 +++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/lib/runtime-c-api/src/instance.rs b/lib/runtime-c-api/src/instance.rs index 09046c7c308..f5ca1a7dfbd 100644 --- a/lib/runtime-c-api/src/instance.rs +++ b/lib/runtime-c-api/src/instance.rs @@ -324,9 +324,48 @@ pub unsafe extern "C" fn wasmer_instance_call( } } -/// Gets Exports for the given instance +/// Gets all the exports of the given WebAssembly instance. /// -/// The caller owns the object and should call `wasmer_exports_destroy` to free it. + +/// This function stores a Rust vector of exports into `exports` as an +/// opaque pointer of kind `wasmer_exports_t`. +/// +/// As is, you can do anything with `exports` except using the +/// companion functions, like `wasmer_exports_len()`, +/// `wasmer_exports_get()` or `wasmer_export_kind()`. See the example below. +/// +/// **Warning**: The caller owns the object and should call +/// `wasmer_exports_destroy()` to free it. +/// +/// Example: +/// +/// ```c +/// // Get the exports. +/// wasmer_exports_t *exports = NULL; +/// wasmer_instance_exports(instance, &exports); +/// +/// // Get the number of exports. +/// int exports_length = wasmer_exports_len(exports); +/// printf("Number of exports: %d\n", exports_length); +/// +/// // Read the first export. +/// wasmer_export_t *export = wasmer_exports_get(exports, 0); +/// +/// // Get the kind of the export. +/// wasmer_import_export_kind export_kind = wasmer_export_kind(export); +/// +/// // Assert it is a function (why not). +/// assert(export_kind == WASM_FUNCTION); +/// +/// // Read the export name. +/// wasmer_byte_array name_bytes = wasmer_export_name(export); +/// +/// assert(name_bytes.bytes_len == sizeof("sum") - 1); +/// assert(memcmp(name_bytes.bytes, "sum", sizeof("sum") - 1) == 0); +/// +/// // Destroy the exports. +/// wasmer_exports_destroy(exports); +/// ``` #[allow(clippy::cast_ptr_alignment)] #[no_mangle] pub unsafe extern "C" fn wasmer_instance_exports( @@ -335,6 +374,7 @@ pub unsafe extern "C" fn wasmer_instance_exports( ) { let instance_ref = &mut *(instance as *mut Instance); let mut exports_vec: Vec = Vec::with_capacity(instance_ref.exports().count()); + for (name, export) in instance_ref.exports() { exports_vec.push(NamedExport { name: name.clone(), @@ -342,7 +382,9 @@ pub unsafe extern "C" fn wasmer_instance_exports( instance: instance as *mut Instance, }); } + let named_exports: Box = Box::new(NamedExports(exports_vec)); + *exports = Box::into_raw(named_exports) as *mut wasmer_exports_t; } From cb632f34523429adf13960775ac953c74ddabb15 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 20 Jan 2020 15:30:00 +0100 Subject: [PATCH 33/46] feat(runtime-c-api) Do nothing if `instance` is null in `wasmer_instance_exports`. --- lib/runtime-c-api/src/instance.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/runtime-c-api/src/instance.rs b/lib/runtime-c-api/src/instance.rs index f5ca1a7dfbd..2aaeb186d2c 100644 --- a/lib/runtime-c-api/src/instance.rs +++ b/lib/runtime-c-api/src/instance.rs @@ -372,6 +372,10 @@ pub unsafe extern "C" fn wasmer_instance_exports( instance: *mut wasmer_instance_t, exports: *mut *mut wasmer_exports_t, ) { + if instance.is_null() { + return; + } + let instance_ref = &mut *(instance as *mut Instance); let mut exports_vec: Vec = Vec::with_capacity(instance_ref.exports().count()); From edf45049e1e2bd70cf8212f949bed0b3a4ed9afd Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 20 Jan 2020 15:42:27 +0100 Subject: [PATCH 34/46] doc(runtime-c-api) Improve documentation of `wasmer_instance_context_t`. --- lib/runtime-c-api/src/instance.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/runtime-c-api/src/instance.rs b/lib/runtime-c-api/src/instance.rs index 2aaeb186d2c..58bc019a7ed 100644 --- a/lib/runtime-c-api/src/instance.rs +++ b/lib/runtime-c-api/src/instance.rs @@ -33,7 +33,9 @@ pub struct wasmer_instance_t; /// `wasmer_instance_context_memory()` function. /// /// It is also possible to get the instance context outside a host -/// function by using the `wasmer_instance_context_get()` function. +/// function by using the `wasmer_instance_context_get()` +/// function. See also `wasmer_instance_context_data_set()` to set the +/// instance context data. /// /// Example: /// From 05dae9ef9df3fea1be135e547399b32286cb8cd6 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 20 Jan 2020 15:42:50 +0100 Subject: [PATCH 35/46] doc(runtime-c-api) Improve documentation of `wasmer_instance_context_data_set`. --- lib/runtime-c-api/src/instance.rs | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/lib/runtime-c-api/src/instance.rs b/lib/runtime-c-api/src/instance.rs index 58bc019a7ed..cf97452e3af 100644 --- a/lib/runtime-c-api/src/instance.rs +++ b/lib/runtime-c-api/src/instance.rs @@ -394,8 +394,34 @@ pub unsafe extern "C" fn wasmer_instance_exports( *exports = Box::into_raw(named_exports) as *mut wasmer_exports_t; } -/// Sets the `data` field of the instance context. This context will be -/// passed to all imported function for instance. +/// Sets the data that can be hold by an instance context. +/// +/// An instance context (represented by the opaque +/// `wasmer_instance_context_t` structure) can hold user-defined +/// data. This function sets the data. This function is complementary +/// of `wasmer_instance_context_data_get()`. +/// +/// This function does nothing if `instance` is a null pointer. +/// +/// Example: +/// +/// ```c +/// // Define your own data. +/// typedef struct { +/// // … +/// } my_data; +/// +/// // Allocate them and set them on the given instance. +/// my_data *data = malloc(sizeof(my_data)); +/// data->… = …; +/// wasmer_instance_context_data_set(instance, (void*) my_data); +/// +/// // You can read your data. +/// { +/// my_data *data = wasmer_instance_context_data_get(wasmer_instance_context_get(instance)); +/// // … +/// } +/// ``` #[allow(clippy::cast_ptr_alignment)] #[no_mangle] pub extern "C" fn wasmer_instance_context_data_set( From 32ee93ef7399529cc9a97557ded0fb497f2f3670 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 20 Jan 2020 15:43:14 +0100 Subject: [PATCH 36/46] fix(runtime-c-api) `wasmer_instance_context_data_set` does nothing if `instance` is null. --- lib/runtime-c-api/src/instance.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/runtime-c-api/src/instance.rs b/lib/runtime-c-api/src/instance.rs index cf97452e3af..e203093a85e 100644 --- a/lib/runtime-c-api/src/instance.rs +++ b/lib/runtime-c-api/src/instance.rs @@ -428,8 +428,13 @@ pub extern "C" fn wasmer_instance_context_data_set( instance: *mut wasmer_instance_t, data_ptr: *mut c_void, ) { - let instance_ref = unsafe { &mut *(instance as *mut Instance) }; - instance_ref.context_mut().data = data_ptr; + if instance.is_null() { + return; + } + + let instance = unsafe { &mut *(instance as *mut Instance) }; + + instance.context_mut().data = data_ptr; } /// Gets the memory within the context at the index `memory_idx`. From c89f53b6fa4072a2fbd5f5609cdf3ada48eca53f Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 20 Jan 2020 15:51:48 +0100 Subject: [PATCH 37/46] doc(runtime-c-api) Improve documentation of `wasmer_instance_context_memory`. --- lib/runtime-c-api/src/instance.rs | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/lib/runtime-c-api/src/instance.rs b/lib/runtime-c-api/src/instance.rs index e203093a85e..a3b587957f1 100644 --- a/lib/runtime-c-api/src/instance.rs +++ b/lib/runtime-c-api/src/instance.rs @@ -418,7 +418,7 @@ pub unsafe extern "C" fn wasmer_instance_exports( /// /// // You can read your data. /// { -/// my_data *data = wasmer_instance_context_data_get(wasmer_instance_context_get(instance)); +/// my_data *data = (my_data*) wasmer_instance_context_data_get(wasmer_instance_context_get(instance)); /// // … /// } /// ``` @@ -437,8 +437,27 @@ pub extern "C" fn wasmer_instance_context_data_set( instance.context_mut().data = data_ptr; } -/// Gets the memory within the context at the index `memory_idx`. -/// The index is always 0 until multiple memories are supported. +/// Gets the `memory_idx`th memory of the instance. +/// +/// Note that the index is always `0` until multiple memories are supported. +/// +/// This function is mostly used inside host functions (aka imported +/// functions) to read the instance memory. +/// +/// Example of a _host function_ that reads and prints a string based on a pointer and a length: +/// +/// ```c +/// void print_string(const wasmer_instance_context_t *context, int32_t pointer, int32_t length) { +/// // Get the 0th memory. +/// const wasmer_memory_t *memory = wasmer_instance_context_memory(context, 0); +/// +/// // Get the memory data as a pointer. +/// uint8_t *memory_bytes = wasmer_memory_data(memory); +/// +/// // Print what we assumed to be a string! +/// printf("%.*s", length, memory_bytes + pointer); +/// } +/// ``` #[allow(clippy::cast_ptr_alignment)] #[no_mangle] pub extern "C" fn wasmer_instance_context_memory( From df2b93ea8183a0a087c9b0d59b82ba8ff3142e77 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 20 Jan 2020 15:52:14 +0100 Subject: [PATCH 38/46] fix(runtime-c-api) `wasmer_instance_context_data_get` returns `void` if `instance` is null. --- lib/runtime-c-api/src/instance.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/runtime-c-api/src/instance.rs b/lib/runtime-c-api/src/instance.rs index a3b587957f1..4dea693bc73 100644 --- a/lib/runtime-c-api/src/instance.rs +++ b/lib/runtime-c-api/src/instance.rs @@ -469,13 +469,25 @@ pub extern "C" fn wasmer_instance_context_memory( memory as *const Memory as *const wasmer_memory_t } -/// Gets the `data` field within the context. +/// Gets the data that can be hold by an instance. +/// +/// This function is complementary of +/// `wasmer_instance_context_data_set()`. Please read its +/// documentation. You can also read the documentation of +/// `wasmer_instance_context_t` to get other examples. +/// +/// This function returns nothing if `ctx` is a null pointer. #[allow(clippy::cast_ptr_alignment)] #[no_mangle] pub extern "C" fn wasmer_instance_context_data_get( ctx: *const wasmer_instance_context_t, ) -> *mut c_void { + if ctx.is_null() { + return ptr::null_mut() as _; + } + let ctx = unsafe { &*(ctx as *const Ctx) }; + ctx.data } From 11e915f00fd6c1f282ab0941002afc99fcd18142 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 20 Jan 2020 15:52:59 +0100 Subject: [PATCH 39/46] test(runtime-c-api) Simplify code. --- lib/runtime-c-api/tests/test-instantiate.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/runtime-c-api/tests/test-instantiate.c b/lib/runtime-c-api/tests/test-instantiate.c index 8a7c2610edc..4d15b2aea94 100644 --- a/lib/runtime-c-api/tests/test-instantiate.c +++ b/lib/runtime-c-api/tests/test-instantiate.c @@ -21,12 +21,14 @@ int main() printf("Compile result: %d\n", compile_result); assert(compile_result == WASMER_OK); - wasmer_value_t param_one; - param_one.tag = WASM_I32; - param_one.value.I32 = 7; - wasmer_value_t param_two; - param_two.tag = WASM_I32; - param_two.value.I32 = 8; + wasmer_value_t param_one = { + .tag = WASM_I32, + .value.I32 = 7, + }; + wasmer_value_t param_two = { + .tag = WASM_I32, + .value.I32 = 8, + }; wasmer_value_t params[] = {param_one, param_two}; wasmer_value_t result_one; From f4c8997c6d750567ea611b6e940041d3e3fcda91 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 20 Jan 2020 15:58:11 +0100 Subject: [PATCH 40/46] doc(runtime-c-api) Fix a link. --- lib/runtime-c-api/src/export.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/runtime-c-api/src/export.rs b/lib/runtime-c-api/src/export.rs index 26c501c747a..6b05632c7ea 100644 --- a/lib/runtime-c-api/src/export.rs +++ b/lib/runtime-c-api/src/export.rs @@ -214,7 +214,7 @@ pub unsafe extern "C" fn wasmer_export_descriptor_kind( /// Frees the memory for the given exports. /// -/// Check the `wasmer_instance_exports` function to get a complete +/// Check the `wasmer_instance_exports()` function to get a complete /// example. /// /// If `exports` is a null pointer, this function does nothing. From 8283b6d0daed64e683ad379a86b88c56bc709933 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 20 Jan 2020 15:58:27 +0100 Subject: [PATCH 41/46] doc(runtime-c-api) Improve documentation of `wasmer_instance_destroy`. --- lib/runtime-c-api/src/instance.rs | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/lib/runtime-c-api/src/instance.rs b/lib/runtime-c-api/src/instance.rs index 4dea693bc73..9fd63fc39fe 100644 --- a/lib/runtime-c-api/src/instance.rs +++ b/lib/runtime-c-api/src/instance.rs @@ -61,6 +61,9 @@ pub struct wasmer_instance_context_t; /// `wasmer_last_error_length()` with `wasmer_last_error_message()` must /// be used to read the error message. /// +/// The caller is responsible to free the instance with +/// `wasmer_instance_destroy()`. +/// /// Example: /// /// ```c @@ -87,6 +90,9 @@ pub struct wasmer_instance_context_t; /// wasmer_last_error_message(error, error_length); /// // Do something with `error`… /// } +/// +/// // 5. Free the memory! +/// wasmer_instance_destroy(instance); /// ``` #[allow(clippy::cast_ptr_alignment)] #[no_mangle] @@ -491,7 +497,23 @@ pub extern "C" fn wasmer_instance_context_data_get( ctx.data } -/// Frees memory for the given Instance +/// Frees memory for the given `wasmer_instance_t`. +/// +/// Check the `wasmer_instantiate()` function to get a complete +/// example. +/// +/// If `instance` is a null pointer, this function does nothing. +/// +/// Example: +/// +/// ```c +/// // Get an instance. +/// wasmer_instance_t *instance = NULL; +/// wasmer_instantiate(&instance, bytes, bytes_length, imports, 0); +/// +/// // Destroy the instance. +/// wasmer_instance_destroy(instance); +/// ``` #[allow(clippy::cast_ptr_alignment)] #[no_mangle] pub extern "C" fn wasmer_instance_destroy(instance: *mut wasmer_instance_t) { From 13f87b1618809f3734b376e43c16f8982c8780be Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 20 Jan 2020 15:59:30 +0100 Subject: [PATCH 42/46] chore(runtime-c-api) Update C/C++ headers. --- lib/runtime-c-api/wasmer.h | 290 +++++++++++++++++++++++++++++++----- lib/runtime-c-api/wasmer.hh | 276 +++++++++++++++++++++++++++++----- 2 files changed, 498 insertions(+), 68 deletions(-) diff --git a/lib/runtime-c-api/wasmer.h b/lib/runtime-c-api/wasmer.h index dd2b523a403..068853bc478 100644 --- a/lib/runtime-c-api/wasmer.h +++ b/lib/runtime-c-api/wasmer.h @@ -66,15 +66,37 @@ typedef uint8_t Version; * List of export/import kinds. */ enum wasmer_import_export_kind { + /** + * The export/import is a function. + */ WASM_FUNCTION = 0, + /** + * The export/import is a global. + */ WASM_GLOBAL = 1, + /** + * The export/import is a memory. + */ WASM_MEMORY = 2, + /** + * The export/import is a table. + */ WASM_TABLE = 3, }; typedef uint32_t wasmer_import_export_kind; +/** + * The `wasmer_result_t` struct is a type that represents either a + * success, or a failure. + */ typedef enum { + /** + * Represents a success. + */ WASMER_OK = 1, + /** + * Represents a failure. + */ WASMER_ERROR = 2, } wasmer_result_t; @@ -164,7 +186,11 @@ typedef struct { } wasmer_memory_t; /** - * Opaque pointer to `NamedExports`. + * Opaque pointer to the opaque structure `crate::NamedExports`, + * which is a wrapper around a vector of the opaque structure + * `crate::NamedExport`. + * + * Check the `wasmer_instance_exports()` function to learn more. */ typedef struct { @@ -226,7 +252,9 @@ typedef struct { * `wasmer_instance_context_memory()` function. * * It is also possible to get the instance context outside a host - * function by using the `wasmer_instance_context_get()` function. + * function by using the `wasmer_instance_context_get()` + * function. See also `wasmer_instance_context_data_set()` to set the + * instance context data. * * Example: * @@ -484,7 +512,23 @@ const wasmer_export_func_t *wasmer_export_to_func(const wasmer_export_t *export_ wasmer_result_t wasmer_export_to_memory(const wasmer_export_t *export_, wasmer_memory_t **memory); /** - * Frees the memory for the given exports + * Frees the memory for the given exports. + * + * Check the `wasmer_instance_exports()` function to get a complete + * example. + * + * If `exports` is a null pointer, this function does nothing. + * + * Example: + * + * ```c + * // Get some exports. + * wasmer_exports_t *exports = NULL; + * wasmer_instance_exports(instance, &exports); + * + * // Destroy the exports. + * wasmer_exports_destroy(exports); + * ``` */ void wasmer_exports_destroy(wasmer_exports_t *exports); @@ -708,13 +752,55 @@ wasmer_import_object_iter_t *wasmer_import_object_iterate_functions(const wasmer wasmer_import_object_t *wasmer_import_object_new(void); /** - * Calls an instances exported function by `name` with the provided parameters. - * Results are set using the provided `results` pointer. + * Calls an exported function of a WebAssembly instance by `name` + * with the provided parameters. The exported function results are + * stored on the provided `results` pointer. * - * Returns `wasmer_result_t::WASMER_OK` upon success. + * This function returns `wasmer_result_t::WASMER_OK` upon success, + * `wasmer_result_t::WASMER_ERROR` otherwise. You can use + * `wasmer_last_error_message()` to get the generated error message. * - * Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` - * and `wasmer_last_error_message` to get an error message. + * Potential errors are the following: + * + * * `instance` is a null pointer, + * * `name` is a null pointer, + * * `params` is a null pointer. + * + * Example of calling an exported function that needs two parameters, and returns one value: + * + * ```c + * // First argument. + * wasmer_value_t argument_one = { + * .tag = WASM_I32, + * .value.I32 = 3, + * }; + * + * // Second argument. + * wasmer_value_t argument_two = { + * .tag = WASM_I32, + * .value.I32 = 4, + * }; + * + * // First result. + * wasmer_value_t result_one; + * + * // All arguments and results. + * wasmer_value_t arguments[] = {argument_one, argument_two}; + * wasmer_value_t results[] = {result_one}; + * + * wasmer_result_t call_result = wasmer_instance_call( + * instance, // instance pointer + * "sum", // the exported function name + * arguments, // the arguments + * 2, // the number of arguments + * results, // the results + * 1 // the number of results + * ); + * + * if (call_result == WASMER_OK) { + * printf("Result is: %d\n", results[0].value.I32); + * } + * ``` */ wasmer_result_t wasmer_instance_call(wasmer_instance_t *instance, const char *name, @@ -724,37 +810,157 @@ wasmer_result_t wasmer_instance_call(wasmer_instance_t *instance, uint32_t results_len); /** - * Gets the `data` field within the context. + * Gets the data that can be hold by an instance. + * + * This function is complementary of + * `wasmer_instance_context_data_set()`. Please read its + * documentation. You can also read the documentation of + * `wasmer_instance_context_t` to get other examples. + * + * This function returns nothing if `ctx` is a null pointer. */ void *wasmer_instance_context_data_get(const wasmer_instance_context_t *ctx); /** - * Sets the `data` field of the instance context. This context will be - * passed to all imported function for instance. + * Sets the data that can be hold by an instance context. + * + * An instance context (represented by the opaque + * `wasmer_instance_context_t` structure) can hold user-defined + * data. This function sets the data. This function is complementary + * of `wasmer_instance_context_data_get()`. + * + * This function does nothing if `instance` is a null pointer. + * + * Example: + * + * ```c + * // Define your own data. + * typedef struct { + * // … + * } my_data; + * + * // Allocate them and set them on the given instance. + * my_data *data = malloc(sizeof(my_data)); + * data->… = …; + * wasmer_instance_context_data_set(instance, (void*) my_data); + * + * // You can read your data. + * { + * my_data *data = (my_data*) wasmer_instance_context_data_get(wasmer_instance_context_get(instance)); + * // … + * } + * ``` */ -void wasmer_instance_context_data_set(wasmer_instance_t *instance, void *data_ptr); +void wasmer_instance_context_data_set(wasmer_instance_t *instance, + void *data_ptr); /** - * Extracts the instance's context and returns it. + * Returns the instance context. Learn more by looking at the + * `wasmer_instance_context_t` struct. + * + * This function returns `null` if `instance` is a null pointer. + * + * Example: + * + * ```c + * const wasmer_instance_context_get *context = wasmer_instance_context_get(instance); + * my_data *data = (my_data *) wasmer_instance_context_data_get(context); + * // Do something with `my_data`. + * ``` + * + * It is often useful with `wasmer_instance_context_data_set()`. */ const wasmer_instance_context_t *wasmer_instance_context_get(wasmer_instance_t *instance); /** - * Gets the memory within the context at the index `memory_idx`. - * The index is always 0 until multiple memories are supported. + * Gets the `memory_idx`th memory of the instance. + * + * Note that the index is always `0` until multiple memories are supported. + * + * This function is mostly used inside host functions (aka imported + * functions) to read the instance memory. + * + * Example of a _host function_ that reads and prints a string based on a pointer and a length: + * + * ```c + * void print_string(const wasmer_instance_context_t *context, int32_t pointer, int32_t length) { + * // Get the 0th memory. + * const wasmer_memory_t *memory = wasmer_instance_context_memory(context, 0); + * + * // Get the memory data as a pointer. + * uint8_t *memory_bytes = wasmer_memory_data(memory); + * + * // Print what we assumed to be a string! + * printf("%.*s", length, memory_bytes + pointer); + * } + * ``` */ const wasmer_memory_t *wasmer_instance_context_memory(const wasmer_instance_context_t *ctx, uint32_t _memory_idx); /** - * Frees memory for the given Instance + * Frees memory for the given `wasmer_instance_t`. + * + * Check the `wasmer_instantiate()` function to get a complete + * example. + * + * If `instance` is a null pointer, this function does nothing. + * + * Example: + * + * ```c + * // Get an instance. + * wasmer_instance_t *instance = NULL; + * wasmer_instantiate(&instance, bytes, bytes_length, imports, 0); + * + * // Destroy the instance. + * wasmer_instance_destroy(instance); + * ``` */ void wasmer_instance_destroy(wasmer_instance_t *instance); /** - * Gets Exports for the given instance + * Gets all the exports of the given WebAssembly instance. + * + * This function stores a Rust vector of exports into `exports` as an + * opaque pointer of kind `wasmer_exports_t`. + * + * As is, you can do anything with `exports` except using the + * companion functions, like `wasmer_exports_len()`, + * `wasmer_exports_get()` or `wasmer_export_kind()`. See the example below. * - * The caller owns the object and should call `wasmer_exports_destroy` to free it. + * **Warning**: The caller owns the object and should call + * `wasmer_exports_destroy()` to free it. + * + * Example: + * + * ```c + * // Get the exports. + * wasmer_exports_t *exports = NULL; + * wasmer_instance_exports(instance, &exports); + * + * // Get the number of exports. + * int exports_length = wasmer_exports_len(exports); + * printf("Number of exports: %d\n", exports_length); + * + * // Read the first export. + * wasmer_export_t *export = wasmer_exports_get(exports, 0); + * + * // Get the kind of the export. + * wasmer_import_export_kind export_kind = wasmer_export_kind(export); + * + * // Assert it is a function (why not). + * assert(export_kind == WASM_FUNCTION); + * + * // Read the export name. + * wasmer_byte_array name_bytes = wasmer_export_name(export); + * + * assert(name_bytes.bytes_len == sizeof("sum") - 1); + * assert(memcmp(name_bytes.bytes, "sum", sizeof("sum") - 1) == 0); + * + * // Destroy the exports. + * wasmer_exports_destroy(exports); + * ``` */ void wasmer_instance_exports(wasmer_instance_t *instance, wasmer_exports_t **exports); @@ -768,6 +974,9 @@ void wasmer_instance_exports(wasmer_instance_t *instance, wasmer_exports_t **exp * `wasmer_last_error_length()` with `wasmer_last_error_message()` must * be used to read the error message. * + * The caller is responsible to free the instance with + * `wasmer_instance_destroy()`. + * * Example: * * ```c @@ -794,6 +1003,9 @@ void wasmer_instance_exports(wasmer_instance_t *instance, wasmer_exports_t **exp * wasmer_last_error_message(error, error_length); * // Do something with `error`… * } + * + * // 5. Free the memory! + * wasmer_instance_destroy(instance); * ``` */ wasmer_result_t wasmer_instantiate(wasmer_instance_t **instance, @@ -803,33 +1015,43 @@ wasmer_result_t wasmer_instantiate(wasmer_instance_t **instance, int imports_len); /** - * Gets the length in bytes of the last error. + * Gets the length in bytes of the last error if any. + * * This can be used to dynamically allocate a buffer with the correct number of * bytes needed to store a message. * - * # Example - * - * ```c - * int error_len = wasmer_last_error_length(); - * char *error_str = malloc(error_len); - * ``` + * See `wasmer_last_error_message()` to get a full example. */ int wasmer_last_error_length(void); /** - * Stores the last error message into the provided buffer up to the given `length`. - * The `length` parameter must be large enough to store the last error message. + * Gets the last error message if any into the provided buffer + * `buffer` up to the given `length`. * - * Returns the length of the string in bytes. - * Returns `-1` if an error occurs. + * The `length` parameter must be large enough to store the last + * error message. Ideally, the value should come from + * `wasmer_last_error_length()`. * - * # Example + * The function returns the length of the string in bytes, `-1` if an + * error occurs. Potential errors are: + * + * * The buffer is a null pointer, + * * The buffer is too smal to hold the error message. + * + * Note: The error message always has a trailing null character. + * + * Example: * * ```c - * int error_len = wasmer_last_error_length(); - * char *error_str = malloc(error_len); - * wasmer_last_error_message(error_str, error_len); - * printf("Error str: `%s`\n", error_str); + * int error_length = wasmer_last_error_length(); + * + * if (error_length > 0) { + * char *error_message = malloc(error_length); + * wasmer_last_error_message(error_message, error_length); + * printf("Error message: `%s`\n", error_message); + * } else { + * printf("No error message\n"); + * } * ``` */ int wasmer_last_error_message(char *buffer, int length); diff --git a/lib/runtime-c-api/wasmer.hh b/lib/runtime-c-api/wasmer.hh index 691002fe363..5a0ac5de4bb 100644 --- a/lib/runtime-c-api/wasmer.hh +++ b/lib/runtime-c-api/wasmer.hh @@ -55,14 +55,22 @@ enum class Version : uint8_t { /// List of export/import kinds. enum class wasmer_import_export_kind : uint32_t { + /// The export/import is a function. WASM_FUNCTION = 0, + /// The export/import is a global. WASM_GLOBAL = 1, + /// The export/import is a memory. WASM_MEMORY = 2, + /// The export/import is a table. WASM_TABLE = 3, }; +/// The `wasmer_result_t` struct is a type that represents either a +/// success, or a failure. enum class wasmer_result_t { + /// Represents a success. WASMER_OK = 1, + /// Represents a failure. WASMER_ERROR = 2, }; @@ -138,7 +146,11 @@ struct wasmer_memory_t { }; -/// Opaque pointer to `NamedExports`. +/// Opaque pointer to the opaque structure `crate::NamedExports`, +/// which is a wrapper around a vector of the opaque structure +/// `crate::NamedExport`. +/// +/// Check the `wasmer_instance_exports()` function to learn more. struct wasmer_exports_t { }; @@ -196,7 +208,9 @@ struct wasmer_import_object_iter_t { /// `wasmer_instance_context_memory()` function. /// /// It is also possible to get the instance context outside a host -/// function by using the `wasmer_instance_context_get()` function. +/// function by using the `wasmer_instance_context_get()` +/// function. See also `wasmer_instance_context_data_set()` to set the +/// instance context data. /// /// Example: /// @@ -406,7 +420,23 @@ const wasmer_export_func_t *wasmer_export_to_func(const wasmer_export_t *export_ /// and `wasmer_last_error_message` to get an error message. wasmer_result_t wasmer_export_to_memory(const wasmer_export_t *export_, wasmer_memory_t **memory); -/// Frees the memory for the given exports +/// Frees the memory for the given exports. +/// +/// Check the `wasmer_instance_exports()` function to get a complete +/// example. +/// +/// If `exports` is a null pointer, this function does nothing. +/// +/// Example: +/// +/// ```c +/// // Get some exports. +/// wasmer_exports_t *exports = NULL; +/// wasmer_instance_exports(instance, &exports); +/// +/// // Destroy the exports. +/// wasmer_exports_destroy(exports); +/// ``` void wasmer_exports_destroy(wasmer_exports_t *exports); /// Gets wasmer_export by index @@ -570,13 +600,55 @@ wasmer_import_object_iter_t *wasmer_import_object_iterate_functions(const wasmer /// See also `wasmer_import_object_append` wasmer_import_object_t *wasmer_import_object_new(); -/// Calls an instances exported function by `name` with the provided parameters. -/// Results are set using the provided `results` pointer. +/// Calls an exported function of a WebAssembly instance by `name` +/// with the provided parameters. The exported function results are +/// stored on the provided `results` pointer. /// -/// Returns `wasmer_result_t::WASMER_OK` upon success. +/// This function returns `wasmer_result_t::WASMER_OK` upon success, +/// `wasmer_result_t::WASMER_ERROR` otherwise. You can use +/// `wasmer_last_error_message()` to get the generated error message. /// -/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length` -/// and `wasmer_last_error_message` to get an error message. +/// Potential errors are the following: +/// +/// * `instance` is a null pointer, +/// * `name` is a null pointer, +/// * `params` is a null pointer. +/// +/// Example of calling an exported function that needs two parameters, and returns one value: +/// +/// ```c +/// // First argument. +/// wasmer_value_t argument_one = { +/// .tag = WASM_I32, +/// .value.I32 = 3, +/// }; +/// +/// // Second argument. +/// wasmer_value_t argument_two = { +/// .tag = WASM_I32, +/// .value.I32 = 4, +/// }; +/// +/// // First result. +/// wasmer_value_t result_one; +/// +/// // All arguments and results. +/// wasmer_value_t arguments[] = {argument_one, argument_two}; +/// wasmer_value_t results[] = {result_one}; +/// +/// wasmer_result_t call_result = wasmer_instance_call( +/// instance, // instance pointer +/// "sum", // the exported function name +/// arguments, // the arguments +/// 2, // the number of arguments +/// results, // the results +/// 1 // the number of results +/// ); +/// +/// if (call_result == WASMER_OK) { +/// printf("Result is: %d\n", results[0].value.I32); +/// } +/// ``` wasmer_result_t wasmer_instance_call(wasmer_instance_t *instance, const char *name, const wasmer_value_t *params, @@ -584,27 +656,147 @@ wasmer_result_t wasmer_instance_call(wasmer_instance_t *instance, wasmer_value_t *results, uint32_t results_len); -/// Gets the `data` field within the context. +/// Gets the data that can be hold by an instance. +/// +/// This function is complementary of +/// `wasmer_instance_context_data_set()`. Please read its +/// documentation. You can also read the documentation of +/// `wasmer_instance_context_t` to get other examples. +/// +/// This function returns nothing if `ctx` is a null pointer. void *wasmer_instance_context_data_get(const wasmer_instance_context_t *ctx); -/// Sets the `data` field of the instance context. This context will be -/// passed to all imported function for instance. -void wasmer_instance_context_data_set(wasmer_instance_t *instance, void *data_ptr); +/// Sets the data that can be hold by an instance context. +/// +/// An instance context (represented by the opaque +/// `wasmer_instance_context_t` structure) can hold user-defined +/// data. This function sets the data. This function is complementary +/// of `wasmer_instance_context_data_get()`. +/// +/// This function does nothing if `instance` is a null pointer. +/// +/// Example: +/// +/// ```c +/// // Define your own data. +/// typedef struct { +/// // … +/// } my_data; +/// +/// // Allocate them and set them on the given instance. +/// my_data *data = malloc(sizeof(my_data)); +/// data->… = …; +/// wasmer_instance_context_data_set(instance, (void*) my_data); +/// +/// // You can read your data. +/// { +/// my_data *data = (my_data*) wasmer_instance_context_data_get(wasmer_instance_context_get(instance)); +/// // … +/// } +/// ``` +void wasmer_instance_context_data_set(wasmer_instance_t *instance, + void *data_ptr); -/// Extracts the instance's context and returns it. +/// Returns the instance context. Learn more by looking at the +/// `wasmer_instance_context_t` struct. +/// +/// This function returns `null` if `instance` is a null pointer. +/// +/// Example: +/// +/// ```c +/// const wasmer_instance_context_get *context = wasmer_instance_context_get(instance); +/// my_data *data = (my_data *) wasmer_instance_context_data_get(context); +/// // Do something with `my_data`. +/// ``` +/// +/// It is often useful with `wasmer_instance_context_data_set()`. const wasmer_instance_context_t *wasmer_instance_context_get(wasmer_instance_t *instance); -/// Gets the memory within the context at the index `memory_idx`. -/// The index is always 0 until multiple memories are supported. +/// Gets the `memory_idx`th memory of the instance. +/// +/// Note that the index is always `0` until multiple memories are supported. +/// +/// This function is mostly used inside host functions (aka imported +/// functions) to read the instance memory. +/// +/// Example of a _host function_ that reads and prints a string based on a pointer and a length: +/// +/// ```c +/// void print_string(const wasmer_instance_context_t *context, int32_t pointer, int32_t length) { +/// // Get the 0th memory. +/// const wasmer_memory_t *memory = wasmer_instance_context_memory(context, 0); +/// +/// // Get the memory data as a pointer. +/// uint8_t *memory_bytes = wasmer_memory_data(memory); +/// +/// // Print what we assumed to be a string! +/// printf("%.*s", length, memory_bytes + pointer); +/// } +/// ``` const wasmer_memory_t *wasmer_instance_context_memory(const wasmer_instance_context_t *ctx, uint32_t _memory_idx); -/// Frees memory for the given Instance +/// Frees memory for the given `wasmer_instance_t`. +/// +/// Check the `wasmer_instantiate()` function to get a complete +/// example. +/// +/// If `instance` is a null pointer, this function does nothing. +/// +/// Example: +/// +/// ```c +/// // Get an instance. +/// wasmer_instance_t *instance = NULL; +/// wasmer_instantiate(&instance, bytes, bytes_length, imports, 0); +/// +/// // Destroy the instance. +/// wasmer_instance_destroy(instance); +/// ``` void wasmer_instance_destroy(wasmer_instance_t *instance); -/// Gets Exports for the given instance +/// Gets all the exports of the given WebAssembly instance. +/// +/// This function stores a Rust vector of exports into `exports` as an +/// opaque pointer of kind `wasmer_exports_t`. +/// +/// As is, you can do anything with `exports` except using the +/// companion functions, like `wasmer_exports_len()`, +/// `wasmer_exports_get()` or `wasmer_export_kind()`. See the example below. +/// +/// **Warning**: The caller owns the object and should call +/// `wasmer_exports_destroy()` to free it. +/// +/// Example: /// -/// The caller owns the object and should call `wasmer_exports_destroy` to free it. +/// ```c +/// // Get the exports. +/// wasmer_exports_t *exports = NULL; +/// wasmer_instance_exports(instance, &exports); +/// +/// // Get the number of exports. +/// int exports_length = wasmer_exports_len(exports); +/// printf("Number of exports: %d\n", exports_length); +/// +/// // Read the first export. +/// wasmer_export_t *export = wasmer_exports_get(exports, 0); +/// +/// // Get the kind of the export. +/// wasmer_import_export_kind export_kind = wasmer_export_kind(export); +/// +/// // Assert it is a function (why not). +/// assert(export_kind == WASM_FUNCTION); +/// +/// // Read the export name. +/// wasmer_byte_array name_bytes = wasmer_export_name(export); +/// +/// assert(name_bytes.bytes_len == sizeof("sum") - 1); +/// assert(memcmp(name_bytes.bytes, "sum", sizeof("sum") - 1) == 0); +/// +/// // Destroy the exports. +/// wasmer_exports_destroy(exports); +/// ``` void wasmer_instance_exports(wasmer_instance_t *instance, wasmer_exports_t **exports); /// Creates a new WebAssembly instance from the given bytes and imports. @@ -616,6 +808,9 @@ void wasmer_instance_exports(wasmer_instance_t *instance, wasmer_exports_t **exp /// `wasmer_last_error_length()` with `wasmer_last_error_message()` must /// be used to read the error message. /// +/// The caller is responsible to free the instance with +/// `wasmer_instance_destroy()`. +/// /// Example: /// /// ```c @@ -642,6 +837,9 @@ void wasmer_instance_exports(wasmer_instance_t *instance, wasmer_exports_t **exp /// wasmer_last_error_message(error, error_length); /// // Do something with `error`… /// } +/// +/// // 5. Free the memory! +/// wasmer_instance_destroy(instance); /// ``` wasmer_result_t wasmer_instantiate(wasmer_instance_t **instance, uint8_t *wasm_bytes, @@ -649,31 +847,41 @@ wasmer_result_t wasmer_instantiate(wasmer_instance_t **instance, wasmer_import_t *imports, int imports_len); -/// Gets the length in bytes of the last error. +/// Gets the length in bytes of the last error if any. +/// /// This can be used to dynamically allocate a buffer with the correct number of /// bytes needed to store a message. /// -/// # Example -/// -/// ```c -/// int error_len = wasmer_last_error_length(); -/// char *error_str = malloc(error_len); -/// ``` +/// See `wasmer_last_error_message()` to get a full example. int wasmer_last_error_length(); -/// Stores the last error message into the provided buffer up to the given `length`. -/// The `length` parameter must be large enough to store the last error message. +/// Gets the last error message if any into the provided buffer +/// `buffer` up to the given `length`. /// -/// Returns the length of the string in bytes. -/// Returns `-1` if an error occurs. +/// The `length` parameter must be large enough to store the last +/// error message. Ideally, the value should come from +/// `wasmer_last_error_length()`. /// -/// # Example +/// The function returns the length of the string in bytes, `-1` if an +/// error occurs. Potential errors are: +/// +/// * The buffer is a null pointer, +/// * The buffer is too smal to hold the error message. +/// +/// Note: The error message always has a trailing null character. +/// +/// Example: /// /// ```c -/// int error_len = wasmer_last_error_length(); -/// char *error_str = malloc(error_len); -/// wasmer_last_error_message(error_str, error_len); -/// printf("Error str: `%s`\n", error_str); +/// int error_length = wasmer_last_error_length(); +/// +/// if (error_length > 0) { +/// char *error_message = malloc(error_length); +/// wasmer_last_error_message(error_message, error_length); +/// printf("Error message: `%s`\n", error_message); +/// } else { +/// printf("No error message\n"); +/// } /// ``` int wasmer_last_error_message(char *buffer, int length); From 16dee04d225ffe986f1d313e1c3b07f6ea9ad67c Mon Sep 17 00:00:00 2001 From: losfair Date: Tue, 21 Jan 2020 01:10:14 +0800 Subject: [PATCH 43/46] Add aarch64-specific failure excludes. --- lib/spectests/tests/excludes.txt | 119 +++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/lib/spectests/tests/excludes.txt b/lib/spectests/tests/excludes.txt index b1c6e5dc8d7..b6690cc99d2 100644 --- a/lib/spectests/tests/excludes.txt +++ b/lib/spectests/tests/excludes.txt @@ -354,3 +354,122 @@ singlepass:fail:linking.wast:181 # AssertReturn - Call failed RuntimeError: unkn singlepass:fail:linking.wast:185 # AssertTrap - expected trap, got Runtime:Error unknown error singlepass:fail:linking.wast:187 # AssertTrap - expected trap, got Runtime:Error unknown error singlepass:fail:linking.wast:388 # AssertReturn - Call failed RuntimeError: unknown error + +# These failures only happen on AArch64 and not on x86-64. +singlepass:fail:conversions.wast:83:*:aarch64 # AssertTrap - expected trap, got [I32(2147483647)] +singlepass:fail:conversions.wast:84:*:aarch64 # AssertTrap - expected trap, got [I32(-2147483648)] +singlepass:fail:conversions.wast:85:*:aarch64 # AssertTrap - expected trap, got [I32(2147483647)] +singlepass:fail:conversions.wast:86:*:aarch64 # AssertTrap - expected trap, got [I32(-2147483648)] +singlepass:fail:conversions.wast:87:*:aarch64 # AssertTrap - expected trap, got [I32(0)] +singlepass:fail:conversions.wast:88:*:aarch64 # AssertTrap - expected trap, got [I32(0)] +singlepass:fail:conversions.wast:89:*:aarch64 # AssertTrap - expected trap, got [I32(0)] +singlepass:fail:conversions.wast:90:*:aarch64 # AssertTrap - expected trap, got [I32(0)] +singlepass:fail:conversions.wast:105:*:aarch64 # AssertTrap - expected trap, got [I32(-1)] +singlepass:fail:conversions.wast:106:*:aarch64 # AssertTrap - expected trap, got [I32(0)] +singlepass:fail:conversions.wast:107:*:aarch64 # AssertTrap - expected trap, got [I32(-1)] +singlepass:fail:conversions.wast:108:*:aarch64 # AssertTrap - expected trap, got [I32(0)] +singlepass:fail:conversions.wast:109:*:aarch64 # AssertTrap - expected trap, got [I32(0)] +singlepass:fail:conversions.wast:110:*:aarch64 # AssertTrap - expected trap, got [I32(0)] +singlepass:fail:conversions.wast:111:*:aarch64 # AssertTrap - expected trap, got [I32(0)] +singlepass:fail:conversions.wast:112:*:aarch64 # AssertTrap - expected trap, got [I32(0)] +singlepass:fail:conversions.wast:128:*:aarch64 # AssertTrap - expected trap, got [I32(2147483647)] +singlepass:fail:conversions.wast:129:*:aarch64 # AssertTrap - expected trap, got [I32(-2147483648)] +singlepass:fail:conversions.wast:130:*:aarch64 # AssertTrap - expected trap, got [I32(2147483647)] +singlepass:fail:conversions.wast:131:*:aarch64 # AssertTrap - expected trap, got [I32(-2147483648)] +singlepass:fail:conversions.wast:132:*:aarch64 # AssertTrap - expected trap, got [I32(0)] +singlepass:fail:conversions.wast:133:*:aarch64 # AssertTrap - expected trap, got [I32(0)] +singlepass:fail:conversions.wast:134:*:aarch64 # AssertTrap - expected trap, got [I32(0)] +singlepass:fail:conversions.wast:135:*:aarch64 # AssertTrap - expected trap, got [I32(0)] +singlepass:fail:conversions.wast:151:*:aarch64 # AssertTrap - expected trap, got [I32(-1)] +singlepass:fail:conversions.wast:152:*:aarch64 # AssertTrap - expected trap, got [I32(0)] +singlepass:fail:conversions.wast:153:*:aarch64 # AssertTrap - expected trap, got [I32(-1)] +singlepass:fail:conversions.wast:154:*:aarch64 # AssertTrap - expected trap, got [I32(-1)] +singlepass:fail:conversions.wast:155:*:aarch64 # AssertTrap - expected trap, got [I32(-1)] +singlepass:fail:conversions.wast:156:*:aarch64 # AssertTrap - expected trap, got [I32(-1)] +singlepass:fail:conversions.wast:157:*:aarch64 # AssertTrap - expected trap, got [I32(0)] +singlepass:fail:conversions.wast:158:*:aarch64 # AssertTrap - expected trap, got [I32(0)] +singlepass:fail:conversions.wast:159:*:aarch64 # AssertTrap - expected trap, got [I32(0)] +singlepass:fail:conversions.wast:160:*:aarch64 # AssertTrap - expected trap, got [I32(0)] +singlepass:fail:conversions.wast:161:*:aarch64 # AssertTrap - expected trap, got [I32(0)] +singlepass:fail:conversions.wast:179:*:aarch64 # AssertTrap - expected trap, got [I64(9223372036854775807)] +singlepass:fail:conversions.wast:180:*:aarch64 # AssertTrap - expected trap, got [I64(-9223372036854775808)] +singlepass:fail:conversions.wast:181:*:aarch64 # AssertTrap - expected trap, got [I64(9223372036854775807)] +singlepass:fail:conversions.wast:182:*:aarch64 # AssertTrap - expected trap, got [I64(-9223372036854775808)] +singlepass:fail:conversions.wast:183:*:aarch64 # AssertTrap - expected trap, got [I64(0)] +singlepass:fail:conversions.wast:184:*:aarch64 # AssertTrap - expected trap, got [I64(0)] +singlepass:fail:conversions.wast:185:*:aarch64 # AssertTrap - expected trap, got [I64(0)] +singlepass:fail:conversions.wast:186:*:aarch64 # AssertTrap - expected trap, got [I64(0)] +singlepass:fail:conversions.wast:199:*:aarch64 # AssertTrap - expected trap, got [I64(-1)] +singlepass:fail:conversions.wast:200:*:aarch64 # AssertTrap - expected trap, got [I64(0)] +singlepass:fail:conversions.wast:201:*:aarch64 # AssertTrap - expected trap, got [I64(-1)] +singlepass:fail:conversions.wast:202:*:aarch64 # AssertTrap - expected trap, got [I64(0)] +singlepass:fail:conversions.wast:203:*:aarch64 # AssertTrap - expected trap, got [I64(0)] +singlepass:fail:conversions.wast:204:*:aarch64 # AssertTrap - expected trap, got [I64(0)] +singlepass:fail:conversions.wast:205:*:aarch64 # AssertTrap - expected trap, got [I64(0)] +singlepass:fail:conversions.wast:206:*:aarch64 # AssertTrap - expected trap, got [I64(0)] +singlepass:fail:conversions.wast:224:*:aarch64 # AssertTrap - expected trap, got [I64(9223372036854775807)] +singlepass:fail:conversions.wast:225:*:aarch64 # AssertTrap - expected trap, got [I64(-9223372036854775808)] +singlepass:fail:conversions.wast:226:*:aarch64 # AssertTrap - expected trap, got [I64(9223372036854775807)] +singlepass:fail:conversions.wast:227:*:aarch64 # AssertTrap - expected trap, got [I64(-9223372036854775808)] +singlepass:fail:conversions.wast:228:*:aarch64 # AssertTrap - expected trap, got [I64(0)] +singlepass:fail:conversions.wast:229:*:aarch64 # AssertTrap - expected trap, got [I64(0)] +singlepass:fail:conversions.wast:230:*:aarch64 # AssertTrap - expected trap, got [I64(0)] +singlepass:fail:conversions.wast:231:*:aarch64 # AssertTrap - expected trap, got [I64(0)] +singlepass:fail:conversions.wast:248:*:aarch64 # AssertTrap - expected trap, got [I64(-1)] +singlepass:fail:conversions.wast:249:*:aarch64 # AssertTrap - expected trap, got [I64(0)] +singlepass:fail:conversions.wast:250:*:aarch64 # AssertTrap - expected trap, got [I64(-1)] +singlepass:fail:conversions.wast:251:*:aarch64 # AssertTrap - expected trap, got [I64(0)] +singlepass:fail:conversions.wast:252:*:aarch64 # AssertTrap - expected trap, got [I64(0)] +singlepass:fail:conversions.wast:253:*:aarch64 # AssertTrap - expected trap, got [I64(0)] +singlepass:fail:conversions.wast:254:*:aarch64 # AssertTrap - expected trap, got [I64(0)] +singlepass:fail:conversions.wast:255:*:aarch64 # AssertTrap - expected trap, got [I64(0)] +singlepass:fail:i32.wast:62:*:aarch64 # AssertTrap - expected trap, got [I32(0)] +singlepass:fail:i32.wast:63:*:aarch64 # AssertTrap - expected trap, got [I32(0)] +singlepass:fail:i32.wast:64:*:aarch64 # AssertTrap - expected trap, got [I32(-2147483648)] +singlepass:fail:i32.wast:82:*:aarch64 # AssertTrap - expected trap, got [I32(0)] +singlepass:fail:i32.wast:83:*:aarch64 # AssertTrap - expected trap, got [I32(0)] +singlepass:fail:i32.wast:99:*:aarch64 # AssertTrap - expected trap, got [I32(1)] +singlepass:fail:i32.wast:100:*:aarch64 # AssertTrap - expected trap, got [I32(0)] +singlepass:fail:i32.wast:120:*:aarch64 # AssertTrap - expected trap, got [I32(1)] +singlepass:fail:i32.wast:121:*:aarch64 # AssertTrap - expected trap, got [I32(0)] +singlepass:fail:i64.wast:62:*:aarch64 # AssertTrap - expected trap, got [I64(0)] +singlepass:fail:i64.wast:63:*:aarch64 # AssertTrap - expected trap, got [I64(0)] +singlepass:fail:i64.wast:64:*:aarch64 # AssertTrap - expected trap, got [I64(-9223372036854775808)] +singlepass:fail:i64.wast:82:*:aarch64 # AssertTrap - expected trap, got [I64(0)] +singlepass:fail:i64.wast:83:*:aarch64 # AssertTrap - expected trap, got [I64(0)] +singlepass:fail:i64.wast:99:*:aarch64 # AssertTrap - expected trap, got [I64(1)] +singlepass:fail:i64.wast:100:*:aarch64 # AssertTrap - expected trap, got [I64(0)] +singlepass:fail:i64.wast:120:*:aarch64 # AssertTrap - expected trap, got [I64(1)] +singlepass:fail:i64.wast:121:*:aarch64 # AssertTrap - expected trap, got [I64(0)] +singlepass:fail:int_exprs.wast:113:*:aarch64 # AssertTrap - expected trap, got [I32(0)] +singlepass:fail:int_exprs.wast:114:*:aarch64 # AssertTrap - expected trap, got [I32(0)] +singlepass:fail:int_exprs.wast:115:*:aarch64 # AssertTrap - expected trap, got [I64(0)] +singlepass:fail:int_exprs.wast:116:*:aarch64 # AssertTrap - expected trap, got [I64(0)] +singlepass:fail:int_exprs.wast:132:*:aarch64 # AssertTrap - expected trap, got [I32(0)] +singlepass:fail:int_exprs.wast:133:*:aarch64 # AssertTrap - expected trap, got [I32(0)] +singlepass:fail:int_exprs.wast:134:*:aarch64 # AssertTrap - expected trap, got [I64(0)] +singlepass:fail:int_exprs.wast:135:*:aarch64 # AssertTrap - expected trap, got [I64(0)] +singlepass:fail:int_exprs.wast:196:*:aarch64 # AssertTrap - expected trap, got [I32(0)] +singlepass:fail:int_exprs.wast:197:*:aarch64 # AssertTrap - expected trap, got [I32(0)] +singlepass:fail:int_exprs.wast:198:*:aarch64 # AssertTrap - expected trap, got [I64(0)] +singlepass:fail:int_exprs.wast:199:*:aarch64 # AssertTrap - expected trap, got [I64(0)] +singlepass:fail:int_exprs.wast:349:*:aarch64 # AssertTrap - expected trap, got [I32(-2147483648)] +singlepass:fail:int_exprs.wast:350:*:aarch64 # AssertTrap - expected trap, got [I64(-9223372036854775808)] +singlepass:fail:traps.wast:16:*:aarch64 # AssertTrap - expected trap, got [] +singlepass:fail:traps.wast:17:*:aarch64 # AssertTrap - expected trap, got [] +singlepass:fail:traps.wast:18:*:aarch64 # AssertTrap - expected trap, got [] +singlepass:fail:traps.wast:19:*:aarch64 # AssertTrap - expected trap, got [] +singlepass:fail:traps.wast:20:*:aarch64 # AssertTrap - expected trap, got [] +singlepass:fail:traps.wast:21:*:aarch64 # AssertTrap - expected trap, got [] +singlepass:fail:traps.wast:34:*:aarch64 # AssertTrap - expected trap, got [] +singlepass:fail:traps.wast:35:*:aarch64 # AssertTrap - expected trap, got [] +singlepass:fail:traps.wast:36:*:aarch64 # AssertTrap - expected trap, got [] +singlepass:fail:traps.wast:37:*:aarch64 # AssertTrap - expected trap, got [] +singlepass:fail:traps.wast:50:*:aarch64 # AssertTrap - expected trap, got [] +singlepass:fail:traps.wast:51:*:aarch64 # AssertTrap - expected trap, got [] +singlepass:fail:traps.wast:52:*:aarch64 # AssertTrap - expected trap, got [] +singlepass:fail:traps.wast:53:*:aarch64 # AssertTrap - expected trap, got [] +singlepass:fail:traps.wast:54:*:aarch64 # AssertTrap - expected trap, got [] +singlepass:fail:traps.wast:55:*:aarch64 # AssertTrap - expected trap, got [] +singlepass:fail:traps.wast:56:*:aarch64 # AssertTrap - expected trap, got [] +singlepass:fail:traps.wast:57:*:aarch64 # AssertTrap - expected trap, got [] \ No newline at end of file From dc216364bee4dcb897a69c6596aebc1d01179d73 Mon Sep 17 00:00:00 2001 From: losfair Date: Tue, 21 Jan 2020 02:07:32 +0800 Subject: [PATCH 44/46] Fix backend string type. --- src/bin/wasmer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/wasmer.rs b/src/bin/wasmer.rs index a84f3d8f7b6..9d37e033832 100644 --- a/src/bin/wasmer.rs +++ b/src/bin/wasmer.rs @@ -868,7 +868,7 @@ fn execute_wasm(options: &Run) -> Result<(), String> { baseline: true, msm: msm, base: instance.module.runnable_module.get_code().unwrap().as_ptr() as usize, - backend: options.backend.to_string().to_owned(), + backend: options.backend.to_string(), runnable_module: instance.module.runnable_module.clone(), }); true From 1b5d9f2a21988ddbc497f3d45badadfe54c1c7d1 Mon Sep 17 00:00:00 2001 From: losfair Date: Tue, 21 Jan 2020 02:21:55 +0800 Subject: [PATCH 45/46] Update changelog. --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a848cb6871a..42e104d7af5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## **[Unreleased]** +- [#1129](https://github.com/wasmerio/wasmer/pull/1129) Standard exception types for singlepass backend. + ## 0.13.1 - 2020-01-16 - Fix bug in wapm related to the `package.wasmer_extra_flags` entry in the manifest From 0d2d4369aa2692ae06f50bf6a4fb2119d6c1d672 Mon Sep 17 00:00:00 2001 From: Syrus Date: Mon, 20 Jan 2020 14:15:02 -0800 Subject: [PATCH 46/46] Fixed lint issue --- lib/runtime-core/src/cache.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/runtime-core/src/cache.rs b/lib/runtime-core/src/cache.rs index b5aa8ccfc27..76a058f8bbb 100644 --- a/lib/runtime-core/src/cache.rs +++ b/lib/runtime-core/src/cache.rs @@ -79,11 +79,9 @@ impl WasmHash { )); } use std::convert::TryInto; - Ok(WasmHash( - bytes[0..32].try_into().map_err(|e| { - Error::DeserializeError(format!("Could not get first 32 bytes: {}", e)) - })? - )) + Ok(WasmHash(bytes[0..32].try_into().map_err(|e| { + Error::DeserializeError(format!("Could not get first 32 bytes: {}", e)) + })?)) } pub(crate) fn into_array(self) -> [u8; 32] {