1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
//! Defined in:
//! Apple: `objc-exception.h`
//! GNUStep: `eh_personality.c`, which is a bit brittle to rely on, but I
//!   think it's fine...
use core::ffi::c_void;
#[cfg(any(apple, gnustep, winobjc))]
use std::os::raw::c_int;

#[cfg(apple)]
use crate::objc_class;
use crate::objc_object;

/// Remember that this is non-null!
#[cfg(apple)]
pub type objc_exception_matcher =
    unsafe extern "C" fn(catch_type: *mut objc_class, exception: *mut objc_object) -> c_int;

/// Remember that this is non-null!
#[cfg(apple)]
pub type objc_exception_preprocessor =
    unsafe extern "C" fn(exception: *mut objc_object) -> *mut objc_object;

/// Remember that this is non-null!
#[cfg(apple)]
pub type objc_uncaught_exception_handler = unsafe extern "C" fn(exception: *mut objc_object);

/// Only available on macOS.
///
/// Remember that this is non-null!
#[cfg(all(apple, target_os = "macos"))]
pub type objc_exception_handler =
    unsafe extern "C" fn(unused: *mut objc_object, context: *mut c_void);

extern "C" {
    pub fn objc_begin_catch(exc_buf: *mut c_void) -> *mut objc_object;
    pub fn objc_end_catch();
    /// See [`objc-exception.h`][objc-exception].
    ///
    /// [objc-exception]: https://opensource.apple.com/source/objc4/objc4-818.2/runtime/objc-exception.h.auto.html
    pub fn objc_exception_throw(exception: *mut objc_object) -> !;
    #[cfg(apple)]
    pub fn objc_exception_rethrow() -> !;
    #[cfg(any(gnustep, winobjc))]
    pub fn objc_exception_rethrow(exc_buf: *mut c_void) -> !;

    #[cfg(apple)]
    pub fn objc_setExceptionMatcher(f: objc_exception_matcher) -> objc_exception_matcher;
    #[cfg(apple)]
    pub fn objc_setExceptionPreprocessor(
        f: objc_exception_preprocessor,
    ) -> objc_exception_preprocessor;
    #[cfg(apple)]
    pub fn objc_setUncaughtExceptionHandler(
        f: objc_uncaught_exception_handler,
    ) -> objc_uncaught_exception_handler;

    /// Only available on macOS.
    #[cfg(all(apple, target_os = "macos"))]
    pub fn objc_addExceptionHandler(f: objc_exception_handler, context: *mut c_void) -> usize;
    /// Only available on macOS.
    #[cfg(all(apple, target_os = "macos"))]
    pub fn objc_removeExceptionHandler(token: usize);

    #[cfg(any(gnustep, winobjc))]
    pub fn objc_set_apple_compatible_objcxx_exceptions(newValue: c_int) -> c_int;
}