diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b1eba184e2..788858a4cf3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ * [#1941](https://github.com/wasmerio/wasmer/pull/1941) Turn `get_remaining_points`/`set_remaining_points` of the `Metering` middleware into free functions to allow using them in an ahead-of-time compilation setup * [#1955](https://github.com/wasmerio/wasmer/pull/1955) Set `jit` as a default feature of the `wasmer-wasm-c-api` crate * [#1944](https://github.com/wasmerio/wasmer/pull/1944) Require `WasmerEnv` to be `Send + Sync` even in dynamic functions. +* [#1963](https://github.com/wasmerio/wasmer/pull/1963) Removed `to_wasm_error` in favour of `impl From for WasmError` ### Fixed diff --git a/lib/compiler-cranelift/src/translator/code_translator.rs b/lib/compiler-cranelift/src/translator/code_translator.rs index 4afc3d4cbe2..b74e7a68770 100644 --- a/lib/compiler-cranelift/src/translator/code_translator.rs +++ b/lib/compiler-cranelift/src/translator/code_translator.rs @@ -45,7 +45,7 @@ use smallvec::SmallVec; use std::vec::Vec; use wasmer_compiler::wasmparser::{MemoryImmediate, Operator}; -use wasmer_compiler::{to_wasm_error, WasmResult}; +use wasmer_compiler::WasmResult; use wasmer_compiler::{wasm_unsupported, ModuleTranslationState}; use wasmer_types::{FunctionIndex, GlobalIndex, MemoryIndex, SignatureIndex, TableIndex}; @@ -383,10 +383,7 @@ pub fn translate_operator( } Operator::BrIf { relative_depth } => translate_br_if(*relative_depth, builder, state), Operator::BrTable { table } => { - let mut depths = table - .targets() - .collect::, _>>() - .map_err(to_wasm_error)?; + let mut depths = table.targets().collect::, _>>()?; let default = depths.pop().unwrap().0; let mut min_depth = default; for (depth, _) in depths.iter() { diff --git a/lib/compiler-cranelift/src/translator/func_translator.rs b/lib/compiler-cranelift/src/translator/func_translator.rs index 7c8ec3e4e09..84482fec245 100644 --- a/lib/compiler-cranelift/src/translator/func_translator.rs +++ b/lib/compiler-cranelift/src/translator/func_translator.rs @@ -19,8 +19,8 @@ use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext, Variable}; use tracing::info; use wasmer_compiler::wasmparser; use wasmer_compiler::{ - to_wasm_error, wasm_unsupported, MiddlewareBinaryReader, ModuleMiddlewareChain, - ModuleTranslationState, WasmResult, + wasm_unsupported, MiddlewareBinaryReader, ModuleMiddlewareChain, ModuleTranslationState, + WasmResult, }; use wasmer_types::LocalFunctionIndex; @@ -174,11 +174,11 @@ fn parse_local_decls( environ: &mut FE, ) -> WasmResult<()> { let mut next_local = num_params; - let local_count = reader.read_local_count().map_err(to_wasm_error)?; + let local_count = reader.read_local_count()?; for _ in 0..local_count { builder.set_srcloc(cur_srcloc(reader)); - let (count, ty) = reader.read_local_decl().map_err(to_wasm_error)?; + let (count, ty) = reader.read_local_decl()?; declare_locals(builder, count, ty, &mut next_local, environ)?; } @@ -239,7 +239,7 @@ fn parse_function_body( // Keep going until the final `End` operator which pops the outermost block. while !state.control_stack.is_empty() { builder.set_srcloc(cur_srcloc(&reader)); - let op = reader.read_operator().map_err(to_wasm_error)?; + let op = reader.read_operator()?; environ.before_translate_operator(&op, builder, state)?; translate_operator(module_translation_state, &op, builder, state, environ)?; environ.after_translate_operator(&op, builder, state)?; diff --git a/lib/compiler-llvm/src/translator/code.rs b/lib/compiler-llvm/src/translator/code.rs index 584d2e48685..12bf5513eef 100644 --- a/lib/compiler-llvm/src/translator/code.rs +++ b/lib/compiler-llvm/src/translator/code.rs @@ -26,8 +26,8 @@ use crate::config::{CompiledKind, LLVM}; use crate::object_file::{load_object_file, CompiledFunction}; use wasmer_compiler::wasmparser::{MemoryImmediate, Operator}; use wasmer_compiler::{ - to_wasm_error, wptype_to_type, CompileError, FunctionBodyData, MiddlewareBinaryReader, - ModuleMiddlewareChain, ModuleTranslationState, RelocationTarget, Symbol, SymbolRegistry, + wptype_to_type, CompileError, FunctionBodyData, MiddlewareBinaryReader, ModuleMiddlewareChain, + ModuleTranslationState, RelocationTarget, Symbol, SymbolRegistry, }; use wasmer_types::entity::PrimaryMap; use wasmer_types::{ @@ -182,9 +182,9 @@ impl FuncTranslator { } let mut locals = vec![]; - let num_locals = reader.read_local_count().map_err(to_wasm_error)?; + let num_locals = reader.read_local_count()?; for _ in 0..num_locals { - let (count, ty) = reader.read_local_decl().map_err(to_wasm_error)?; + let (count, ty) = reader.read_local_decl()?; let ty = wptype_to_type(ty).map_err(to_compile_error)?; let ty = type_to_llvm(&intrinsics, ty)?; for _ in 0..count { @@ -224,7 +224,7 @@ impl FuncTranslator { while fcg.state.has_control_frames() { let pos = reader.current_position() as u32; - let op = reader.read_operator().map_err(to_wasm_error)?; + let op = reader.read_operator()?; fcg.translate_operator(op, pos)?; } @@ -1530,10 +1530,7 @@ impl<'ctx, 'a> LLVMFunctionCodeGenerator<'ctx, 'a> { .get_insert_block() .ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?; - let mut label_depths = table - .targets() - .collect::, _>>() - .map_err(to_wasm_error)?; + let mut label_depths = table.targets().collect::, _>>()?; let default_depth = label_depths.pop().unwrap().0; let index = self.state.pop1()?; diff --git a/lib/compiler/src/error.rs b/lib/compiler/src/error.rs index d71af061674..0d554c15e8c 100644 --- a/lib/compiler/src/error.rs +++ b/lib/compiler/src/error.rs @@ -18,7 +18,7 @@ use thiserror::Error; pub enum CompileError { /// A Wasm translation error occured. #[cfg_attr(feature = "std", error("WebAssembly translation error: {0}"))] - Wasm(#[cfg_attr(feature = "std", from)] WasmError), + Wasm(WasmError), /// A compilation error occured. #[cfg_attr(feature = "std", error("Compilation error: {0}"))] @@ -42,6 +42,12 @@ pub enum CompileError { Resource(String), } +impl From for CompileError { + fn from(original: WasmError) -> Self { + Self::Wasm(original) + } +} + /// A WebAssembly translation error. /// /// When a WebAssembly function can't be translated, one of these error codes will be returned diff --git a/lib/compiler/src/lib.rs b/lib/compiler/src/lib.rs index e9171cc7b35..090a484f8d2 100644 --- a/lib/compiler/src/lib.rs +++ b/lib/compiler/src/lib.rs @@ -85,9 +85,9 @@ pub use crate::target::{ }; #[cfg(feature = "translator")] pub use crate::translator::{ - to_wasm_error, translate_module, wptype_to_type, FunctionBodyData, FunctionMiddleware, - MiddlewareBinaryReader, MiddlewareReaderState, ModuleEnvironment, ModuleInfoTranslation, - ModuleMiddleware, ModuleMiddlewareChain, ModuleTranslationState, + translate_module, wptype_to_type, FunctionBodyData, FunctionMiddleware, MiddlewareBinaryReader, + MiddlewareReaderState, ModuleEnvironment, ModuleInfoTranslation, ModuleMiddleware, + ModuleMiddlewareChain, ModuleTranslationState, }; pub use crate::trap::TrapInformation; pub use crate::unwind::CompiledFunctionUnwindInfo; diff --git a/lib/compiler/src/translator/error.rs b/lib/compiler/src/translator/error.rs index c2191d0a839..07a6397d552 100644 --- a/lib/compiler/src/translator/error.rs +++ b/lib/compiler/src/translator/error.rs @@ -1,4 +1,4 @@ -use crate::WasmError; +use crate::{CompileError, WasmError}; use wasmparser::BinaryReaderError; /// Return an `Err(WasmError::Unsupported(msg))` where `msg` the string built by calling `format!` @@ -8,10 +8,51 @@ macro_rules! wasm_unsupported { ($($arg:tt)*) => { $crate::WasmError::Unsupported(format!($($arg)*)) } } -/// Converts a Wasm binary reading error to a runtime Wasm error -pub fn to_wasm_error(e: BinaryReaderError) -> WasmError { - WasmError::InvalidWebAssembly { - message: e.message().into(), - offset: e.offset(), +impl From for WasmError { + fn from(original: BinaryReaderError) -> Self { + Self::InvalidWebAssembly { + message: original.message().into(), + offset: original.offset(), + } + } +} + +impl From for CompileError { + fn from(original: BinaryReaderError) -> Self { + // `From` does not seem to be transitive by default, so we convert + // BinaryReaderError -> WasmError -> CompileError + Self::from(WasmError::from(original)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use wasmparser::BinaryReader; + + #[test] + fn can_convert_binary_reader_error_to_wasm_error() { + let mut reader = BinaryReader::new(b"\0\0\0\0"); + let binary_reader_error = reader.read_bytes(10).unwrap_err(); + match WasmError::from(binary_reader_error) { + WasmError::InvalidWebAssembly { message, offset } => { + assert_eq!(message, "Unexpected EOF"); + assert_eq!(offset, 0); + } + err => panic!("Unexpected error: {:?}", err), + } + } + + #[test] + fn can_convert_binary_reader_error_to_compile_error() { + let mut reader = BinaryReader::new(b"\0\0\0\0"); + let binary_reader_error = reader.read_bytes(10).unwrap_err(); + match CompileError::from(binary_reader_error) { + CompileError::Wasm(WasmError::InvalidWebAssembly { message, offset }) => { + assert_eq!(message, "Unexpected EOF"); + assert_eq!(offset, 0); + } + err => panic!("Unexpected error: {:?}", err), + } } } diff --git a/lib/compiler/src/translator/mod.rs b/lib/compiler/src/translator/mod.rs index a3b4fcf178c..4a3a8ac23c2 100644 --- a/lib/compiler/src/translator/mod.rs +++ b/lib/compiler/src/translator/mod.rs @@ -14,7 +14,6 @@ mod error; mod sections; pub use self::environ::{FunctionBodyData, ModuleEnvironment, ModuleInfoTranslation}; -pub use self::error::to_wasm_error; pub use self::middleware::{ FunctionMiddleware, MiddlewareBinaryReader, MiddlewareReaderState, ModuleMiddleware, ModuleMiddlewareChain, diff --git a/lib/compiler/src/translator/module.rs b/lib/compiler/src/translator/module.rs index 8855a7a5f54..4bb3442d0e1 100644 --- a/lib/compiler/src/translator/module.rs +++ b/lib/compiler/src/translator/module.rs @@ -4,7 +4,6 @@ //! Translation skeleton that traverses the whole WebAssembly module and call helper functions //! to deal with each part of it. use super::environ::ModuleEnvironment; -use super::error::to_wasm_error; use super::sections::{ parse_data_section, parse_element_section, parse_export_section, parse_function_section, parse_global_section, parse_import_section, parse_memory_section, parse_name_section, @@ -23,7 +22,7 @@ pub fn translate_module<'data>( let mut module_translation_state = ModuleTranslationState::new(); for payload in Parser::new(0).parse_all(data) { - match payload.map_err(to_wasm_error)? { + match payload? { Payload::Version { .. } | Payload::End => {} Payload::TypeSection(types) => { @@ -69,7 +68,7 @@ pub fn translate_module<'data>( let offset = code.original_position(); environ.define_function_body( &module_translation_state, - code.read_bytes(size).map_err(to_wasm_error)?, + code.read_bytes(size)?, offset, )?; } @@ -94,10 +93,7 @@ pub fn translate_module<'data>( name: "name", data, data_offset, - } => parse_name_section( - NameSectionReader::new(data, data_offset).map_err(to_wasm_error)?, - environ, - )?, + } => parse_name_section(NameSectionReader::new(data, data_offset)?, environ)?, Payload::CustomSection { name, data, .. } => environ.custom_section(name, data)?, diff --git a/lib/compiler/src/translator/sections.rs b/lib/compiler/src/translator/sections.rs index 99e5b603823..cd05753c446 100644 --- a/lib/compiler/src/translator/sections.rs +++ b/lib/compiler/src/translator/sections.rs @@ -11,7 +11,6 @@ //! is handled, according to the semantics of WebAssembly, to only specific expressions that are //! interpreted on the fly. use super::environ::ModuleEnvironment; -use super::error::to_wasm_error; use super::state::ModuleTranslationState; use crate::wasm_unsupported; use crate::{WasmError, WasmResult}; @@ -94,7 +93,7 @@ pub fn parse_import_section<'data>( environ.reserve_imports(imports.get_count())?; for entry in imports { - let import = entry.map_err(to_wasm_error)?; + let import = entry?; let module_name = import.module; let field_name = import.field; @@ -168,7 +167,7 @@ pub fn parse_function_section( environ.reserve_func_types(num_functions)?; for entry in functions { - let sigindex = entry.map_err(to_wasm_error)?; + let sigindex = entry?; environ.declare_func_type(SignatureIndex::from_u32(sigindex))?; } @@ -183,7 +182,7 @@ pub fn parse_table_section( environ.reserve_tables(tables.get_count())?; for entry in tables { - let table = entry.map_err(to_wasm_error)?; + let table = entry?; environ.declare_table(TableType { ty: wptype_to_type(table.element_type).unwrap(), minimum: table.limits.initial, @@ -202,7 +201,7 @@ pub fn parse_memory_section( environ.reserve_memories(memories.get_count())?; for entry in memories { - let memory = entry.map_err(to_wasm_error)?; + let memory = entry?; match memory { WPMemoryType::M32 { limits, shared } => { environ.declare_memory(MemoryType { @@ -232,9 +231,9 @@ pub fn parse_global_section( mutable, }, init_expr, - } = entry.map_err(to_wasm_error)?; + } = entry?; let mut init_expr_reader = init_expr.get_binary_reader(); - let initializer = match init_expr_reader.read_operator().map_err(to_wasm_error)? { + let initializer = match init_expr_reader.read_operator()? { Operator::I32Const { value } => GlobalInit::I32Const(value), Operator::I64Const { value } => GlobalInit::I64Const(value), Operator::F32Const { value } => GlobalInit::F32Const(f32::from_bits(value.bits())), @@ -276,7 +275,7 @@ pub fn parse_export_section<'data>( field, ref kind, index, - } = entry.map_err(to_wasm_error)?; + } = entry?; // The input has already been validated, so we should be able to // assume valid UTF-8 and use `from_utf8_unchecked` if performance @@ -310,10 +309,10 @@ pub fn parse_start_section(index: u32, environ: &mut ModuleEnvironment) -> WasmR } fn read_elems(items: &ElementItems) -> WasmResult> { - let items_reader = items.get_items_reader().map_err(to_wasm_error)?; + let items_reader = items.get_items_reader()?; let mut elems = Vec::with_capacity(usize::try_from(items_reader.get_count()).unwrap()); for item in items_reader { - let elem = match item.map_err(to_wasm_error)? { + let elem = match item? { ElementItem::Null(_ty) => FunctionIndex::reserved_value(), ElementItem::Func(index) => FunctionIndex::from_u32(index), }; @@ -330,7 +329,7 @@ pub fn parse_element_section<'data>( environ.reserve_table_initializers(elements.get_count())?; for (index, entry) in elements.into_iter().enumerate() { - let Element { kind, items, ty } = entry.map_err(to_wasm_error)?; + let Element { kind, items, ty } = entry?; if ty != wasmparser::Type::FuncRef { return Err(wasm_unsupported!( "unsupported table element type: {:?}", @@ -344,19 +343,18 @@ pub fn parse_element_section<'data>( init_expr, } => { let mut init_expr_reader = init_expr.get_binary_reader(); - let (base, offset) = - match init_expr_reader.read_operator().map_err(to_wasm_error)? { - Operator::I32Const { value } => (None, value as u32 as usize), - Operator::GlobalGet { global_index } => { - (Some(GlobalIndex::from_u32(global_index)), 0) - } - ref s => { - return Err(wasm_unsupported!( - "unsupported init expr in element section: {:?}", - s - )); - } - }; + let (base, offset) = match init_expr_reader.read_operator()? { + Operator::I32Const { value } => (None, value as u32 as usize), + Operator::GlobalGet { global_index } => { + (Some(GlobalIndex::from_u32(global_index)), 0) + } + ref s => { + return Err(wasm_unsupported!( + "unsupported init expr in element section: {:?}", + s + )); + } + }; environ.declare_table_initializers( TableIndex::from_u32(table_index), base, @@ -382,26 +380,25 @@ pub fn parse_data_section<'data>( environ.reserve_data_initializers(data.get_count())?; for (index, entry) in data.into_iter().enumerate() { - let Data { kind, data } = entry.map_err(to_wasm_error)?; + let Data { kind, data } = entry?; match kind { DataKind::Active { memory_index, init_expr, } => { let mut init_expr_reader = init_expr.get_binary_reader(); - let (base, offset) = - match init_expr_reader.read_operator().map_err(to_wasm_error)? { - Operator::I32Const { value } => (None, value as u32 as usize), - Operator::GlobalGet { global_index } => { - (Some(GlobalIndex::from_u32(global_index)), 0) - } - ref s => { - return Err(wasm_unsupported!( - "unsupported init expr in data section: {:?}", - s - )) - } - }; + let (base, offset) = match init_expr_reader.read_operator()? { + Operator::I32Const { value } => (None, value as u32 as usize), + Operator::GlobalGet { global_index } => { + (Some(GlobalIndex::from_u32(global_index)), 0) + } + ref s => { + return Err(wasm_unsupported!( + "unsupported init expr in data section: {:?}", + s + )) + } + }; environ.declare_data_initialization( MemoryIndex::from_u32(memory_index), base,