wasmtime/runtime/vm/sys/unix/
traphandlers.rs

1#[cfg(has_host_compiler_backend)]
2use crate::vm::VMContext;
3#[cfg(has_host_compiler_backend)]
4use core::ptr::NonNull;
5
6#[cfg(has_host_compiler_backend)]
7#[link(name = "wasmtime-helpers")]
8unsafe extern "C" {
9    #[wasmtime_versioned_export_macros::versioned_link]
10    #[allow(improper_ctypes)]
11    pub fn wasmtime_setjmp(
12        jmp_buf: *mut *const u8,
13        callback: extern "C" fn(*mut u8, NonNull<VMContext>) -> bool,
14        payload: *mut u8,
15        callee: NonNull<VMContext>,
16    ) -> bool;
17
18    #[wasmtime_versioned_export_macros::versioned_link]
19    pub fn wasmtime_longjmp(jmp_buf: *const u8) -> !;
20}
21
22cfg_if::cfg_if! {
23    if #[cfg(not(has_native_signals))] {
24        // If signals-based traps are disabled statically then there's no
25        // platform signal handler and no per-thread init, so stub these both
26        // out.
27        pub enum SignalHandler {}
28
29        #[inline]
30        pub fn lazy_per_thread_init() {}
31    } else if #[cfg(target_vendor = "apple")] {
32        // On macOS a dynamic decision is made to use mach ports or signals at
33        // process initialization time.
34
35        /// Whether or not macOS is using mach ports.
36        static mut USE_MACH_PORTS: bool = false;
37
38        pub use super::signals::SignalHandler;
39
40        pub enum TrapHandler {
41            Signals(super::signals::TrapHandler),
42            #[allow(dead_code)] // used for its drop
43            MachPorts(super::machports::TrapHandler),
44        }
45
46        impl TrapHandler {
47            pub unsafe fn new(macos_use_mach_ports: bool) -> TrapHandler {
48                USE_MACH_PORTS = macos_use_mach_ports;
49                if macos_use_mach_ports {
50                    TrapHandler::MachPorts(super::machports::TrapHandler::new())
51                } else {
52                    TrapHandler::Signals(super::signals::TrapHandler::new(false))
53                }
54            }
55
56            pub fn validate_config(&self, macos_use_mach_ports: bool) {
57                match self {
58                    TrapHandler::Signals(t) => t.validate_config(macos_use_mach_ports),
59                    TrapHandler::MachPorts(_) => assert!(macos_use_mach_ports),
60                }
61            }
62        }
63
64        pub fn lazy_per_thread_init() {
65            unsafe {
66                if USE_MACH_PORTS {
67                    super::machports::lazy_per_thread_init();
68                } else {
69                    super::signals::lazy_per_thread_init();
70                }
71            }
72        }
73    } else {
74        // Otherwise unix platforms use the signals-based implementation of
75        // these functions.
76        pub use super::signals::{TrapHandler, SignalHandler, lazy_per_thread_init};
77    }
78}