Skip to content

Commit 7a42f8e

Browse files
committed
Support super in msg_send_id
1 parent f9329c9 commit 7a42f8e

File tree

2 files changed

+82
-0
lines changed

2 files changed

+82
-0
lines changed

objc2/src/macros.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,28 @@ macro_rules! msg_send_bool {
203203
/// TODO
204204
#[macro_export]
205205
macro_rules! msg_send_id {
206+
(super($obj:expr, $superclass:expr), $name:ident) => ({
207+
let sel = $crate::sel!($name);
208+
const NAME: &[u8] = stringify!($name).as_bytes();
209+
use $crate::rc::{__Assert, __MsgSendId};
210+
$crate::__msg_send_inner! {
211+
@id NAME,
212+
$crate::__msg_send_inner! {
213+
@call <__Assert<ALLOC, INIT, RETAINED>>::__send_super_message_id($obj, $superclass, sel, ())
214+
}
215+
}
216+
});
217+
(super($obj:expr, $superclass:expr), $($name:ident: $arg:expr),+ $(,)?) => ({
218+
let sel = $crate::sel!($($name:)+);
219+
const NAME: &[u8] = concat!($(stringify!($name), ':'),+).as_bytes();
220+
use $crate::rc::{__Assert, __MsgSendId};
221+
$crate::__msg_send_inner! {
222+
@id NAME,
223+
$crate::__msg_send_inner! {
224+
@call <__Assert<ALLOC, INIT, RETAINED>>::__send_super_message_id($obj, $superclass, sel, ($($arg,)+))
225+
}
226+
}
227+
});
206228
($obj:expr, $name:ident) => ({
207229
let sel = $crate::sel!($name);
208230
const NAME: &[u8] = stringify!($name).as_bytes();

objc2/src/rc/alloc.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ pub trait __MsgSendId<T, U> {
2727
sel: Sel,
2828
args: A,
2929
) -> Result<U, MessageError>;
30+
31+
unsafe fn __send_super_message_id<A: MessageArguments>(
32+
obj: T,
33+
superclass: &Class,
34+
sel: Sel,
35+
args: A,
36+
) -> Result<U, MessageError>;
3037
}
3138

3239
impl<T: ?Sized + Message, O: Ownership> __MsgSendId<&'_ Class, Id<Allocated<T>, O>>
@@ -43,6 +50,19 @@ impl<T: ?Sized + Message, O: Ownership> __MsgSendId<&'_ Class, Id<Allocated<T>,
4350
.map(|r| Id::new(r).expect("Failed allocating"))
4451
}
4552
}
53+
54+
#[inline(always)]
55+
unsafe fn __send_super_message_id<A: MessageArguments>(
56+
cls: &Class,
57+
superclass: &Class,
58+
sel: Sel,
59+
args: A,
60+
) -> Result<Id<Allocated<T>, O>, MessageError> {
61+
unsafe {
62+
MessageReceiver::send_super_message(&cls, superclass, sel, args)
63+
.map(|r| Id::new(r).expect("Failed allocating"))
64+
}
65+
}
4666
}
4767

4868
impl<T: ?Sized + Message, O: Ownership> __MsgSendId<Id<Allocated<T>, O>, Option<Id<T, O>>>
@@ -57,6 +77,19 @@ impl<T: ?Sized + Message, O: Ownership> __MsgSendId<Id<Allocated<T>, O>, Option<
5777
let obj = ManuallyDrop::new(obj);
5878
unsafe { MessageReceiver::send_message(&obj, sel, args).map(|r| Id::new(r)) }
5979
}
80+
81+
#[inline(always)]
82+
unsafe fn __send_super_message_id<A: MessageArguments>(
83+
obj: Id<Allocated<T>, O>,
84+
superclass: &Class,
85+
sel: Sel,
86+
args: A,
87+
) -> Result<Option<Id<T, O>>, MessageError> {
88+
let obj = ManuallyDrop::new(obj);
89+
unsafe {
90+
MessageReceiver::send_super_message(&obj, superclass, sel, args).map(|r| Id::new(r))
91+
}
92+
}
6093
}
6194

6295
impl<T: MessageReceiver, U: ?Sized + Message, O: Ownership> __MsgSendId<T, Option<Id<U, O>>>
@@ -70,6 +103,18 @@ impl<T: MessageReceiver, U: ?Sized + Message, O: Ownership> __MsgSendId<T, Optio
70103
) -> Result<Option<Id<U, O>>, MessageError> {
71104
unsafe { MessageReceiver::send_message(&obj, sel, args).map(|r| Id::new(r)) }
72105
}
106+
107+
#[inline(always)]
108+
unsafe fn __send_super_message_id<A: MessageArguments>(
109+
obj: T,
110+
superclass: &Class,
111+
sel: Sel,
112+
args: A,
113+
) -> Result<Option<Id<U, O>>, MessageError> {
114+
unsafe {
115+
MessageReceiver::send_super_message(&obj, superclass, sel, args).map(|r| Id::new(r))
116+
}
117+
}
73118
}
74119

75120
impl<T: MessageReceiver, U: Message, O: Ownership> __MsgSendId<T, Option<Id<U, O>>>
@@ -87,4 +132,19 @@ impl<T: MessageReceiver, U: Message, O: Ownership> __MsgSendId<T, Option<Id<U, O
87132
MessageReceiver::send_message(&obj, sel, args).map(|r| Id::retain_autoreleased(r))
88133
}
89134
}
135+
136+
#[inline(always)]
137+
unsafe fn __send_super_message_id<A: MessageArguments>(
138+
obj: T,
139+
superclass: &Class,
140+
sel: Sel,
141+
args: A,
142+
) -> Result<Option<Id<U, O>>, MessageError> {
143+
// All code between the message send and the `retain_autoreleased`
144+
// must be able to be optimized away for this to work.
145+
unsafe {
146+
MessageReceiver::send_super_message(&obj, superclass, sel, args)
147+
.map(|r| Id::retain_autoreleased(r))
148+
}
149+
}
90150
}

0 commit comments

Comments
 (0)