2019-01-29 13:04:42 -08:00
use crate ::types ::{
FuncSig , GlobalDescriptor , MemoryDescriptor , MemoryIndex , TableDescriptor , TableIndex , Type ,
} ;
2019-02-14 18:19:18 -08:00
use core ::borrow ::Borrow ;
2019-01-29 10:16:39 -08:00
use std ::sync ::Arc ;
2019-01-18 10:54:16 -08:00
2019-02-02 15:28:50 -08:00
pub type Result < T > = std ::result ::Result < T , Error > ;
pub type CompileResult < T > = std ::result ::Result < T , CompileError > ;
2019-01-18 13:44:44 -08:00
pub type LinkResult < T > = std ::result ::Result < T , Vec < LinkError > > ;
2019-02-02 15:28:50 -08:00
pub type RuntimeResult < T > = std ::result ::Result < T , RuntimeError > ;
pub type CallResult < T > = std ::result ::Result < T , CallError > ;
pub type ResolveResult < T > = std ::result ::Result < T , ResolveError > ;
2019-01-18 10:54:16 -08:00
/// This is returned when the chosen compiler is unable to
/// successfully compile the provided webassembly module into
/// a `Module`.
///
/// Comparing two `CompileError`s always evaluates to false.
#[ derive(Debug, Clone) ]
pub enum CompileError {
ValidationError { msg : String } ,
InternalError { msg : String } ,
}
impl PartialEq for CompileError {
fn eq ( & self , _other : & CompileError ) -> bool {
false
}
}
2019-02-14 21:08:35 -08:00
impl std ::fmt ::Display for CompileError {
fn fmt ( & self , f : & mut std ::fmt ::Formatter ) -> std ::fmt ::Result {
match self {
CompileError ::InternalError { msg } = > {
write! ( f , " Internal compiler error: \" {} \" " , msg )
}
CompileError ::ValidationError { msg } = > write! ( f , " Validation error \" {} \" " , msg ) ,
}
}
}
impl std ::error ::Error for CompileError { }
2019-01-18 10:54:16 -08:00
/// This is returned when the runtime is unable to
/// correctly link the module with the provided imports.
///
/// Comparing two `LinkError`s always evaluates to false.
#[ derive(Debug, Clone) ]
pub enum LinkError {
IncorrectImportType {
namespace : String ,
name : String ,
expected : String ,
found : String ,
} ,
IncorrectImportSignature {
namespace : String ,
name : String ,
2019-01-29 10:16:39 -08:00
expected : Arc < FuncSig > ,
found : Arc < FuncSig > ,
2019-01-18 10:54:16 -08:00
} ,
ImportNotFound {
namespace : String ,
name : String ,
} ,
2019-01-29 13:04:42 -08:00
IncorrectMemoryDescriptor {
2019-01-18 10:54:16 -08:00
namespace : String ,
name : String ,
2019-01-29 13:04:42 -08:00
expected : MemoryDescriptor ,
found : MemoryDescriptor ,
2019-01-18 10:54:16 -08:00
} ,
2019-01-29 13:04:42 -08:00
IncorrectTableDescriptor {
2019-01-18 10:54:16 -08:00
namespace : String ,
name : String ,
2019-01-29 13:04:42 -08:00
expected : TableDescriptor ,
found : TableDescriptor ,
2019-01-18 10:54:16 -08:00
} ,
2019-01-29 13:04:42 -08:00
IncorrectGlobalDescriptor {
2019-01-18 10:54:16 -08:00
namespace : String ,
name : String ,
2019-01-29 13:04:42 -08:00
expected : GlobalDescriptor ,
found : GlobalDescriptor ,
2019-01-18 10:54:16 -08:00
} ,
}
impl PartialEq for LinkError {
fn eq ( & self , _other : & LinkError ) -> bool {
false
}
}
2019-02-14 18:40:52 -08:00
impl std ::fmt ::Display for LinkError {
fn fmt ( & self , f : & mut std ::fmt ::Formatter ) -> std ::fmt ::Result {
match self {
LinkError ::ImportNotFound { namespace , name } = > write! ( f , " Import not found, namespace: {}, name: {} " , namespace , name ) ,
LinkError ::IncorrectGlobalDescriptor { namespace , name , expected , found } = > {
write! ( f , " Incorrect global descriptor, namespace: {}, name: {}, expected global descriptor: {:?}, found global descriptor: {:?} " , namespace , name , expected , found )
} ,
LinkError ::IncorrectImportSignature { namespace , name , expected , found } = > {
write! ( f , " Incorrect import signature, namespace: {}, name: {}, expected signature: {}, found signature: {} " , namespace , name , expected , found )
}
LinkError ::IncorrectImportType { namespace , name , expected , found } = > {
write! ( f , " Incorrect import type, namespace: {}, name: {}, expected type: {}, found type: {} " , namespace , name , expected , found )
}
LinkError ::IncorrectMemoryDescriptor { namespace , name , expected , found } = > {
write! ( f , " Incorrect memory descriptor, namespace: {}, name: {}, expected memory descriptor: {:?}, found memory descriptor: {:?} " , namespace , name , expected , found )
} ,
LinkError ::IncorrectTableDescriptor { namespace , name , expected , found } = > {
write! ( f , " Incorrect table descriptor, namespace: {}, name: {}, expected table descriptor: {:?}, found table descriptor: {:?} " , namespace , name , expected , found )
} ,
}
}
}
impl std ::error ::Error for LinkError { }
2019-01-18 10:54:16 -08:00
/// This is the error type returned when calling
/// a webassembly function.
///
/// The main way to do this is `Instance.call`.
///
/// Comparing two `RuntimeError`s always evaluates to false.
#[ derive(Debug, Clone) ]
pub enum RuntimeError {
2019-02-07 14:44:28 -08:00
OutOfBoundsAccess {
memory : MemoryIndex ,
addr : Option < u32 > ,
} ,
TableOutOfBounds {
table : TableIndex ,
} ,
IndirectCallSignature {
table : TableIndex ,
} ,
IndirectCallToNull {
table : TableIndex ,
} ,
2019-01-18 16:45:30 -08:00
IllegalArithmeticOperation ,
2019-02-08 13:08:03 -08:00
User {
msg : String ,
} ,
2019-02-07 14:44:28 -08:00
Unknown {
msg : String ,
} ,
2019-01-18 10:54:16 -08:00
}
impl PartialEq for RuntimeError {
fn eq ( & self , _other : & RuntimeError ) -> bool {
false
}
}
2019-01-23 15:30:35 -08:00
/// This error type is produced by resolving a wasm function
/// given its name.
///
/// Comparing two `ResolveError`s always evaluates to false.
#[ derive(Debug, Clone) ]
pub enum ResolveError {
2019-01-29 10:16:39 -08:00
Signature {
expected : Arc < FuncSig > ,
found : Vec < Type > ,
} ,
ExportNotFound {
name : String ,
} ,
ExportWrongType {
name : String ,
} ,
2019-01-23 15:30:35 -08:00
}
impl PartialEq for ResolveError {
fn eq ( & self , _other : & ResolveError ) -> bool {
false
}
}
2019-02-14 18:19:18 -08:00
impl std ::fmt ::Display for ResolveError {
fn fmt ( & self , f : & mut std ::fmt ::Formatter ) -> std ::fmt ::Result {
match self {
ResolveError ::ExportNotFound { name } = > write! ( f , " Export not found: {} " , name ) ,
ResolveError ::ExportWrongType { name } = > write! ( f , " Export wrong type: {} " , name ) ,
ResolveError ::Signature { expected , found } = > {
let found = found
. as_slice ( )
. iter ( )
. map ( | p | p . to_string ( ) )
. collect ::< Vec < _ > > ( )
. join ( " , " ) ;
let expected : & FuncSig = expected . borrow ( ) ;
write! (
f ,
" Parameters of type [{}] did not match signature {} " ,
found , expected
)
}
}
}
}
impl std ::error ::Error for ResolveError { }
2019-01-18 10:54:16 -08:00
/// This error type is produced by calling a wasm function
/// exported from a module.
///
/// If the module traps in some way while running, this will
/// be the `CallError::Runtime(RuntimeError)` variant.
///
/// Comparing two `CallError`s always evaluates to false.
#[ derive(Debug, Clone) ]
pub enum CallError {
2019-01-23 15:30:35 -08:00
Resolve ( ResolveError ) ,
2019-01-18 10:54:16 -08:00
Runtime ( RuntimeError ) ,
}
impl PartialEq for CallError {
fn eq ( & self , _other : & CallError ) -> bool {
false
}
}
2019-01-29 15:44:15 -08:00
/// This error type is produced when creating something,
/// like a `Memory` or a `Table`.
#[ derive(Debug, Clone) ]
pub enum CreationError {
UnableToCreateMemory ,
UnableToCreateTable ,
}
impl PartialEq for CreationError {
fn eq ( & self , _other : & CreationError ) -> bool {
false
}
}
2019-02-14 19:22:19 -08:00
impl std ::fmt ::Display for CreationError {
fn fmt ( & self , f : & mut std ::fmt ::Formatter ) -> std ::fmt ::Result {
match self {
CreationError ::UnableToCreateMemory = > write! ( f , " Unable to Create Memory " ) ,
CreationError ::UnableToCreateTable = > write! ( f , " Unable to Create Table " ) ,
}
}
}
impl std ::error ::Error for CreationError { }
2019-01-18 10:54:16 -08:00
/// The amalgamation of all errors that can occur
/// during the compilation, instantiation, or execution
/// of a webassembly module.
///
/// Comparing two `Error`s always evaluates to false.
#[ derive(Debug, Clone) ]
pub enum Error {
CompileError ( CompileError ) ,
2019-01-18 13:44:44 -08:00
LinkError ( Vec < LinkError > ) ,
2019-01-18 10:54:16 -08:00
RuntimeError ( RuntimeError ) ,
2019-01-24 10:51:20 -08:00
ResolveError ( ResolveError ) ,
2019-01-18 10:54:16 -08:00
CallError ( CallError ) ,
2019-01-29 15:44:15 -08:00
CreationError ( CreationError ) ,
2019-01-18 10:54:16 -08:00
}
impl PartialEq for Error {
fn eq ( & self , _other : & Error ) -> bool {
false
}
}
2019-02-02 15:28:50 -08:00
impl From < CompileError > for Error {
2019-01-23 15:30:35 -08:00
fn from ( compile_err : CompileError ) -> Self {
2019-02-02 15:28:50 -08:00
Error ::CompileError ( compile_err )
2019-01-23 15:30:35 -08:00
}
}
2019-02-02 15:28:50 -08:00
impl From < RuntimeError > for Error {
2019-01-23 15:30:35 -08:00
fn from ( runtime_err : RuntimeError ) -> Self {
2019-02-02 15:28:50 -08:00
Error ::RuntimeError ( runtime_err )
2019-01-23 15:30:35 -08:00
}
}
2019-02-02 16:02:28 -08:00
impl From < ResolveError > for Error {
fn from ( resolve_err : ResolveError ) -> Self {
Error ::ResolveError ( resolve_err )
}
}
2019-02-02 15:28:50 -08:00
impl From < CallError > for Error {
2019-01-23 15:30:35 -08:00
fn from ( call_err : CallError ) -> Self {
2019-02-02 15:28:50 -08:00
Error ::CallError ( call_err )
2019-01-23 15:30:35 -08:00
}
}
2019-02-02 15:28:50 -08:00
impl From < CreationError > for Error {
2019-01-29 15:44:15 -08:00
fn from ( creation_err : CreationError ) -> Self {
2019-02-02 15:28:50 -08:00
Error ::CreationError ( creation_err )
}
}
impl From < Vec < LinkError > > for Error {
fn from ( link_errs : Vec < LinkError > ) -> Self {
Error ::LinkError ( link_errs )
2019-01-29 15:44:15 -08:00
}
}
2019-02-02 15:28:50 -08:00
impl From < RuntimeError > for CallError {
2019-01-23 15:30:35 -08:00
fn from ( runtime_err : RuntimeError ) -> Self {
2019-02-02 15:28:50 -08:00
CallError ::Runtime ( runtime_err )
2019-01-23 15:30:35 -08:00
}
}
2019-02-02 15:28:50 -08:00
impl From < ResolveError > for CallError {
2019-01-23 15:30:35 -08:00
fn from ( resolve_err : ResolveError ) -> Self {
2019-02-02 15:28:50 -08:00
CallError ::Resolve ( resolve_err )
2019-01-23 15:30:35 -08:00
}
}