mirror of
https://github.com/fluencelabs/wasmer
synced 2024-12-04 18:10:18 +00:00
Define runtime error values explicitly in Singlepass
This commit is contained in:
parent
bfb6814f23
commit
b9ec8f9845
@ -1,12 +1,12 @@
|
||||
use crate::{
|
||||
relocation::{TrapData, TrapSink, TrapCode},
|
||||
relocation::{TrapData, TrapSink},
|
||||
resolver::FuncResolver,
|
||||
trampoline::Trampolines,
|
||||
};
|
||||
use libc::c_void;
|
||||
use std::{any::Any, cell::Cell, ptr::NonNull, sync::Arc};
|
||||
use std::{cell::Cell, ptr::NonNull, sync::Arc};
|
||||
use wasmer_runtime_core::{
|
||||
backend::{RunnableModule, ExceptionCode},
|
||||
backend::RunnableModule,
|
||||
error::{InvokeError, RuntimeError},
|
||||
module::ModuleInfo,
|
||||
typed_func::{Trampoline, Wasm},
|
||||
@ -30,23 +30,6 @@ thread_local! {
|
||||
pub static TRAP_EARLY_DATA: Cell<Option<RuntimeError>> = Cell::new(None);
|
||||
}
|
||||
|
||||
pub enum CallProtError {
|
||||
UnknownTrap {
|
||||
address: usize,
|
||||
signal: &'static str,
|
||||
},
|
||||
TrapCode {
|
||||
code: ExceptionCode,
|
||||
srcloc: u32,
|
||||
},
|
||||
UnknownTrapCode {
|
||||
trap_code: TrapCode,
|
||||
srcloc: u32,
|
||||
},
|
||||
EarlyTrap(RuntimeError),
|
||||
Misc(Box<dyn Any + Send>),
|
||||
}
|
||||
|
||||
pub struct Caller {
|
||||
handler_data: HandlerData,
|
||||
trampolines: Arc<Trampolines>,
|
||||
@ -99,7 +82,7 @@ impl RunnableModule for Caller {
|
||||
// probably makes the most sense to actually do a translation here to a
|
||||
// a generic type defined in runtime-core
|
||||
// TODO: figure out _this_ error return story
|
||||
*error_out = Some(err.0);
|
||||
*error_out = Some(err);
|
||||
false
|
||||
}
|
||||
Ok(()) => true,
|
||||
|
@ -10,7 +10,7 @@
|
||||
//! unless you have memory unsafety elsewhere in your code.
|
||||
//!
|
||||
use crate::relocation::{TrapCode, TrapData};
|
||||
use crate::signal::{CallProtError, HandlerData};
|
||||
use crate::signal::HandlerData;
|
||||
use libc::{c_int, c_void, siginfo_t};
|
||||
use nix::sys::signal::{
|
||||
sigaction, SaFlags, SigAction, SigHandler, SigSet, Signal, SIGBUS, SIGFPE, SIGILL, SIGSEGV,
|
||||
@ -19,6 +19,7 @@ use std::cell::{Cell, UnsafeCell};
|
||||
use std::ptr;
|
||||
use std::sync::Once;
|
||||
use wasmer_runtime_core::backend::ExceptionCode;
|
||||
use wasmer_runtime_core::error::InvokeError;
|
||||
|
||||
extern "C" fn signal_trap_handler(
|
||||
signum: ::nix::libc::c_int,
|
||||
@ -65,7 +66,7 @@ pub unsafe fn trigger_trap() -> ! {
|
||||
pub fn call_protected<T>(
|
||||
handler_data: &HandlerData,
|
||||
f: impl FnOnce() -> T,
|
||||
) -> Result<T, CallProtError> {
|
||||
) -> Result<T, InvokeError> {
|
||||
unsafe {
|
||||
let jmp_buf = SETJMP_BUFFER.with(|buf| buf.get());
|
||||
let prev_jmp_buf = *jmp_buf;
|
||||
@ -79,15 +80,11 @@ pub fn call_protected<T>(
|
||||
*jmp_buf = prev_jmp_buf;
|
||||
|
||||
if let Some(data) = super::TRAP_EARLY_DATA.with(|cell| cell.replace(None)) {
|
||||
Err(CallProtError::EarlyTrap(data))
|
||||
Err(InvokeError::EarlyTrap(Box::new(data)))
|
||||
} else {
|
||||
let (faulting_addr, inst_ptr) = CAUGHT_ADDRESSES.with(|cell| cell.get());
|
||||
|
||||
if let Some(TrapData {
|
||||
trapcode,
|
||||
srcloc,
|
||||
}) = handler_data.lookup(inst_ptr)
|
||||
{
|
||||
if let Some(TrapData { trapcode, srcloc }) = handler_data.lookup(inst_ptr) {
|
||||
let code = match Signal::from_c_int(signum) {
|
||||
Ok(SIGILL) => match trapcode {
|
||||
TrapCode::StackOverflow => ExceptionCode::MemoryOutOfBounds,
|
||||
@ -101,8 +98,8 @@ pub fn call_protected<T>(
|
||||
TrapCode::BadConversionToInteger => ExceptionCode::IllegalArithmetic,
|
||||
TrapCode::UnreachableCodeReached => ExceptionCode::Unreachable,
|
||||
_ => {
|
||||
return Err(CallProtError::UnknownTrapCode {
|
||||
trap_code: trapcode,
|
||||
return Err(InvokeError::UnknownTrapCode {
|
||||
trap_code: format!("{:?}", trapcode),
|
||||
srcloc,
|
||||
})
|
||||
}
|
||||
@ -114,10 +111,7 @@ pub fn call_protected<T>(
|
||||
Signal::from_c_int(signum)
|
||||
),
|
||||
};
|
||||
Err(CallProtError::TrapCode {
|
||||
srcloc,
|
||||
code,
|
||||
})
|
||||
Err(InvokeError::TrapCode { srcloc, code })
|
||||
} else {
|
||||
let signal = match Signal::from_c_int(signum) {
|
||||
Ok(SIGFPE) => "floating-point exception",
|
||||
@ -128,7 +122,7 @@ pub fn call_protected<T>(
|
||||
_ => "unknown trapped signal",
|
||||
};
|
||||
// When the trap-handler is fully implemented, this will return more information.
|
||||
Err(CallProtError::UnknownTrap {
|
||||
Err(InvokeError::UnknownTrap {
|
||||
address: faulting_addr as usize,
|
||||
signal,
|
||||
})
|
||||
|
@ -11,7 +11,6 @@ use inkwell::{
|
||||
};
|
||||
use libc::c_char;
|
||||
use std::{
|
||||
any::Any,
|
||||
cell::RefCell,
|
||||
ffi::{c_void, CString},
|
||||
mem,
|
||||
@ -27,6 +26,7 @@ use wasmer_runtime_core::{
|
||||
CacheGen, ExceptionCode, RunnableModule,
|
||||
},
|
||||
cache::Error as CacheError,
|
||||
error::{InvokeError, RuntimeError},
|
||||
module::ModuleInfo,
|
||||
state::ModuleStateMap,
|
||||
structures::TypedIndex,
|
||||
@ -56,7 +56,7 @@ extern "C" {
|
||||
/// but this is cleaner, I think?
|
||||
#[cfg_attr(nightly, unwind(allowed))]
|
||||
#[allow(improper_ctypes)]
|
||||
fn throw_any(data: *mut dyn Any) -> !;
|
||||
fn throw_runtime_error(data: RuntimeError) -> !;
|
||||
|
||||
#[allow(improper_ctypes)]
|
||||
fn cxx_invoke_trampoline(
|
||||
@ -66,7 +66,7 @@ extern "C" {
|
||||
params: *const u64,
|
||||
results: *mut u64,
|
||||
trap_out: *mut i32,
|
||||
error_out: *mut Option<Box<dyn Any + Send>>,
|
||||
error_out: *mut Option<InvokeError>,
|
||||
invoke_env: Option<NonNull<c_void>>,
|
||||
) -> bool;
|
||||
}
|
||||
@ -79,7 +79,7 @@ unsafe extern "C" fn invoke_trampoline(
|
||||
func_ptr: NonNull<vm::Func>,
|
||||
params: *const u64,
|
||||
results: *mut u64,
|
||||
error_out: *mut Option<Box<dyn Any + Send>>,
|
||||
error_out: *mut Option<InvokeError>,
|
||||
invoke_env: Option<NonNull<c_void>>,
|
||||
) -> bool {
|
||||
let mut trap_out: i32 = -1;
|
||||
@ -95,15 +95,22 @@ unsafe extern "C" fn invoke_trampoline(
|
||||
);
|
||||
// Translate trap code if an error occurred.
|
||||
if !ret && (*error_out).is_none() && trap_out != -1 {
|
||||
*error_out = Some(Box::new(match trap_out {
|
||||
0 => ExceptionCode::Unreachable,
|
||||
1 => ExceptionCode::IncorrectCallIndirectSignature,
|
||||
2 => ExceptionCode::MemoryOutOfBounds,
|
||||
3 => ExceptionCode::CallIndirectOOB,
|
||||
4 => ExceptionCode::IllegalArithmetic,
|
||||
5 => ExceptionCode::MisalignedAtomicAccess,
|
||||
_ => return ret,
|
||||
}));
|
||||
*error_out = {
|
||||
let exception_code = match trap_out {
|
||||
0 => ExceptionCode::Unreachable,
|
||||
1 => ExceptionCode::IncorrectCallIndirectSignature,
|
||||
2 => ExceptionCode::MemoryOutOfBounds,
|
||||
3 => ExceptionCode::CallIndirectOOB,
|
||||
4 => ExceptionCode::IllegalArithmetic,
|
||||
5 => ExceptionCode::MisalignedAtomicAccess,
|
||||
_ => return ret,
|
||||
};
|
||||
Some(InvokeError::TrapCode {
|
||||
code: exception_code,
|
||||
// TODO:
|
||||
srcloc: 0,
|
||||
})
|
||||
};
|
||||
}
|
||||
ret
|
||||
}
|
||||
@ -467,8 +474,9 @@ impl RunnableModule for LLVMBackend {
|
||||
self.msm.clone()
|
||||
}
|
||||
|
||||
unsafe fn do_early_trap(&self, data: Box<dyn Any + Send>) -> ! {
|
||||
throw_any(Box::leak(data))
|
||||
unsafe fn do_early_trap(&self, data: RuntimeError) -> ! {
|
||||
// maybe need to box leak it?
|
||||
throw_runtime_error(data)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
use wasmer_runtime_core::{
|
||||
codegen::{Event, EventSink, FunctionMiddleware, InternalEvent},
|
||||
error::RuntimeError,
|
||||
module::ModuleInfo,
|
||||
vm::{Ctx, InternalField},
|
||||
wasmparser::{Operator, Type as WpType, TypeOrFuncType as WpTypeOrFuncType},
|
||||
@ -96,7 +97,7 @@ impl FunctionMiddleware for Metering {
|
||||
ty: WpTypeOrFuncType::Type(WpType::EmptyBlockType),
|
||||
}));
|
||||
sink.push(Event::Internal(InternalEvent::Breakpoint(Box::new(|_| {
|
||||
Err(Box::new(ExecutionLimitExceededError))
|
||||
Err(RuntimeError::Metering(Box::new(ExecutionLimitExceededError)))
|
||||
}))));
|
||||
sink.push(Event::WasmOwned(Operator::End));
|
||||
}
|
||||
|
@ -6,13 +6,12 @@ use crate::{
|
||||
backend::RunnableModule,
|
||||
backend::{CacheGen, Compiler, CompilerConfig, Features, Token},
|
||||
cache::{Artifact, Error as CacheError},
|
||||
error::{CompileError, CompileResult},
|
||||
error::{CompileError, CompileResult, RuntimeError},
|
||||
module::{ModuleInfo, ModuleInner},
|
||||
structures::Map,
|
||||
types::{FuncIndex, FuncSig, SigIndex},
|
||||
};
|
||||
use smallvec::SmallVec;
|
||||
use std::any::Any;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
use std::fmt::Debug;
|
||||
@ -23,7 +22,7 @@ use wasmparser::{Operator, Type as WpType};
|
||||
|
||||
/// A type that defines a function pointer, which is called when breakpoints occur.
|
||||
pub type BreakpointHandler =
|
||||
Box<dyn Fn(BreakpointInfo) -> Result<(), Box<dyn Any + Send>> + Send + Sync + 'static>;
|
||||
Box<dyn Fn(BreakpointInfo) -> Result<(), RuntimeError> + Send + Sync + 'static>;
|
||||
|
||||
/// Maps instruction pointers to their breakpoint handlers.
|
||||
pub type BreakpointMap = Arc<HashMap<usize, BreakpointHandler>>;
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! 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::backend::ExceptionCode;
|
||||
use crate::backend::ExceptionCode;
|
||||
use crate::types::{FuncSig, GlobalDescriptor, MemoryDescriptor, TableDescriptor, Type};
|
||||
use core::borrow::Borrow;
|
||||
use std::any::Any;
|
||||
@ -222,31 +222,63 @@ impl std::error::Error for RuntimeError {}
|
||||
/// extremely rare and impossible to handle.
|
||||
#[derive(Debug)]
|
||||
pub enum RuntimeError {
|
||||
/// When an invoke returns an error (this is where exception codes come from?)
|
||||
/// When an invoke returns an error
|
||||
InvokeError(InvokeError),
|
||||
/// A metering triggered error value.
|
||||
///
|
||||
/// An error of this type indicates that it was returned by the metering system.
|
||||
Metering(Box<dyn Any + Send>),
|
||||
/// A user triggered error value.
|
||||
///
|
||||
/// An error returned from a host function.
|
||||
User(Box<dyn Any + Send>)
|
||||
User(Box<dyn Any + Send>),
|
||||
}
|
||||
|
||||
/// TODO:
|
||||
#[derive(Debug)]
|
||||
pub enum InvokeError {
|
||||
/// not yet handled error cases, ideally we should be able to handle them all
|
||||
Misc(Box<dyn Any + Send>),
|
||||
/// Indicates an exceptional circumstance such as a bug that should be reported or
|
||||
/// a hardware failure.
|
||||
FailedWithNoError,
|
||||
|
||||
/// TODO:
|
||||
UnknownTrap {
|
||||
/// TODO:
|
||||
address: usize,
|
||||
/// TODO:
|
||||
signal: &'static str,
|
||||
},
|
||||
/// TODO:
|
||||
TrapCode {
|
||||
/// TODO:
|
||||
code: ExceptionCode,
|
||||
/// TODO:
|
||||
srcloc: u32,
|
||||
},
|
||||
/// TODO:
|
||||
UnknownTrapCode {
|
||||
/// TODO:
|
||||
trap_code: String,
|
||||
/// TODO:
|
||||
srcloc: u32,
|
||||
},
|
||||
/// extra TODO: investigate if this can be a `Box<InvokeError>` instead (looks like probably no)
|
||||
/// TODO:
|
||||
EarlyTrap(Box<RuntimeError>),
|
||||
/// Indicates an error that ocurred related to breakpoints. (currently Singlepass only)
|
||||
Breakpoint(Box<RuntimeError>),
|
||||
}
|
||||
|
||||
//impl std::error::Error for InvokeError {}
|
||||
|
||||
impl std::error::Error for RuntimeError {}
|
||||
|
||||
impl std::fmt::Display for RuntimeError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
// TODO: ideally improve the error type of invoke
|
||||
// TODO: update invoke error formatting
|
||||
RuntimeError::InvokeError(_) => write!(f, "Error when calling invoke"),
|
||||
RuntimeError::Metering(_) => write!(f, "unknown metering error type"),
|
||||
RuntimeError::User(user_error) => {
|
||||
write!(f, "User supplied error: ")?;
|
||||
if let Some(s) = user_error.downcast_ref::<String>() {
|
||||
@ -256,9 +288,9 @@ impl std::fmt::Display for RuntimeError {
|
||||
} else if let Some(n) = user_error.downcast_ref::<i32>() {
|
||||
write!(f, "{}", n)
|
||||
} else {
|
||||
write!(f, "unknown error type")
|
||||
write!(f, "unknown user error type")
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -270,8 +302,6 @@ impl From<InternalError> for RuntimeError {
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/// This error type is produced by resolving a wasm function
|
||||
/// given its name.
|
||||
|
@ -29,14 +29,14 @@ pub mod raw {
|
||||
|
||||
use crate::codegen::{BreakpointInfo, BreakpointMap};
|
||||
use crate::state::x64::{build_instance_image, read_stack, X64Register, GPR};
|
||||
use crate::state::{CodeVersion, ExecutionStateImage};
|
||||
use crate::state::{CodeVersion, ExecutionStateImage, InstanceImage};
|
||||
use crate::error::{RuntimeError, InvokeError};
|
||||
use crate::vm;
|
||||
use libc::{mmap, mprotect, siginfo_t, MAP_ANON, MAP_PRIVATE, PROT_NONE, PROT_READ, PROT_WRITE};
|
||||
use nix::sys::signal::{
|
||||
sigaction, SaFlags, SigAction, SigHandler, SigSet, Signal, SIGBUS, SIGFPE, SIGILL, SIGINT,
|
||||
SIGSEGV, SIGTRAP,
|
||||
};
|
||||
use std::any::Any;
|
||||
use std::cell::{Cell, RefCell, UnsafeCell};
|
||||
use std::ffi::c_void;
|
||||
use std::process;
|
||||
@ -61,7 +61,7 @@ type SetJmpBuffer = [i32; SETJMP_BUFFER_LEN];
|
||||
struct UnwindInfo {
|
||||
jmpbuf: SetJmpBuffer, // in
|
||||
breakpoints: Option<BreakpointMap>,
|
||||
payload: Option<Box<dyn Any + Send>>, // out
|
||||
payload: Option<RuntimeError>, // out
|
||||
}
|
||||
|
||||
/// A store for boundary register preservation.
|
||||
@ -182,7 +182,7 @@ pub unsafe fn clear_wasm_interrupt() {
|
||||
pub unsafe fn catch_unsafe_unwind<R, F: FnOnce() -> R>(
|
||||
f: F,
|
||||
breakpoints: Option<BreakpointMap>,
|
||||
) -> Result<R, Box<dyn Any + Send>> {
|
||||
) -> Result<R, RuntimeError> {
|
||||
let unwind = UNWIND.with(|x| x.get());
|
||||
let old = (*unwind).take();
|
||||
*unwind = Some(UnwindInfo {
|
||||
@ -205,7 +205,7 @@ pub unsafe fn catch_unsafe_unwind<R, F: FnOnce() -> R>(
|
||||
}
|
||||
|
||||
/// Begins an unsafe unwind.
|
||||
pub unsafe fn begin_unsafe_unwind(e: Box<dyn Any + Send>) -> ! {
|
||||
pub unsafe fn begin_unsafe_unwind(e: RuntimeError) -> ! {
|
||||
let unwind = UNWIND.with(|x| x.get());
|
||||
let inner = (*unwind)
|
||||
.as_mut()
|
||||
@ -279,7 +279,7 @@ extern "C" fn signal_trap_handler(
|
||||
static ARCH: Architecture = Architecture::Aarch64;
|
||||
|
||||
let mut should_unwind = false;
|
||||
let mut unwind_result: Box<dyn Any + Send> = Box::new(());
|
||||
let mut unwind_result: Option<Result<InstanceImage, RuntimeError>> = None;
|
||||
|
||||
unsafe {
|
||||
let fault = get_fault_info(siginfo as _, ucontext);
|
||||
@ -302,7 +302,7 @@ extern "C" fn signal_trap_handler(
|
||||
) {
|
||||
match ib.ty {
|
||||
InlineBreakpointType::Middleware => {
|
||||
let out: Option<Result<(), Box<dyn Any + Send>>> =
|
||||
let out: Option<Result<(), RuntimeError>> =
|
||||
with_breakpoint_map(|bkpt_map| {
|
||||
bkpt_map.and_then(|x| x.get(&ip)).map(|x| {
|
||||
x(BreakpointInfo {
|
||||
@ -313,7 +313,7 @@ extern "C" fn signal_trap_handler(
|
||||
if let Some(Ok(())) = out {
|
||||
} else if let Some(Err(e)) = out {
|
||||
should_unwind = true;
|
||||
unwind_result = e;
|
||||
unwind_result = Some(Err(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -328,7 +328,7 @@ extern "C" fn signal_trap_handler(
|
||||
})
|
||||
});
|
||||
if should_unwind {
|
||||
begin_unsafe_unwind(unwind_result);
|
||||
begin_unsafe_unwind(unwind_result.unwrap().unwrap_err());
|
||||
}
|
||||
if early_return {
|
||||
return;
|
||||
@ -342,9 +342,9 @@ extern "C" fn signal_trap_handler(
|
||||
match Signal::from_c_int(signum) {
|
||||
Ok(SIGTRAP) => {
|
||||
// breakpoint
|
||||
let out: Option<Result<(), Box<dyn Any + Send>>> =
|
||||
with_breakpoint_map(|bkpt_map| {
|
||||
bkpt_map.and_then(|x| x.get(&(fault.ip.get()))).map(|x| {
|
||||
let out: Option<Result<(), RuntimeError>> =
|
||||
with_breakpoint_map(|bkpt_map| -> Option<Result<(), RuntimeError>> {
|
||||
bkpt_map.and_then(|x| x.get(&(fault.ip.get()))).map(|x| -> Result<(), RuntimeError> {
|
||||
x(BreakpointInfo {
|
||||
fault: Some(&fault),
|
||||
})
|
||||
@ -355,7 +355,7 @@ extern "C" fn signal_trap_handler(
|
||||
return false;
|
||||
}
|
||||
Some(Err(e)) => {
|
||||
unwind_result = e;
|
||||
unwind_result = Some(Err(e));
|
||||
return true;
|
||||
}
|
||||
None => {}
|
||||
@ -387,7 +387,7 @@ extern "C" fn signal_trap_handler(
|
||||
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);
|
||||
unwind_result = Some(Ok(image));
|
||||
} else {
|
||||
// Otherwise, this is a real exception and we just throw it to the caller.
|
||||
if !es_image.frames.is_empty() {
|
||||
@ -415,7 +415,11 @@ extern "C" fn signal_trap_handler(
|
||||
None
|
||||
});
|
||||
if let Some(code) = exc_code {
|
||||
unwind_result = Box::new(code);
|
||||
unwind_result = Some(Err(RuntimeError::InvokeError(InvokeError::TrapCode {
|
||||
code,
|
||||
// TODO:
|
||||
srcloc: 0,
|
||||
})));
|
||||
}
|
||||
}
|
||||
|
||||
@ -423,7 +427,7 @@ extern "C" fn signal_trap_handler(
|
||||
});
|
||||
|
||||
if should_unwind {
|
||||
begin_unsafe_unwind(unwind_result);
|
||||
begin_unsafe_unwind(unwind_result.unwrap().unwrap_err());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
use crate::{
|
||||
backend::RunnableModule,
|
||||
backing::{ImportBacking, LocalBacking},
|
||||
error::{CallResult, ResolveError, ResolveResult, Result, RuntimeError, InvokeError},
|
||||
error::{CallResult, InvokeError, ResolveError, ResolveResult, Result, RuntimeError},
|
||||
export::{Context, Export, ExportIter, Exportable, FuncPointer},
|
||||
global::Global,
|
||||
import::{ImportObject, LikeNamespace},
|
||||
@ -587,15 +587,17 @@ pub(crate) fn call_func_with_index_inner(
|
||||
let run_wasm = |result_space: *mut u64| -> CallResult<()> {
|
||||
let mut error_out = None;
|
||||
|
||||
let success = unsafe { invoke(
|
||||
trampoline,
|
||||
ctx_ptr,
|
||||
func_ptr,
|
||||
raw_args.as_ptr(),
|
||||
result_space,
|
||||
&mut error_out,
|
||||
invoke_env,
|
||||
)};
|
||||
let success = unsafe {
|
||||
invoke(
|
||||
trampoline,
|
||||
ctx_ptr,
|
||||
func_ptr,
|
||||
raw_args.as_ptr(),
|
||||
result_space,
|
||||
&mut error_out,
|
||||
invoke_env,
|
||||
)
|
||||
};
|
||||
|
||||
if success {
|
||||
Ok(())
|
||||
|
@ -705,7 +705,7 @@ pub mod x64 {
|
||||
use crate::structures::TypedIndex;
|
||||
use crate::types::LocalGlobalIndex;
|
||||
use crate::vm::Ctx;
|
||||
use std::any::Any;
|
||||
use crate::error::RuntimeError;
|
||||
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
unsafe fn compute_vmctx_deref(vmctx: *const Ctx, seq: &[usize]) -> u64 {
|
||||
@ -738,7 +738,7 @@ pub mod x64 {
|
||||
image: InstanceImage,
|
||||
vmctx: &mut Ctx,
|
||||
breakpoints: Option<BreakpointMap>,
|
||||
) -> Result<u64, Box<dyn Any + Send>> {
|
||||
) -> Result<u64, RuntimeError> {
|
||||
let mut stack: Vec<u64> = vec![0; 1048576 * 8 / 8]; // 8MB stack
|
||||
let mut stack_offset: usize = stack.len();
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! The typed func module implements a way of representing a wasm function
|
||||
//! with the correct types from rust. Function calls using a typed func have a low overhead.
|
||||
use crate::{
|
||||
error::{RuntimeError, InvokeError},
|
||||
error::{InvokeError, RuntimeError},
|
||||
export::{Context, Export, FuncPointer},
|
||||
import::IsExport,
|
||||
types::{FuncSig, NativeWasmType, Type, WasmExternType},
|
||||
@ -340,7 +340,9 @@ impl<'a> DynamicFunc<'a> {
|
||||
Err(e) => {
|
||||
// At this point, there is an error that needs to be trapped.
|
||||
drop(args); // Release the Vec which will leak otherwise.
|
||||
(&*vmctx.module).runnable_module.do_early_trap(RuntimeError::User(e))
|
||||
(&*vmctx.module)
|
||||
.runnable_module
|
||||
.do_early_trap(RuntimeError::User(e))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,6 @@ use dynasmrt::x64::Assembler;
|
||||
use dynasmrt::{AssemblyOffset, DynamicLabel, DynasmApi, DynasmLabelApi};
|
||||
use smallvec::SmallVec;
|
||||
use std::{
|
||||
any::Any,
|
||||
collections::{BTreeMap, HashMap},
|
||||
ffi::c_void,
|
||||
iter, mem,
|
||||
@ -29,6 +28,7 @@ use wasmer_runtime_core::{
|
||||
codegen::*,
|
||||
fault::{self, raw::register_preservation_trampoline},
|
||||
loader::CodeMemory,
|
||||
error::{InvokeError, RuntimeError},
|
||||
memory::MemoryType,
|
||||
module::{ModuleInfo, ModuleInner},
|
||||
state::{
|
||||
@ -214,7 +214,7 @@ pub struct X64FunctionCode {
|
||||
breakpoints: Option<
|
||||
HashMap<
|
||||
AssemblyOffset,
|
||||
Box<dyn Fn(BreakpointInfo) -> Result<(), Box<dyn Any + Send>> + Send + Sync + 'static>,
|
||||
Box<dyn Fn(BreakpointInfo) -> Result<(), RuntimeError> + Send + Sync + 'static>,
|
||||
>,
|
||||
>,
|
||||
returns: SmallVec<[WpType; 1]>,
|
||||
@ -507,7 +507,7 @@ impl RunnableModule for X64ExecutionContext {
|
||||
func: NonNull<vm::Func>,
|
||||
args: *const u64,
|
||||
rets: *mut u64,
|
||||
error_out: *mut Option<Box<dyn Any + Send>>,
|
||||
error_out: *mut Option<InvokeError>,
|
||||
num_params_plus_one: Option<NonNull<c_void>>,
|
||||
) -> bool {
|
||||
let rm: &Box<dyn RunnableModule> = &(&*(*ctx).module).runnable_module;
|
||||
@ -655,7 +655,7 @@ impl RunnableModule for X64ExecutionContext {
|
||||
true
|
||||
}
|
||||
Err(err) => {
|
||||
*error_out = Some(err);
|
||||
*error_out = Some(InvokeError::Breakpoint(Box::new(err)));
|
||||
false
|
||||
}
|
||||
};
|
||||
@ -680,7 +680,7 @@ impl RunnableModule for X64ExecutionContext {
|
||||
})
|
||||
}
|
||||
|
||||
unsafe fn do_early_trap(&self, data: Box<dyn Any + Send>) -> ! {
|
||||
unsafe fn do_early_trap(&self, data: RuntimeError) -> ! {
|
||||
fault::begin_unsafe_unwind(data);
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@ use wasmer_runtime::{
|
||||
};
|
||||
use wasmer_runtime_core::{
|
||||
self,
|
||||
error::RuntimeError,
|
||||
backend::{Compiler, CompilerConfig, MemoryBoundCheckMode},
|
||||
loader::{Instance as LoadedInstance, LocalLoader},
|
||||
Module,
|
||||
@ -437,9 +438,12 @@ fn execute_wasi(
|
||||
}
|
||||
|
||||
if let Err(ref err) = result {
|
||||
if let Some(error_code) = err.0.downcast_ref::<wasmer_wasi::ExitCode>() {
|
||||
std::process::exit(error_code.code as i32)
|
||||
if let RuntimeError::User(user_error) = err {
|
||||
if let Some(error_code) = user_error.downcast_ref::<wasmer_wasi::ExitCode>() {
|
||||
std::process::exit(error_code.code as i32)
|
||||
}
|
||||
}
|
||||
|
||||
return Err(format!("error: {:?}", err));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user