Try to return an error from call_protected when an exception occurs.

Something breaks pretty drastically sometimes, not sure why.
This commit is contained in:
Lachlan Sneff
2019-03-02 19:08:15 -08:00
parent caf2205936
commit 9cfda6800f
5 changed files with 98 additions and 30 deletions

View File

@ -17,11 +17,14 @@ use std::{
};
use wasmer_runtime_core::{
backend::{FuncResolver, ProtectedCaller, Token, UserTrapper},
error::RuntimeResult,
error::{RuntimeError, RuntimeResult},
export::Context,
module::{ModuleInfo, ModuleInner},
structures::TypedIndex,
types::{FuncIndex, FuncSig, LocalFuncIndex, LocalOrImport, SigIndex, Type, Value},
types::{
FuncIndex, FuncSig, LocalFuncIndex, LocalOrImport, MemoryIndex, SigIndex, TableIndex, Type,
Value,
},
vm::{self, ImportBacking},
vmcalls,
};
@ -52,6 +55,14 @@ enum LLVMResult {
OBJECT_LOAD_FAILURE,
}
#[repr(C)]
enum WasmTrapType {
Unreachable = 0,
IncorrectCallIndirectSignature = 1,
MemoryOutOfBounds = 2,
Unknown,
}
#[repr(C)]
struct Callbacks {
alloc_memory: extern "C" fn(usize, MemProtect, &mut *mut u8, &mut usize) -> LLVMResult,
@ -80,7 +91,8 @@ extern "C" {
func_ptr: *const vm::Func,
params: *const u64,
results: *mut u64,
);
trap_out: *mut WasmTrapType,
) -> bool;
}
fn get_callbacks() -> Callbacks {
@ -358,27 +370,50 @@ impl ProtectedCaller for LLVMProtectedCaller {
mem::transmute(symbol)
};
let mut trap_out = WasmTrapType::Unknown;
// Here we go.
unsafe {
let success = unsafe {
invoke_trampoline(
trampoline,
vmctx_ptr,
func_ptr,
param_vec.as_ptr(),
return_vec.as_mut_ptr(),
);
}
&mut trap_out,
)
};
Ok(return_vec
.iter()
.zip(signature.returns().iter())
.map(|(&x, ty)| match ty {
Type::I32 => Value::I32(x as i32),
Type::I64 => Value::I64(x as i64),
Type::F32 => Value::F32(f32::from_bits(x as u32)),
Type::F64 => Value::F64(f64::from_bits(x as u64)),
if success {
Ok(return_vec
.iter()
.zip(signature.returns().iter())
.map(|(&x, ty)| match ty {
Type::I32 => Value::I32(x as i32),
Type::I64 => Value::I64(x as i64),
Type::F32 => Value::F32(f32::from_bits(x as u32)),
Type::F64 => Value::F64(f64::from_bits(x as u64)),
})
.collect())
} else {
Err(match trap_out {
WasmTrapType::Unreachable => RuntimeError::User {
msg: "unreachable".into(),
},
WasmTrapType::IncorrectCallIndirectSignature => {
RuntimeError::IndirectCallSignature {
table: TableIndex::new(0),
}
}
WasmTrapType::MemoryOutOfBounds => RuntimeError::OutOfBoundsAccess {
memory: MemoryIndex::new(0),
addr: None,
},
WasmTrapType::Unknown => RuntimeError::Unknown {
msg: "unknown error".into(),
},
})
.collect())
}
}
fn get_early_trapper(&self) -> Box<dyn UserTrapper> {

View File

@ -118,8 +118,6 @@ pub fn parse_function_bodies(
})?;
}
module.print_to_stderr();
generate_trampolines(info, &signatures, &module, &context, &builder, &intrinsics);
let pass_manager = PassManager::create_for_module();

View File

@ -46,7 +46,7 @@ extern "C" {
pub unsafe fn install_signal_handler() {
let sa = SigAction::new(
SigHandler::SigAction(signal_trap_handler),
SaFlags::SA_ONSTACK,
SaFlags::SA_ONSTACK | SaFlags::SA_SIGINFO,
SigSet::empty(),
);
sigaction(SIGFPE, &sa).unwrap();