Skip to content

Commit

Permalink
Make objc_sys::IMP nullable
Browse files Browse the repository at this point in the history
Probably all of the underlying APIs can handle NULL values, so not having this possibility is restricting.

And most of them can sometimes _return_ a NULL value, so not handling that is unsound!
  • Loading branch information
madsmtm committed Sep 5, 2021
1 parent 98ae6d3 commit a275174
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 12 deletions.
16 changes: 12 additions & 4 deletions objc/src/declare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,12 @@ impl ClassDecl {
);

let types = method_type_encoding(&F::Ret::ENCODING, encs);
let success =
runtime::class_addMethod(self.cls as _, sel.as_ptr() as _, func.imp(), types.as_ptr());
let success = runtime::class_addMethod(
self.cls as _,
sel.as_ptr() as _,
Some(func.imp()),
types.as_ptr(),
);
assert!(success != NO, "Failed to add method {:?}", sel);
}

Expand Down Expand Up @@ -213,8 +217,12 @@ impl ClassDecl {

let types = method_type_encoding(&F::Ret::ENCODING, encs);
let metaclass = (*self.cls).metaclass() as *const _ as *mut _;
let success =
runtime::class_addMethod(metaclass, sel.as_ptr() as _, func.imp(), types.as_ptr());
let success = runtime::class_addMethod(
metaclass,
sel.as_ptr() as _,
Some(func.imp()),
types.as_ptr(),
);
assert!(success != NO, "Failed to add class method {:?}", sel);
}

Expand Down
4 changes: 2 additions & 2 deletions objc/src/message/gnustep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ where

let receiver = obj as *mut T as *mut Object;
let msg_send_fn = objc_msg_lookup(receiver as *mut _, sel.as_ptr() as *const _);
objc_try!({ A::invoke(msg_send_fn, receiver, sel, args) })
objc_try!({ A::invoke(msg_send_fn.expect("Null IMP"), receiver, sel, args) })
}

pub unsafe fn send_super_unverified<T, A, R>(
Expand All @@ -36,5 +36,5 @@ where
super_class: superclass as *const Class as *const _,
};
let msg_send_fn = objc_msg_lookup_super(&sup, sel.as_ptr() as *const _);
objc_try!({ A::invoke(msg_send_fn, receiver, sel, args) })
objc_try!({ A::invoke(msg_send_fn.expect("Null IMP"), receiver, sel, args) })
}
4 changes: 2 additions & 2 deletions objc/src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ pub struct Protocol(objc_sys::Protocol);
pub struct Object(objc_sys::objc_object);

/// A pointer to the start of a method implementation.
pub type Imp = objc_sys::IMP;
pub type Imp = unsafe extern "C" fn();

impl Sel {
/// Registers a method with the Objective-C runtime system,
Expand Down Expand Up @@ -189,7 +189,7 @@ impl Method {

/// Returns the implementation of self.
pub fn implementation(&self) -> Imp {
unsafe { method_getImplementation(self.as_ptr()) }
unsafe { method_getImplementation(self.as_ptr()).expect("Null IMP") }
}
}

Expand Down
2 changes: 1 addition & 1 deletion objc_sys/src/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ extern "C" {
name: *const objc_selector,
imp: IMP,
types: *const c_char,
) -> Option<IMP>;
) -> IMP;
pub fn class_replaceProperty(
cls: *mut objc_class,
name: *const c_char,
Expand Down
6 changes: 3 additions & 3 deletions objc_sys/src/various.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ pub struct objc_ivar {
_p: OpaqueData,
}

/// A pointer to the start of a method implementation.
/// A nullable pointer to the start of a method implementation.
///
/// This must be non-null. Use `Option<IMP>` when nullability is desired.
pub type IMP = unsafe extern "C" fn();
/// Not all APIs are guaranteed to take NULL values; read the docs!
pub type IMP = Option<unsafe extern "C" fn()>;

/// Not available on macOS x86.
///
Expand Down

0 comments on commit a275174

Please sign in to comment.