Skip to content

Commit bf75ec3

Browse files
authored
Merge pull request #38 from madsmtm/better-message
Improve message sending
2 parents 923b893 + 18b26ba commit bf75ec3

17 files changed

+324
-188
lines changed

objc2/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ let cls = class!(NSObject);
1919
unsafe {
2020
let obj: *mut Object = msg_send![cls, new];
2121
let hash: usize = msg_send![obj, hash];
22-
let is_kind: BOOL = msg_send![obj, isKindOfClass:cls];
22+
let is_kind: BOOL = msg_send![obj, isKindOfClass: cls];
2323
// Even void methods must have their return type annotated
2424
let _: () = msg_send![obj, release];
2525
}

objc2/src/declare.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ mod tests {
372372
// Registering the custom class is in test_utils
373373
let obj = test_utils::custom_object();
374374
unsafe {
375-
let _: () = msg_send![obj, setFoo:13u32];
375+
let _: () = msg_send![obj, setFoo: 13u32];
376376
let result: u32 = msg_send![obj, foo];
377377
assert!(result == 13);
378378
}

objc2/src/exception.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use core::ptr::NonNull;
22

3-
use crate::rc::Id;
3+
use crate::rc::{Id, Shared};
44
use crate::runtime::Object;
5-
use objc2_exception::{r#try, Exception};
5+
use objc2_exception::r#try;
66

77
// Comment copied from `objc2_exception`
88

@@ -21,6 +21,8 @@ use objc2_exception::{r#try, Exception};
2121
/// undefined behaviour until `C-unwind` is stabilized, see [RFC-2945].
2222
///
2323
/// [RFC-2945]: https://rust-lang.github.io/rfcs/2945-c-unwind-abi.html
24-
pub unsafe fn catch_exception<R>(closure: impl FnOnce() -> R) -> Result<R, Id<Exception>> {
25-
r#try(closure).map_err(|e| Id::new(NonNull::new(e).unwrap()))
24+
pub unsafe fn catch_exception<R>(
25+
closure: impl FnOnce() -> R,
26+
) -> Result<R, Option<Id<Object, Shared>>> {
27+
r#try(closure).map_err(|e| NonNull::new(e).map(|e| Id::new(e.cast())))
2628
}

objc2/src/lib.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Objective-C objects can be messaged using the [`msg_send!`](macro.msg_send!.html
1212
let cls = class!(NSObject);
1313
let obj: *mut Object = msg_send![cls, new];
1414
let hash: usize = msg_send![obj, hash];
15-
let is_kind: BOOL = msg_send![obj, isKindOfClass:cls];
15+
let is_kind: BOOL = msg_send![obj, isKindOfClass: cls];
1616
// Even void methods must have their return type annotated
1717
let _: () = msg_send![obj, release];
1818
# }
@@ -81,12 +81,10 @@ extern "C" {}
8181

8282
pub use objc2_encode::{Encode, EncodeArguments, Encoding, RefEncode};
8383

84-
pub use crate::message::{Message, MessageArguments, MessageError};
84+
pub use crate::message::{Message, MessageArguments, MessageError, MessageReceiver};
8585

8686
pub use crate::cache::CachedClass as __CachedClass;
8787
pub use crate::cache::CachedSel as __CachedSel;
88-
pub use crate::message::send_message as __send_message;
89-
pub use crate::message::send_super_message as __send_super_message;
9088

9189
#[macro_use]
9290
mod macros;

objc2/src/macros.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,9 @@ method's argument's encoding does not match the encoding of the given arguments.
9393
let obj: *mut Object;
9494
# let obj: *mut Object = 0 as *mut Object;
9595
let description: *const Object = msg_send![obj, description];
96-
let _: () = msg_send![obj, setArg1:1 arg2:2];
96+
let _: () = msg_send![obj, setArg1: 1 arg2: 2];
97+
// Or with an optional comma between arguments:
98+
let _: () = msg_send![obj, setArg1: 1, arg2: 2];
9799
# }
98100
```
99101
*/
@@ -102,16 +104,16 @@ macro_rules! msg_send {
102104
(super($obj:expr, $superclass:expr), $name:ident) => ({
103105
let sel = $crate::sel!($name);
104106
let result;
105-
match $crate::__send_super_message(&*$obj, $superclass, sel, ()) {
107+
match $crate::MessageReceiver::send_super_message(&$obj, $superclass, sel, ()) {
106108
Err(s) => panic!("{}", s),
107109
Ok(r) => result = r,
108110
}
109111
result
110112
});
111-
(super($obj:expr, $superclass:expr), $($name:ident : $arg:expr)+) => ({
113+
(super($obj:expr, $superclass:expr), $($name:ident : $arg:expr $(,)?)+) => ({
112114
let sel = $crate::sel!($($name:)+);
113115
let result;
114-
match $crate::__send_super_message(&*$obj, $superclass, sel, ($($arg,)*)) {
116+
match $crate::MessageReceiver::send_super_message(&$obj, $superclass, sel, ($($arg,)+)) {
115117
Err(s) => panic!("{}", s),
116118
Ok(r) => result = r,
117119
}
@@ -120,16 +122,16 @@ macro_rules! msg_send {
120122
($obj:expr, $name:ident) => ({
121123
let sel = $crate::sel!($name);
122124
let result;
123-
match $crate::__send_message(&*$obj, sel, ()) {
125+
match $crate::MessageReceiver::send_message(&$obj, sel, ()) {
124126
Err(s) => panic!("{}", s),
125127
Ok(r) => result = r,
126128
}
127129
result
128130
});
129-
($obj:expr, $($name:ident : $arg:expr)+) => ({
131+
($obj:expr, $($name:ident : $arg:expr $(,)?)+) => ({
130132
let sel = $crate::sel!($($name:)+);
131133
let result;
132-
match $crate::__send_message(&*$obj, sel, ($($arg,)*)) {
134+
match $crate::MessageReceiver::send_message(&$obj, sel, ($($arg,)+)) {
133135
Err(s) => panic!("{}", s),
134136
Ok(r) => result = r,
135137
}

objc2/src/message/apple/mod.rs

+13-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use objc2_sys::objc_super;
22

3-
use super::{Encode, Message, MessageArguments, MessageError};
3+
use super::{conditional_try, Encode, MessageArguments, MessageError};
44
use crate::runtime::{Class, Imp, Object, Sel};
55

66
#[cfg(target_arch = "x86")]
@@ -23,33 +23,36 @@ trait MsgSendFn: Encode {
2323
const MSG_SEND_SUPER: Imp;
2424
}
2525

26-
pub unsafe fn send_unverified<T, A, R>(obj: *const T, sel: Sel, args: A) -> Result<R, MessageError>
26+
#[inline(always)]
27+
pub unsafe fn send_unverified<A, R>(
28+
receiver: *mut Object,
29+
sel: Sel,
30+
args: A,
31+
) -> Result<R, MessageError>
2732
where
28-
T: Message,
2933
A: MessageArguments,
3034
R: Encode,
3135
{
32-
let receiver = obj as *mut T as *mut Object;
3336
let msg_send_fn = R::MSG_SEND;
34-
objc_try!({ A::invoke(msg_send_fn, receiver, sel, args) })
37+
conditional_try(|| A::invoke(msg_send_fn, receiver, sel, args))
3538
}
3639

37-
pub unsafe fn send_super_unverified<T, A, R>(
38-
obj: *const T,
40+
#[inline]
41+
pub unsafe fn send_super_unverified<A, R>(
42+
receiver: *mut Object,
3943
superclass: &Class,
4044
sel: Sel,
4145
args: A,
4246
) -> Result<R, MessageError>
4347
where
44-
T: Message,
4548
A: MessageArguments,
4649
R: Encode,
4750
{
4851
let sup = objc_super {
49-
receiver: obj as *mut T as *mut Object as *mut _,
52+
receiver: receiver as *mut _,
5053
super_class: superclass as *const Class as *const _,
5154
};
5255
let receiver = &sup as *const objc_super as *mut Object;
5356
let msg_send_fn = R::MSG_SEND_SUPER;
54-
objc_try!({ A::invoke(msg_send_fn, receiver, sel, args) })
57+
conditional_try(|| A::invoke(msg_send_fn, receiver, sel, args))
5558
}

objc2/src/message/gnustep.rs

+11-11
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,40 @@
11
use core::mem;
22
use objc2_sys::{objc_msg_lookup, objc_msg_lookup_super, objc_super};
33

4-
use super::{Encode, Message, MessageArguments, MessageError};
4+
use super::{conditional_try, Encode, MessageArguments, MessageError};
55
use crate::runtime::{Class, Object, Sel};
66

7-
pub unsafe fn send_unverified<T, A, R>(obj: *const T, sel: Sel, args: A) -> Result<R, MessageError>
7+
pub unsafe fn send_unverified<A, R>(
8+
receiver: *mut Object,
9+
sel: Sel,
10+
args: A,
11+
) -> Result<R, MessageError>
812
where
9-
T: Message,
1013
A: MessageArguments,
1114
R: Encode,
1215
{
13-
if obj.is_null() {
16+
if receiver.is_null() {
1417
return mem::zeroed();
1518
}
1619

17-
let receiver = obj as *mut T as *mut Object;
1820
let msg_send_fn = objc_msg_lookup(receiver as *mut _, sel.as_ptr() as *const _);
19-
objc_try!({ A::invoke(msg_send_fn.expect("Null IMP"), receiver, sel, args) })
21+
conditional_try(|| A::invoke(msg_send_fn.expect("Null IMP"), receiver, sel, args))
2022
}
2123

22-
pub unsafe fn send_super_unverified<T, A, R>(
23-
obj: *const T,
24+
pub unsafe fn send_super_unverified<A, R>(
25+
receiver: *mut Object,
2426
superclass: &Class,
2527
sel: Sel,
2628
args: A,
2729
) -> Result<R, MessageError>
2830
where
29-
T: Message,
3031
A: MessageArguments,
3132
R: Encode,
3233
{
33-
let receiver = obj as *mut T as *mut Object;
3434
let sup = objc_super {
3535
receiver: receiver as *mut _,
3636
super_class: superclass as *const Class as *const _,
3737
};
3838
let msg_send_fn = objc_msg_lookup_super(&sup, sel.as_ptr() as *const _);
39-
objc_try!({ A::invoke(msg_send_fn.expect("Null IMP"), receiver, sel, args) })
39+
conditional_try(|| A::invoke(msg_send_fn.expect("Null IMP"), receiver, sel, args))
4040
}

0 commit comments

Comments
 (0)