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