diff --git a/Cargo.lock b/Cargo.lock index 312039a490..a98c6db8a3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3643,7 +3643,6 @@ dependencies = [ "rustc-demangle", "serde", "target-lexicon", - "thiserror", "wasmtime-environ", "wasmtime-jit-debug", "wasmtime-jit-icache-coherence", @@ -3687,7 +3686,6 @@ dependencies = [ "paste", "rand 0.8.5", "rustix", - "thiserror", "wasmtime-asm-macros", "wasmtime-environ", "wasmtime-fiber", diff --git a/crates/jit/Cargo.toml b/crates/jit/Cargo.toml index ee392be6df..5a21eb7d84 100644 --- a/crates/jit/Cargo.toml +++ b/crates/jit/Cargo.toml @@ -14,7 +14,6 @@ edition.workspace = true wasmtime-environ = { workspace = true } wasmtime-jit-debug = { workspace = true, features = ["perf_jitdump"], optional = true } wasmtime-runtime = { workspace = true } -thiserror = { workspace = true } target-lexicon = { workspace = true } anyhow = { workspace = true } cfg-if = "1.0" diff --git a/crates/jit/src/instantiate.rs b/crates/jit/src/instantiate.rs index 730daa0596..52f7297b32 100644 --- a/crates/jit/src/instantiate.rs +++ b/crates/jit/src/instantiate.rs @@ -14,39 +14,16 @@ use std::convert::TryFrom; use std::ops::Range; use std::str; use std::sync::Arc; -use thiserror::Error; use wasmtime_environ::obj; use wasmtime_environ::{ - CompileError, DefinedFuncIndex, FuncIndex, FunctionLoc, MemoryInitialization, Module, - ModuleTranslation, PrimaryMap, SignatureIndex, StackMapInformation, Tunables, WasmFunctionInfo, + DefinedFuncIndex, FuncIndex, FunctionLoc, MemoryInitialization, Module, ModuleTranslation, + PrimaryMap, SignatureIndex, StackMapInformation, Tunables, WasmFunctionInfo, }; use wasmtime_runtime::{ - CompiledModuleId, CompiledModuleIdAllocator, GdbJitImageRegistration, InstantiationError, - MmapVec, VMFunctionBody, VMTrampoline, + CompiledModuleId, CompiledModuleIdAllocator, GdbJitImageRegistration, MmapVec, VMFunctionBody, + VMTrampoline, }; -/// An error condition while setting up a wasm instance, be it validation, -/// compilation, or instantiation. -#[derive(Error, Debug)] -pub enum SetupError { - /// The module did not pass validation. - #[error("Validation error: {0}")] - Validate(String), - - /// A wasm translation error occurred. - #[error("WebAssembly failed to compile")] - Compile(#[from] CompileError), - - /// Some runtime resource was unavailable or insufficient, or the start function - /// trapped. - #[error("Instantiation failed during setup")] - Instantiate(#[from] InstantiationError), - - /// Debug information generation error occurred. - #[error("Debug information error")] - DebugInfo(#[from] anyhow::Error), -} - /// Secondary in-memory results of compilation. /// /// This opaque structure can be optionally passed back to @@ -446,7 +423,7 @@ impl CompiledModule { if self.meta.native_debug_info_present { let text = self.text(); let bytes = create_gdbjit_image(self.mmap().to_vec(), (text.as_ptr(), text.len())) - .map_err(SetupError::DebugInfo)?; + .context("failed to create jit image for gdb")?; profiler.module_load(self, Some(&bytes)); let reg = GdbJitImageRegistration::register(bytes); self.dbg_jit_registration = Some(reg); diff --git a/crates/jit/src/lib.rs b/crates/jit/src/lib.rs index 7cba8ed153..1c7e44df58 100644 --- a/crates/jit/src/lib.rs +++ b/crates/jit/src/lib.rs @@ -29,7 +29,7 @@ mod unwind; pub use crate::code_memory::CodeMemory; pub use crate::instantiate::{ - subslice_range, CompiledModule, CompiledModuleInfo, ObjectBuilder, SetupError, SymbolizeContext, + subslice_range, CompiledModule, CompiledModuleInfo, ObjectBuilder, SymbolizeContext, }; pub use demangling::*; pub use profiling::*; diff --git a/crates/runtime/Cargo.toml b/crates/runtime/Cargo.toml index c832707f6e..5bf5a26684 100644 --- a/crates/runtime/Cargo.toml +++ b/crates/runtime/Cargo.toml @@ -19,7 +19,6 @@ libc = { version = "0.2.112", default-features = false } log = { workspace = true } memoffset = "0.6.0" indexmap = "1.0.2" -thiserror = { workspace = true } cfg-if = "1.0" rand = { version = "0.8.3", features = ['small_rng'] } anyhow = { workspace = true } diff --git a/crates/runtime/src/cow.rs b/crates/runtime/src/cow.rs index d083e4d975..8f9ded83f0 100644 --- a/crates/runtime/src/cow.rs +++ b/crates/runtime/src/cow.rs @@ -3,7 +3,6 @@ #![cfg_attr(not(unix), allow(unused_imports, unused_variables))] -use crate::InstantiationError; use crate::MmapVec; use anyhow::Result; use libc::c_void; @@ -486,7 +485,7 @@ impl MemoryImageSlot { initial_size_bytes: usize, maybe_image: Option<&Arc>, style: &MemoryStyle, - ) -> Result<(), InstantiationError> { + ) -> Result<()> { assert!(!self.dirty); assert!(initial_size_bytes <= self.static_size); @@ -499,16 +498,14 @@ impl MemoryImageSlot { // extent of the prior initialization image in order to preserve // resident memory that might come before or after the image. if self.image.as_ref() != maybe_image { - self.remove_image() - .map_err(|e| InstantiationError::Resource(e.into()))?; + self.remove_image()?; } // The next order of business is to ensure that `self.accessible` is // appropriate. First up is to grow the read/write portion of memory if // it's not large enough to accommodate `initial_size_bytes`. if self.accessible < initial_size_bytes { - self.set_protection(self.accessible..initial_size_bytes, true) - .map_err(|e| InstantiationError::Resource(e.into()))?; + self.set_protection(self.accessible..initial_size_bytes, true)?; self.accessible = initial_size_bytes; } @@ -523,8 +520,7 @@ impl MemoryImageSlot { if initial_size_bytes < self.accessible { match style { MemoryStyle::Static { .. } => { - self.set_protection(initial_size_bytes..self.accessible, false) - .map_err(|e| InstantiationError::Resource(e.into()))?; + self.set_protection(initial_size_bytes..self.accessible, false)?; self.accessible = initial_size_bytes; } MemoryStyle::Dynamic { .. } => {} @@ -543,9 +539,7 @@ impl MemoryImageSlot { ); if image.len > 0 { unsafe { - image - .map_at(self.base) - .map_err(|e| InstantiationError::Resource(e.into()))?; + image.map_at(self.base)?; } } } diff --git a/crates/runtime/src/instance/allocator.rs b/crates/runtime/src/instance/allocator.rs index ffbb3a7e1e..9ea6d95011 100644 --- a/crates/runtime/src/instance/allocator.rs +++ b/crates/runtime/src/instance/allocator.rs @@ -3,13 +3,12 @@ use crate::instance::{Instance, InstanceHandle, RuntimeMemoryCreator}; use crate::memory::{DefaultMemoryCreator, Memory}; use crate::table::Table; use crate::{CompiledModuleId, ModuleRuntimeInfo, Store}; -use anyhow::Result; +use anyhow::{anyhow, bail, Result}; use std::alloc; use std::any::Any; use std::convert::TryFrom; use std::ptr; use std::sync::Arc; -use thiserror::Error; use wasmtime_environ::{ DefinedMemoryIndex, DefinedTableIndex, HostPtr, InitMemory, MemoryInitialization, MemoryInitializer, Module, PrimaryMap, TableInitialization, TableInitializer, Trap, VMOffsets, @@ -86,46 +85,6 @@ impl StorePtr { } } -/// An link error while instantiating a module. -#[derive(Error, Debug)] -#[error("Link error: {0}")] -pub struct LinkError(pub String); - -/// An error while instantiating a module. -#[derive(Error, Debug)] -pub enum InstantiationError { - /// Insufficient resources available for execution. - #[error("Insufficient resources: {0}")] - Resource(anyhow::Error), - - /// A wasm link error occurred. - #[error("Failed to link module")] - Link(#[from] LinkError), - - /// A trap ocurred during instantiation, after linking. - #[error("Trap occurred during instantiation")] - Trap(Trap), - - /// A limit on how many instances are supported has been reached. - #[error("Limit of {0} concurrent instances has been reached")] - Limit(u32), -} - -/// An error while creating a fiber stack. -#[cfg(feature = "async")] -#[derive(Error, Debug)] -pub enum FiberStackError { - /// Insufficient resources available for the request. - #[error("Insufficient resources: {0}")] - Resource(anyhow::Error), - /// An error for when the allocator doesn't support fiber stacks. - #[error("fiber stacks are not supported by the allocator")] - NotSupported, - /// A limit on how many fibers are supported has been reached. - #[error("Limit of {0} concurrent fibers has been reached")] - Limit(u32), -} - /// Represents a runtime instance allocator. /// /// # Safety @@ -151,10 +110,7 @@ pub unsafe trait InstanceAllocator: Send + Sync { /// /// This method is not inherently unsafe, but care must be made to ensure /// pointers passed in the allocation request outlive the returned instance. - unsafe fn allocate( - &self, - req: InstanceAllocationRequest, - ) -> Result; + unsafe fn allocate(&self, req: InstanceAllocationRequest) -> Result; /// Finishes the instantiation process started by an instance allocator. /// @@ -166,7 +122,7 @@ pub unsafe trait InstanceAllocator: Send + Sync { handle: &mut InstanceHandle, module: &Module, is_bulk_memory: bool, - ) -> Result<(), InstantiationError>; + ) -> Result<()>; /// Deallocates a previously allocated instance. /// @@ -180,7 +136,7 @@ pub unsafe trait InstanceAllocator: Send + Sync { /// Allocates a fiber stack for calling async functions on. #[cfg(feature = "async")] - fn allocate_fiber_stack(&self) -> Result; + fn allocate_fiber_stack(&self) -> Result; /// Deallocates a fiber stack that was previously allocated with `allocate_fiber_stack`. /// @@ -198,10 +154,7 @@ pub unsafe trait InstanceAllocator: Send + Sync { fn purge_module(&self, module: CompiledModuleId); } -fn get_table_init_start( - init: &TableInitializer, - instance: &Instance, -) -> Result { +fn get_table_init_start(init: &TableInitializer, instance: &Instance) -> Result { match init.base { Some(base) => { let val = unsafe { @@ -212,20 +165,15 @@ fn get_table_init_start( } }; - init.offset.checked_add(val).ok_or_else(|| { - InstantiationError::Link(LinkError( - "element segment global base overflows".to_owned(), - )) - }) + init.offset + .checked_add(val) + .ok_or_else(|| anyhow!("element segment global base overflows")) } None => Ok(init.offset), } } -fn check_table_init_bounds( - instance: &mut Instance, - module: &Module, -) -> Result<(), InstantiationError> { +fn check_table_init_bounds(instance: &mut Instance, module: &Module) -> Result<()> { match &module.table_initialization { TableInitialization::FuncTable { segments, .. } | TableInitialization::Segments { segments } => { @@ -240,9 +188,7 @@ fn check_table_init_bounds( // Initializer is in bounds } _ => { - return Err(InstantiationError::Link(LinkError( - "table out of bounds: elements segment does not fit".to_owned(), - ))) + bail!("table out of bounds: elements segment does not fit") } } } @@ -252,7 +198,7 @@ fn check_table_init_bounds( Ok(()) } -fn initialize_tables(instance: &mut Instance, module: &Module) -> Result<(), InstantiationError> { +fn initialize_tables(instance: &mut Instance, module: &Module) -> Result<()> { // Note: if the module's table initializer state is in // FuncTable mode, we will lazily initialize tables based on // any statically-precomputed image of FuncIndexes, but there @@ -264,15 +210,13 @@ fn initialize_tables(instance: &mut Instance, module: &Module) -> Result<(), Ins TableInitialization::FuncTable { segments, .. } | TableInitialization::Segments { segments } => { for segment in segments { - instance - .table_init_segment( - segment.table_index, - &segment.elements, - get_table_init_start(segment, instance)?, - 0, - segment.elements.len() as u32, - ) - .map_err(InstantiationError::Trap)?; + instance.table_init_segment( + segment.table_index, + &segment.elements, + get_table_init_start(segment, instance)?, + 0, + segment.elements.len() as u32, + )?; } } } @@ -280,10 +224,7 @@ fn initialize_tables(instance: &mut Instance, module: &Module) -> Result<(), Ins Ok(()) } -fn get_memory_init_start( - init: &MemoryInitializer, - instance: &Instance, -) -> Result { +fn get_memory_init_start(init: &MemoryInitializer, instance: &Instance) -> Result { match init.base { Some(base) => { let mem64 = instance.module().memory_plans[init.memory_index] @@ -302,18 +243,15 @@ fn get_memory_init_start( } }; - init.offset.checked_add(val).ok_or_else(|| { - InstantiationError::Link(LinkError("data segment global base overflows".to_owned())) - }) + init.offset + .checked_add(val) + .ok_or_else(|| anyhow!("data segment global base overflows")) } None => Ok(init.offset), } } -fn check_memory_init_bounds( - instance: &Instance, - initializers: &[MemoryInitializer], -) -> Result<(), InstantiationError> { +fn check_memory_init_bounds(instance: &Instance, initializers: &[MemoryInitializer]) -> Result<()> { for init in initializers { let memory = instance.get_memory(init.memory_index); let start = get_memory_init_start(init, instance)?; @@ -326,9 +264,7 @@ fn check_memory_init_bounds( // Initializer is in bounds } _ => { - return Err(InstantiationError::Link(LinkError( - "memory out of bounds: data segment does not fit".into(), - ))) + bail!("memory out of bounds: data segment does not fit") } } } @@ -336,7 +272,7 @@ fn check_memory_init_bounds( Ok(()) } -fn initialize_memories(instance: &mut Instance, module: &Module) -> Result<(), InstantiationError> { +fn initialize_memories(instance: &mut Instance, module: &Module) -> Result<()> { let memory_size_in_pages = &|memory| (instance.get_memory(memory).current_length() as u64) / u64::from(WASM_PAGE_SIZE); @@ -392,13 +328,13 @@ fn initialize_memories(instance: &mut Instance, module: &Module) -> Result<(), I }, ); if !ok { - return Err(InstantiationError::Trap(Trap::MemoryOutOfBounds)); + return Err(Trap::MemoryOutOfBounds.into()); } Ok(()) } -fn check_init_bounds(instance: &mut Instance, module: &Module) -> Result<(), InstantiationError> { +fn check_init_bounds(instance: &mut Instance, module: &Module) -> Result<()> { check_table_init_bounds(instance, module)?; match &instance.module().memory_initialization { @@ -416,7 +352,7 @@ fn initialize_instance( instance: &mut Instance, module: &Module, is_bulk_memory: bool, -) -> Result<(), InstantiationError> { +) -> Result<()> { // If bulk memory is not enabled, bounds check the data and element segments before // making any changes. With bulk memory enabled, initializers are processed // in-order and side effects are observed up to the point of an out-of-bounds @@ -456,20 +392,17 @@ impl OnDemandInstanceAllocator { fn create_tables( store: &mut StorePtr, runtime_info: &Arc, - ) -> Result, InstantiationError> { + ) -> Result> { let module = runtime_info.module(); let num_imports = module.num_imported_tables; let mut tables: PrimaryMap = PrimaryMap::with_capacity(module.table_plans.len() - num_imports); for (_, table) in module.table_plans.iter().skip(num_imports) { - tables.push( - Table::new_dynamic(table, unsafe { - store - .get() - .expect("if module has table plans, store is not empty") - }) - .map_err(InstantiationError::Resource)?, - ); + tables.push(Table::new_dynamic(table, unsafe { + store + .get() + .expect("if module has table plans, store is not empty") + })?); } Ok(tables) } @@ -478,7 +411,7 @@ impl OnDemandInstanceAllocator { &self, store: &mut StorePtr, runtime_info: &Arc, - ) -> Result, InstantiationError> { + ) -> Result> { let module = runtime_info.module(); let creator = self .mem_creator @@ -491,23 +424,18 @@ impl OnDemandInstanceAllocator { let defined_memory_idx = module .defined_memory_index(memory_idx) .expect("Skipped imports, should never be None"); - let image = runtime_info - .memory_image(defined_memory_idx) - .map_err(|err| InstantiationError::Resource(err.into()))?; + let image = runtime_info.memory_image(defined_memory_idx)?; - memories.push( - Memory::new_dynamic( - plan, - creator, - unsafe { - store - .get() - .expect("if module has memory plans, store is not empty") - }, - image, - ) - .map_err(InstantiationError::Resource)?, - ); + memories.push(Memory::new_dynamic( + plan, + creator, + unsafe { + store + .get() + .expect("if module has memory plans, store is not empty") + }, + image, + )?); } Ok(memories) } @@ -532,7 +460,7 @@ impl Default for OnDemandInstanceAllocator { pub unsafe fn allocate_single_memory_instance( req: InstanceAllocationRequest, memory: Memory, -) -> Result { +) -> Result { let mut memories = PrimaryMap::default(); memories.push(memory); let tables = PrimaryMap::default(); @@ -554,10 +482,7 @@ pub unsafe fn deallocate(handle: &InstanceHandle) { } unsafe impl InstanceAllocator for OnDemandInstanceAllocator { - unsafe fn allocate( - &self, - mut req: InstanceAllocationRequest, - ) -> Result { + unsafe fn allocate(&self, mut req: InstanceAllocationRequest) -> Result { let memories = self.create_memories(&mut req.store, &req.runtime_info)?; let tables = Self::create_tables(&mut req.store, &req.runtime_info)?; let module = req.runtime_info.module(); @@ -577,7 +502,7 @@ unsafe impl InstanceAllocator for OnDemandInstanceAllocator { handle: &mut InstanceHandle, module: &Module, is_bulk_memory: bool, - ) -> Result<(), InstantiationError> { + ) -> Result<()> { initialize_instance(handle.instance_mut(), module, is_bulk_memory) } @@ -586,13 +511,13 @@ unsafe impl InstanceAllocator for OnDemandInstanceAllocator { } #[cfg(feature = "async")] - fn allocate_fiber_stack(&self) -> Result { + fn allocate_fiber_stack(&self) -> Result { if self.stack_size == 0 { - return Err(FiberStackError::NotSupported); + bail!("fiber stacks are not supported by the allocator") } - wasmtime_fiber::FiberStack::new(self.stack_size) - .map_err(|e| FiberStackError::Resource(e.into())) + let stack = wasmtime_fiber::FiberStack::new(self.stack_size)?; + Ok(stack) } #[cfg(feature = "async")] diff --git a/crates/runtime/src/instance/allocator/pooling.rs b/crates/runtime/src/instance/allocator/pooling.rs index 71f56c1196..b40ab8b2ab 100644 --- a/crates/runtime/src/instance/allocator/pooling.rs +++ b/crates/runtime/src/instance/allocator/pooling.rs @@ -7,10 +7,7 @@ //! Using the pooling instance allocator can speed up module instantiation //! when modules can be constrained based on configurable limits. -use super::{ - initialize_instance, InstanceAllocationRequest, InstanceAllocator, InstanceHandle, - InstantiationError, -}; +use super::{initialize_instance, InstanceAllocationRequest, InstanceAllocator, InstanceHandle}; use crate::{instance::Instance, Memory, Mmap, Table}; use crate::{CompiledModuleId, MemoryImageSlot, ModuleRuntimeInfo, Store}; use anyhow::{anyhow, bail, Context, Result}; @@ -41,9 +38,6 @@ use imp::{commit_table_pages, decommit_table_pages}; #[cfg(all(feature = "async", unix))] use imp::{commit_stack_pages, reset_stack_pages_to_zero}; -#[cfg(feature = "async")] -use super::FiberStackError; - fn round_up_to_pow2(n: usize, to: usize) -> usize { debug_assert!(to > 0); debug_assert!(to.is_power_of_two()); @@ -167,7 +161,7 @@ impl InstancePool { &self, instance_index: usize, req: InstanceAllocationRequest, - ) -> Result { + ) -> Result { let module = req.runtime_info.module(); // Before doing anything else ensure that our instance slot is actually @@ -175,9 +169,7 @@ impl InstancePool { // If this fails then it's a configuration error at the `Engine` level // from when this pooling allocator was created and that needs updating // if this is to succeed. - let offsets = self - .validate_instance_size(module) - .map_err(InstantiationError::Resource)?; + let offsets = self.validate_instance_size(module)?; let mut memories = PrimaryMap::with_capacity(module.memory_plans.len() - module.num_imported_memories); @@ -214,14 +206,16 @@ impl InstancePool { }) } - fn allocate( - &self, - req: InstanceAllocationRequest, - ) -> Result { + fn allocate(&self, req: InstanceAllocationRequest) -> Result { let id = self .index_allocator .alloc(req.runtime_info.unique_id()) - .ok_or_else(|| InstantiationError::Limit(self.max_instances as u32))?; + .ok_or_else(|| { + anyhow!( + "maximum concurrent instance limit of {} reached", + self.max_instances + ) + })?; match unsafe { self.initialize_instance(id.index(), req) } { Ok(handle) => Ok(handle), @@ -271,7 +265,7 @@ impl InstancePool { store: Option<*mut dyn Store>, memories: &mut PrimaryMap, tables: &mut PrimaryMap, - ) -> Result<(), InstantiationError> { + ) -> Result<()> { self.allocate_memories(instance_index, runtime_info, store, memories)?; self.allocate_tables(instance_index, runtime_info, store, tables)?; @@ -284,11 +278,10 @@ impl InstancePool { runtime_info: &dyn ModuleRuntimeInfo, store: Option<*mut dyn Store>, memories: &mut PrimaryMap, - ) -> Result<(), InstantiationError> { + ) -> Result<()> { let module = runtime_info.module(); - self.validate_memory_plans(module) - .map_err(InstantiationError::Resource)?; + self.validate_memory_plans(module)?; for (memory_index, plan) in module .memory_plans @@ -321,9 +314,7 @@ impl InstancePool { let mut slot = self .memories .take_memory_image_slot(instance_index, defined_index); - let image = runtime_info - .memory_image(defined_index) - .map_err(|err| InstantiationError::Resource(err.into()))?; + let image = runtime_info.memory_image(defined_index)?; let initial_size = plan.memory.minimum * WASM_PAGE_SIZE as u64; // If instantiation fails, we can propagate the error @@ -339,13 +330,11 @@ impl InstancePool { // the process to continue, because we never perform a // mmap that would leave an open space for someone // else to come in and map something. - slot.instantiate(initial_size as usize, image, &plan.style) - .map_err(|e| InstantiationError::Resource(e.into()))?; + slot.instantiate(initial_size as usize, image, &plan.style)?; - memories.push( - Memory::new_static(plan, memory, slot, unsafe { &mut *store.unwrap() }) - .map_err(InstantiationError::Resource)?, - ); + memories.push(Memory::new_static(plan, memory, slot, unsafe { + &mut *store.unwrap() + })?); } Ok(()) @@ -380,11 +369,10 @@ impl InstancePool { runtime_info: &dyn ModuleRuntimeInfo, store: Option<*mut dyn Store>, tables: &mut PrimaryMap, - ) -> Result<(), InstantiationError> { + ) -> Result<()> { let module = runtime_info.module(); - self.validate_table_plans(module) - .map_err(InstantiationError::Resource)?; + self.validate_table_plans(module)?; let mut bases = self.tables.get(instance_index); for (_, plan) in module.table_plans.iter().skip(module.num_imported_tables) { @@ -393,19 +381,13 @@ impl InstancePool { commit_table_pages( base as *mut u8, self.tables.max_elements as usize * mem::size_of::<*mut u8>(), - ) - .map_err(InstantiationError::Resource)?; + )?; - tables.push( - Table::new_static( - plan, - unsafe { - std::slice::from_raw_parts_mut(base, self.tables.max_elements as usize) - }, - unsafe { &mut *store.unwrap() }, - ) - .map_err(InstantiationError::Resource)?, - ); + tables.push(Table::new_static( + plan, + unsafe { std::slice::from_raw_parts_mut(base, self.tables.max_elements as usize) }, + unsafe { &mut *store.unwrap() }, + )?); } Ok(()) @@ -930,15 +912,20 @@ impl StackPool { }) } - fn allocate(&self) -> Result { + fn allocate(&self) -> Result { if self.stack_size == 0 { - return Err(FiberStackError::NotSupported); + bail!("pooling allocator not configured to enable fiber stack allocation"); } let index = self .index_allocator .alloc(None) - .ok_or(FiberStackError::Limit(self.max_instances as u32))? + .ok_or_else(|| { + anyhow!( + "maximum concurrent fiber limit of {} reached", + self.max_instances + ) + })? .index(); assert!(index < self.max_instances); @@ -952,11 +939,11 @@ impl StackPool { .as_mut_ptr() .add((index * self.stack_size) + self.page_size); - commit_stack_pages(bottom_of_stack, size_without_guard) - .map_err(FiberStackError::Resource)?; + commit_stack_pages(bottom_of_stack, size_without_guard)?; - wasmtime_fiber::FiberStack::from_top_ptr(bottom_of_stack.add(size_without_guard)) - .map_err(|e| FiberStackError::Resource(e.into())) + let stack = + wasmtime_fiber::FiberStack::from_top_ptr(bottom_of_stack.add(size_without_guard))?; + Ok(stack) } } @@ -1106,10 +1093,7 @@ unsafe impl InstanceAllocator for PoolingInstanceAllocator { Ok(()) } - unsafe fn allocate( - &self, - req: InstanceAllocationRequest, - ) -> Result { + unsafe fn allocate(&self, req: InstanceAllocationRequest) -> Result { self.instances.allocate(req) } @@ -1118,7 +1102,7 @@ unsafe impl InstanceAllocator for PoolingInstanceAllocator { handle: &mut InstanceHandle, module: &Module, is_bulk_memory: bool, - ) -> Result<(), InstantiationError> { + ) -> Result<()> { let instance = handle.instance_mut(); initialize_instance(instance, module, is_bulk_memory) } @@ -1128,7 +1112,7 @@ unsafe impl InstanceAllocator for PoolingInstanceAllocator { } #[cfg(all(feature = "async", unix))] - fn allocate_fiber_stack(&self) -> Result { + fn allocate_fiber_stack(&self) -> Result { self.stacks.allocate() } @@ -1138,14 +1122,14 @@ unsafe impl InstanceAllocator for PoolingInstanceAllocator { } #[cfg(all(feature = "async", windows))] - fn allocate_fiber_stack(&self) -> Result { + fn allocate_fiber_stack(&self) -> Result { if self.stack_size == 0 { - return Err(FiberStackError::NotSupported); + bail!("fiber stack allocation not supported") } // On windows, we don't use a stack pool as we use the native fiber implementation - wasmtime_fiber::FiberStack::new(self.stack_size) - .map_err(|e| FiberStackError::Resource(e.into())) + let stack = wasmtime_fiber::FiberStack::new(self.stack_size)?; + Ok(stack) } #[cfg(all(feature = "async", windows))] @@ -1269,7 +1253,7 @@ mod test { host_state: Box::new(()), store: StorePtr::empty(), }) { - Err(InstantiationError::Limit(3)) => {} + Err(_) => {} _ => panic!("unexpected error"), }; @@ -1414,10 +1398,7 @@ mod test { assert_eq!(pool.index_allocator.testing_freelist(), []); - match pool.allocate().unwrap_err() { - FiberStackError::Limit(10) => {} - _ => panic!("unexpected error"), - }; + pool.allocate().unwrap_err(); for stack in stacks { pool.deallocate(&stack); diff --git a/crates/runtime/src/lib.rs b/crates/runtime/src/lib.rs index 2c1db36ad1..373081b1a5 100644 --- a/crates/runtime/src/lib.rs +++ b/crates/runtime/src/lib.rs @@ -55,7 +55,7 @@ pub use crate::externref::*; pub use crate::imports::Imports; pub use crate::instance::{ allocate_single_memory_instance, InstanceAllocationRequest, InstanceAllocator, InstanceHandle, - InstantiationError, LinkError, OnDemandInstanceAllocator, StorePtr, + OnDemandInstanceAllocator, StorePtr, }; #[cfg(feature = "pooling-allocator")] pub use crate::instance::{ diff --git a/crates/wasmtime/src/instance.rs b/crates/wasmtime/src/instance.rs index a0c5869cca..65440e2216 100644 --- a/crates/wasmtime/src/instance.rs +++ b/crates/wasmtime/src/instance.rs @@ -5,13 +5,13 @@ use crate::{ AsContextMut, Engine, Export, Extern, Func, Global, Memory, Module, SharedMemory, StoreContextMut, Table, TypedFunc, }; -use anyhow::{anyhow, bail, Context, Error, Result}; +use anyhow::{anyhow, bail, Context, Result}; use std::mem; use std::sync::Arc; use wasmtime_environ::{EntityType, FuncIndex, GlobalIndex, MemoryIndex, PrimaryMap, TableIndex}; use wasmtime_runtime::{ - Imports, InstanceAllocationRequest, InstantiationError, StorePtr, VMContext, VMFunctionBody, - VMFunctionImport, VMGlobalImport, VMMemoryImport, VMOpaqueContext, VMTableImport, + Imports, InstanceAllocationRequest, StorePtr, VMContext, VMFunctionBody, VMFunctionImport, + VMGlobalImport, VMMemoryImport, VMOpaqueContext, VMTableImport, }; /// An instantiated WebAssembly module. @@ -317,20 +317,11 @@ impl Instance { // items from this instance into other instances should be ok when // those items are loaded and run we'll have all the metadata to // look at them. - store - .engine() - .allocator() - .initialize( - &mut instance_handle, - compiled_module.module(), - store.engine().config().features.bulk_memory, - ) - .map_err(|e| -> Error { - match e { - InstantiationError::Trap(trap) => trap.into(), - other => other.into(), - } - })?; + store.engine().allocator().initialize( + &mut instance_handle, + compiled_module.module(), + store.engine().config().features.bulk_memory, + )?; Ok((instance, compiled_module.module().start_func)) } diff --git a/crates/wasmtime/src/trampoline/memory.rs b/crates/wasmtime/src/trampoline/memory.rs index 6a136f00ae..6f349db74e 100644 --- a/crates/wasmtime/src/trampoline/memory.rs +++ b/crates/wasmtime/src/trampoline/memory.rs @@ -8,8 +8,8 @@ use std::sync::Arc; use wasmtime_environ::{EntityIndex, MemoryPlan, MemoryStyle, Module, WASM_PAGE_SIZE}; use wasmtime_runtime::{ allocate_single_memory_instance, DefaultMemoryCreator, Imports, InstanceAllocationRequest, - InstantiationError, Memory, MemoryImage, RuntimeLinearMemory, RuntimeMemoryCreator, - SharedMemory, StorePtr, VMMemoryDefinition, + Memory, MemoryImage, RuntimeLinearMemory, RuntimeMemoryCreator, SharedMemory, StorePtr, + VMMemoryDefinition, }; /// Create a "frankenstein" instance with a single memory. @@ -48,8 +48,7 @@ pub fn create_memory( .as_mut() .expect("the store pointer cannot be null here") }; - Memory::new_dynamic(&plan, creator, store, None) - .map_err(|err| InstantiationError::Resource(err.into()))? + Memory::new_dynamic(&plan, creator, store, None)? } }; diff --git a/tests/all/limits.rs b/tests/all/limits.rs index 333583f657..2d798e5d1d 100644 --- a/tests/all/limits.rs +++ b/tests/all/limits.rs @@ -253,7 +253,7 @@ fn test_initial_memory_limits_exceeded() -> Result<()> { Ok(_) => unreachable!(), Err(e) => assert_eq!( e.to_string(), - "Insufficient resources: memory minimum size of 11 pages exceeds memory limits" + "memory minimum size of 11 pages exceeds memory limits" ), } @@ -261,7 +261,7 @@ fn test_initial_memory_limits_exceeded() -> Result<()> { Ok(_) => unreachable!(), Err(e) => assert_eq!( e.to_string(), - "Insufficient resources: memory minimum size of 25 pages exceeds memory limits" + "memory minimum size of 25 pages exceeds memory limits" ), } @@ -329,7 +329,7 @@ fn test_initial_table_limits_exceeded() -> Result<()> { Ok(_) => unreachable!(), Err(e) => assert_eq!( e.to_string(), - "Insufficient resources: table minimum size of 23 elements exceeds table limits" + "table minimum size of 23 elements exceeds table limits" ), } @@ -341,7 +341,7 @@ fn test_initial_table_limits_exceeded() -> Result<()> { Ok(_) => unreachable!(), Err(e) => assert_eq!( e.to_string(), - "Insufficient resources: table minimum size of 99 elements exceeds table limits" + "table minimum size of 99 elements exceeds table limits" ), } @@ -374,7 +374,7 @@ fn test_pooling_allocator_initial_limits_exceeded() -> Result<()> { Ok(_) => unreachable!(), Err(e) => assert_eq!( e.to_string(), - "Insufficient resources: memory minimum size of 5 pages exceeds memory limits" + "memory minimum size of 5 pages exceeds memory limits" ), } diff --git a/tests/all/pooling_allocator.rs b/tests/all/pooling_allocator.rs index d2f38924d6..0354a9c743 100644 --- a/tests/all/pooling_allocator.rs +++ b/tests/all/pooling_allocator.rs @@ -428,7 +428,7 @@ fn instantiation_limit() -> Result<()> { Err(e) => assert_eq!( e.to_string(), format!( - "Limit of {} concurrent instances has been reached", + "maximum concurrent instance limit of {} reached", INSTANCE_LIMIT ) ),