Skip to content

Commit

Permalink
Remove MessageArguments in favour of ConvertArguments
Browse files Browse the repository at this point in the history
To hide more implementation details, and to in the future make it possible to always do the fast autorelease optimization, even when working with out parameters.
  • Loading branch information
madsmtm committed Sep 20, 2023
1 parent b8bc138 commit 641e394
Show file tree
Hide file tree
Showing 16 changed files with 405 additions and 426 deletions.
4 changes: 2 additions & 2 deletions crates/objc2/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
who are `IsAllocableAnyThread`.
* **BREAKING**: Moved the `MethodImplementation` trait from the `declare`
module to the `runtime` module.
* **BREAKING**: Moved the `MessageReceiver` and `MessageArguments` traits to
the `runtime` module.
* **BREAKING**: Moved the `MessageReceiver` trait to the `runtime` module.

### Deprecated
* Soft deprecated using `msg_send!` without a comma between arguments (i.e.
Expand Down Expand Up @@ -64,6 +63,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Removed
* **BREAKING**: Removed `ProtocolType` implementation for `NSObject`.
Use the more precise `NSObjectProtocol` trait instead!
* **BREAKING**: Removed the `MessageArguments` trait.


## 0.4.1 - 2023-07-31
Expand Down
162 changes: 161 additions & 1 deletion crates/objc2/src/__macro_helpers/convert.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::encode::{EncodeArgument, EncodeReturn};
use crate::encode::{EncodeArgument, EncodeArguments, EncodeReturn};
use crate::rc::Id;
use crate::runtime::Bool;
use crate::Message;
Expand Down Expand Up @@ -121,6 +121,166 @@ impl ConvertReturn for bool {
}
}

pub trait ConvertArguments {
#[doc(hidden)]
type __Inner: EncodeArguments;

#[doc(hidden)]
type __StoredBeforeMessage: Sized;

#[doc(hidden)]
fn __into_arguments(self) -> (Self::__Inner, Self::__StoredBeforeMessage);

#[doc(hidden)]
unsafe fn __process_after_message_send(_stored: Self::__StoredBeforeMessage) {}
}

pub trait TupleExtender<T> {
#[doc(hidden)]
type PlusOneArgument;
#[doc(hidden)]
fn add_argument(self, arg: T) -> Self::PlusOneArgument;
}

macro_rules! args_impl {
($($a:ident: $t:ident),*) => (
impl<$($t: ConvertArgument),*> ConvertArguments for ($($t,)*) {
type __Inner = ($($t::__Inner,)*);

type __StoredBeforeMessage = ($($t::__StoredBeforeMessage,)*);

#[inline]
fn __into_arguments(self) -> (Self::__Inner, Self::__StoredBeforeMessage) {
let ($($a,)*) = self;
$(let $a = ConvertArgument::__into_argument($a);)*

(($($a.0,)*), ($($a.1,)*))
}

#[inline]
unsafe fn __process_after_message_send(($($a,)*): Self::__StoredBeforeMessage) {
$(
unsafe { <$t as ConvertArgument>::__process_after_message_send($a) };
)*
}
}

impl<$($t,)* T> TupleExtender<T> for ($($t,)*) {
type PlusOneArgument = ($($t,)* T,);

fn add_argument(self, arg: T) -> Self::PlusOneArgument {
let ($($a,)*) = self;
($($a,)* arg,)
}
}
);
}

args_impl!();
args_impl!(a: A);
args_impl!(a: A, b: B);
args_impl!(a: A, b: B, c: C);
args_impl!(a: A, b: B, c: C, d: D);
args_impl!(a: A, b: B, c: C, d: D, e: E);
args_impl!(a: A, b: B, c: C, d: D, e: E, f: F);
args_impl!(a: A, b: B, c: C, d: D, e: E, f: F, g: G);
args_impl!(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H);
args_impl!(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I);
args_impl!(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J);
args_impl!(
a: A,
b: B,
c: C,
d: D,
e: E,
f: F,
g: G,
h: H,
i: I,
j: J,
k: K
);
args_impl!(
a: A,
b: B,
c: C,
d: D,
e: E,
f: F,
g: G,
h: H,
i: I,
j: J,
k: K,
l: L
);
args_impl!(
a: A,
b: B,
c: C,
d: D,
e: E,
f: F,
g: G,
h: H,
i: I,
j: J,
k: K,
l: L,
m: M
);
args_impl!(
a: A,
b: B,
c: C,
d: D,
e: E,
f: F,
g: G,
h: H,
i: I,
j: J,
k: K,
l: L,
m: M,
n: N
);
args_impl!(
a: A,
b: B,
c: C,
d: D,
e: E,
f: F,
g: G,
h: H,
i: I,
j: J,
k: K,
l: L,
m: M,
n: N,
o: O
);
args_impl!(
a: A,
b: B,
c: C,
d: D,
e: E,
f: F,
g: G,
h: H,
i: I,
j: J,
k: K,
l: L,
m: M,
n: N,
o: O,
p: P
);

#[cfg(test)]
mod tests {
use super::*;
Expand Down
2 changes: 1 addition & 1 deletion crates/objc2/src/__macro_helpers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ mod writeback;

pub use self::cache::{CachedClass, CachedSel};
pub use self::common_selectors::{alloc_sel, dealloc_sel, init_sel, new_sel};
pub use self::convert::{ConvertArgument, ConvertReturn};
pub use self::convert::{ConvertArgument, ConvertArguments, ConvertReturn, TupleExtender};
pub use self::declare_class::{
assert_mutability_matches_superclass_mutability, IdReturnValue, MaybeOptionId,
MessageRecieveId, ValidSubclassMutability,
Expand Down
21 changes: 10 additions & 11 deletions crates/objc2/src/__macro_helpers/msg_send_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@ use core::ptr;

use crate::encode::Encode;
use crate::rc::{Allocated, Id};
use crate::runtime::message::__TupleExtender;
use crate::runtime::{AnyClass, AnyObject, MessageArguments, MessageReceiver, Sel};
use crate::runtime::{AnyClass, AnyObject, MessageReceiver, Sel};
use crate::{sel, Message};

use super::{Alloc, CopyOrMutCopy, Init, New, Other};
use super::{Alloc, ConvertArguments, CopyOrMutCopy, Init, New, Other, TupleExtender};

pub trait MsgSendId<T, U> {
#[track_caller]
unsafe fn send_message_id<A: MessageArguments, R: MaybeUnwrap<Input = U>>(
unsafe fn send_message_id<A: ConvertArguments, R: MaybeUnwrap<Input = U>>(
obj: T,
sel: Sel,
args: A,
Expand All @@ -23,8 +22,8 @@ pub trait MsgSendId<T, U> {
unsafe fn send_message_id_error<A, E>(obj: T, sel: Sel, args: A) -> Result<U, Id<E>>
where
*mut *mut E: Encode,
A: __TupleExtender<*mut *mut E>,
<A as __TupleExtender<*mut *mut E>>::PlusOneArgument: MessageArguments,
A: TupleExtender<*mut *mut E>,
<A as TupleExtender<*mut *mut E>>::PlusOneArgument: ConvertArguments,
E: Message,
Option<U>: MaybeUnwrap<Input = U>,
{
Expand Down Expand Up @@ -69,7 +68,7 @@ unsafe fn encountered_error<E: Message>(err: *mut E) -> Id<E> {

impl<T: MessageReceiver, U: ?Sized + Message> MsgSendId<T, Id<U>> for New {
#[inline]
unsafe fn send_message_id<A: MessageArguments, R: MaybeUnwrap<Input = Id<U>>>(
unsafe fn send_message_id<A: ConvertArguments, R: MaybeUnwrap<Input = Id<U>>>(
obj: T,
sel: Sel,
args: A,
Expand All @@ -88,7 +87,7 @@ impl<T: MessageReceiver, U: ?Sized + Message> MsgSendId<T, Id<U>> for New {

impl<T: ?Sized + Message> MsgSendId<&'_ AnyClass, Allocated<T>> for Alloc {
#[inline]
unsafe fn send_message_id<A: MessageArguments, R: MaybeUnwrap<Input = Allocated<T>>>(
unsafe fn send_message_id<A: ConvertArguments, R: MaybeUnwrap<Input = Allocated<T>>>(
cls: &AnyClass,
sel: Sel,
args: A,
Expand All @@ -103,7 +102,7 @@ impl<T: ?Sized + Message> MsgSendId<&'_ AnyClass, Allocated<T>> for Alloc {

impl<T: ?Sized + Message> MsgSendId<Option<Allocated<T>>, Id<T>> for Init {
#[inline]
unsafe fn send_message_id<A: MessageArguments, R: MaybeUnwrap<Input = Id<T>>>(
unsafe fn send_message_id<A: ConvertArguments, R: MaybeUnwrap<Input = Id<T>>>(
obj: Option<Allocated<T>>,
sel: Sel,
args: A,
Expand All @@ -124,7 +123,7 @@ impl<T: ?Sized + Message> MsgSendId<Option<Allocated<T>>, Id<T>> for Init {

impl<T: MessageReceiver, U: ?Sized + Message> MsgSendId<T, Id<U>> for CopyOrMutCopy {
#[inline]
unsafe fn send_message_id<A: MessageArguments, R: MaybeUnwrap<Input = Id<U>>>(
unsafe fn send_message_id<A: ConvertArguments, R: MaybeUnwrap<Input = Id<U>>>(
obj: T,
sel: Sel,
args: A,
Expand All @@ -140,7 +139,7 @@ impl<T: MessageReceiver, U: ?Sized + Message> MsgSendId<T, Id<U>> for CopyOrMutC

impl<T: MessageReceiver, U: Message> MsgSendId<T, Id<U>> for Other {
#[inline]
unsafe fn send_message_id<A: MessageArguments, R: MaybeUnwrap<Input = Id<U>>>(
unsafe fn send_message_id<A: ConvertArguments, R: MaybeUnwrap<Input = Id<U>>>(
obj: T,
sel: Sel,
args: A,
Expand Down
Loading

0 comments on commit 641e394

Please sign in to comment.