Skip to content

Commit

Permalink
Simplify internal msg_send_id output
Browse files Browse the repository at this point in the history
  • Loading branch information
madsmtm committed Oct 27, 2022
1 parent de5ed69 commit 155abd3
Show file tree
Hide file tree
Showing 18 changed files with 160 additions and 131 deletions.
68 changes: 38 additions & 30 deletions objc2/src/__macro_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use alloc::vec::Vec;
#[cfg(feature = "verify_message")]
use std::collections::HashSet;

use crate::__sel_inner;
use crate::declare::ClassBuilder;
#[cfg(feature = "verify_message")]
use crate::declare::MethodImplementation;
Expand All @@ -12,6 +11,7 @@ use crate::rc::{Allocated, Id, Ownership};
use crate::runtime::MethodDescription;
use crate::runtime::{Class, Object, Protocol, Sel};
use crate::{Message, MessageArguments, MessageReceiver};
use crate::{__sel_data, __sel_inner};

pub use crate::cache::CachedClass;
pub use crate::cache::CachedSel;
Expand All @@ -38,19 +38,16 @@ pub use std::sync::Once;
// actual assembly is as one would expect.

#[inline]
pub fn alloc() -> Sel {
// SAFETY: Must have NUL byte
__sel_inner!("alloc\0", "alloc")
pub fn alloc_sel() -> Sel {
__sel_inner!(__sel_data!(alloc), "alloc")
}
#[inline]
pub fn init() -> Sel {
// SAFETY: Must have NUL byte
__sel_inner!("init\0", "init")
pub fn init_sel() -> Sel {
__sel_inner!(__sel_data!(init), "init")
}
#[inline]
pub fn new() -> Sel {
// SAFETY: Must have NUL byte
__sel_inner!("new\0", "new")
pub fn new_sel() -> Sel {
__sel_inner!(__sel_data!(new), "new")
}

/// Helper for specifying the retain semantics for a given selector family.
Expand All @@ -72,22 +69,33 @@ pub fn new() -> Sel {
/// means it can't be a class method!
///
/// <https://clang.llvm.org/docs/AutomaticReferenceCounting.html#retainable-object-pointers-as-operands-and-arguments>
pub struct RetainSemantics<
// `new` family
const NEW: bool,
// `alloc` family
const ALLOC: bool,
// `init` family
const INIT: bool,
// `copy` or `mutableCopy` family
const COPY_OR_MUT_COPY: bool,
> {}

type New = RetainSemantics<true, false, false, false>;
type Alloc = RetainSemantics<false, true, false, false>;
type Init = RetainSemantics<false, false, true, false>;
type CopyOrMutCopy = RetainSemantics<false, false, false, true>;
type Other = RetainSemantics<false, false, false, false>;
// TODO: Use an enum instead of u8 here when stable
pub struct RetainSemantics<const INNER: u8> {}

pub type New = RetainSemantics<1>;
pub type Alloc = RetainSemantics<2>;
pub type Init = RetainSemantics<3>;
pub type CopyOrMutCopy = RetainSemantics<4>;
pub type Other = RetainSemantics<5>;

pub const fn retain_semantics(selector: &str) -> u8 {
let selector = selector.as_bytes();
match (
in_selector_family(selector, b"new"),
in_selector_family(selector, b"alloc"),
in_selector_family(selector, b"init"),
in_selector_family(selector, b"copy"),
in_selector_family(selector, b"mutableCopy"),
) {
(true, false, false, false, false) => 1,
(false, true, false, false, false) => 2,
(false, false, true, false, false) => 3,
(false, false, false, true, false) => 4,
(false, false, false, false, true) => 4,
(false, false, false, false, false) => 5,
_ => unreachable!(),
}
}

pub trait MsgSendId<T, U> {
unsafe fn send_message_id<A: MessageArguments, R: MaybeUnwrap<Input = U>>(
Expand Down Expand Up @@ -266,7 +274,7 @@ impl<'a> MsgSendIdFailed<'a> for New {
if let Some(obj) = obj {
let cls = obj.class();
if cls.is_metaclass() {
if sel == new() {
if sel == new_sel() {
panic!("failed creating new instance of {:?}", cls)
} else {
panic!("failed creating new instance using +[{:?} {:?}]", cls, sel)
Expand All @@ -286,7 +294,7 @@ impl<'a> MsgSendIdFailed<'a> for Alloc {
#[cold]
#[track_caller]
fn failed((cls, sel): Self::Args) -> ! {
if sel == alloc() {
if sel == alloc_sel() {
panic!("failed allocating {:?}", cls)
} else {
panic!("failed allocating with +[{:?} {:?}]", cls, sel)
Expand All @@ -305,7 +313,7 @@ impl MsgSendIdFailed<'_> for Init {
} else {
// We can't really display a more descriptive message here since the
// object is consumed by `init` and may not be valid any more.
if sel == init() {
if sel == init_sel() {
panic!("failed initializing object")
} else {
panic!("failed initializing object with -{:?}", sel)
Expand Down Expand Up @@ -347,7 +355,7 @@ impl<'a> MsgSendIdFailed<'a> for Other {
/// Checks whether a given selector is said to be in a given selector family.
///
/// <https://clang.llvm.org/docs/AutomaticReferenceCounting.html#arc-method-families>
pub const fn in_selector_family(mut selector: &[u8], mut family: &[u8]) -> bool {
const fn in_selector_family(mut selector: &[u8], mut family: &[u8]) -> bool {
// Skip leading underscores from selector
loop {
selector = match selector {
Expand Down
69 changes: 46 additions & 23 deletions objc2/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,21 +185,34 @@ macro_rules! __class_inner {
#[macro_export]
macro_rules! sel {
(alloc) => ({
$crate::__macro_helpers::alloc()
$crate::__macro_helpers::alloc_sel()
});
(init) => ({
$crate::__macro_helpers::init()
$crate::__macro_helpers::init_sel()
});
(new) => ({
$crate::__macro_helpers::new()
$crate::__macro_helpers::new_sel()
});
($first:ident $(: $($rest:ident :)*)?) => ({
use $crate::__macro_helpers::{concat, stringify, str};
const SELECTOR_DATA: &str = concat!(stringify!($first), $(':', $(stringify!($rest), ':',)*)? '\0');
$crate::__sel_inner!(SELECTOR_DATA, $crate::__hash_idents!($first $($($rest)*)?))
$crate::__sel_inner!(
$crate::__sel_data!($first $(: $($rest :)*)?),
$crate::__hash_idents!($first $($($rest)*)?)
)
});
}

#[doc(hidden)]
#[macro_export]
macro_rules! __sel_data {
($first:ident $(: $($rest:ident :)*)?) => {
$crate::__macro_helpers::concat!(
$crate::__macro_helpers::stringify!($first),
$(':', $($crate::__macro_helpers::stringify!($rest), ':',)*)?
'\0',
)
};
}

#[doc(hidden)]
#[macro_export]
#[cfg(not(feature = "unstable-static-sel"))]
Expand Down Expand Up @@ -961,22 +974,42 @@ macro_rules! msg_send_bool {
/// ```
#[macro_export]
macro_rules! msg_send_id {
[$obj:expr, new $(,)?] => ({
let sel = $crate::sel!(new);
let result;
result = <$crate::__macro_helpers::New as $crate::__macro_helpers::MsgSendId<_, _>>::send_message_id($obj, sel, ());
result
});
[$obj:expr, alloc $(,)?] => ({
let sel = $crate::sel!(alloc);
let result;
result = <$crate::__macro_helpers::Alloc as $crate::__macro_helpers::MsgSendId<_, _>>::send_message_id($obj, sel, ());
result
});
[$obj:expr, init $(,)?] => ({
let sel = $crate::sel!(init);
let result;
result = <$crate::__macro_helpers::Init as $crate::__macro_helpers::MsgSendId<_, _>>::send_message_id($obj, sel, ());
result
});
[$obj:expr, $selector:ident $(,)?] => ({
$crate::__msg_send_id_helper!(@verify $selector);
let sel = $crate::sel!($selector);
const NAME: &[$crate::__macro_helpers::u8] = $crate::__macro_helpers::stringify!($selector).as_bytes();
$crate::__msg_send_id_helper!(@get_assert_consts NAME);
const NAME: &$crate::__macro_helpers::str = $crate::__macro_helpers::stringify!($selector);
let result;
result = <RS as $crate::__macro_helpers::MsgSendId<_, _>>::send_message_id($obj, sel, ());
result = <$crate::__macro_helpers::RetainSemantics<{
$crate::__macro_helpers::retain_semantics(NAME)
}> as $crate::__macro_helpers::MsgSendId<_, _>>::send_message_id($obj, sel, ());
result
});
[$obj:expr, $($selector:ident : $argument:expr),+ $(,)?] => ({
let sel = $crate::sel!($($selector:)+);
const NAME: &[$crate::__macro_helpers::u8] =
$crate::__macro_helpers::concat!($($crate::__macro_helpers::stringify!($selector), ':'),+).as_bytes();
$crate::__msg_send_id_helper!(@get_assert_consts NAME);
const NAME: &$crate::__macro_helpers::str =
$crate::__macro_helpers::concat!($($crate::__macro_helpers::stringify!($selector), ':'),+);
let result;
result = <RS as $crate::__macro_helpers::MsgSendId<_, _>>::send_message_id($obj, sel, ($($argument,)+));
result = <$crate::__macro_helpers::RetainSemantics<{
$crate::__macro_helpers::retain_semantics(NAME)
}> as $crate::__macro_helpers::MsgSendId<_, _>>::send_message_id($obj, sel, ($($argument,)+));
result
});
}
Expand All @@ -1001,14 +1034,4 @@ macro_rules! __msg_send_id_helper {
)
}};
(@verify $selector:ident) => {{}};
(@get_assert_consts $selector:ident) => {
use $crate::__macro_helpers::{bool, in_selector_family, RetainSemantics};
const NEW: bool = in_selector_family($selector, b"new");
const ALLOC: bool = in_selector_family($selector, b"alloc");
const INIT: bool = in_selector_family($selector, b"init");
const COPY_OR_MUT_COPY: bool = {
in_selector_family($selector, b"copy") || in_selector_family($selector, b"mutableCopy")
};
type RS = RetainSemantics<NEW, ALLOC, INIT, COPY_OR_MUT_COPY>;
};
}
14 changes: 7 additions & 7 deletions test-assembly/crates/test_msg_send_id/expected/apple-aarch64.s
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Lloh1:
add x2, x2, l_anon.[ID].1@PAGEOFF
mov x0, x20
mov x1, x19
bl SYM(<objc2::__macro_helpers::RetainSemantics<_,_,_,_> as objc2::__macro_helpers::MsgSendIdFailed>::failed::GENERATED_ID, 0)
bl SYM(<objc2::__macro_helpers::RetainSemantics<1_u8> as objc2::__macro_helpers::MsgSendIdFailed>::failed::GENERATED_ID, 0)
.loh AdrpAdd Lloh0, Lloh1

.globl _handle_alloc
Expand Down Expand Up @@ -52,7 +52,7 @@ Lloh3:
add x2, x2, l_anon.[ID].2@PAGEOFF
mov x0, x20
mov x1, x19
bl SYM(<objc2::__macro_helpers::RetainSemantics<_,_,_,_> as objc2::__macro_helpers::MsgSendIdFailed>::failed::GENERATED_ID, 1)
bl SYM(<objc2::__macro_helpers::RetainSemantics<2_u8> as objc2::__macro_helpers::MsgSendIdFailed>::failed::GENERATED_ID, 0)
.loh AdrpAdd Lloh2, Lloh3

.globl _handle_init
Expand Down Expand Up @@ -80,7 +80,7 @@ Lloh5:
add x2, x2, l_anon.[ID].3@PAGEOFF
mov x0, x20
mov x1, x19
bl SYM(<objc2::__macro_helpers::RetainSemantics<_,_,_,_> as objc2::__macro_helpers::MsgSendIdFailed>::failed::GENERATED_ID, 2)
bl SYM(<objc2::__macro_helpers::RetainSemantics<3_u8> as objc2::__macro_helpers::MsgSendIdFailed>::failed::GENERATED_ID, 0)
.loh AdrpAdd Lloh4, Lloh5

.globl _handle_alloc_init
Expand Down Expand Up @@ -138,7 +138,7 @@ Lloh6:
adrp x0, l_anon.[ID].4@PAGE
Lloh7:
add x0, x0, l_anon.[ID].4@PAGEOFF
bl SYM(<objc2::__macro_helpers::RetainSemantics<_,_,_,_> as objc2::__macro_helpers::MsgSendIdFailed>::failed::GENERATED_ID, 3)
bl SYM(<objc2::__macro_helpers::RetainSemantics<4_u8> as objc2::__macro_helpers::MsgSendIdFailed>::failed::GENERATED_ID, 0)
.loh AdrpAdd Lloh6, Lloh7

.globl _handle_autoreleased
Expand Down Expand Up @@ -177,7 +177,7 @@ Lloh9:
add x2, x2, l_anon.[ID].5@PAGEOFF
mov x0, x20
mov x1, x19
bl SYM(<objc2::__macro_helpers::RetainSemantics<_,_,_,_> as objc2::__macro_helpers::MsgSendIdFailed>::failed::GENERATED_ID, 4)
bl SYM(<objc2::__macro_helpers::RetainSemantics<5_u8> as objc2::__macro_helpers::MsgSendIdFailed>::failed::GENERATED_ID, 0)
.loh AdrpAdd Lloh8, Lloh9

.section __TEXT,__const
Expand All @@ -203,11 +203,11 @@ l_anon.[ID].3:
.p2align 3
l_anon.[ID].4:
.quad l_anon.[ID].0
.asciz ",\000\000\000\000\000\000\000@\000\000\000\005\000\000"
.asciz ",\000\000\000\000\000\000\000>\000\000\000\005\000\000"

.p2align 3
l_anon.[ID].5:
.quad l_anon.[ID].0
.asciz ",\000\000\000\000\000\000\000J\000\000\000\005\000\000"
.asciz ",\000\000\000\000\000\000\000H\000\000\000\005\000\000"

.subsections_via_symbols
14 changes: 7 additions & 7 deletions test-assembly/crates/test_msg_send_id/expected/apple-armv7.s
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ LBB1_1:
LPC1_0:
add r2, pc, r2
mov lr, pc
b SYM(<objc2::__macro_helpers::RetainSemantics<_,_,_,_> as objc2::__macro_helpers::MsgSendIdFailed>::failed::GENERATED_ID, 0)
b SYM(<objc2::__macro_helpers::RetainSemantics<1_u8> as objc2::__macro_helpers::MsgSendIdFailed>::failed::GENERATED_ID, 0)

.globl _handle_alloc
.p2align 2
Expand All @@ -52,7 +52,7 @@ LBB3_1:
LPC3_0:
add r2, pc, r2
mov lr, pc
b SYM(<objc2::__macro_helpers::RetainSemantics<_,_,_,_> as objc2::__macro_helpers::MsgSendIdFailed>::failed::GENERATED_ID, 1)
b SYM(<objc2::__macro_helpers::RetainSemantics<2_u8> as objc2::__macro_helpers::MsgSendIdFailed>::failed::GENERATED_ID, 0)

.globl _handle_init
.p2align 2
Expand All @@ -79,7 +79,7 @@ LBB5_1:
LPC5_0:
add r2, pc, r2
mov lr, pc
b SYM(<objc2::__macro_helpers::RetainSemantics<_,_,_,_> as objc2::__macro_helpers::MsgSendIdFailed>::failed::GENERATED_ID, 2)
b SYM(<objc2::__macro_helpers::RetainSemantics<3_u8> as objc2::__macro_helpers::MsgSendIdFailed>::failed::GENERATED_ID, 0)

.globl _handle_alloc_init
.p2align 2
Expand Down Expand Up @@ -137,7 +137,7 @@ LBB10_1:
LPC10_0:
add r0, pc, r0
mov lr, pc
b SYM(<objc2::__macro_helpers::RetainSemantics<_,_,_,_> as objc2::__macro_helpers::MsgSendIdFailed>::failed::GENERATED_ID, 3)
b SYM(<objc2::__macro_helpers::RetainSemantics<4_u8> as objc2::__macro_helpers::MsgSendIdFailed>::failed::GENERATED_ID, 0)

.globl _handle_autoreleased
.p2align 2
Expand Down Expand Up @@ -175,7 +175,7 @@ LBB12_1:
LPC12_0:
add r2, pc, r2
mov lr, pc
b SYM(<objc2::__macro_helpers::RetainSemantics<_,_,_,_> as objc2::__macro_helpers::MsgSendIdFailed>::failed::GENERATED_ID, 4)
b SYM(<objc2::__macro_helpers::RetainSemantics<5_u8> as objc2::__macro_helpers::MsgSendIdFailed>::failed::GENERATED_ID, 0)

.section __TEXT,__const
l_anon.[ID].0:
Expand All @@ -200,11 +200,11 @@ l_anon.[ID].3:
.p2align 2
l_anon.[ID].4:
.long l_anon.[ID].0
.asciz ",\000\000\000@\000\000\000\005\000\000"
.asciz ",\000\000\000>\000\000\000\005\000\000"

.p2align 2
l_anon.[ID].5:
.long l_anon.[ID].0
.asciz ",\000\000\000J\000\000\000\005\000\000"
.asciz ",\000\000\000H\000\000\000\005\000\000"

.subsections_via_symbols
Loading

0 comments on commit 155abd3

Please sign in to comment.