mirror of
https://github.com/wez/wezterm.git
synced 2024-09-20 11:17:15 +03:00
macos: workaround UB and undefined instruction issue
The compiler emitted `ud2` right around this code, effectively breaking wezterm on startup. In talking this through with @dtolnay, the definition of the structs in the core_foundation crate makes it undefined behavior to pass a null pointer to its fields, despite that being a valid and documented way to use the struct. This commit works around this by defining our own local versions of the types and functions with the safe signature. I'll follow up with the owners of the core_foundation crate to submit an equivalent patch upstream.
This commit is contained in:
parent
7323e30be7
commit
398f333c32
@ -69,6 +69,45 @@ impl Connection {
|
||||
}
|
||||
}
|
||||
|
||||
/* Begin: workaround UB in CFRunLoopTimerContext struct.
|
||||
* This can be removed once an equivalent change is upstreamed to the
|
||||
* core_foundation crate */
|
||||
|
||||
use core_foundation::string::__CFString;
|
||||
use std::ffi::c_void;
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct __CFRunLoopTimer(c_void);
|
||||
|
||||
#[repr(C)]
|
||||
#[allow(non_snake_case)]
|
||||
pub struct CFRunLoopTimerContext {
|
||||
pub version: i64,
|
||||
pub info: *mut c_void,
|
||||
pub retain: Option<extern "C" fn(*const c_void) -> *const c_void>,
|
||||
pub release: Option<extern "C" fn(*const c_void)>,
|
||||
pub copyDescription: Option<extern "C" fn(*const c_void) -> *const __CFString>,
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
fn CFRunLoopTimerCreate(
|
||||
allocator: *const c_void,
|
||||
fireDate: f64,
|
||||
interval: f64,
|
||||
flags: u32,
|
||||
order: i64,
|
||||
callout: extern "C" fn(*mut __CFRunLoopTimer, *mut c_void),
|
||||
context: *mut CFRunLoopTimerContext,
|
||||
) -> *mut __CFRunLoopTimer;
|
||||
fn CFRunLoopAddTimer(
|
||||
rl: *mut __CFRunLoop,
|
||||
timer: *mut __CFRunLoopTimer,
|
||||
mode: *const __CFString,
|
||||
);
|
||||
}
|
||||
|
||||
/* End: UB workaround */
|
||||
|
||||
impl ConnectionOps for Connection {
|
||||
fn terminate_message_loop(&self) {
|
||||
unsafe {
|
||||
@ -103,7 +142,7 @@ impl ConnectionOps for Connection {
|
||||
let callback = Box::into_raw(Box::new(callback));
|
||||
|
||||
extern "C" fn timer_callback<F: FnMut()>(
|
||||
_timer_ref: CFRunLoopTimerRef,
|
||||
_timer_ref: *mut __CFRunLoopTimer,
|
||||
callback_ptr: *mut std::ffi::c_void,
|
||||
) {
|
||||
unsafe {
|
||||
@ -126,10 +165,10 @@ impl ConnectionOps for Connection {
|
||||
0,
|
||||
timer_callback::<F>,
|
||||
&mut CFRunLoopTimerContext {
|
||||
copyDescription: std::mem::MaybeUninit::zeroed().assume_init(),
|
||||
copyDescription: None,
|
||||
info: callback as _,
|
||||
release: release_callback::<F>,
|
||||
retain: std::mem::MaybeUninit::zeroed().assume_init(),
|
||||
release: Some(release_callback::<F>),
|
||||
retain: None,
|
||||
version: 0,
|
||||
},
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user