From 0a278c55eec5dff6389a0e25fa7a37daef84d353 Mon Sep 17 00:00:00 2001
From: Nick Lewycky <nick@wasmer.io>
Date: Mon, 9 Dec 2019 18:22:30 -0800
Subject: [PATCH 1/2] For error handling and breakpoints, use Box<Any + Send>
 instead of Box<Any>.

---
 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/protect_unix.rs |  6 +++---
 12 files changed, 36 insertions(+), 34 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<Option<Box<dyn Any>>> = Cell::new(None);
+    pub static TRAP_EARLY_DATA: Cell<Option<Box<dyn Any + Send>>> = Cell::new(None);
 }
 
 pub enum CallProtError {
     Trap(WasmTrapInfo),
-    Error(Box<dyn Any>),
+    Error(Box<dyn Any + Send>),
 }
 
 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<Box<dyn Any>>,
+            user_error: *mut Option<Box<dyn Any + Send>>,
             invoke_env: Option<NonNull<c_void>>,
         ) -> 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<dyn Any>) -> ! {
+    unsafe fn do_early_trap(&self, data: Box<dyn Any + Send>) -> ! {
         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<Box<dyn Any>>,
+        user_error: *mut Option<Box<dyn Any + Send>>,
         invoke_env: Option<NonNull<c_void>>,
     ) -> bool;
 }
@@ -427,7 +427,7 @@ impl RunnableModule for LLVMBackend {
         self.msm.clone()
     }
 
-    unsafe fn do_early_trap(&self, data: Box<dyn Any>) -> ! {
+    unsafe fn do_early_trap(&self, data: Box<dyn Any + Send>) -> ! {
         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<dyn std::any::Any>> = callback(BreakpointInfo { fault: None });
+    let result: Result<(), Box<dyn std::any::Any + Send>> =
+        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<Wasm>;
 
-    unsafe fn do_early_trap(&self, data: Box<dyn Any>) -> !;
+    unsafe fn do_early_trap(&self, data: Box<dyn Any + Send>) -> !;
 
     /// 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<dyn Fn(BreakpointInfo) -> Result<(), Box<dyn Any>> + Send + Sync + 'static>;
+    Box<dyn Fn(BreakpointInfo) -> Result<(), Box<dyn Any + Send>> + Send + Sync + 'static>;
 
 /// Maps instruction pointers to their breakpoint handlers.
 pub type BreakpointMap = Arc<HashMap<usize, BreakpointHandler>>;
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<dyn Any>,
+        data: Box<dyn Any + Send>,
     },
 }
 
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<BreakpointMap>,
-    payload: Option<Box<dyn Any>>, // out
+    payload: Option<Box<dyn Any + Send>>, // 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>> {
+) -> Result<R, Box<dyn Any + Send>> {
     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>) -> ! {
+pub unsafe fn begin_unsafe_unwind(e: Box<dyn Any + Send>) -> ! {
     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<dyn Any> = Box::new(());
+    let mut unwind_result: Box<dyn Any + Send> = 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<Result<(), Box<dyn Any>>> =
+                                    let out: Option<Result<(), Box<dyn Any + Send>>> =
                                         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<Result<(), Box<dyn Any>>> = 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<Result<(), Box<dyn Any + Send>>> =
+                        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<BreakpointMap>,
-    ) -> Result<u64, Box<dyn Any>> {
+    ) -> Result<u64, Box<dyn Any + Send>> {
         let mut stack: Vec<u64> = 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<Box<dyn Any>>,
+    user_error: *mut Option<Box<dyn Any + Send>>,
     extra: Option<NonNull<c_void>>,
 ) -> 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<Rets, Self::Error>;
 }
@@ -219,7 +219,7 @@ where
 impl<Rets, E> TrapEarly<Rets> for Result<Rets, E>
 where
     Rets: WasmTypeList,
-    E: 'static,
+    E: Send + 'static,
 {
     type Error = E;
     fn report(self) -> Result<Rets, E> {
@@ -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<dyn Any>
+                            b as Box<dyn Any + Send>
                         },
                         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<dyn Any>
+                            b as Box<dyn Any + Send>
                         },
                         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<Wasm> {
                 unimplemented!("generate_module::get_trampoline")
             }
-            unsafe fn do_early_trap(&self, _: Box<dyn Any>) -> ! {
+            unsafe fn do_early_trap(&self, _: Box<dyn Any + Send>) -> ! {
                 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<dyn Fn(BreakpointInfo) -> Result<(), Box<dyn Any>> + Send + Sync + 'static>,
+            Box<dyn Fn(BreakpointInfo) -> Result<(), Box<dyn Any + Send>> + 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<Box<dyn Any>>,
+            user_error: *mut Option<Box<dyn Any + Send>>,
             num_params_plus_one: Option<NonNull<c_void>>,
         ) -> bool {
             let rm: &Box<dyn RunnableModule> = &(&*(*ctx).module).runnable_module;
@@ -533,7 +533,7 @@ impl RunnableModule for X64ExecutionContext {
         })
     }
 
-    unsafe fn do_early_trap(&self, data: Box<dyn Any>) -> ! {
+    unsafe fn do_early_trap(&self, data: Box<dyn Any + Send>) -> ! {
         protect_unix::TRAP_EARLY_DATA.with(|x| x.set(Some(data)));
         protect_unix::trigger_trap();
     }
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<Option<Box<dyn Any>>> = Cell::new(None);
+    pub static TRAP_EARLY_DATA: Cell<Option<Box<dyn Any + Send>>> = Cell::new(None);
 }
 
 pub unsafe fn trigger_trap() -> ! {
@@ -25,7 +25,7 @@ pub unsafe fn trigger_trap() -> ! {
 
 pub enum CallProtError {
     Trap(WasmTrapInfo),
-    Error(Box<dyn Any>),
+    Error(Box<dyn Any + Send>),
 }
 
 pub fn call_protected<T>(
@@ -48,6 +48,6 @@ pub fn call_protected<T>(
     }
 }
 
-pub unsafe fn throw(payload: Box<dyn Any>) -> ! {
+pub unsafe fn throw(payload: Box<dyn Any + Send>) -> ! {
     begin_unsafe_unwind(payload);
 }

From 5198c7ed502d745a65371d2474b5bd8c46f8fa58 Mon Sep 17 00:00:00 2001
From: Nick Lewycky <nick@wasmer.io>
Date: Tue, 10 Dec 2019 13:24:59 -0800
Subject: [PATCH 2/2] Add changelog entry.

---
 CHANGELOG.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index e013b0dc05b..0d693646c03 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,7 @@
 
 ## **[Unreleased]**
 
+- [#1053](https://github.com/wasmerio/wasmer/pull/1053) For RuntimeError and breakpoints, use Box<Any + Send> instead of Box<Any>.
 - [#1050](https://github.com/wasmerio/wasmer/pull/1050) Attach C & C++ headers to releases.
 - [#1033](https://github.com/wasmerio/wasmer/pull/1033) Set cranelift backend as default compiler backend again, require at least one backend to be enabled for Wasmer CLI
 - [#1030](https://github.com/wasmerio/wasmer/pull/1030) Ability to generate `ImportObject` for a specific version WASI version with the C API.