Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Actually catch traps/panics/etc when using a typed func. #338

Merged
merged 9 commits into from
Apr 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 45 additions & 5 deletions lib/clif-backend/src/signal/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ use crate::relocation::{TrapData, TrapSink};
use crate::trampoline::Trampolines;
use hashbrown::HashSet;
use libc::c_void;
use std::{any::Any, cell::Cell, sync::Arc};
use std::{any::Any, cell::Cell, ptr::NonNull, sync::Arc};
use wasmer_runtime_core::{
backend::{ProtectedCaller, Token, UserTrapper},
error::RuntimeResult,
export::Context,
module::{ExportIndex, ModuleInfo, ModuleInner},
typed_func::{Wasm, WasmTrapInfo},
types::{FuncIndex, FuncSig, LocalOrImport, SigIndex, Type, Value},
vm::{self, ImportBacking},
};
Expand Down Expand Up @@ -148,6 +149,46 @@ impl ProtectedCaller for Caller {
.collect())
}

fn get_wasm_trampoline(&self, module: &ModuleInner, sig_index: SigIndex) -> Option<Wasm> {
unsafe extern "C" fn invoke(
trampoline: unsafe extern "C" fn(*mut vm::Ctx, NonNull<vm::Func>, *const u64, *mut u64),
ctx: *mut vm::Ctx,
func: NonNull<vm::Func>,
args: *const u64,
rets: *mut u64,
trap_info: *mut WasmTrapInfo,
invoke_env: Option<NonNull<c_void>>,
) -> bool {
let handler_data = &*invoke_env.unwrap().cast().as_ptr();

#[cfg(not(target_os = "windows"))]
let res = call_protected(handler_data, || unsafe {
// Leap of faith.
trampoline(ctx, func, args, rets);
})
.is_ok();

// the trampoline is called from C on windows
#[cfg(target_os = "windows")]
let res = call_protected(handler_data, trampoline, ctx, func, args, rets).is_ok();

res
}

let trampoline = self
.trampolines
.lookup(sig_index)
.expect("that trampoline doesn't exist");

Some(unsafe {
Wasm::from_raw_parts(
trampoline,
invoke,
Some(NonNull::from(&self.handler_data).cast()),
)
})
}

fn get_early_trapper(&self) -> Box<dyn UserTrapper> {
Box::new(Trapper)
}
Expand All @@ -157,7 +198,7 @@ fn get_func_from_index<'a>(
module: &'a ModuleInner,
import_backing: &ImportBacking,
func_index: FuncIndex,
) -> (*const vm::Func, Context, &'a FuncSig, SigIndex) {
) -> (NonNull<vm::Func>, Context, &'a FuncSig, SigIndex) {
let sig_index = *module
.info
.func_assoc
Expand All @@ -170,14 +211,13 @@ fn get_func_from_index<'a>(
.func_resolver
.get(&module, local_func_index)
.expect("broken invariant, func resolver not synced with module.exports")
.cast()
.as_ptr() as *const _,
.cast(),
Context::Internal,
),
LocalOrImport::Import(imported_func_index) => {
let imported_func = import_backing.imported_func(imported_func_index);
(
imported_func.func as *const _,
NonNull::new(imported_func.func as *mut _).unwrap(),
Context::External(imported_func.vmctx),
)
}
Expand Down
4 changes: 2 additions & 2 deletions lib/clif-backend/src/signal/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::signal::HandlerData;
use crate::trampoline::Trampoline;
use std::cell::Cell;
use std::ffi::c_void;
use std::ptr;
use std::ptr::{self, NonNull};
use wasmer_runtime_core::error::{RuntimeError, RuntimeResult};
use wasmer_runtime_core::vm::Ctx;
use wasmer_runtime_core::vm::Func;
Expand All @@ -25,7 +25,7 @@ pub fn call_protected(
handler_data: &HandlerData,
trampoline: Trampoline,
ctx: *mut Ctx,
func: *const Func,
func: NonNull<Func>,
param_vec: *const u64,
return_vec: *mut u64,
) -> RuntimeResult<()> {
Expand Down
5 changes: 2 additions & 3 deletions lib/clif-backend/src/trampoline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use cranelift_codegen::{
};
use hashbrown::HashMap;
use std::ffi::c_void;
use std::{iter, mem};
use std::{iter, mem, ptr::NonNull};
use wasmer_runtime_core::{
backend::sys::{Memory, Protect},
module::{ExportIndex, ModuleInfo},
Expand All @@ -23,8 +23,7 @@ impl RelocSink for NullRelocSink {
fn reloc_jt(&mut self, _: u32, _: Reloc, _: ir::JumpTable) {}
}

pub type Trampoline =
unsafe extern "C" fn(*mut vm::Ctx, *const vm::Func, *const u64, *mut u64) -> c_void;
pub type Trampoline = unsafe extern "C" fn(*mut vm::Ctx, NonNull<vm::Func>, *const u64, *mut u64);

pub struct Trampolines {
memory: Memory,
Expand Down
5 changes: 5 additions & 0 deletions lib/dynasm-backend/src/codegen_x64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use wasmer_runtime_core::{
memory::MemoryType,
module::{ModuleInfo, ModuleInner},
structures::{Map, TypedIndex},
typed_func::Wasm,
types::{
FuncIndex, FuncSig, ImportedMemoryIndex, LocalFuncIndex, LocalGlobalIndex,
LocalMemoryIndex, LocalOrImport, MemoryIndex, SigIndex, Type, Value,
Expand Down Expand Up @@ -459,6 +460,10 @@ impl ProtectedCaller for X64ExecutionContext {
})
}

fn get_wasm_trampoline(&self, _module: &ModuleInner, _sig_index: SigIndex) -> Option<Wasm> {
unimplemented!()
}

fn get_early_trapper(&self) -> Box<dyn UserTrapper> {
pub struct Trapper;

Expand Down
7 changes: 7 additions & 0 deletions lib/emscripten/src/varargs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,11 @@ impl VarArgs {

unsafe impl WasmExternType for VarArgs {
const TYPE: Type = Type::I32;

fn to_bits(self) -> u64 {
self.pointer as u64
}
fn from_bits(n: u64) -> Self {
Self { pointer: n as u32 }
}
}
Loading