|
| 1 | +use core::hint; |
1 | 2 | use core::mem;
|
2 | 3 |
|
3 | 4 | use super::conditional_try;
|
4 | 5 | use crate::ffi;
|
5 |
| -use crate::runtime::{Class, Object, Sel}; |
| 6 | +use crate::runtime::{Class, Imp, Object, Sel}; |
6 | 7 | use crate::{Encode, MessageArguments};
|
7 | 8 |
|
| 9 | +#[inline] |
| 10 | +fn unwrap_msg_send_fn(msg_send_fn: Option<Imp>) -> Imp { |
| 11 | + match msg_send_fn { |
| 12 | + Some(msg_send_fn) => msg_send_fn, |
| 13 | + None => { |
| 14 | + // SAFETY: This will never be NULL, even if the selector is not |
| 15 | + // found a callable function pointer will still be returned! |
| 16 | + // |
| 17 | + // `clang` doesn't insert a NULL check here either. |
| 18 | + unsafe { hint::unreachable_unchecked() } |
| 19 | + } |
| 20 | + } |
| 21 | +} |
| 22 | + |
8 | 23 | #[track_caller]
|
9 | 24 | pub(crate) unsafe fn send_unverified<A, R>(receiver: *mut Object, sel: Sel, args: A) -> R
|
10 | 25 | where
|
|
22 | 37 | }
|
23 | 38 |
|
24 | 39 | let msg_send_fn = unsafe { ffi::objc_msg_lookup(receiver.cast(), sel.as_ptr()) };
|
25 |
| - let msg_send_fn = msg_send_fn.expect("Null IMP"); |
| 40 | + let msg_send_fn = unwrap_msg_send_fn(msg_send_fn); |
26 | 41 | unsafe { conditional_try(|| A::__invoke(msg_send_fn, receiver, sel, args)) }
|
27 | 42 | }
|
28 | 43 |
|
|
48 | 63 | super_class: superclass.cast(),
|
49 | 64 | };
|
50 | 65 | let msg_send_fn = unsafe { ffi::objc_msg_lookup_super(&sup, sel.as_ptr()) };
|
51 |
| - let msg_send_fn = msg_send_fn.expect("Null IMP"); |
| 66 | + let msg_send_fn = unwrap_msg_send_fn(msg_send_fn); |
52 | 67 | unsafe { conditional_try(|| A::__invoke(msg_send_fn, receiver, sel, args)) }
|
53 | 68 | }
|
0 commit comments