From 449821c7cb9c5445e9e6b77ed5fd3db509459739 Mon Sep 17 00:00:00 2001 From: Nick Lewycky Date: Mon, 9 Dec 2019 18:22:30 -0800 Subject: [PATCH] For error handling and breakpoints, use Box instead of Box. --- lib/clif-backend/src/signal/mod.rs | 8 +- lib/llvm-backend/src/backend.rs | 4 +- lib/llvm-backend/src/code.rs | 3 +- lib/runtime-core/src/backend.rs | 2 +- lib/runtime-core/src/codegen.rs | 2 +- lib/runtime-core/src/error.rs | 2 +- lib/runtime-core/src/fault.rs | 23 +++--- lib/runtime-core/src/state.rs | 2 +- lib/runtime-core/src/typed_func.rs | 10 +-- lib/runtime-core/src/vm.rs | 2 +- lib/singlepass-backend/src/codegen_x64.rs | 6 +- lib/singlepass-backend/src/emitter_x64.rs | 88 ++++++++++++++++------ lib/singlepass-backend/src/protect_unix.rs | 6 +- 13 files changed, 102 insertions(+), 56 deletions(-) diff --git a/lib/clif-backend/src/signal/mod.rs b/lib/clif-backend/src/signal/mod.rs index 116da3f56ef..5526cc4e215 100644 --- a/lib/clif-backend/src/signal/mod.rs +++ b/lib/clif-backend/src/signal/mod.rs @@ -26,12 +26,12 @@ pub use self::unix::*; pub use self::windows::*; thread_local! { - pub static TRAP_EARLY_DATA: Cell>> = Cell::new(None); + pub static TRAP_EARLY_DATA: Cell>> = Cell::new(None); } pub enum CallProtError { Trap(WasmTrapInfo), - Error(Box), + Error(Box), } pub struct Caller { @@ -67,7 +67,7 @@ impl RunnableModule for Caller { args: *const u64, rets: *mut u64, trap_info: *mut WasmTrapInfo, - user_error: *mut Option>, + user_error: *mut Option>, invoke_env: Option>, ) -> bool { let handler_data = &*invoke_env.unwrap().cast().as_ptr(); @@ -108,7 +108,7 @@ impl RunnableModule for Caller { }) } - unsafe fn do_early_trap(&self, data: Box) -> ! { + unsafe fn do_early_trap(&self, data: Box) -> ! { TRAP_EARLY_DATA.with(|cell| cell.set(Some(data))); trigger_trap() } diff --git a/lib/llvm-backend/src/backend.rs b/lib/llvm-backend/src/backend.rs index 468c3fc7c72..05831733ffa 100644 --- a/lib/llvm-backend/src/backend.rs +++ b/lib/llvm-backend/src/backend.rs @@ -66,7 +66,7 @@ extern "C" { params: *const u64, results: *mut u64, trap_out: *mut WasmTrapInfo, - user_error: *mut Option>, + user_error: *mut Option>, invoke_env: Option>, ) -> bool; } @@ -427,7 +427,7 @@ impl RunnableModule for LLVMBackend { self.msm.clone() } - unsafe fn do_early_trap(&self, data: Box) -> ! { + unsafe fn do_early_trap(&self, data: Box) -> ! { throw_any(Box::leak(data)) } } diff --git a/lib/llvm-backend/src/code.rs b/lib/llvm-backend/src/code.rs index 4365dbf3326..f2d52349296 100644 --- a/lib/llvm-backend/src/code.rs +++ b/lib/llvm-backend/src/code.rs @@ -856,7 +856,8 @@ pub unsafe extern "C" fn callback_trampoline( callback: *mut BreakpointHandler, ) { let callback = Box::from_raw(callback); - let result: Result<(), Box> = callback(BreakpointInfo { fault: None }); + let result: Result<(), Box> = + callback(BreakpointInfo { fault: None }); match result { Ok(()) => *b = None, Err(e) => *b = Some(e), diff --git a/lib/runtime-core/src/backend.rs b/lib/runtime-core/src/backend.rs index f41d2b30048..a1647817660 100644 --- a/lib/runtime-core/src/backend.rs +++ b/lib/runtime-core/src/backend.rs @@ -271,7 +271,7 @@ pub trait RunnableModule: Send + Sync { /// signature and an invoke function that can call the trampoline. fn get_trampoline(&self, info: &ModuleInfo, sig_index: SigIndex) -> Option; - unsafe fn do_early_trap(&self, data: Box) -> !; + unsafe fn do_early_trap(&self, data: Box) -> !; /// Returns the machine code associated with this module. fn get_code(&self) -> Option<&[u8]> { diff --git a/lib/runtime-core/src/codegen.rs b/lib/runtime-core/src/codegen.rs index a3ed432e846..bf8c5868265 100644 --- a/lib/runtime-core/src/codegen.rs +++ b/lib/runtime-core/src/codegen.rs @@ -23,7 +23,7 @@ use wasmparser::{Operator, Type as WpType}; /// A type that defines a function pointer, which is called when breakpoints occur. pub type BreakpointHandler = - Box Result<(), Box> + Send + Sync + 'static>; + Box Result<(), Box> + Send + Sync + 'static>; /// Maps instruction pointers to their breakpoint handlers. pub type BreakpointMap = Arc>; diff --git a/lib/runtime-core/src/error.rs b/lib/runtime-core/src/error.rs index f2fcf7ebd32..391386e3b4f 100644 --- a/lib/runtime-core/src/error.rs +++ b/lib/runtime-core/src/error.rs @@ -187,7 +187,7 @@ pub enum RuntimeError { /// Error. Error { /// Error data. - data: Box, + data: Box, }, } diff --git a/lib/runtime-core/src/fault.rs b/lib/runtime-core/src/fault.rs index bc64c15fa52..89d5b800ea7 100644 --- a/lib/runtime-core/src/fault.rs +++ b/lib/runtime-core/src/fault.rs @@ -61,7 +61,7 @@ type SetJmpBuffer = [i32; SETJMP_BUFFER_LEN]; struct UnwindInfo { jmpbuf: SetJmpBuffer, // in breakpoints: Option, - payload: Option>, // out + payload: Option>, // 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: F, breakpoints: Option, -) -> Result> { +) -> Result> { 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>( } /// Begins an unsafe unwind. -pub unsafe fn begin_unsafe_unwind(e: Box) -> ! { +pub unsafe fn begin_unsafe_unwind(e: Box) -> ! { let unwind = UNWIND.with(|x| x.get()); let inner = (*unwind) .as_mut() @@ -283,7 +283,7 @@ extern "C" fn signal_trap_handler( static ARCH: Architecture = Architecture::Aarch64; let mut should_unwind = false; - let mut unwind_result: Box = Box::new(()); + let mut unwind_result: Box = Box::new(()); unsafe { let fault = get_fault_info(siginfo as _, ucontext); @@ -307,7 +307,7 @@ extern "C" fn signal_trap_handler( match ib.ty { InlineBreakpointType::Trace => {} InlineBreakpointType::Middleware => { - let out: Option>> = + let out: Option>> = with_breakpoint_map(|bkpt_map| { bkpt_map.and_then(|x| x.get(&ip)).map(|x| { x(BreakpointInfo { @@ -348,13 +348,14 @@ extern "C" fn signal_trap_handler( match Signal::from_c_int(signum) { Ok(SIGTRAP) => { // breakpoint - let out: Option>> = with_breakpoint_map(|bkpt_map| { - bkpt_map.and_then(|x| x.get(&(fault.ip.get()))).map(|x| { - x(BreakpointInfo { - fault: Some(&fault), + let out: Option>> = + with_breakpoint_map(|bkpt_map| { + bkpt_map.and_then(|x| x.get(&(fault.ip.get()))).map(|x| { + x(BreakpointInfo { + fault: Some(&fault), + }) }) - }) - }); + }); match out { Some(Ok(())) => { return false; diff --git a/lib/runtime-core/src/state.rs b/lib/runtime-core/src/state.rs index a5a0a003647..7465f735e84 100644 --- a/lib/runtime-core/src/state.rs +++ b/lib/runtime-core/src/state.rs @@ -652,7 +652,7 @@ pub mod x64 { image: InstanceImage, vmctx: &mut Ctx, breakpoints: Option, - ) -> Result> { + ) -> Result> { let mut stack: Vec = vec![0; 1048576 * 8 / 8]; // 8MB stack let mut stack_offset: usize = stack.len(); diff --git a/lib/runtime-core/src/typed_func.rs b/lib/runtime-core/src/typed_func.rs index f1e62c23815..82b49b33cc3 100644 --- a/lib/runtime-core/src/typed_func.rs +++ b/lib/runtime-core/src/typed_func.rs @@ -78,7 +78,7 @@ pub type Invoke = unsafe extern "C" fn( args: *const u64, rets: *mut u64, trap_info: *mut WasmTrapInfo, - user_error: *mut Option>, + user_error: *mut Option>, extra: Option>, ) -> bool; @@ -201,7 +201,7 @@ where Rets: WasmTypeList, { /// The error type for this trait. - type Error: 'static; + type Error: Send + 'static; /// Get returns or error result. fn report(self) -> Result; } @@ -219,7 +219,7 @@ where impl TrapEarly for Result where Rets: WasmTypeList, - E: 'static, + E: Send + 'static, { type Error = E; fn report(self) -> Result { @@ -507,7 +507,7 @@ macro_rules! impl_traits { Ok(Ok(returns)) => return returns.into_c_struct(), Ok(Err(err)) => { let b: Box<_> = err.into(); - b as Box + b as Box }, Err(err) => err, }; @@ -619,7 +619,7 @@ macro_rules! impl_traits { Ok(Ok(returns)) => return returns.into_c_struct(), Ok(Err(err)) => { let b: Box<_> = err.into(); - b as Box + b as Box }, Err(err) => err, }; diff --git a/lib/runtime-core/src/vm.rs b/lib/runtime-core/src/vm.rs index a976336a678..352836ebff2 100644 --- a/lib/runtime-core/src/vm.rs +++ b/lib/runtime-core/src/vm.rs @@ -1069,7 +1069,7 @@ mod vm_ctx_tests { fn get_trampoline(&self, _module: &ModuleInfo, _sig_index: SigIndex) -> Option { unimplemented!("generate_module::get_trampoline") } - unsafe fn do_early_trap(&self, _: Box) -> ! { + unsafe fn do_early_trap(&self, _: Box) -> ! { unimplemented!("generate_module::do_early_trap") } } diff --git a/lib/singlepass-backend/src/codegen_x64.rs b/lib/singlepass-backend/src/codegen_x64.rs index eee81e3b573..1f1d3d4862f 100644 --- a/lib/singlepass-backend/src/codegen_x64.rs +++ b/lib/singlepass-backend/src/codegen_x64.rs @@ -206,7 +206,7 @@ pub struct X64FunctionCode { breakpoints: Option< HashMap< AssemblyOffset, - Box Result<(), Box> + Send + Sync + 'static>, + Box Result<(), Box> + Send + Sync + 'static>, >, >, returns: SmallVec<[WpType; 1]>, @@ -359,7 +359,7 @@ impl RunnableModule for X64ExecutionContext { args: *const u64, rets: *mut u64, trap_info: *mut WasmTrapInfo, - user_error: *mut Option>, + user_error: *mut Option>, num_params_plus_one: Option>, ) -> bool { let rm: &Box = &(&*(*ctx).module).runnable_module; @@ -533,7 +533,7 @@ impl RunnableModule for X64ExecutionContext { }) } - unsafe fn do_early_trap(&self, data: Box) -> ! { + unsafe fn do_early_trap(&self, data: Box) -> ! { protect_unix::TRAP_EARLY_DATA.with(|x| x.set(Some(data))); protect_unix::trigger_trap(); } diff --git a/lib/singlepass-backend/src/emitter_x64.rs b/lib/singlepass-backend/src/emitter_x64.rs index 0bf6fc2b079..fb727d8156d 100644 --- a/lib/singlepass-backend/src/emitter_x64.rs +++ b/lib/singlepass-backend/src/emitter_x64.rs @@ -816,14 +816,18 @@ impl Emitter for Assembler { match (sz, src) { (Size::S64, Location::Imm32(src)) => dynasm!(self ; push src as i32), (Size::S64, Location::GPR(src)) => dynasm!(self ; push Rq(src as u8)), - (Size::S64, Location::Memory(src, disp)) => dynasm!(self ; push QWORD [Rq(src as u8) + disp]), + (Size::S64, Location::Memory(src, disp)) => { + dynasm!(self ; push QWORD [Rq(src as u8) + disp]) + } _ => panic!("singlepass can't emit PUSH {:?} {:?}", sz, src), } } fn emit_pop(&mut self, sz: Size, dst: Location) { match (sz, dst) { (Size::S64, Location::GPR(dst)) => dynasm!(self ; pop Rq(dst as u8)), - (Size::S64, Location::Memory(dst, disp)) => dynasm!(self ; pop QWORD [Rq(dst as u8) + disp]), + (Size::S64, Location::Memory(dst, disp)) => { + dynasm!(self ; pop QWORD [Rq(dst as u8) + disp]) + } _ => panic!("singlepass can't emit POP {:?} {:?}", sz, dst), } } @@ -845,13 +849,21 @@ impl Emitter for Assembler { fn emit_neg(&mut self, sz: Size, value: Location) { match (sz, value) { (Size::S8, Location::GPR(value)) => dynasm!(self ; neg Rb(value as u8)), - (Size::S8, Location::Memory(value, disp)) => dynasm!(self ; neg [Rq(value as u8) + disp]), + (Size::S8, Location::Memory(value, disp)) => { + dynasm!(self ; neg [Rq(value as u8) + disp]) + } (Size::S16, Location::GPR(value)) => dynasm!(self ; neg Rw(value as u8)), - (Size::S16, Location::Memory(value, disp)) => dynasm!(self ; neg [Rq(value as u8) + disp]), + (Size::S16, Location::Memory(value, disp)) => { + dynasm!(self ; neg [Rq(value as u8) + disp]) + } (Size::S32, Location::GPR(value)) => dynasm!(self ; neg Rd(value as u8)), - (Size::S32, Location::Memory(value, disp)) => dynasm!(self ; neg [Rq(value as u8) + disp]), + (Size::S32, Location::Memory(value, disp)) => { + dynasm!(self ; neg [Rq(value as u8) + disp]) + } (Size::S64, Location::GPR(value)) => dynasm!(self ; neg Rq(value as u8)), - (Size::S64, Location::Memory(value, disp)) => dynasm!(self ; neg [Rq(value as u8) + disp]), + (Size::S64, Location::Memory(value, disp)) => { + dynasm!(self ; neg [Rq(value as u8) + disp]) + } _ => panic!("singlepass can't emit NEG {:?} {:?}", sz, value), } } @@ -1104,18 +1116,30 @@ impl Emitter for Assembler { fn emit_vmovaps(&mut self, src: XMMOrMemory, dst: XMMOrMemory) { match (src, dst) { - (XMMOrMemory::XMM(src), XMMOrMemory::XMM(dst)) => dynasm!(self ; movaps Rx(dst as u8), Rx(src as u8)), - (XMMOrMemory::Memory(base, disp), XMMOrMemory::XMM(dst)) => dynasm!(self ; movaps Rx(dst as u8), [Rq(base as u8) + disp]), - (XMMOrMemory::XMM(src), XMMOrMemory::Memory(base, disp)) => dynasm!(self ; movaps [Rq(base as u8) + disp], Rx(src as u8)), + (XMMOrMemory::XMM(src), XMMOrMemory::XMM(dst)) => { + dynasm!(self ; movaps Rx(dst as u8), Rx(src as u8)) + } + (XMMOrMemory::Memory(base, disp), XMMOrMemory::XMM(dst)) => { + dynasm!(self ; movaps Rx(dst as u8), [Rq(base as u8) + disp]) + } + (XMMOrMemory::XMM(src), XMMOrMemory::Memory(base, disp)) => { + dynasm!(self ; movaps [Rq(base as u8) + disp], Rx(src as u8)) + } _ => panic!("singlepass can't emit VMOVAPS {:?} {:?}", src, dst), }; } fn emit_vmovapd(&mut self, src: XMMOrMemory, dst: XMMOrMemory) { match (src, dst) { - (XMMOrMemory::XMM(src), XMMOrMemory::XMM(dst)) => dynasm!(self ; movapd Rx(dst as u8), Rx(src as u8)), - (XMMOrMemory::Memory(base, disp), XMMOrMemory::XMM(dst)) => dynasm!(self ; movapd Rx(dst as u8), [Rq(base as u8) + disp]), - (XMMOrMemory::XMM(src), XMMOrMemory::Memory(base, disp)) => dynasm!(self ; movapd [Rq(base as u8) + disp], Rx(src as u8)), + (XMMOrMemory::XMM(src), XMMOrMemory::XMM(dst)) => { + dynasm!(self ; movapd Rx(dst as u8), Rx(src as u8)) + } + (XMMOrMemory::Memory(base, disp), XMMOrMemory::XMM(dst)) => { + dynasm!(self ; movapd Rx(dst as u8), [Rq(base as u8) + disp]) + } + (XMMOrMemory::XMM(src), XMMOrMemory::Memory(base, disp)) => { + dynasm!(self ; movapd [Rq(base as u8) + disp], Rx(src as u8)) + } _ => panic!("singlepass can't emit VMOVAPD {:?} {:?}", src, dst), }; } @@ -1187,57 +1211,77 @@ impl Emitter for Assembler { fn emit_vblendvps(&mut self, src1: XMM, src2: XMMOrMemory, mask: XMM, dst: XMM) { match src2 { - XMMOrMemory::XMM(src2) => dynasm!(self ; vblendvps Rx(dst as u8), Rx(mask as u8), Rx(src2 as u8), Rx(src1 as u8)), - XMMOrMemory::Memory(base, disp) => dynasm!(self ; vblendvps Rx(dst as u8), Rx(mask as u8), [Rq(base as u8) + disp], Rx(src1 as u8)), + XMMOrMemory::XMM(src2) => { + dynasm!(self ; vblendvps Rx(dst as u8), Rx(mask as u8), Rx(src2 as u8), Rx(src1 as u8)) + } + XMMOrMemory::Memory(base, disp) => { + dynasm!(self ; vblendvps Rx(dst as u8), Rx(mask as u8), [Rq(base as u8) + disp], Rx(src1 as u8)) + } } } fn emit_vblendvpd(&mut self, src1: XMM, src2: XMMOrMemory, mask: XMM, dst: XMM) { match src2 { - XMMOrMemory::XMM(src2) => dynasm!(self ; vblendvpd Rx(dst as u8), Rx(mask as u8), Rx(src2 as u8), Rx(src1 as u8)), - XMMOrMemory::Memory(base, disp) => dynasm!(self ; vblendvpd Rx(dst as u8), Rx(mask as u8), [Rq(base as u8) + disp], Rx(src1 as u8)), + XMMOrMemory::XMM(src2) => { + dynasm!(self ; vblendvpd Rx(dst as u8), Rx(mask as u8), Rx(src2 as u8), Rx(src1 as u8)) + } + XMMOrMemory::Memory(base, disp) => { + dynasm!(self ; vblendvpd Rx(dst as u8), Rx(mask as u8), [Rq(base as u8) + disp], Rx(src1 as u8)) + } } } fn emit_ucomiss(&mut self, src: XMMOrMemory, dst: XMM) { match src { XMMOrMemory::XMM(x) => dynasm!(self ; ucomiss Rx(dst as u8), Rx(x as u8)), - XMMOrMemory::Memory(base, disp) => dynasm!(self ; ucomiss Rx(dst as u8), [Rq(base as u8) + disp]), + XMMOrMemory::Memory(base, disp) => { + dynasm!(self ; ucomiss Rx(dst as u8), [Rq(base as u8) + disp]) + } } } fn emit_ucomisd(&mut self, src: XMMOrMemory, dst: XMM) { match src { XMMOrMemory::XMM(x) => dynasm!(self ; ucomisd Rx(dst as u8), Rx(x as u8)), - XMMOrMemory::Memory(base, disp) => dynasm!(self ; ucomisd Rx(dst as u8), [Rq(base as u8) + disp]), + XMMOrMemory::Memory(base, disp) => { + dynasm!(self ; ucomisd Rx(dst as u8), [Rq(base as u8) + disp]) + } } } fn emit_cvttss2si_32(&mut self, src: XMMOrMemory, dst: GPR) { match src { XMMOrMemory::XMM(x) => dynasm!(self ; cvttss2si Rd(dst as u8), Rx(x as u8)), - XMMOrMemory::Memory(base, disp) => dynasm!(self ; cvttss2si Rd(dst as u8), [Rq(base as u8) + disp]), + XMMOrMemory::Memory(base, disp) => { + dynasm!(self ; cvttss2si Rd(dst as u8), [Rq(base as u8) + disp]) + } } } fn emit_cvttss2si_64(&mut self, src: XMMOrMemory, dst: GPR) { match src { XMMOrMemory::XMM(x) => dynasm!(self ; cvttss2si Rq(dst as u8), Rx(x as u8)), - XMMOrMemory::Memory(base, disp) => dynasm!(self ; cvttss2si Rq(dst as u8), [Rq(base as u8) + disp]), + XMMOrMemory::Memory(base, disp) => { + dynasm!(self ; cvttss2si Rq(dst as u8), [Rq(base as u8) + disp]) + } } } fn emit_cvttsd2si_32(&mut self, src: XMMOrMemory, dst: GPR) { match src { XMMOrMemory::XMM(x) => dynasm!(self ; cvttsd2si Rd(dst as u8), Rx(x as u8)), - XMMOrMemory::Memory(base, disp) => dynasm!(self ; cvttsd2si Rd(dst as u8), [Rq(base as u8) + disp]), + XMMOrMemory::Memory(base, disp) => { + dynasm!(self ; cvttsd2si Rd(dst as u8), [Rq(base as u8) + disp]) + } } } fn emit_cvttsd2si_64(&mut self, src: XMMOrMemory, dst: GPR) { match src { XMMOrMemory::XMM(x) => dynasm!(self ; cvttsd2si Rq(dst as u8), Rx(x as u8)), - XMMOrMemory::Memory(base, disp) => dynasm!(self ; cvttsd2si Rq(dst as u8), [Rq(base as u8) + disp]), + XMMOrMemory::Memory(base, disp) => { + dynasm!(self ; cvttsd2si Rq(dst as u8), [Rq(base as u8) + disp]) + } } } diff --git a/lib/singlepass-backend/src/protect_unix.rs b/lib/singlepass-backend/src/protect_unix.rs index 136f9bf081a..e145d367e18 100644 --- a/lib/singlepass-backend/src/protect_unix.rs +++ b/lib/singlepass-backend/src/protect_unix.rs @@ -16,7 +16,7 @@ use wasmer_runtime_core::fault::{begin_unsafe_unwind, catch_unsafe_unwind, ensur use wasmer_runtime_core::typed_func::WasmTrapInfo; thread_local! { - pub static TRAP_EARLY_DATA: Cell>> = Cell::new(None); + pub static TRAP_EARLY_DATA: Cell>> = Cell::new(None); } pub unsafe fn trigger_trap() -> ! { @@ -25,7 +25,7 @@ pub unsafe fn trigger_trap() -> ! { pub enum CallProtError { Trap(WasmTrapInfo), - Error(Box), + Error(Box), } pub fn call_protected( @@ -48,6 +48,6 @@ pub fn call_protected( } } -pub unsafe fn throw(payload: Box) -> ! { +pub unsafe fn throw(payload: Box) -> ! { begin_unsafe_unwind(payload); }