diff --git a/crates/icrate/examples/browser.rs b/crates/icrate/examples/browser.rs index 1bc466863..46c734ccd 100644 --- a/crates/icrate/examples/browser.rs +++ b/crates/icrate/examples/browser.rs @@ -1,5 +1,5 @@ #![deny(unsafe_op_in_unsafe_fn)] -use core::{cell::OnceCell, ptr::NonNull}; +use core::cell::OnceCell; use icrate::{ AppKit::{ @@ -18,26 +18,23 @@ use icrate::{ WebKit::{WKNavigation, WKNavigationDelegate, WKWebView}, }; use objc2::{ - declare::{Ivar, IvarDrop}, - declare_class, msg_send, msg_send_id, + declare_class, msg_send_id, mutability::MainThreadOnly, - rc::Id, + rc::{Allocated, Id}, runtime::{AnyObject, ProtocolObject, Sel}, - sel, ClassType, + sel, ClassType, DeclaredClass, }; -type IdCell = Box>>; - macro_rules! idcell { ($name:ident => $this:expr) => { - $this.$name.set($name).expect(&format!( + $this.ivars().$name.set($name).expect(&format!( "ivar should not already be initialized: `{}`", stringify!($name) )); }; ($name:ident <= $this:expr) => { #[rustfmt::skip] - let Some($name) = $this.$name.get() else { + let Some($name) = $this.ivars().$name.get() else { unreachable!( "ivar should be initialized: `{}`", stringify!($name) @@ -46,13 +43,15 @@ macro_rules! idcell { }; } +#[derive(Default)] +struct Ivars { + nav_url: OnceCell>, + web_view: OnceCell>, + window: OnceCell>, +} + declare_class!( - struct Delegate { - nav_url: IvarDrop, "_nav_url">, - web_view: IvarDrop, "_web_view">, - window: IvarDrop, "_window">, - } - mod ivars; + struct Delegate; unsafe impl ClassType for Delegate { type Super = NSObject; @@ -60,16 +59,15 @@ declare_class!( const NAME: &'static str = "Delegate"; } + impl DeclaredClass for Delegate { + type Ivars = Ivars; + } + unsafe impl Delegate { - #[method(init)] - unsafe fn init(this: *mut Self) -> Option> { - let this: Option<&mut Self> = msg_send![super(this), init]; - this.map(|this| { - Ivar::write(&mut this.nav_url, IdCell::default()); - Ivar::write(&mut this.web_view, IdCell::default()); - Ivar::write(&mut this.window, IdCell::default()); - NonNull::from(this) - }) + #[method_id(init)] + fn init(this: Allocated) -> Option> { + let this = this.set_ivars(Ivars::default()); + unsafe { msg_send_id![super(this), init] } } } diff --git a/crates/icrate/examples/delegate.rs b/crates/icrate/examples/delegate.rs index 5d4e44457..dc655a7dc 100644 --- a/crates/icrate/examples/delegate.rs +++ b/crates/icrate/examples/delegate.rs @@ -1,27 +1,26 @@ #![deny(unsafe_op_in_unsafe_fn)] -use std::ptr::NonNull; - use icrate::AppKit::{NSApplication, NSApplicationActivationPolicyRegular, NSApplicationDelegate}; use icrate::Foundation::{ ns_string, MainThreadMarker, NSCopying, NSNotification, NSObject, NSObjectProtocol, NSString, }; -use objc2::declare::{Ivar, IvarBool, IvarDrop, IvarEncode}; -use objc2::rc::Id; +use objc2::rc::{Allocated, Id}; use objc2::runtime::ProtocolObject; -use objc2::{declare_class, msg_send, msg_send_id, mutability, ClassType}; +use objc2::{declare_class, msg_send_id, mutability, ClassType, DeclaredClass}; + +#[derive(Debug)] +#[allow(unused)] +struct Ivars { + ivar: u8, + another_ivar: bool, + box_ivar: Box, + maybe_box_ivar: Option>, + id_ivar: Id, + maybe_id_ivar: Option>, +} declare_class!( #[derive(Debug)] - struct AppDelegate { - ivar: IvarEncode, - another_ivar: IvarBool<"_another_ivar">, - box_ivar: IvarDrop, "_box_ivar">, - maybe_box_ivar: IvarDrop>, "_maybe_box_ivar">, - id_ivar: IvarDrop, "_id_ivar">, - maybe_id_ivar: IvarDrop>, "_maybe_id_ivar">, - } - - mod ivars; + struct AppDelegate; unsafe impl ClassType for AppDelegate { type Super = NSObject; @@ -29,24 +28,25 @@ declare_class!( const NAME: &'static str = "MyAppDelegate"; } + impl DeclaredClass for AppDelegate { + type Ivars = Ivars; + } + unsafe impl AppDelegate { - #[method(initWith:another:)] - unsafe fn init_with( - this: *mut Self, + #[method_id(initWith:another:)] + fn init_with( + this: Allocated, ivar: u8, another_ivar: bool, - ) -> Option> { - let this: Option<&mut Self> = unsafe { msg_send![super(this), init] }; - - this.map(|this| { - Ivar::write(&mut this.ivar, ivar); - Ivar::write(&mut this.another_ivar, another_ivar); - Ivar::write(&mut this.maybe_box_ivar, None); - Ivar::write(&mut this.maybe_id_ivar, Some(ns_string!("def").copy())); - Ivar::write(&mut this.box_ivar, Box::new(2)); - Ivar::write(&mut this.id_ivar, NSString::from_str("abc")); - NonNull::from(this) - }) + ) -> Option> { + let this = this.set_ivars(Ivars { + ivar,another_ivar, + box_ivar: Box::new(2), + maybe_box_ivar: None, + id_ivar: NSString::from_str("abc"), + maybe_id_ivar: Some(ns_string!("def").copy()), + }); + unsafe { msg_send_id![super(this), init] } } } diff --git a/crates/icrate/examples/metal.rs b/crates/icrate/examples/metal.rs index 7b31d439e..f537d4d65 100644 --- a/crates/icrate/examples/metal.rs +++ b/crates/icrate/examples/metal.rs @@ -20,12 +20,11 @@ use icrate::{ MetalKit::{MTKView, MTKViewDelegate}, }; use objc2::{ - declare::{Ivar, IvarDrop}, - declare_class, msg_send, msg_send_id, + declare_class, msg_send_id, mutability::MainThreadOnly, - rc::Id, + rc::{Allocated, Id}, runtime::ProtocolObject, - ClassType, + ClassType, DeclaredClass, }; #[rustfmt::skip] @@ -101,18 +100,16 @@ pub struct Color { pub b: f32, } -type IdCell = Box>>; - macro_rules! idcell { ($name:ident => $this:expr) => { - $this.$name.set($name).expect(&format!( + $this.ivars().$name.set($name).expect(&format!( "ivar should not already be initialized: `{}`", stringify!($name) )); }; ($name:ident <= $this:expr) => { #[rustfmt::skip] - let Some($name) = $this.$name.get() else { + let Some($name) = $this.ivars().$name.get() else { unreachable!( "ivar should be initialized: `{}`", stringify!($name) @@ -121,17 +118,17 @@ macro_rules! idcell { }; } +// declare the desired instance variables +struct Ivars { + start_date: Id, + command_queue: OnceCell>>, + pipeline_state: OnceCell>>, + window: OnceCell>, +} + // declare the Objective-C class machinery declare_class!( - // declare the delegate class with our instance variables - #[rustfmt::skip] // FIXME: rustfmt breaks the macro parsing apparently - struct Delegate { - start_date: IvarDrop, "_start_date">, - command_queue: IvarDrop>, "_command_queue">, - pipeline_state: IvarDrop>, "_pipeline_state">, - window: IvarDrop, "_window">, - } - mod ivars; + struct Delegate; // declare the class type unsafe impl ClassType for Delegate { @@ -140,18 +137,21 @@ declare_class!( const NAME: &'static str = "Delegate"; } + impl DeclaredClass for Delegate { + type Ivars = Ivars; + } + // define the Delegate methods (e.g., initializer) unsafe impl Delegate { - #[method(init)] - unsafe fn init(this: *mut Self) -> Option> { - let this: Option<&mut Self> = msg_send![super(this), init]; - this.map(|this| { - Ivar::write(&mut this.start_date, unsafe { NSDate::now() }); - Ivar::write(&mut this.command_queue, IdCell::default()); - Ivar::write(&mut this.pipeline_state, IdCell::default()); - Ivar::write(&mut this.window, IdCell::default()); - NonNull::from(this) - }) + #[method_id(init)] + fn init(this: Allocated) -> Option> { + let this = this.set_ivars(Ivars { + start_date: unsafe { NSDate::now() }, + command_queue: OnceCell::default(), + pipeline_state: OnceCell::default(), + window: OnceCell::default(), + }); + unsafe { msg_send_id![super(this), init] } } } @@ -277,7 +277,7 @@ declare_class!( // compute the scene properties let scene_properties_data = &SceneProperties { - time: unsafe { self.start_date.timeIntervalSinceNow() } as f32, + time: unsafe { self.ivars().start_date.timeIntervalSinceNow() } as f32, }; // write the scene properties to the vertex shader argument buffer at index 0 let scene_properties_bytes = NonNull::from(scene_properties_data); diff --git a/crates/icrate/src/fixes/Foundation/copying.rs b/crates/icrate/src/fixes/Foundation/copying.rs index b0d7c8ef4..f6e68601a 100644 --- a/crates/icrate/src/fixes/Foundation/copying.rs +++ b/crates/icrate/src/fixes/Foundation/copying.rs @@ -34,6 +34,15 @@ extern_protocol!( /// # Safety /// /// The zone pointer must be valid or NULL. + /// + /// + /// # Examples + /// + /// Examples on how to implement copyWithZone: + /// + /// TODO + /// + /// The different ways described in apples doc #[method_id(copyWithZone:)] unsafe fn copyWithZone(&self, zone: *mut NSZone) -> Id where diff --git a/crates/icrate/tests/array.rs b/crates/icrate/tests/array.rs index 04fb17adf..398c894c6 100644 --- a/crates/icrate/tests/array.rs +++ b/crates/icrate/tests/array.rs @@ -122,7 +122,7 @@ fn test_retains_stored() { drop(obj); expected.release += 1; - expected.dealloc += 1; + expected.drop += 1; expected.assert_current(); } @@ -187,7 +187,7 @@ fn test_iter_minimal_retains() { assert_eq!(iter.count(), 0); expected.release += 1; - expected.dealloc += 1; + expected.drop += 1; expected.assert_current(); } diff --git a/crates/icrate/tests/auto_traits.rs b/crates/icrate/tests/auto_traits.rs index 262c58aa6..4e1e0a2ec 100644 --- a/crates/icrate/tests/auto_traits.rs +++ b/crates/icrate/tests/auto_traits.rs @@ -7,7 +7,7 @@ use icrate::Foundation::*; use objc2::mutability::{Immutable, Mutable}; use objc2::rc::Id; use objc2::runtime::AnyObject; -use objc2::{declare_class, ClassType}; +use objc2::{declare_class, ClassType, DeclaredClass}; // We expect most Foundation types to be UnwindSafe and RefUnwindSafe, // since they follow Rust's usual mutability rules (&T = immutable). @@ -40,6 +40,8 @@ macro_rules! helper { type Mutability = $mutability; const NAME: &'static str = concat!(stringify!($name), "Test"); } + + impl DeclaredClass for $name {} ); }; } diff --git a/crates/icrate/tests/mutable_array.rs b/crates/icrate/tests/mutable_array.rs index ddb09028e..4d06d6e6e 100644 --- a/crates/icrate/tests/mutable_array.rs +++ b/crates/icrate/tests/mutable_array.rs @@ -151,7 +151,7 @@ fn test_remove() { array.removeAllObjects(); expected.release += 2; - expected.dealloc += 2; + expected.drop += 2; expected.assert_current(); assert_eq!(array.len(), 0); } diff --git a/crates/icrate/tests/mutable_dictionary.rs b/crates/icrate/tests/mutable_dictionary.rs index 61db87512..6d3933079 100644 --- a/crates/icrate/tests/mutable_dictionary.rs +++ b/crates/icrate/tests/mutable_dictionary.rs @@ -102,7 +102,7 @@ fn test_insert_key_copies() { dict.removeAllObjects(); // Release key expected.release += 1; - expected.dealloc += 1; + expected.drop += 1; expected.assert_current(); } @@ -137,7 +137,7 @@ fn test_insert_value_retain_release() { drop(old); expected.release += 1; - expected.dealloc += 1; + expected.drop += 1; expected.assert_current(); } @@ -183,7 +183,7 @@ fn test_remove_clear_release_dealloc() { dict.removeAllObjects(); expected.release += 2; - expected.dealloc += 2; + expected.drop += 2; expected.assert_current(); assert_eq!(dict.len(), 0); } diff --git a/crates/icrate/tests/mutable_set.rs b/crates/icrate/tests/mutable_set.rs index da18d0266..d997449b9 100644 --- a/crates/icrate/tests/mutable_set.rs +++ b/crates/icrate/tests/mutable_set.rs @@ -113,7 +113,7 @@ fn test_clear_release_dealloc() { set.removeAllObjects(); expected.release += 4; - expected.dealloc += 4; + expected.drop += 4; expected.assert_current(); assert_eq!(set.len(), 0); } diff --git a/crates/icrate/tests/set.rs b/crates/icrate/tests/set.rs index fe4a5fbd4..ec96addbd 100644 --- a/crates/icrate/tests/set.rs +++ b/crates/icrate/tests/set.rs @@ -227,7 +227,7 @@ fn test_retains_stored() { drop(obj); expected.release += 1; - expected.dealloc += 1; + expected.drop += 1; expected.assert_current(); } @@ -291,7 +291,7 @@ fn test_iter_minimal_retains() { assert_eq!(iter.count(), 0); expected.release += 1; - expected.dealloc += 1; + expected.drop += 1; expected.assert_current(); } diff --git a/crates/objc2/examples/class_with_lifetime.rs b/crates/objc2/examples/class_with_lifetime.rs index 54410530d..95e4984bc 100644 --- a/crates/objc2/examples/class_with_lifetime.rs +++ b/crates/objc2/examples/class_with_lifetime.rs @@ -4,36 +4,19 @@ use std::marker::PhantomData; use std::sync::Once; -use objc2::declare::{ClassBuilder, Ivar, IvarEncode, IvarType}; +use objc2::declare::ClassBuilder; use objc2::mutability::Mutable; use objc2::rc::Id; use objc2::runtime::{AnyClass, NSObject, Sel}; use objc2::{msg_send, msg_send_id, sel}; use objc2::{ClassType, Encoding, Message, RefEncode}; -/// Helper type for the instance variable -struct NumberIvar<'a> { - // Doesn't actually matter what we put here, but we have to use the - // lifetime parameter somehow - p: PhantomData<&'a mut u8>, -} - -unsafe impl<'a> IvarType for NumberIvar<'a> { - type Type = IvarEncode<&'a mut u8>; - const NAME: &'static str = "_number_ptr"; -} - /// Struct that represents our custom object. #[repr(C)] pub struct MyObject<'a> { // Required to give MyObject the proper layout superclass: NSObject, - // SAFETY: The ivar is declared below, and is properly initialized in the - // designated initializer. - // - // Note! Attempting to acess the ivar before it has been initialized is - // undefined behaviour! - number: Ivar>, + p: PhantomData<&'a mut u8>, } unsafe impl RefEncode for MyObject<'_> { @@ -50,8 +33,12 @@ impl<'a> MyObject<'a> { ) -> Option<&'s mut Self> { let this: Option<&mut Self> = unsafe { msg_send![super(self), init] }; this.map(|this| { - // Properly initialize the number reference - Ivar::write(&mut this.number, ptr.expect("got NULL number ptr")); + let ivar = Self::class().instance_variable("number").unwrap(); + // SAFETY: The ivar is added with the same type below + unsafe { + ivar.load_ptr::<&mut u8>(&this.superclass) + .write(ptr.expect("got NULL number ptr")) + }; this }) } @@ -63,11 +50,15 @@ impl<'a> MyObject<'a> { } pub fn get(&self) -> &u8 { - &self.number + let ivar = Self::class().instance_variable("number").unwrap(); + // SAFETY: The ivar is added with the same type below, and is initialized in `init_with_ptr` + unsafe { *ivar.load::<&mut u8>(&self.superclass) } } pub fn set(&mut self, number: u8) { - **self.number = number; + let ivar = Self::class().instance_variable("number").unwrap(); + // SAFETY: The ivar is added with the same type below, and is initialized in `init_with_ptr` + unsafe { **ivar.load_mut::<&mut u8>(&mut self.superclass) = number }; } } @@ -84,7 +75,7 @@ unsafe impl<'a> ClassType for MyObject<'a> { let superclass = NSObject::class(); let mut builder = ClassBuilder::new(Self::NAME, superclass).unwrap(); - builder.add_static_ivar::>(); + builder.add_ivar::<&mut u8>("number"); unsafe { builder.add_method( diff --git a/crates/objc2/src/__macro_helpers/common_selectors.rs b/crates/objc2/src/__macro_helpers/common_selectors.rs index 508a2f3c1..1bcfd9167 100644 --- a/crates/objc2/src/__macro_helpers/common_selectors.rs +++ b/crates/objc2/src/__macro_helpers/common_selectors.rs @@ -28,3 +28,77 @@ pub fn new_sel() -> Sel { pub fn dealloc_sel() -> Sel { __sel_inner!(__sel_data!(dealloc), "dealloc") } + +/// An undocumented selector called by the Objective-C runtime when +/// initalizing instance variables. +#[inline] +#[allow(dead_code)] // May be useful in the future +fn cxx_construct_sel() -> Sel { + __sel_inner!(".cxx_construct\0", ".cxx_construct") +} + +/// Objective-C runtimes call `.cxx_destruct` as part of the final `dealloc` +/// call inside `NSObject` (and has done so since macOS 10.4). +/// +/// While [GCC does document it somewhat][gcc-docs], this is still severely +/// undocumented in clang - but since this selector is emitted into the final +/// binary, it is fine to rely on this being available. +/// +/// Unfortunately though, this only works +/// +/// The ABI of `.cxx_destruct` in Apple's runtime is actually that it does NOT +/// take a selector, unlike every other Objective-C method, see: +/// +/// +/// So the signature is `extern "C" fn(*mut AnyObject)`. +/// +/// This is likely because it's not a real Objective-C method that can be +/// called from userspace / objc_msgSend, and it's more efficient to not pass +/// the selector. +/// +/// Note that even if Apple decides to suddenly add the selector one day, +/// ignoring it will still be sound, since the function uses the C calling +/// convention, where such an ignored parameter would be allowed on all +/// relevant architectures. +/// +/// TODO: Unsure whether "C-unwind" is allowed? +/// +/// [gcc-docs]: https://gcc.gnu.org/onlinedocs/gcc/Objective-C-and-Objective-C_002b_002b-Dialect-Options.html#index-fobjc-call-cxx-cdtors +#[inline] +#[allow(dead_code)] // May be useful in the future +fn cxx_destruct_sel() -> Sel { + __sel_inner!(".cxx_destruct\0", ".cxx_destruct") +} + +#[cfg(test)] +mod tests { + use core::sync::atomic::{AtomicBool, Ordering}; + + use crate::declare::ClassBuilder; + use crate::rc::Id; + use crate::runtime::NSObject; + use crate::{msg_send_id, ClassType}; + + use super::*; + + /// Test the unfortunate fact that we can't use .cxx_destruct on dynamic classes. + #[test] + fn test_destruct() { + static HAS_RUN: AtomicBool = AtomicBool::new(false); + + let mut builder = ClassBuilder::new("TestCxxDestruct", NSObject::class()).unwrap(); + + unsafe extern "C" fn destruct(_: *mut NSObject, _: Sel) { + HAS_RUN.store(true, Ordering::Relaxed); + } + + // Note: The ABI is not upheld here, but its fine for this test + unsafe { builder.add_method(cxx_destruct_sel(), destruct as unsafe extern "C" fn(_, _)) }; + + let cls = builder.register(); + + let obj: Id = unsafe { msg_send_id![cls, new] }; + drop(obj); + assert!(!HAS_RUN.load(Ordering::Relaxed)); + } +} diff --git a/crates/objc2/src/__macro_helpers/declare_class.rs b/crates/objc2/src/__macro_helpers/declare_class.rs index 38eaba628..7bfc4fc22 100644 --- a/crates/objc2/src/__macro_helpers/declare_class.rs +++ b/crates/objc2/src/__macro_helpers/declare_class.rs @@ -4,18 +4,15 @@ use core::marker::PhantomData; #[cfg(all(debug_assertions, feature = "verify"))] use std::collections::HashSet; +use crate::declare::ClassBuilder; +use crate::encode::{Encode, Encoding}; +use crate::rc::{Allocated, Id}; +use crate::runtime::{AnyClass, AnyObject, MessageReceiver, MethodImplementation, Sel}; #[cfg(all(debug_assertions, feature = "verify"))] use crate::runtime::{AnyProtocol, MethodDescription}; +use crate::{ClassType, DeclaredClass, Message, ProtocolType}; -use objc2_encode::Encoding; - -use crate::declare::{ClassBuilder, IvarType}; -use crate::encode::Encode; -use crate::rc::{Allocated, Id}; -use crate::runtime::{AnyClass, MethodImplementation, Sel}; -use crate::runtime::{AnyObject, MessageReceiver}; -use crate::{ClassType, Message, ProtocolType}; - +use super::declared_ivars::{register_with_ivars, setup_dealloc}; use super::{CopyOrMutCopy, Init, MaybeUnwrap, New, Other}; use crate::mutability; @@ -213,7 +210,7 @@ fn failed_declaring_class(name: &str) -> ! { panic!("could not create new class {name}. Perhaps a class with that name already exists?") } -impl ClassBuilderHelper { +impl ClassBuilderHelper { #[inline] #[track_caller] #[allow(clippy::new_without_default)] @@ -221,11 +218,13 @@ impl ClassBuilderHelper { where T::Super: ClassType, { - let builder = match ClassBuilder::new(T::NAME, ::class()) { + let mut builder = match ClassBuilder::new(T::NAME, ::class()) { Some(builder) => builder, None => failed_declaring_class(T::NAME), }; + setup_dealloc::(&mut builder); + Self { builder, p: PhantomData, @@ -291,13 +290,8 @@ impl ClassBuilderHelper { } #[inline] - pub fn add_static_ivar(&mut self) { - self.builder.add_static_ivar::() - } - - #[inline] - pub fn register(self) -> &'static AnyClass { - self.builder.register() + pub fn register(self) -> (&'static AnyClass, isize, isize) { + register_with_ivars::(self.builder) } } @@ -324,7 +318,7 @@ pub struct ClassProtocolMethodsBuilder<'a, T: ?Sized> { registered_class_methods: HashSet, } -impl ClassProtocolMethodsBuilder<'_, T> { +impl ClassProtocolMethodsBuilder<'_, T> { // Addition: This restricts to callee `T` #[inline] pub unsafe fn add_method(&mut self, sel: Sel, func: F) diff --git a/crates/objc2/src/__macro_helpers/declared_ivars.rs b/crates/objc2/src/__macro_helpers/declared_ivars.rs new file mode 100644 index 000000000..8b24ccf3e --- /dev/null +++ b/crates/objc2/src/__macro_helpers/declared_ivars.rs @@ -0,0 +1,546 @@ +//! # Supporting code for instance variables on declared classes. +//! +//! Adding instance variables to Objective-C classes is fairly simple, it can +//! be done using `ClassBuilder::add_ivar`. +//! +//! However, things become more complicated once we have to handle `Drop`, +//! deallocation and unwind safety. +//! +//! TODO about Swift also + +// TODO SAFETY: +// - The ivars are in a type used as an Objective-C object. +// - The ivar is added to the class in `__objc2_declare_ivars`. +// - Caller upholds that the ivars are properly initialized. + +use alloc::borrow::Cow; +use alloc::format; +use core::mem; +use core::ptr::{self, NonNull}; + +use crate::declare::ClassBuilder; +use crate::encode::{Encode, Encoding}; +use crate::runtime::{AnyClass, AnyObject, MessageReceiver, Sel}; +use crate::{sel, ClassType, DeclaredClass}; + +/// Helper function for marking the cold path when branching. +#[inline] +#[cold] +fn cold_path() {} + +/// Helper function for getting a pointer to the instance variable. +#[inline] +unsafe fn ptr_to_ivar(ptr: NonNull) -> NonNull { + // SAFETY: That an instance variable with the given type exists at the + // specified offset is ensured by `DeclaredClass` trait implementor. + // TODO + unsafe { AnyObject::ivar_at_offset::(ptr.cast(), T::__ivars_offset()) } +} + +/// Helper function for getting a pointer to the drop flag. +/// +/// # Safety +/// +/// The pointer must be valid, and a drop flag must have been initialized. +#[inline] +unsafe fn ptr_to_drop_flag(ptr: NonNull) -> NonNull { + // SAFETY: That a drop flag exists at the specified offset is ensured + // by caller. + unsafe { AnyObject::ivar_at_offset::(ptr.cast(), T::__drop_flag_offset()) } +} + +// I think the most efficient way to do the storage is as follows: +// +// match (mem::needs_drop::(), mem::needs_drop::()) { +// (false, false) => { +// struct { +// ivars: Self::Ivars, +// } +// } +// (false, true) if None::.is_all_zeroes_bitpattern() => { +// struct { +// ivars: Option, +// } +// } +// _ => { +// struct { +// ivars: Self::Ivars, +// drop_flag: u8, +// } +// } +// } +// +// TODO: Maybe we can reuse the drop flag when subclassing an already +// declared class? +// +// if None::.is_all_zeroes_bitpattern( +// +// Note that it'd be wonderful if we could do this optimization for +// ivars that have a zero niche, e.g. somehow know if the type is safe to drop when zero-initialized, +// but detecting if the `None` is all +// zeroes requires reading the bytes, which is not possible for +// types that may have padding. +// +// FUture: bytemuck::Zeroable +// +// See: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=ea068e8d9e55801aa9520ea914eb2822 +#[repr(u8)] +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)] +pub(crate) enum DropFlag { + /// Set to zero to ensure that this is the default when created from + /// Objective-C as well. + /// + /// Ivars are [documented][obj-init-zeroed] to be zero-initialized after + /// allocation, and that has been true since at least [the Objective-C + /// version shipped with Mac OS X 10.0][objc4-208-init]. + /// + /// [obj-init-zeroed]: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/WorkingwithObjects/WorkingwithObjects.html#//apple_ref/doc/uid/TP40011210-CH4-SW7 + /// [objc4-208-init]: https://github.com/apple-oss-distributions/objc4/blob/objc4-208/runtime/objc-class.m#L367 + #[default] + Allocated = 0, + InitializedIvars = 1, + Finalized = 2, +} + +// SAFETY: The DropFlag is #[repr(u8)] +unsafe impl Encode for DropFlag { + const ENCODING: Encoding = u8::ENCODING; +} + +/// The `dealloc` Objective-C method. +/// +/// See the following links for more details about `dealloc`: +/// - +/// - +/// - +/// +/// TODO: Change this to `extern "C-unwind"`, unwinding in dealloc is allowed. +unsafe extern "C" fn dealloc(this: NonNull, cmd: Sel) +where + T::Super: ClassType, +{ + // SAFETY: `dealloc` is only registered when there is a need for dropping, + // and hence a need for a drop flag. + let drop_flag = unsafe { *ptr_to_drop_flag(this).as_ptr() }; + + if mem::needs_drop::() { + match drop_flag { + // Don't deallocate the current instance if it has not been fully + // initialized. + // + // Note that we still run the superclass deinitializer below. + DropFlag::Allocated | DropFlag::InitializedIvars => cold_path(), + // SAFETY: This is the `dealloc` method, so we know that the type + // never needs to be deallocated again. + // + // Additionally, we know that the type was fully initialized, since + // that's what the drop flag says. + DropFlag::Finalized => unsafe { ptr::drop_in_place(this.as_ptr()) }, + } + } + + // TODO: Debug assertions that the retain count is still 1 here. + + // Note: This should be done inside `.cxx_destruct`, since if a superclass + // calls an overwritten method in its `dealloc`, it can access + // deinitialized instance variables, but we can't do that without + // generating statics, so we have to do it here for now. + // + // Another possibility would be to read the contents of the ivars onto the + // stack here, and only deinitialize after the superclass' `dealloc`, but + // that would break the pinning guarantee that ivars otherwise have. + if mem::needs_drop::() { + match drop_flag { + // Do nothing if the ivars have not been initialized. + DropFlag::Allocated => cold_path(), + DropFlag::InitializedIvars | DropFlag::Finalized => { + // SAFETY: The instance TODO + unsafe { ptr::drop_in_place(ptr_to_ivar(this).as_ptr()) }; + } + } + } + + // The superclass' "marker" that this stores is wrapped in `ManuallyDrop`, + // we drop it by calling the superclass' `dealloc` method instead. + // + // Note: ARC does this automatically, which means most Objective-C code in + // the wild don't contain this call; but we _are_ ARC, so we must do this. + unsafe { + MessageReceiver::send_super_message( + this, + ::Super::class(), + cmd, // Reuse the selector + (), // No arguments + ) + } +} + +pub(crate) fn setup_dealloc(builder: &mut ClassBuilder) +where + T::Super: ClassType, +{ + // Add dealloc if the class or the ivars need dropping. + // + // `needs_drop::` can reliably detect a direct implementation of + // `Drop`, since the type only includes `ManuallyDrop` or `PhantomData` + // fields. + if mem::needs_drop::() | mem::needs_drop::() { + let func: unsafe extern "C" fn(_, _) = dealloc::; + unsafe { builder.add_method(sel!(dealloc), func) }; + } +} + +#[inline] +pub(crate) fn register_with_ivars( + mut builder: ClassBuilder, +) -> (&'static AnyClass, isize, isize) { + let (ivar_name, drop_flag_name): (Cow<'static, str>, Cow<'static, str>) = { + if cfg!(feature = "gnustep-1-7") { + // GNUStep does not support a subclass having an ivar with the + // same name as a superclass, so let's just use the class name as + // the ivar name to ensure uniqueness. + ( + format!("{}_ivars", T::NAME).into(), + format!("{}_drop_flag", T::NAME).into(), + ) + } else { + ("ivars".into(), "drop_flag".into()) + } + }; + + // Only add ivar if we need the runtime to allocate memory for it. + let has_ivars = + mem::size_of::() > 0 || mem::align_of::() > mem::align_of::<*mut T>(); + if has_ivars { + // TODO about why we add the encoding. Swift doesn't do that! + let ivar_encoding = Encoding::Array( + mem::size_of::() as u64, + match mem::align_of::() { + 1 => &u8::ENCODING, + 2 => &u16::ENCODING, + 4 => &u32::ENCODING, + // The alignment of `u64` may not be 8 on all architectures + 8 if mem::align_of::() == 8 => &u64::ENCODING, + alignment => panic!("unsupported alignment {alignment}"), + }, + ); + unsafe { builder.add_ivar_inner::(&ivar_name, &ivar_encoding) }; + } + + // Only add drop flag if the type or the ivars need it. + // + // TODO: Maybe we can get around the need for the "is finalized" drop + // flag when the ivars are zero-sized? + let has_drop_flag = mem::needs_drop::() || mem::needs_drop::(); + if has_drop_flag { + builder.add_ivar::(&drop_flag_name); + } + + let cls = builder.register(); + + let ivars_offset = if has_ivars { + cls.instance_variable(&ivar_name) + .expect("failed retrieving instance variable on newly declared class") + .offset() + } else { + // Fallback to an offset of zero. + // + // This is fine, since any reads here will only be via. zero-sized + // ivars, where the actual pointer doesn't matter. + 0 + }; + + let drop_flag_offset = if has_drop_flag { + cls.instance_variable(&drop_flag_name) + .expect("failed retrieving instance variable on newly declared class") + .offset() + } else { + // Fall back to an offset of zero. + // + // This is fine, since the drop flag is never actually used in the + // cases where it was not added. + 0 + }; + + (cls, ivars_offset, drop_flag_offset) +} + +/// # Safety +/// +/// The pointer must be a valid allocated instance. +#[inline] +pub(crate) unsafe fn initialize_ivars(ptr: NonNull, val: T::Ivars) { + // TODO: Debug assert drop flag? + + // SAFETY: + // - Caller ensures the pointer is valid. + // - The location is properly aligned by `ClassBuilder::add_ivar`. + // + // TODO regarding concurrency + unsafe { ptr_to_ivar(ptr).as_ptr().write(val) }; + + // Write to drop flag that we've initialized the instance variables. + // + // Note: We intentionally only do this _after_ writing to the ivars, + // for better unwind safety. + // + // TODO regarding concurrency + if mem::needs_drop::() { + // SAFETY: The ivars need drop, hence the drop flag is available. + unsafe { + ptr_to_drop_flag(ptr) + .as_ptr() + .write(DropFlag::InitializedIvars) + } + } +} + +/// # Safety +/// +/// The pointer must be valid and finalized (i.e. all super initializers must +/// have been run). +#[inline] +pub(crate) unsafe fn set_finalized(ptr: NonNull) { + // Write to drop flag that we've fully initialized the class. + // + // TODO regarding concurrency + if mem::needs_drop::() { + // SAFETY: The type needs drop, hence the drop flag is available. + unsafe { ptr_to_drop_flag(ptr).as_ptr().write(DropFlag::Finalized) } + } +} + +/// # Safety +/// +/// The pointer must be valid and the instance variables must be initialized. +#[inline] +pub(crate) unsafe fn get_initialized_ivar_ptr( + ptr: NonNull, +) -> NonNull { + #[cfg(debug_assertions)] + if mem::needs_drop::() { + // SAFETY: The ivars need drop, hence the drop flag is available. + match unsafe { *ptr_to_drop_flag(ptr).as_ptr() } { + DropFlag::Allocated => { + unreachable!("tried to access uninitialized instance variable") + } + // TODO: Note: The class itself is allowed to not be _set_ as initialized yet, since that only happens after being initialized, but it may be accessed in subclasses before this. + DropFlag::InitializedIvars => {} + DropFlag::Finalized => {} + } + } + + // SAFETY: That the pointer is valid is ensured by caller. + unsafe { ptr_to_ivar(ptr) } +} + +#[cfg(test)] +mod tests { + use core::sync::atomic::{AtomicBool, Ordering}; + + use alloc::boxed::Box; + + use super::*; + use crate::mutability::Mutable; + use crate::rc::{Allocated, Id, __RcTestObject, __ThreadTestData}; + use crate::runtime::NSObject; + use crate::{declare_class, msg_send, msg_send_id, ClassType, DeclaredClass}; + + #[test] + fn assert_size() { + assert_eq!(mem::size_of::(), 1); + } + + #[test] + fn ensure_custom_drop_is_possible() { + static HAS_RUN_DEALLOC: AtomicBool = AtomicBool::new(false); + + #[derive(Default, Debug, PartialEq, Eq)] + struct Ivars { + ivar: u8, + ivar_bool: bool, + } + + declare_class!( + struct CustomDrop; + + unsafe impl ClassType for CustomDrop { + type Super = NSObject; + type Mutability = Mutable; + const NAME: &'static str = "CustomDrop"; + } + + impl DeclaredClass for CustomDrop { + type Ivars = Ivars; + } + + unsafe impl CustomDrop { + #[method_id(init)] + fn init(this: Allocated) -> Id { + let this = this.set_ivars(Ivars::default()); + unsafe { msg_send_id![super(this), init] } + } + } + ); + + impl Drop for CustomDrop { + fn drop(&mut self) { + HAS_RUN_DEALLOC.store(true, Ordering::Relaxed); + } + } + + let _: Id = unsafe { msg_send_id![CustomDrop::class(), new] }; + + assert!(HAS_RUN_DEALLOC.load(Ordering::Relaxed)); + } + + #[derive(Debug, PartialEq, Eq)] + struct IvarTesterIvars { + ivar1: Id<__RcTestObject>, + ivar2: Option>, + ivar3: Box>, + ivar4: Option>>, + } + + declare_class!( + #[derive(Debug, PartialEq, Eq)] + struct IvarTester; + + unsafe impl ClassType for IvarTester { + type Super = NSObject; + type Mutability = Mutable; + const NAME: &'static str = "IvarTester"; + } + + impl DeclaredClass for IvarTester { + type Ivars = IvarTesterIvars; + } + + unsafe impl IvarTester { + #[method_id(init)] + fn init(this: Allocated) -> Option> { + let this = this.set_ivars(IvarTesterIvars { + ivar1: __RcTestObject::new(), + ivar2: Some(__RcTestObject::new()), + ivar3: Box::new(__RcTestObject::new()), + ivar4: Some(Box::new(__RcTestObject::new())), + }); + unsafe { msg_send_id![super(this), init] } + } + + #[method(initInvalid)] + fn init_invalid(this: *mut Self) -> *mut Self { + // Don't actually initialize anything here; this creates an + // invalid instance, where accessing the two ivars `ivar1` + // and `ivar3` is UB + unsafe { msg_send![super(this), init] } + } + } + ); + + #[derive(Debug, PartialEq, Eq)] + struct IvarTesterSubclassIvars { + ivar5: Id<__RcTestObject>, + } + + declare_class!( + #[derive(Debug, PartialEq, Eq)] + struct IvarTesterSubclass; + + unsafe impl ClassType for IvarTesterSubclass { + type Super = IvarTester; + type Mutability = Mutable; + const NAME: &'static str = "IvarTesterSubclass"; + } + + impl DeclaredClass for IvarTesterSubclass { + type Ivars = IvarTesterSubclassIvars; + } + + unsafe impl IvarTesterSubclass { + #[method_id(init)] + fn init(this: Allocated) -> Option> { + let this = this.set_ivars(IvarTesterSubclassIvars { + ivar5: __RcTestObject::new(), + }); + unsafe { msg_send_id![super(this), init] } + } + } + ); + + #[test] + fn test_alloc_dealloc() { + let expected = __ThreadTestData::current(); + + let obj: Allocated = unsafe { msg_send_id![IvarTester::class(), alloc] }; + expected.assert_current(); + + drop(obj); + expected.assert_current(); + } + + #[test] + fn test_init_drop() { + let mut expected = __ThreadTestData::current(); + + let mut obj: Id = unsafe { msg_send_id![IvarTester::class(), new] }; + expected.alloc += 4; + expected.init += 4; + expected.assert_current(); + + obj.ivars_mut().ivar1 = obj.ivars().ivar1.clone(); + expected.retain += 1; + expected.release += 1; + expected.assert_current(); + + obj.ivars_mut().ivar2 = None; + expected.release += 1; + expected.drop += 1; + expected.assert_current(); + + drop(obj); + expected.release += 3; + expected.drop += 3; + expected.assert_current(); + } + + #[test] + fn test_subclass() { + let mut expected = __ThreadTestData::current(); + + let mut obj: Id = + unsafe { msg_send_id![IvarTesterSubclass::class(), new] }; + expected.alloc += 5; + expected.init += 5; + expected.assert_current(); + + obj.ivars_mut().ivar5 = (&**obj).ivars().ivar1.clone(); + expected.retain += 1; + expected.release += 1; + expected.drop += 1; + expected.assert_current(); + + drop(obj); + expected.release += 5; + expected.drop += 4; + expected.assert_current(); + } + + #[test] + #[cfg_attr(not(debug_assertions), ignore = "only panics with debug assertions")] + #[should_panic = "internal error: entered unreachable code: tried to access uninitialized instance variable"] + fn test_init_invalid_ref() { + let obj: Id = unsafe { msg_send_id![IvarTester::alloc(), initInvalid] }; + + std::println!("{:?}", obj.ivars().ivar1); + } + + #[test] + #[cfg_attr(not(debug_assertions), ignore = "only panics with debug assertions")] + #[should_panic = "internal error: entered unreachable code: tried to access uninitialized instance variable"] + fn test_init_invalid_mut() { + let mut obj: Id = unsafe { msg_send_id![IvarTester::alloc(), initInvalid] }; + + obj.ivars_mut().ivar1 = __RcTestObject::new(); + } +} diff --git a/crates/objc2/src/__macro_helpers/mod.rs b/crates/objc2/src/__macro_helpers/mod.rs index b7cffdbf7..d71158f81 100644 --- a/crates/objc2/src/__macro_helpers/mod.rs +++ b/crates/objc2/src/__macro_helpers/mod.rs @@ -2,11 +2,10 @@ pub use core::borrow::{Borrow, BorrowMut}; pub use core::cell::UnsafeCell; pub use core::convert::{AsMut, AsRef}; pub use core::marker::{PhantomData, Sized}; -pub use core::mem::{needs_drop, size_of, ManuallyDrop}; +pub use core::mem::{size_of, ManuallyDrop, MaybeUninit}; pub use core::ops::{Deref, DerefMut}; pub use core::option::Option::{self, None, Some}; -pub use core::primitive::{bool, str, u8}; -pub use core::ptr::drop_in_place; +pub use core::primitive::{bool, isize, str, u8}; pub use core::{compile_error, concat, panic, stringify}; // TODO: Use `core::cell::LazyCell` pub use std::sync::Once; @@ -15,6 +14,7 @@ mod cache; mod common_selectors; mod convert; mod declare_class; +pub(crate) mod declared_ivars; mod method_family; mod msg_send; mod msg_send_id; @@ -32,7 +32,7 @@ pub use self::method_family::{ retain_semantics, Alloc, CopyOrMutCopy, Init, New, Other, RetainSemantics, }; pub use self::msg_send::MsgSend; -pub use self::msg_send_id::{MaybeUnwrap, MsgSendId}; +pub use self::msg_send_id::{MaybeUnwrap, MsgSendId, MsgSendSuperId}; /// Helper struct for emitting the module info that macOS 32-bit requires. /// diff --git a/crates/objc2/src/__macro_helpers/msg_send_id.rs b/crates/objc2/src/__macro_helpers/msg_send_id.rs index 85bf82e66..cfb932f08 100644 --- a/crates/objc2/src/__macro_helpers/msg_send_id.rs +++ b/crates/objc2/src/__macro_helpers/msg_send_id.rs @@ -1,10 +1,11 @@ -use core::ptr; +use core::ptr::{self, NonNull}; -use crate::encode::Encode; -use crate::rc::{Allocated, Id}; +use crate::encode::{Encode, RefEncode}; +use crate::rc::{Allocated, Id, PartialInit}; use crate::runtime::{AnyClass, AnyObject, Sel}; -use crate::{sel, Message}; +use crate::{sel, ClassType, DeclaredClass, Message}; +use super::declared_ivars::set_finalized; use super::{Alloc, ConvertArguments, CopyOrMutCopy, Init, MsgSend, New, Other, TupleExtender}; pub trait MsgSendId { @@ -57,6 +58,94 @@ pub trait MsgSendId { } } +/// new: T -> Option> +/// alloc: &AnyClass -> Allocated +/// init: PartialInit -> Option> // Changed +/// copy/mutableCopy: T -> Option> // Disallow for now, unsure if we want it to return a helper type? +/// others: T -> Option> +#[doc(hidden)] +pub trait MsgSendSuperId { + type Inner: ?Sized + RefEncode; + + unsafe fn send_super_message_id>( + obj: T, + superclass: &AnyClass, + sel: Sel, + args: A, + ) -> R; + + #[inline] + #[track_caller] + unsafe fn send_super_message_id_static>( + obj: T, + sel: Sel, + args: A, + ) -> R + where + Self::Inner: ClassType, + ::Super: ClassType, + { + unsafe { + Self::send_super_message_id(obj, ::Super::class(), sel, args) + } + } + + #[inline] + #[track_caller] + unsafe fn send_super_message_id_error( + obj: T, + superclass: &AnyClass, + sel: Sel, + args: A, + ) -> Result> + where + *mut *mut E: Encode, + A: TupleExtender<*mut *mut E>, + >::PlusOneArgument: ConvertArguments, + E: Message, + Option: MaybeUnwrap, + { + let mut err: *mut E = ptr::null_mut(); + let args = args.add_argument(&mut err); + // SAFETY: See `send_message_id_error` + let res: Option = unsafe { Self::send_super_message_id(obj, superclass, sel, args) }; + if let Some(res) = res { + Ok(res) + } else { + // SAFETY: See `send_message_id_error` + Err(unsafe { encountered_error(err) }) + } + } + + #[inline] + #[track_caller] + unsafe fn send_super_message_id_static_error( + obj: T, + sel: Sel, + args: A, + ) -> Result> + where + Self::Inner: ClassType, + ::Super: ClassType, + *mut *mut E: Encode, + A: TupleExtender<*mut *mut E>, + >::PlusOneArgument: ConvertArguments, + E: Message, + Option: MaybeUnwrap, + { + let mut err: *mut E = ptr::null_mut(); + let args = args.add_argument(&mut err); + // SAFETY: See `send_message_id_error` + let res: Option = unsafe { Self::send_super_message_id_static(obj, sel, args) }; + if let Some(res) = res { + Ok(res) + } else { + // SAFETY: See `send_message_id_error` + Err(unsafe { encountered_error(err) }) + } + } +} + // Marked `cold` to tell the optimizer that errors are comparatively rare. // And intentionally not inlined, for much the same reason. #[cold] @@ -85,6 +174,26 @@ impl MsgSendId>> for New { } } +impl MsgSendSuperId>> for New { + type Inner = T::Inner; + + #[inline] + unsafe fn send_super_message_id>>>( + obj: T, + superclass: &AnyClass, + sel: Sel, + args: A, + ) -> R { + let ptr = obj.into_raw_receiver(); + // SAFETY: Same as in `send_message_id` + let obj = unsafe { MsgSend::send_super_message(ptr, superclass, sel, args) }; + // SAFETY: Same as in `send_message_id` + let obj = unsafe { Id::new(obj) }; + // SAFETY: Same as in `send_message_id` + R::maybe_unwrap::(obj, (unsafe { ptr.as_ref() }, sel)) + } +} + impl MsgSendId<&'_ AnyClass, Allocated> for Alloc { #[inline] unsafe fn send_message_id>>( @@ -100,6 +209,24 @@ impl MsgSendId<&'_ AnyClass, Allocated> for Alloc { } } +impl MsgSendSuperId<&'_ AnyClass, Allocated> for Alloc { + type Inner = AnyClass; + + #[inline] + unsafe fn send_super_message_id>>( + cls: &AnyClass, + superclass: &AnyClass, + sel: Sel, + args: A, + ) -> R { + // SAFETY: Same as in `send_message_id` + let obj = unsafe { MsgSend::send_super_message(cls, superclass, sel, args) }; + // SAFETY: Same as in `send_message_id` + let obj = unsafe { Allocated::new(obj) }; + R::maybe_unwrap::(obj, ()) + } +} + impl MsgSendId, Option>> for Init { #[inline] unsafe fn send_message_id>>>( @@ -121,6 +248,32 @@ impl MsgSendId, Option>> for Init { } } +impl MsgSendSuperId, Option>> for Init { + type Inner = T; + + #[inline] + unsafe fn send_super_message_id>>>( + obj: PartialInit, + superclass: &AnyClass, + sel: Sel, + args: A, + ) -> R { + let ptr = PartialInit::into_ptr(obj); + // SAFETY: Same as `send_message_id`. + let ptr = unsafe { MsgSend::send_super_message(ptr, superclass, sel, args) }; + // SAFETY: The returned pointer is the same as the one we passed in. + // + // TODO: If this is not the case, a lot will have gone wrong anyhow, + // so unsure if we can do anything better than just ignore the issue? + if let Some(ptr) = NonNull::new(ptr) { + unsafe { set_finalized(ptr) } + } + // SAFETY: Same as `send_message_id` + let obj = unsafe { Id::new(ptr) }; + R::maybe_unwrap::(obj, (ptr.cast(), sel)) + } +} + impl MsgSendId>> for CopyOrMutCopy { #[inline] unsafe fn send_message_id>>>( @@ -137,6 +290,24 @@ impl MsgSendId>> for CopyOrMutC } } +impl MsgSendSuperId>> for CopyOrMutCopy { + type Inner = T::Inner; + + #[inline] + unsafe fn send_super_message_id>>>( + obj: T, + superclass: &AnyClass, + sel: Sel, + args: A, + ) -> R { + // SAFETY: Same as in `send_message_id` + let obj = unsafe { MsgSend::send_super_message(obj, superclass, sel, args) }; + // SAFETY: Same as in `send_message_id` + let obj = unsafe { Id::new(obj) }; + R::maybe_unwrap::(obj, ()) + } +} + impl MsgSendId>> for Other { #[inline] unsafe fn send_message_id>>>( @@ -160,6 +331,26 @@ impl MsgSendId>> for Other { } } +impl MsgSendSuperId>> for Other { + type Inner = T::Inner; + + #[inline] + unsafe fn send_super_message_id>>>( + obj: T, + superclass: &AnyClass, + sel: Sel, + args: A, + ) -> R { + let ptr = obj.into_raw_receiver(); + // SAFETY: Same as `send_message_id` + let obj = unsafe { MsgSend::send_super_message(ptr, superclass, sel, args) }; + // SAFETY: Same as `send_message_id` + let obj = unsafe { Id::retain_autoreleased(obj) }; + // SAFETY: Same as `send_message_id` + R::maybe_unwrap::(obj, (unsafe { ptr.as_ref() }, sel)) + } +} + pub trait MaybeUnwrap { type Input; #[track_caller] @@ -349,7 +540,8 @@ mod tests { drop(obj); expected.release += 1; - expected.dealloc += 1; + // Drop flag ensures uninitialized do not Drop + // expected.drop += 1; expected.assert_current(); } @@ -427,7 +619,7 @@ mod tests { expected.assert_current(); }); expected.release += 5; - expected.dealloc += 4; + expected.drop += 4; expected.assert_current(); } diff --git a/crates/objc2/src/__macro_helpers/writeback.rs b/crates/objc2/src/__macro_helpers/writeback.rs index 3b4e78f77..aaf2a3fd7 100644 --- a/crates/objc2/src/__macro_helpers/writeback.rs +++ b/crates/objc2/src/__macro_helpers/writeback.rs @@ -258,7 +258,7 @@ mod tests { if error.is_some() { expected.release += 1; - expected.dealloc += 1; + expected.drop += 1; } drop(error); expected.assert_current(); @@ -279,7 +279,7 @@ mod tests { expected.init += 1; expected.retain += 1; expected.release += 1; - expected.dealloc += 1; + expected.drop += 1; helper(&mut expected, true, Some(__RcTestObject::new())); } @@ -328,19 +328,19 @@ mod tests { drop(obj); expected.release += 1; if AUTORELEASE_SKIPPED { - expected.dealloc += 1; + expected.drop += 1; } expected.assert_current(); }); if !AUTORELEASE_SKIPPED { expected.release += 1; - expected.dealloc += 1; + expected.drop += 1; } expected.assert_current(); drop(err); expected.release += 1; - expected.dealloc += 1; + expected.drop += 1; expected.assert_current(); } } diff --git a/crates/objc2/src/declare/ivar.rs b/crates/objc2/src/declare/ivar.rs deleted file mode 100644 index d89b32a6e..000000000 --- a/crates/objc2/src/declare/ivar.rs +++ /dev/null @@ -1,388 +0,0 @@ -use core::fmt; -use core::marker::PhantomData; -use core::mem::{self, MaybeUninit}; -use core::ops::{Deref, DerefMut}; -use core::ptr::{self, NonNull}; - -use crate::encode::Encode; -use crate::runtime::AnyObject; - -pub(crate) mod private { - pub trait Sealed {} -} - -/// Types that may be used in ivars. -/// -/// This may be either: -/// - [`IvarBool`][super::IvarBool]. -/// - [`IvarDrop`][super::IvarDrop]. -/// - [`IvarEncode`][super::IvarEncode]. -/// -/// This is a sealed trait, and should not need to be implemented. Open an -/// issue if you know a use-case where this restrition should be lifted! -/// -/// -/// # Safety -/// -/// You cannot rely on any safety guarantees from this. -// -// The type must have the same memory layout as the output type. -// -// Additionally, the type must be safe to drop even if zero-initialized. -// -// Ivars are documented to be zero-initialized in [this section of the -// Objective-C manual][obj-dynamically-created], and that has been true since -// at least [the Objective-C version shipped with Mac OS X 10.0][objc4-208]. -// -// [obj-dynamically-created]: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/WorkingwithObjects/WorkingwithObjects.html#//apple_ref/doc/uid/TP40011210-CH4-SW7 -// [objc4-208]: https://github.com/apple-oss-distributions/objc4/blob/objc4-208/runtime/objc-class.m#L367 -pub unsafe trait InnerIvarType: private::Sealed + Encode { - /// The type that an `Ivar` containing this will dereference to. - /// - /// E.g. `Ivar>>` will deref to `Box`. - type Output; - - /// # Safety - /// - /// The instance variable must have been initialized. - #[doc(hidden)] - unsafe fn __deref(&self) -> &Self::Output; - - /// # Safety - /// - /// The instance variable must have been initialized. - #[doc(hidden)] - unsafe fn __deref_mut(&mut self) -> &mut Self::Output; -} - -/// Helper trait for defining instance variables. -/// -/// This should be implemented for an empty marker type, which can then be -/// used within [`Ivar`] to refer to the instance variable. -/// -/// -/// # Safety -/// -/// Really, [`Ivar`] should be marked as `unsafe`, but since we can't do that -/// we'll mark this trait as `unsafe` instead. See [`Ivar`] for safety -/// requirements. -/// -/// -/// # Examples -/// -/// Create an instance variable `myCustomIvar` with type `i32`. -/// -/// ``` -/// use objc2::declare::{IvarEncode, IvarType}; -/// -/// // Helper type -/// struct MyCustomIvar; -/// -/// unsafe impl IvarType for MyCustomIvar { -/// type Type = IvarEncode; -/// const NAME: &'static str = "myCustomIvar"; -/// } -/// -/// // `Ivar` can now be used -/// ``` -pub unsafe trait IvarType { - /// The type of the instance variable. - type Type: InnerIvarType; - /// The name of the instance variable. - const NAME: &'static str; - - #[doc(hidden)] - unsafe fn __ivar_ptr(ptr: NonNull) -> NonNull { - // FIXME: This is currently unsound! Looking up the instance variable - // dynamically will return the wrong variable if two variables with - // the same name exist. - let ivar = unsafe { ptr.as_ref() }.lookup_instance_variable_dynamically(Self::NAME); - ivar.debug_assert_encoding(&Self::Type::ENCODING); - unsafe { AnyObject::ivar_at_offset(ptr, ivar.offset()) } - } -} - -/// A wrapper type over a custom instance variable. -/// -/// This type is not meant to be constructed by itself, it must reside within -/// another struct meant to represent an Objective-C object. -/// -/// On [`Deref`] it then uses the [`IvarType::NAME`] string to access the ivar -/// of the containing object. -/// -/// Note that this is not ([currently][zst-hack]) allowed by [stacked -/// borrows][sb], but due to objects being zero-sized types, we don't have -/// provenance over the ivars anyhow, this should be just as sound as normal -/// instance variable access. -/// -/// [sb]: https://github.com/rust-lang/unsafe-code-guidelines/blob/e21202c60c7be03dd2ab016ada92fb5305d40438/wip/stacked-borrows.md -/// [zst-hack]: https://github.com/rust-lang/unsafe-code-guidelines/issues/305 -/// -/// -/// # `bool` handling -/// -/// This does _not_ perform a conversion step between [`bool`] and the -/// Objective-C `BOOL`; use [`runtime::Bool`][crate::runtime::Bool] when you -/// want your instance variable to be accessible from other Objective-C code. -/// -/// -/// # Safety -/// -/// This must be used within a type that act as an Objective-C object. In -/// particular, this is never safe to have on the stack by itself. -/// -/// Additionally, the instance variable described by `T` must be available on -/// the specific instance, and be of the exact same type. When declaring the -/// object yourself, you can ensure this using -/// [`ClassBuilder::add_static_ivar`]. -/// -/// Finally, two ivars with the same name must not be used on the same object. -/// -/// [`ClassBuilder::add_static_ivar`]: crate::declare::ClassBuilder::add_static_ivar -/// -/// -/// # Examples -/// -/// ``` -/// use objc2::declare::{Ivar, IvarEncode, IvarType}; -/// use objc2::runtime::NSObject; -/// -/// // Declare ivar with given type and name -/// struct MyCustomIvar; -/// unsafe impl IvarType for MyCustomIvar { -/// type Type = IvarEncode; -/// const NAME: &'static str = "myCustomIvar"; -/// } -/// -/// // Custom object -/// #[repr(C)] -/// pub struct MyObject { -/// inner: NSObject, -/// // SAFETY: The instance variable is used within an object, and it is -/// // properly declared below. -/// my_ivar: Ivar, -/// } -/// -/// # use objc2::ClassType; -/// # use objc2::declare::ClassBuilder; -/// # let mut builder = ClassBuilder::new("MyObject", NSObject::class()).unwrap(); -/// // Declare the class and add the instance variable to it -/// builder.add_static_ivar::(); -/// # let _cls = builder.register(); -/// -/// let obj: MyObject; -/// // You can now access `obj.my_ivar` -/// ``` -/// -/// See also the `declare_ivar.rs` example. -#[repr(C)] -// Must not be `Copy` nor `Clone`! -pub struct Ivar { - /// Make this type allowed in `repr(C)` - inner: [u8; 0], - /// For proper variance and auto traits - item: PhantomData, -} - -impl Drop for Ivar { - #[inline] - fn drop(&mut self) { - if mem::needs_drop::() { - unsafe { ptr::drop_in_place(self.as_inner_mut_ptr().as_ptr()) } - } - } -} - -impl Ivar { - /// Get a pointer to the instance variable. - /// - /// Note that if the ivar has already been initialized, you can use the - /// `Deref` implementation to get a reference. - /// - /// This is similar to [`MaybeUninit::as_ptr`], see that for usage - /// instructions. - pub fn as_ptr(this: &Self) -> *const ::Target { - this.as_inner_ptr().as_ptr().cast() - } - - fn as_inner_ptr(&self) -> NonNull { - let ptr: NonNull = NonNull::from(self).cast(); - - // SAFETY: The user ensures that this is placed in a struct that can - // be reinterpreted as an `AnyObject`. Since `Ivar` can never be - // constructed by itself (and is neither Copy nor Clone), we know that - // it is guaranteed to _stay_ in said struct. - // - // Even if the user were to do `mem::swap`, the `Ivar` has a unique - // type (and does not hold any data), so that wouldn't break anything. - // - // Note: We technically don't have provenance over the object, nor the - // ivar, but the object doesn't have provenance over the ivar either, - // so that is fine. - unsafe { T::__ivar_ptr(ptr) } - } - - /// Get a mutable pointer to the instance variable. - /// - /// This is useful when you want to initialize the ivar inside an `init` - /// method (where it may otherwise not have been safely initialized yet). - /// - /// Note that if the ivar has already been initialized, you can use the - /// `DerefMut` implementation to get a mutable reference. - /// - /// This is similar to [`MaybeUninit::as_mut_ptr`], see that for usage - /// instructions. - pub fn as_mut_ptr(this: &mut Self) -> *mut ::Target { - this.as_inner_mut_ptr().as_ptr().cast() - } - - fn as_inner_mut_ptr(&mut self) -> NonNull { - let ptr: NonNull = NonNull::from(self).cast(); - - // SAFETY: Same as `as_inner_ptr` - unsafe { T::__ivar_ptr(ptr) } - } - - /// Sets the value of the instance variable. - /// - /// This is useful when you want to initialize the ivar inside an `init` - /// method (where it may otherwise not have been safely initialized yet). - /// - /// This is similar to [`MaybeUninit::write`], see that for usage - /// instructions. - pub fn write(this: &mut Self, val: ::Target) -> &mut ::Target { - let ptr: *mut ::Output = Self::as_mut_ptr(this); - let ptr: *mut MaybeUninit<::Output> = ptr.cast(); - let ivar = unsafe { ptr.as_mut().unwrap_unchecked() }; - ivar.write(val) - } -} - -impl Deref for Ivar { - type Target = ::Output; - - #[inline] - fn deref(&self) -> &Self::Target { - // SAFETY: User ensures that the `Ivar` is only used when the ivar - // exists, has the correct type, and has been properly initialized. - // - // Since all accesses to a particular ivar only goes through one - // `Ivar`, if we have `&Ivar` we know that `&T` is safe. - unsafe { self.as_inner_ptr().as_ref().__deref() } - } -} - -impl DerefMut for Ivar { - #[inline] - fn deref_mut(&mut self) -> &mut Self::Target { - // SAFETY: User ensures that the `Ivar` is only used when the ivar - // exists, has the correct type, and has been properly initialized. - // - // Safe as mutable because there is only one access to a - // particular ivar at a time (since we have `&mut self`). - - // Note: We're careful not to create `&mut AnyObject` because the user - // might have two mutable references to different ivars, as such: - // - // ``` - // #[repr(C)] - // struct X { - // inner: AnyObject, - // ivar1: Ivar, - // ivar2: Ivar, - // } - // - // let mut x: X; - // let ivar1: &mut Ivar = &mut x.ivar1; - // let ivar2: &mut Ivar = &mut x.ivar2; - // ``` - // - // And using `mut` would create aliasing mutable reference to the - // object. - unsafe { self.as_inner_mut_ptr().as_mut().__deref_mut() } - } -} - -/// Format as a pointer to the instance variable. -impl fmt::Pointer for Ivar { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Pointer::fmt(&Self::as_ptr(self), f) - } -} - -#[cfg(test)] -mod tests { - use core::mem; - use core::panic::{RefUnwindSafe, UnwindSafe}; - use std::sync::atomic::{AtomicBool, Ordering}; - - use super::*; - use crate::declare::{IvarBool, IvarEncode}; - use crate::mutability::Mutable; - use crate::rc::Id; - use crate::runtime::NSObject; - use crate::{declare_class, msg_send, msg_send_id, test_utils, ClassType}; - - struct TestIvar; - - unsafe impl IvarType for TestIvar { - type Type = IvarEncode; - const NAME: &'static str = "_foo"; - } - - #[repr(C)] - struct IvarTestObject { - inner: NSObject, - foo: Ivar, - } - - #[test] - fn auto_traits() { - fn assert_auto_traits() {} - assert_auto_traits::>(); - - // Ensure that `Ivar` is zero-sized - assert_eq!(mem::size_of::>(), 0); - assert_eq!(mem::align_of::>(), 1); - } - - #[test] - fn access_ivar() { - let mut obj = test_utils::custom_object(); - let _: () = unsafe { msg_send![&mut obj, setFoo: 42u32] }; - - let obj = unsafe { Id::as_ptr(&obj).cast::().as_ref().unwrap() }; - assert_eq!(*obj.foo, 42); - } - - #[test] - fn ensure_custom_drop_is_possible() { - static HAS_RUN_DEALLOC: AtomicBool = AtomicBool::new(false); - - declare_class!( - #[derive(Debug, PartialEq, Eq)] - struct CustomDrop { - ivar: IvarEncode, - ivar_bool: IvarBool<"_ivar_bool">, - } - - mod customdrop; - - unsafe impl ClassType for CustomDrop { - type Super = NSObject; - type Mutability = Mutable; - const NAME: &'static str = "CustomDrop"; - } - ); - - impl Drop for CustomDrop { - fn drop(&mut self) { - HAS_RUN_DEALLOC.store(true, Ordering::Relaxed); - } - } - - let _: Id = unsafe { msg_send_id![CustomDrop::class(), new] }; - - assert!(HAS_RUN_DEALLOC.load(Ordering::Relaxed)); - } -} diff --git a/crates/objc2/src/declare/ivar_bool.rs b/crates/objc2/src/declare/ivar_bool.rs deleted file mode 100644 index f7e1930a5..000000000 --- a/crates/objc2/src/declare/ivar_bool.rs +++ /dev/null @@ -1,50 +0,0 @@ -use crate::encode::{Encode, Encoding}; - -use super::InnerIvarType; - -/// Ivar of [`bool`]. -/// -/// This is used to work around the fact that `bool` is not [`Encode`]. -/// -/// If you want to access this instance variable to Objective-C, you must do -/// so using C99 `_Bool`; if you want to use `BOOL` in Objective-C, you should -/// use `IvarEncode`. -#[repr(transparent)] -#[allow(missing_copy_implementations)] -#[allow(missing_debug_implementations)] -pub struct IvarBool(bool); - -unsafe impl Encode for IvarBool { - const ENCODING: Encoding = Encoding::Bool; -} - -impl super::ivar::private::Sealed for IvarBool {} - -// SAFETY: IvarBool is `#[repr(transparent)]`, and `bool` is safe to -// zero-initialize -unsafe impl InnerIvarType for IvarBool { - type Output = bool; - - #[inline] - unsafe fn __deref(&self) -> &Self::Output { - &self.0 - } - - #[inline] - unsafe fn __deref_mut(&mut self) -> &mut Self::Output { - &mut self.0 - } -} - -#[cfg(test)] -mod tests { - use super::*; - - use core::mem; - - #[test] - fn needs_drop() { - assert!(!mem::needs_drop::()); - assert_eq!(mem::size_of::(), mem::size_of::()); - } -} diff --git a/crates/objc2/src/declare/ivar_drop.rs b/crates/objc2/src/declare/ivar_drop.rs deleted file mode 100644 index 0fa488608..000000000 --- a/crates/objc2/src/declare/ivar_drop.rs +++ /dev/null @@ -1,378 +0,0 @@ -use alloc::boxed::Box; -use core::ffi::c_void; - -use crate::encode::{Encode, Encoding}; -use crate::rc::Id; -use crate::Message; - -use super::InnerIvarType; - -mod private { - /// # Safety - /// - /// The inner type must be safe to zero-initialize. - pub unsafe trait IvarDropHelper { - type Inner; - } -} - -/// Ivar types that may drop. -/// -/// This currently works with the following types: -/// - `Box` -/// - `Option>` -/// - `Id` -/// - `Option>` -/// -/// Further may be added when the standard library guarantee their layout. -#[repr(transparent)] -#[allow(missing_debug_implementations)] -pub struct IvarDrop(::Inner); - -impl super::ivar::private::Sealed for IvarDrop {} - -// Note that we use `*const c_void` and not `*const T` to allow _any_ type, -// not just types that can be encoded by Objective-C -unsafe impl Encode for IvarDrop> { - const ENCODING: Encoding = <*const c_void>::ENCODING; -} - -// SAFETY: `Option>` is safe to zero-initialize -unsafe impl private::IvarDropHelper for Box { - type Inner = Option>; -} - -// SAFETY: The memory layout of `Box` is guaranteed to be a pointer: -// -// -// The user ensures that the Box has been initialized in an `init` method -// before being used. -unsafe impl InnerIvarType for IvarDrop> { - type Output = Box; - - #[inline] - unsafe fn __deref(&self) -> &Self::Output { - match &self.0 { - Some(inner) => inner, - None => unsafe { box_unreachable() }, - } - } - - #[inline] - unsafe fn __deref_mut(&mut self) -> &mut Self::Output { - match &mut self.0 { - Some(inner) => inner, - None => unsafe { box_unreachable() }, - } - } -} - -unsafe impl Encode for IvarDrop>> { - const ENCODING: Encoding = <*const c_void>::ENCODING; -} - -// SAFETY: `Option>` is safe to zero-initialize -unsafe impl private::IvarDropHelper for Option> { - type Inner = Option>; -} - -// SAFETY: `Option>` guarantees the null-pointer optimization, so for -// `T: Sized` the layout is just a pointer: -// -// -// This is valid to initialize as all-zeroes, so the user doesn't have to do -// anything to initialize it. -unsafe impl InnerIvarType for IvarDrop>> { - type Output = Option>; - - #[inline] - unsafe fn __deref(&self) -> &Self::Output { - &self.0 - } - - #[inline] - unsafe fn __deref_mut(&mut self) -> &mut Self::Output { - &mut self.0 - } -} - -unsafe impl Encode for IvarDrop> { - const ENCODING: Encoding = <*const T>::ENCODING; -} - -// SAFETY: `Option>` is safe to zero-initialize -unsafe impl private::IvarDropHelper for Id { - type Inner = Option>; -} - -// SAFETY: `Id` is `NonNull`, and hence safe to store as a pointer. -// -// The user ensures that the Id has been initialized in an `init` method -// before being used. -// -// Note: We could technically do `impl InnerIvarType for Ivar>` -// directly today, but since we can't do so for `Box` (because that is -// `#[fundamental]`), I think it makes sense to handle them similarly. -unsafe impl InnerIvarType for IvarDrop> { - type Output = Id; - - #[inline] - unsafe fn __deref(&self) -> &Self::Output { - match &self.0 { - Some(inner) => inner, - None => unsafe { id_unreachable() }, - } - } - - #[inline] - unsafe fn __deref_mut(&mut self) -> &mut Self::Output { - match &mut self.0 { - Some(inner) => inner, - None => unsafe { id_unreachable() }, - } - } -} - -unsafe impl Encode for IvarDrop>> { - const ENCODING: Encoding = <*const T>::ENCODING; -} - -// SAFETY: `Option>` is safe to zero-initialize -unsafe impl private::IvarDropHelper for Option> { - type Inner = Option>; -} - -// SAFETY: `Id` guarantees the null-pointer optimization. -// -// This is valid to initialize as all-zeroes, so the user doesn't have to do -// anything to initialize it. -unsafe impl InnerIvarType for IvarDrop>> { - type Output = Option>; - - #[inline] - unsafe fn __deref(&self) -> &Self::Output { - &self.0 - } - - #[inline] - unsafe fn __deref_mut(&mut self) -> &mut Self::Output { - &mut self.0 - } -} - -// TODO: Allow the following once their layout is guaranteed by `std`: -// - Arc -// - Option> -// - sync::Weak -// - Rc -// - Option> -// - rc::Weak -// - Vec -// - String - -// TODO: Allow `WeakId` once we figure out how to allow it being initialized -// by default. - -#[inline] -#[track_caller] -unsafe fn id_unreachable() -> ! { - #[cfg(debug_assertions)] - { - unreachable!("an Id in instance variables must always be initialized before use!") - } - // SAFETY: Checked by caller - #[cfg(not(debug_assertions))] - unsafe { - core::hint::unreachable_unchecked() - } -} - -#[inline] -#[track_caller] -unsafe fn box_unreachable() -> ! { - #[cfg(debug_assertions)] - { - unreachable!("a Box in instance variables must always be initialized before use!") - } - // SAFETY: Checked by caller - #[cfg(not(debug_assertions))] - unsafe { - core::hint::unreachable_unchecked() - } -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::declare::{Ivar, IvarType}; - use crate::mutability::Mutable; - use crate::rc::{Allocated, __RcTestObject, __ThreadTestData}; - use crate::runtime::NSObject; - use crate::{declare_class, msg_send, msg_send_id, ClassType}; - - struct TestIvar1; - unsafe impl IvarType for TestIvar1 { - type Type = IvarDrop>; - const NAME: &'static str = "_abc"; - } - - struct TestIvar2; - unsafe impl IvarType for TestIvar2 { - type Type = IvarDrop>>; - const NAME: &'static str = "_abc"; - } - - struct TestIvar3; - unsafe impl IvarType for TestIvar3 { - type Type = IvarDrop>; - const NAME: &'static str = "_abc"; - } - - struct TestIvar4; - unsafe impl IvarType for TestIvar4 { - type Type = IvarDrop>>; - const NAME: &'static str = "_abc"; - } - - declare_class!( - #[derive(Debug, PartialEq, Eq)] - struct IvarTester { - ivar1: IvarDrop, "_ivar1">, - ivar2: IvarDrop>, "_ivar2">, - ivar3: IvarDrop>, "_ivar3">, - ivar4: IvarDrop>>, "_ivar4">, - } - - mod ivartester; - - unsafe impl ClassType for IvarTester { - type Super = NSObject; - type Mutability = Mutable; - const NAME: &'static str = "IvarTester"; - } - - unsafe impl IvarTester { - #[method(init)] - fn init(&mut self) -> Option<&mut Self> { - let this: Option<&mut Self> = unsafe { msg_send![super(self), init] }; - this.map(|this| { - Ivar::write(&mut this.ivar1, __RcTestObject::new()); - *this.ivar2 = Some(__RcTestObject::new()); - Ivar::write(&mut this.ivar3, Box::new(__RcTestObject::new())); - *this.ivar4 = Some(Box::new(__RcTestObject::new())); - this - }) - } - - #[method(initInvalid)] - fn init_invalid(&mut self) -> Option<&mut Self> { - // Don't actually initialize anything here; this creates an - // invalid instance, where accessing the two ivars `ivar1` - // and `ivar3` is UB - unsafe { msg_send![super(self), init] } - } - } - ); - - declare_class!( - #[derive(Debug, PartialEq, Eq)] - struct IvarTesterSubclass { - ivar5: IvarDrop, "_ivar5">, - } - - mod ivartestersubclass; - - unsafe impl ClassType for IvarTesterSubclass { - type Super = IvarTester; - type Mutability = Mutable; - const NAME: &'static str = "IvarTesterSubclass"; - } - - unsafe impl IvarTesterSubclass { - #[method(init)] - fn init(&mut self) -> Option<&mut Self> { - let this: Option<&mut Self> = unsafe { msg_send![super(self), init] }; - this.map(|this| { - Ivar::write(&mut this.ivar5, __RcTestObject::new()); - this - }) - } - } - ); - - #[test] - fn test_alloc_dealloc() { - let expected = __ThreadTestData::current(); - - let obj: Allocated = unsafe { msg_send_id![IvarTester::class(), alloc] }; - expected.assert_current(); - - drop(obj); - expected.assert_current(); - } - - #[test] - fn test_init_drop() { - let mut expected = __ThreadTestData::current(); - - let mut obj: Id = unsafe { msg_send_id![IvarTester::class(), new] }; - expected.alloc += 4; - expected.init += 4; - expected.assert_current(); - - *obj.ivar1 = (*obj.ivar1).clone(); - expected.retain += 1; - expected.release += 1; - expected.assert_current(); - - *obj.ivar2 = None; - expected.release += 1; - expected.dealloc += 1; - expected.assert_current(); - - drop(obj); - expected.release += 3; - expected.dealloc += 3; - expected.assert_current(); - } - - #[test] - fn test_subclass() { - let mut expected = __ThreadTestData::current(); - - let mut obj: Id = - unsafe { msg_send_id![IvarTesterSubclass::class(), new] }; - expected.alloc += 5; - expected.init += 5; - expected.assert_current(); - - *obj.ivar5 = (*obj.ivar1).clone(); - expected.retain += 1; - expected.release += 1; - expected.dealloc += 1; - expected.assert_current(); - - drop(obj); - expected.release += 5; - expected.dealloc += 4; - expected.assert_current(); - } - - #[test] - #[cfg_attr(not(debug_assertions), ignore = "only panics in debug mode")] - #[should_panic = "an Id in instance variables must always be initialized before use"] - fn test_init_invalid_ref() { - let obj: Id = unsafe { msg_send_id![IvarTester::alloc(), initInvalid] }; - - std::println!("{:?}", obj.ivar1); - } - - #[test] - #[cfg_attr(not(debug_assertions), ignore = "only panics in debug mode")] - #[should_panic = "an Id in instance variables must always be initialized before use"] - fn test_init_invalid_mut() { - let mut obj: Id = unsafe { msg_send_id![IvarTester::alloc(), initInvalid] }; - - *obj.ivar1 = __RcTestObject::new(); - } -} diff --git a/crates/objc2/src/declare/ivar_encode.rs b/crates/objc2/src/declare/ivar_encode.rs deleted file mode 100644 index 3a4300059..000000000 --- a/crates/objc2/src/declare/ivar_encode.rs +++ /dev/null @@ -1,75 +0,0 @@ -use core::mem::MaybeUninit; - -use crate::encode::{Encode, Encoding}; - -use super::InnerIvarType; - -/// Ivar types that are [`Encode`]. -// -// Note: We put the inner type in a `MaybeUninit`, since we may need to access -// this type before the inner type has been properly initialized. -#[repr(transparent)] -#[allow(missing_debug_implementations)] -pub struct IvarEncode(MaybeUninit); - -// We intentionally don't implement `Drop`, since that may happen before the -// ivar has been initialized. -// -// For example in the case of `NonNull`, it would be zero-initialized, -// which is an invalid state for that to have. - -// SAFETY: `IvarEncode` is `#[repr(transparent)]`, and the layout of -// `MaybeUninit` is the same as `T`. -unsafe impl Encode for IvarEncode { - const ENCODING: Encoding = T::ENCODING; -} - -impl super::ivar::private::Sealed for IvarEncode {} - -// SAFETY: `IvarEncode` has the same memory layout as T, and -// `MaybeUninit` is safe to zero-initialize. -unsafe impl InnerIvarType for IvarEncode { - type Output = T; - - #[inline] - unsafe fn __deref(&self) -> &Self::Output { - // SAFETY: Checked by caller - unsafe { self.0.assume_init_ref() } - } - - #[inline] - unsafe fn __deref_mut(&mut self) -> &mut Self::Output { - // SAFETY: Checked by caller - unsafe { self.0.assume_init_mut() } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - use core::mem; - - #[test] - fn needs_drop() { - assert!(!mem::needs_drop::>()); - assert!(!mem::needs_drop::>()); - - // You wouldn't do this, but let's make sure it works as expected - #[repr(transparent)] - struct DropAndEncode(i32); - - unsafe impl Encode for DropAndEncode { - const ENCODING: Encoding = i32::ENCODING; - } - - impl Drop for DropAndEncode { - fn drop(&mut self) {} - } - - assert!(mem::needs_drop::()); - assert!(!mem::needs_drop::>()); - - assert_eq!(mem::size_of::>(), mem::size_of::()); - } -} diff --git a/crates/objc2/src/declare/ivar_forwarding_impls.rs b/crates/objc2/src/declare/ivar_forwarding_impls.rs deleted file mode 100644 index 3b80f25c7..000000000 --- a/crates/objc2/src/declare/ivar_forwarding_impls.rs +++ /dev/null @@ -1,340 +0,0 @@ -//! Trivial forwarding impls on `Ivar`. -//! -//! Kept here to keep `ivar.rs` free from this boilerplate. -//! -//! `#[inline]` is used where the standard library `Box` uses it. - -#![forbid(unsafe_code)] - -// use alloc::borrow; -use alloc::string::String; -use alloc::vec::Vec; -use core::cmp::Ordering; -use core::fmt; -use core::future::Future; -use core::hash; -use core::iter::FusedIterator; -use core::ops::Deref; -use core::pin::Pin; -use core::task::{Context, Poll}; -use std::error::Error; -use std::io; - -use super::{Ivar, IvarType}; - -impl PartialEq for Ivar -where - ::Target: PartialEq, -{ - #[inline] - fn eq(&self, other: &Self) -> bool { - (**self).eq(&**other) - } - - #[inline] - #[allow(clippy::partialeq_ne_impl)] - fn ne(&self, other: &Self) -> bool { - (**self).ne(&**other) - } -} - -impl Eq for Ivar where ::Target: Eq {} - -impl PartialOrd for Ivar -where - ::Target: PartialOrd, -{ - #[inline] - fn partial_cmp(&self, other: &Self) -> Option { - (**self).partial_cmp(&**other) - } - #[inline] - fn lt(&self, other: &Self) -> bool { - (**self).lt(&**other) - } - #[inline] - fn le(&self, other: &Self) -> bool { - (**self).le(&**other) - } - #[inline] - fn ge(&self, other: &Self) -> bool { - (**self).ge(&**other) - } - #[inline] - fn gt(&self, other: &Self) -> bool { - (**self).gt(&**other) - } -} - -impl Ord for Ivar -where - ::Target: Ord, -{ - #[inline] - fn cmp(&self, other: &Self) -> Ordering { - (**self).cmp(&**other) - } -} - -impl hash::Hash for Ivar -where - ::Target: hash::Hash, -{ - fn hash(&self, state: &mut H) { - (**self).hash(state) - } -} - -impl hash::Hasher for Ivar -where - ::Target: hash::Hasher, -{ - fn finish(&self) -> u64 { - (**self).finish() - } - fn write(&mut self, bytes: &[u8]) { - (**self).write(bytes) - } - fn write_u8(&mut self, i: u8) { - (**self).write_u8(i) - } - fn write_u16(&mut self, i: u16) { - (**self).write_u16(i) - } - fn write_u32(&mut self, i: u32) { - (**self).write_u32(i) - } - fn write_u64(&mut self, i: u64) { - (**self).write_u64(i) - } - fn write_u128(&mut self, i: u128) { - (**self).write_u128(i) - } - fn write_usize(&mut self, i: usize) { - (**self).write_usize(i) - } - fn write_i8(&mut self, i: i8) { - (**self).write_i8(i) - } - fn write_i16(&mut self, i: i16) { - (**self).write_i16(i) - } - fn write_i32(&mut self, i: i32) { - (**self).write_i32(i) - } - fn write_i64(&mut self, i: i64) { - (**self).write_i64(i) - } - fn write_i128(&mut self, i: i128) { - (**self).write_i128(i) - } - fn write_isize(&mut self, i: isize) { - (**self).write_isize(i) - } -} - -impl fmt::Display for Ivar -where - ::Target: fmt::Display, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - (**self).fmt(f) - } -} - -impl fmt::Debug for Ivar -where - ::Target: fmt::Debug, -{ - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - (**self).fmt(f) - } -} - -impl Iterator for Ivar -where - ::Target: Iterator, -{ - type Item = <::Target as Iterator>::Item; - fn next(&mut self) -> Option<<::Target as Iterator>::Item> { - (**self).next() - } - fn size_hint(&self) -> (usize, Option) { - (**self).size_hint() - } - fn nth(&mut self, n: usize) -> Option<<::Target as Iterator>::Item> { - (**self).nth(n) - } -} - -impl DoubleEndedIterator for Ivar -where - ::Target: DoubleEndedIterator, -{ - fn next_back(&mut self) -> Option<<::Target as Iterator>::Item> { - (**self).next_back() - } - fn nth_back(&mut self, n: usize) -> Option<<::Target as Iterator>::Item> { - (**self).nth_back(n) - } -} - -impl ExactSizeIterator for Ivar -where - ::Target: ExactSizeIterator, -{ - fn len(&self) -> usize { - (**self).len() - } -} - -impl FusedIterator for Ivar where ::Target: FusedIterator {} - -// impl borrow::Borrow<::Target> for Ivar { -// fn borrow(&self) -> &::Target { -// self -// } -// } -// -// impl borrow::BorrowMut<::Target> for Ivar { -// fn borrow_mut(&mut self) -> &mut ::Target { -// self -// } -// } - -impl AsRef<::Target> for Ivar { - fn as_ref(&self) -> &::Target { - // Auto-derefs - self - } -} - -impl AsMut<::Target> for Ivar { - fn as_mut(&mut self) -> &mut ::Target { - // Auto-derefs - self - } -} - -impl Error for Ivar -where - ::Target: Error, -{ - fn source(&self) -> Option<&(dyn Error + 'static)> { - (**self).source() - } -} - -impl io::Read for Ivar -where - ::Target: io::Read, -{ - #[inline] - fn read(&mut self, buf: &mut [u8]) -> io::Result { - (**self).read(buf) - } - - #[inline] - fn read_vectored(&mut self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result { - (**self).read_vectored(bufs) - } - - #[inline] - fn read_to_end(&mut self, buf: &mut Vec) -> io::Result { - (**self).read_to_end(buf) - } - - #[inline] - fn read_to_string(&mut self, buf: &mut String) -> io::Result { - (**self).read_to_string(buf) - } - - #[inline] - fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { - (**self).read_exact(buf) - } -} - -impl io::Write for Ivar -where - ::Target: io::Write, -{ - #[inline] - fn write(&mut self, buf: &[u8]) -> io::Result { - (**self).write(buf) - } - - #[inline] - fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result { - (**self).write_vectored(bufs) - } - - #[inline] - fn flush(&mut self) -> io::Result<()> { - (**self).flush() - } - - #[inline] - fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { - (**self).write_all(buf) - } - - #[inline] - fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> { - (**self).write_fmt(fmt) - } -} - -impl io::Seek for Ivar -where - ::Target: io::Seek, -{ - #[inline] - fn seek(&mut self, pos: io::SeekFrom) -> io::Result { - (**self).seek(pos) - } - - #[inline] - fn stream_position(&mut self) -> io::Result { - (**self).stream_position() - } -} - -impl io::BufRead for Ivar -where - ::Target: io::BufRead, -{ - #[inline] - fn fill_buf(&mut self) -> io::Result<&[u8]> { - (**self).fill_buf() - } - - #[inline] - fn consume(&mut self, amt: usize) { - (**self).consume(amt) - } - - #[inline] - fn read_until(&mut self, byte: u8, buf: &mut Vec) -> io::Result { - (**self).read_until(byte, buf) - } - - #[inline] - fn read_line(&mut self, buf: &mut String) -> io::Result { - (**self).read_line(buf) - } -} - -impl Future for Ivar -where - Self: Unpin, - ::Target: Future + Unpin, -{ - type Output = <::Target as Future>::Output; - - fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - <::Target as Future>::poll(Pin::new(&mut *self), cx) - } -} - -// TODO: impl Fn traits, CoerceUnsized, Stream and so on when stabilized diff --git a/crates/objc2/src/declare/mod.rs b/crates/objc2/src/declare/mod.rs index 6f61fc867..0daa8155c 100644 --- a/crates/objc2/src/declare/mod.rs +++ b/crates/objc2/src/declare/mod.rs @@ -4,12 +4,6 @@ //! variables and methods can then be added before the class is ultimately //! registered. -mod ivar; -mod ivar_bool; -mod ivar_drop; -mod ivar_encode; -mod ivar_forwarding_impls; - use alloc::format; use alloc::string::ToString; use core::mem; @@ -24,11 +18,6 @@ use crate::runtime::{AnyClass, AnyObject, AnyProtocol, Bool, Imp, MethodImplemen use crate::sel; use crate::Message; -pub use ivar::{InnerIvarType, Ivar, IvarType}; -pub use ivar_bool::IvarBool; -pub use ivar_drop::IvarDrop; -pub use ivar_encode::IvarEncode; - fn method_type_encoding(ret: &Encoding, args: &[Encoding]) -> CString { // First two arguments are always self and the selector let mut types = format!("{ret}{}{}", <*mut AnyObject>::ENCODING, Sel::ENCODING); @@ -399,6 +388,10 @@ impl ClassBuilder { unsafe { self.add_ivar_inner::(name, &T::ENCODING) } } + pub(crate) unsafe fn add_ivar_inner(&mut self, name: &str, encoding: &Encoding) { + unsafe { self.add_ivar_inner_mono(name, mem::size_of::(), T::LOG2_ALIGNMENT, encoding) } + } + // Monomorphized version unsafe fn add_ivar_inner_mono( &mut self, @@ -430,21 +423,6 @@ impl ClassBuilder { assert!(success.as_bool(), "failed to add ivar {name}"); } - unsafe fn add_ivar_inner(&mut self, name: &str, encoding: &Encoding) { - unsafe { self.add_ivar_inner_mono(name, mem::size_of::(), T::LOG2_ALIGNMENT, encoding) } - } - - /// Adds an instance variable from an [`IvarType`]. - /// - /// - /// # Panics - /// - /// Same as [`ClassBuilder::add_ivar`]. - pub fn add_static_ivar(&mut self) { - // SAFETY: The encoding is correct - unsafe { self.add_ivar_inner::(T::NAME, &T::Type::ENCODING) } - } - /// Adds the given protocol to self. /// /// # Panics @@ -617,7 +595,8 @@ mod tests { use crate::rc::Id; use crate::runtime::{NSObject, NSObjectProtocol}; use crate::{ - declare_class, extern_methods, msg_send, msg_send_id, test_utils, ClassType, ProtocolType, + declare_class, extern_methods, msg_send, msg_send_id, test_utils, ClassType, DeclaredClass, + ProtocolType, }; #[test] @@ -905,6 +884,8 @@ mod tests { type Mutability = Immutable; const NAME: &'static str = "TestInheritedNSObjectMethodsWork"; } + + impl DeclaredClass for Custom {} ); extern_methods!( @@ -923,7 +904,7 @@ mod tests { // description let expected = - format!("Custom {{ __superclass: ManuallyDrop {{ value: }} }}"); + format!("Custom {{ __superclass: ManuallyDrop {{ value: }}, __ivars: PhantomData<()> }}"); assert_eq!(format!("{obj1:?}"), expected); // hash diff --git a/crates/objc2/src/lib.rs b/crates/objc2/src/lib.rs index 1dbaeb38e..c6cec5447 100644 --- a/crates/objc2/src/lib.rs +++ b/crates/objc2/src/lib.rs @@ -190,7 +190,7 @@ pub use objc_sys as ffi; #[doc(no_inline)] pub use self::encode::{Encode, Encoding, RefEncode}; -pub use self::top_level_traits::{ClassType, Message, ProtocolType}; +pub use self::top_level_traits::{ClassType, DeclaredClass, Message, ProtocolType}; #[cfg(feature = "objc2-proc-macros")] #[doc(hidden)] diff --git a/crates/objc2/src/macros/__field_helpers.rs b/crates/objc2/src/macros/__field_helpers.rs deleted file mode 100644 index b545f17c6..000000000 --- a/crates/objc2/src/macros/__field_helpers.rs +++ /dev/null @@ -1,355 +0,0 @@ -#[doc(hidden)] -#[macro_export] -macro_rules! __emit_struct_and_ivars { - ( - ($(#[$m:meta])*) - ($v:vis) - ($($struct:tt)*) - ($($ivar_helper_module_v:vis mod $ivar_helper_module:ident)?) - ($($fields:tt)*) - ($($parsed_fields:tt)*) - ) => { - $crate::__parse_fields! { - ($($fields)*) - ($($ivar_helper_module_v mod $ivar_helper_module)?) - () () // No parsed ivars - ($($parsed_fields)*) - - ($crate::__emit_struct) - ($(#[$m])*) - ($v) - ($($struct)*) - } - } -} - -#[doc(hidden)] -#[macro_export] -macro_rules! __emit_struct { - ( - ($(#[$m:meta])*) - ($v:vis) - ($($struct:tt)*) - - ($($fields:tt)*) - ) => { - $(#[$m])* - #[repr(C)] - $v struct $($struct)* { - // These are at this point all zero-sized. - $($fields)* - } - } -} - -#[doc(hidden)] -#[macro_export] -macro_rules! __parse_fields { - // Base-case, no ivars, no module - ( - () // No more fields left - () // No module - () () // No ivars - ($($parsed_fields:tt)*) - - ($out_macro:path) - $($macro_args:tt)* - ) => { - $out_macro! { - $($macro_args)* - - ($($parsed_fields)*) - } - }; - - // Base-case, has ivars, no module - ( - () // No more fields left - () // No module - ($($ivar_output:tt)+) ($($ivar_type_name:tt)+) - ($($parsed_fields:tt)*) - - ($out_macro:path) - $($macro_args:tt)* - ) => { - $crate::__macro_helpers::compile_error!( - "must specify an ivar module when the type has ivars" - ); - - $($ivar_output)+ - - $out_macro! { - $($macro_args)* - - ($($parsed_fields)*) - } - }; - - // Base-case, no ivars, has module - ( - () // No more fields left - ($ivar_helper_module_v:vis mod $ivar_helper_module:ident) - () () // No ivars - ($($parsed_fields:tt)*) - - ($out_macro:path) - $($macro_args:tt)* - ) => { - $ivar_helper_module_v mod $ivar_helper_module { - $crate::__macro_helpers::compile_error!( - "no need to specify an ivar module when the type has no ivars" - ); - - pub(super) fn __objc2_declare_ivars( - __objc2_builder: &mut $crate::__macro_helpers::ClassBuilderHelper, - ) {} - } - - $out_macro! { - $($macro_args)* - - ($($parsed_fields)*) - } - }; - - // Base-case, has ivars, has module - ( - () // No more fields left - ($ivar_helper_module_v:vis mod $ivar_helper_module:ident) - ($($ivar_output:tt)+) ($($ivar_type_name:ident)+) - ($($parsed_fields:tt)*) - - ($out_macro:path) - $($macro_args:tt)* - ) => { - $ivar_helper_module_v mod $ivar_helper_module { - use super::*; - - $($ivar_output)+ - - pub(super) fn __objc2_declare_ivars( - __objc2_builder: &mut $crate::__macro_helpers::ClassBuilderHelper, - ) { - // Ivars - $( - __objc2_builder.add_static_ivar::<$ivar_type_name>(); - )+ - } - } - - $out_macro! { - $($macro_args)* - - ($($parsed_fields)*) - } - }; - - // PhantomData - ( - ( - $(#[$m:meta])* - $vis:vis $field_name:ident: PhantomData<$ty:ty> - $(, $($rest_fields:tt)*)? - ) - ($($ivar_helper_module_v:vis mod $ivar_helper_module:ident)?) - ($($ivar_output:tt)*) ($($ivar_type_name:ident)*) - ($($parsed_fields:tt)*) - - ($out_macro:path) - $($macro_args:tt)* - ) => { - $crate::__parse_fields! { - ($($($rest_fields)*)?) - ($($ivar_helper_module_v mod $ivar_helper_module)?) - ($($ivar_output)*) ($($ivar_type_name)*) - ( - $($parsed_fields)* - - // A user could have defined their own PhantomData-like, type, - // and then tried to use it here, which we would accept, but - // which wouldn't necessarily be zero-sized! - // - // Hence we wrap it in an extra PhantomData, to ensure it is - // (while still not generating "unused imports" for the user). - $(#[$m])* - $vis $field_name: $crate::__macro_helpers::PhantomData>, - ) - - ($out_macro) - $($macro_args)* - } - }; - - // IvarDrop - ( - ( - $(#[$m:meta])* - $vis:vis $field_name:ident: IvarDrop<$ty:ty, $ivar_name:literal> - $(, $($rest_fields:tt)*)? - ) - ($($ivar_helper_module_v:vis mod $ivar_helper_module:ident)?) - ($($ivar_output:tt)*) ($($ivar_type_name:ident)*) - ($($parsed_fields:tt)*) - - ($out_macro:path) - $($macro_args:tt)* - ) => { - $crate::__parse_fields! { - ($($($rest_fields)*)?) - ($($ivar_helper_module_v mod $ivar_helper_module)?) - ( - $($ivar_output)* - - #[allow(non_camel_case_types)] - #[allow(unreachable_pub)] - pub struct $field_name { - __priv: (), - } - - // SAFETY: - // - The ivars are in a type used as an Objective-C object. - // - The ivar is added to the class in `__objc2_declare_ivars`. - // - Caller upholds that the ivars are properly initialized. - unsafe impl $crate::declare::IvarType for $field_name { - type Type = IvarDrop<$ty>; - const NAME: &'static $crate::__macro_helpers::str = $ivar_name; - } - ) ($($ivar_type_name)* $field_name) - ( - $($parsed_fields)* - - $(#[$m])* - $vis $field_name: $crate::declare::Ivar<$($ivar_helper_module ::)? $field_name>, - ) - - ($out_macro) - $($macro_args)* - } - }; - - // IvarEncode - ( - ( - $(#[$m:meta])* - $vis:vis $field_name:ident: IvarEncode<$ty:ty, $ivar_name:literal> - $(, $($rest_fields:tt)*)? - ) - ($($ivar_helper_module_v:vis mod $ivar_helper_module:ident)?) - ($($ivar_output:tt)*) ($($ivar_type_name:ident)*) - ($($parsed_fields:tt)*) - - ($out_macro:path) - $($macro_args:tt)* - ) => { - $crate::__parse_fields! { - ($($($rest_fields)*)?) - ($($ivar_helper_module_v mod $ivar_helper_module)?) - ( - $($ivar_output)* - - #[allow(non_camel_case_types)] - #[allow(unreachable_pub)] - pub struct $field_name { - __priv: (), - } - - // SAFETY: See above - unsafe impl $crate::declare::IvarType for $field_name { - type Type = IvarEncode<$ty>; - const NAME: &'static $crate::__macro_helpers::str = $ivar_name; - } - ) ($($ivar_type_name)* $field_name) - ( - $($parsed_fields)* - - $(#[$m])* - $vis $field_name: $crate::declare::Ivar<$($ivar_helper_module ::)? $field_name>, - ) - - ($out_macro) - $($macro_args)* - } - }; - - // IvarBool - ( - ( - $(#[$m:meta])* - $vis:vis $field_name:ident: IvarBool<$ivar_name:literal> - $(, $($rest_fields:tt)*)? - ) - ($($ivar_helper_module_v:vis mod $ivar_helper_module:ident)?) - ($($ivar_output:tt)*) ($($ivar_type_name:ident)*) - ($($parsed_fields:tt)*) - - ($out_macro:path) - $($macro_args:tt)* - ) => { - $crate::__parse_fields! { - ($($($rest_fields)*)?) - ($($ivar_helper_module_v mod $ivar_helper_module)?) - ( - $($ivar_output)* - - #[allow(non_camel_case_types)] - #[allow(unreachable_pub)] - pub struct $field_name { - __priv: (), - } - - // SAFETY: See above - unsafe impl $crate::declare::IvarType for $field_name { - type Type = IvarBool; - const NAME: &'static $crate::__macro_helpers::str = $ivar_name; - } - ) ($($ivar_type_name)* $field_name) - ( - $($parsed_fields)* - - $(#[$m])* - $vis $field_name: $crate::declare::Ivar<$($ivar_helper_module ::)? $field_name>, - ) - - ($out_macro) - $($macro_args)* - } - }; - - // Invalid type - ( - ( - $(#[$m:meta])* - $vis:vis $field_name:ident: $ty:ty - $(, $($rest_fields:tt)*)? - ) - ($($ivar_helper_module_v:vis mod $ivar_helper_module:ident)?) - ($($ivar_output:tt)*) ($($ivar_type_name:ident)*) - ($($parsed_fields:tt)*) - - ($out_macro:path) - $($macro_args:tt)* - ) => { - $crate::__macro_helpers::compile_error!($crate::__macro_helpers::concat!( - "invalid type ", - $crate::__macro_helpers::stringify!($ty), - " in field ", - $crate::__macro_helpers::stringify!($field_name), - ". Type must be either `PhantomData`, `IvarDrop`, `IvarBool` or `IvarEncode`." - )); - - $crate::__parse_fields! { - ($($($rest_fields)*)?) - ($($ivar_helper_module_v mod $ivar_helper_module)?) - ($($ivar_output)*) ($($ivar_type_name)*) - ( - $($parsed_fields)* - - $(#[$m])* - $vis $field_name: $ty, - ) - - ($out_macro) - $($macro_args)* - } - } -} diff --git a/crates/objc2/src/macros/__method_msg_send.rs b/crates/objc2/src/macros/__method_msg_send.rs index fbcccf9b8..3dfe8a238 100644 --- a/crates/objc2/src/macros/__method_msg_send.rs +++ b/crates/objc2/src/macros/__method_msg_send.rs @@ -167,6 +167,7 @@ macro_rules! __method_msg_send_id { $crate::__msg_send_id_helper! { ($receiver) ($($retain_semantics)?) + (MsgSendId) (send_message_id) ($sel) () @@ -255,6 +256,7 @@ macro_rules! __method_msg_send_id { $crate::__msg_send_id_helper! { ($receiver) ($($retain_semantics)?) + (MsgSendId) (send_message_id) ($($sel_parsed)*) ($($arg_parsed)*) @@ -275,6 +277,7 @@ macro_rules! __method_msg_send_id { $crate::__msg_send_id_helper! { ($receiver) ($($retain_semantics)?) + (MsgSendId) // Use error method (send_message_id_error) ($($sel_parsed)* $sel :) diff --git a/crates/objc2/src/macros/__msg_send_parse.rs b/crates/objc2/src/macros/__msg_send_parse.rs index e6ee0c5fa..31f25fce9 100644 --- a/crates/objc2/src/macros/__msg_send_parse.rs +++ b/crates/objc2/src/macros/__msg_send_parse.rs @@ -139,6 +139,7 @@ macro_rules! __comma_between_args { #[macro_export] #[cfg(feature = "unstable-msg-send-always-comma")] macro_rules! __comma_between_args { + // msg_send! ( (send_super_message_static) ($($args:tt)*) @@ -169,12 +170,37 @@ macro_rules! __comma_between_args { ($crate::__macro_helpers::stringify!($obj), $($args)*) } }; - // Catch-all for msg_send_id! + // msg_send_id! ( - ($fn:ident) + (send_super_message_id_static) + ($($args:tt)*) + ($obj:expr) + () + (MsgSendSuperId) + ) => { + $crate::__comma_between_args_inner! { + ("msg_send_id") + ($crate::__macro_helpers::stringify!(super($obj)), $($args)*) + } + }; + ( + (send_super_message_id) + ($($args:tt)*) + ($obj:expr, $superclass:expr) + () + (MsgSendSuperId) + ) => { + $crate::__comma_between_args_inner! { + ("msg_send_id") + ($crate::__macro_helpers::stringify!(super($obj, $superclass)), $($args)*) + } + }; + ( + (send_message_id) ($($args:tt)*) ($obj:expr) () + (MsgSendId) ) => { $crate::__comma_between_args_inner! { ("msg_send_id") diff --git a/crates/objc2/src/macros/declare_class.rs b/crates/objc2/src/macros/declare_class.rs index 2b710477c..60c28e140 100644 --- a/crates/objc2/src/macros/declare_class.rs +++ b/crates/objc2/src/macros/declare_class.rs @@ -17,8 +17,9 @@ /// # Specification /// /// This macro consists of roughly four parts: -/// - The type and ivar definition. +/// - The type declaration. /// - The [`ClassType`] implementation. +/// - The [`DeclaredClass`] definition. /// - Any number of method definitions. /// - Any number of protocol implementations. /// @@ -30,35 +31,23 @@ /// [`extern_methods!`]: crate::extern_methods /// /// -/// ## Ivar definition +/// ## Type declaration /// -/// The type definition works a lot like [`extern_class!`] (including the +/// The type declaration works a lot like [`extern_class!`] (including the /// allowed attributes), with the added capability that struct fields are /// automatically defined as custom instance variables, which are then /// accessible on instances of the class. (E.g. you can use `self.my_ivar` as /// if the class was a normal Rust struct). /// -/// The instance variables are specified as such: -/// - [`IvarEncode`](crate::declare::IvarEncode) -/// - [`IvarBool<"my_crate_ivar">`](crate::declare::IvarBool) -/// - [`IvarDrop`](crate::declare::IvarDrop) -/// -/// This is special syntax that will be used to generate helper types that -/// implement [`declare::IvarType`], which is then used inside the new struct. -/// -/// Instance variable names must be unique, and must not conflict with any -/// superclass' instance variables - this means is is good practice to name -/// them with a prefix of your crate name, or similar. -/// -/// [`declare::IvarType`]: crate::declare::IvarType +/// Additionally TODO /// /// /// ## `ClassType` implementation /// -/// This also resembles that in [`extern_class!`], except that -/// [`ClassType::NAME`] must be specified, and it must be unique across the -/// entire application. Good practice here is to include your crate name in -/// the prefix. +/// This resembles that in [`extern_class!`], except that [`ClassType::NAME`] +/// must be specified, and it must be unique across the entire application. +/// +/// Good practice here is to include your crate name in the prefix. /// /// The class is guaranteed to have been created and registered with the /// Objective-C runtime after the [`ClassType::class`] function has been @@ -71,6 +60,27 @@ /// [`ClassType::class`]: crate::ClassType::class /// /// +/// ## `DeclaredClass` definition +/// +/// TODO +/// +/// Beware that the ivars must be initialized in an init method; this should be ensured by the `extern_methods` that declares the methods to initialize. +/// +/// The instance variables are specified as such: +/// - [`IvarEncode`](crate::declare::IvarEncode) +/// - [`IvarBool<"my_crate_ivar">`](crate::declare::IvarBool) +/// - [`IvarDrop`](crate::declare::IvarDrop) +/// +/// This is special syntax that will be used to generate helper types that +/// implement [`declare::IvarType`], which is then used inside the new struct. +/// +/// Instance variable names must be unique, and must not conflict with any +/// superclass' instance variables - this means is is good practice to name +/// them with a prefix of your crate name, or similar. +/// +/// [`declare::IvarType`]: crate::declare::IvarType +/// +/// /// ## Method definitions /// /// Within the `impl` block you can define two types of functions; @@ -161,6 +171,7 @@ /// - Any instance variables you specify under the struct definition must /// either be able to be created using [`MaybeUninit::zeroed`], or be /// properly initialized in an `init` method. +/// - `Drop` implementation TODO. /// /// `unsafe impl T { ... }` asserts that the types match those that are /// expected when the method is invoked from Objective-C. Note that unlike @@ -189,20 +200,21 @@ /// # use objc2::runtime::{NSObject, NSObjectProtocol, NSZone}; /// # #[cfg(available_in_icrate)] /// use icrate::Foundation::{NSCopying, NSObject, NSObjectProtocol, NSZone}; -/// use objc2::declare::{Ivar, IvarDrop, IvarEncode}; -/// use objc2::rc::Id; +/// use objc2::rc::{Allocated, Id}; /// use objc2::{ -/// declare_class, extern_protocol, msg_send, msg_send_id, mutability, ClassType, ProtocolType, +/// declare_class, extern_protocol, msg_send, msg_send_id, mutability, ClassType, +/// DeclaredClass, ProtocolType, /// }; /// -/// declare_class!( -/// struct MyCustomObject { -/// foo: IvarEncode, -/// pub bar: IvarEncode, -/// object: IvarDrop, "_object">, -/// } +/// #[derive(Clone)] +/// struct Ivars { +/// foo: u8, +/// bar: c_int, +/// object: Id, +/// } /// -/// mod ivars; +/// declare_class!( +/// struct MyCustomObject; /// /// unsafe impl ClassType for MyCustomObject { /// type Super = NSObject; @@ -210,40 +222,29 @@ /// const NAME: &'static str = "MyCustomObject"; /// } /// +/// impl DeclaredClass for MyCustomObject { +/// type Ivars = Ivars; +/// } +/// /// unsafe impl MyCustomObject { -/// #[method(initWithFoo:)] -/// fn init_with(this: &mut Self, foo: u8) -> Option<&mut Self> { -/// let this: Option<&mut Self> = unsafe { -/// msg_send![super(this), init] -/// }; -/// -/// this.map(|this| { -/// // Initialize instance variables -/// -/// // Some types like `u8`, `bool`, `Option>` and -/// // `Option>` are safe to zero-initialize, and we can -/// // write to the variable as normal: -/// *this.foo = foo; -/// *this.bar = 42; -/// -/// // For others like `&u8`, `Box` or `Id`, we have to -/// // initialize them with `Ivar::write`: -/// Ivar::write(&mut this.object, NSObject::new()); -/// -/// // All the instance variables have been initialized; our -/// // initializer is sound -/// this -/// }) +/// #[method_id(initWithFoo:)] +/// fn init_with(this: Allocated, foo: u8) -> Option> { +/// let this = this.set_ivars(Ivars { +/// foo, +/// bar: 42, +/// object: NSObject::new(), +/// }); +/// unsafe { msg_send_id![super(this), init] } /// } /// /// #[method(foo)] /// fn __get_foo(&self) -> u8 { -/// *self.foo +/// self.ivars().foo /// } /// /// #[method_id(object)] /// fn __get_object(&self) -> Id { -/// self.object.clone() +/// self.ivars().object.clone() /// } /// /// #[method(myClassMethod)] @@ -253,9 +254,8 @@ /// # /// # #[method_id(copyWithZone:)] /// # fn copyWithZone(&self, _zone: *const NSZone) -> Id { -/// # let mut obj = Self::new(*self.foo); -/// # *obj.bar = *self.bar; -/// # obj +/// # let new = Self::alloc().set_ivars(self.ivars().clone()); +/// # unsafe { msg_send_id![super(new), init] } /// # } /// } /// @@ -265,9 +265,8 @@ /// unsafe impl NSCopying for MyCustomObject { /// #[method_id(copyWithZone:)] /// fn copyWithZone(&self, _zone: *const NSZone) -> Id { -/// let mut obj = Self::new(*self.foo); -/// *obj.bar = *self.bar; -/// obj +/// let new = Self::alloc().set_ivars(self.ivars().clone()); +/// unsafe { msg_send_id![super(new), init] } /// } /// /// // If we have tried to add other methods here, or had forgotten @@ -296,9 +295,9 @@ /// /// fn main() { /// let obj = MyCustomObject::new(3); -/// assert_eq!(*obj.foo, 3); -/// assert_eq!(*obj.bar, 42); -/// assert!(obj.object.is_kind_of::()); +/// assert_eq!(obj.ivars().foo, 3); +/// assert_eq!(obj.ivars().bar, 42); +/// assert!(obj.ivars().object.is_kind_of::()); /// /// # let obj: Id = unsafe { msg_send_id![&obj, copy] }; /// # #[cfg(available_in_icrate)] @@ -316,22 +315,18 @@ /// ```text /// #import /// -/// @interface MyCustomObject: NSObject { -/// // Public ivar -/// int bar; -/// } -/// +/// @interface MyCustomObject: NSObject /// - (instancetype)initWithFoo:(uint8_t)foo; /// - (uint8_t)foo; /// - (NSObject*)object; /// + (BOOL)myClassMethod; -/// /// @end /// /// /// @implementation MyCustomObject { -/// // Private ivar +/// // Instance variables /// uint8_t foo; +/// int bar; /// NSObject* _Nonnull object; /// } /// @@ -360,9 +355,10 @@ /// // NSCopying /// /// - (id)copyWithZone:(NSZone *)_zone { -/// MyCustomObject* obj = [[MyCustomObject alloc] initWithFoo: self->foo]; -/// obj->bar = self->bar; -/// return obj; +/// MyCustomObject* new = [[MyCustomObject alloc] initWithFoo: self->foo]; +/// new->bar = self->bar; +/// new->obj = self->obj; +/// return new; /// } /// /// @end @@ -371,16 +367,11 @@ #[doc(alias = "@implementation")] #[macro_export] macro_rules! declare_class { - // With ivar helper { $(#[$m:meta])* - $v:vis struct $name:ident { - $($fields:tt)* - } - - $ivar_helper_module_v:vis mod $ivar_helper_module:ident; + $v:vis struct $name:ident; - unsafe impl ClassType for $for:ty { + unsafe impl ClassType for $for_class:ty { $(#[inherits($($inheritance_rest:ty),+)])? type Super = $superclass:ty; @@ -389,238 +380,108 @@ macro_rules! declare_class { const NAME: &'static str = $name_const:expr; } - $($impls:tt)* - } => { - $crate::__emit_struct_and_ivars! { - ($(#[$m])*) - ($v) - ($name) - ($ivar_helper_module_v mod $ivar_helper_module) - ($($fields)*) - ( - // Superclasses are deallocated by calling `[super dealloc]`. - __superclass: $crate::__macro_helpers::ManuallyDrop<$superclass>, - ) - } - - $crate::__declare_class_inner! { - ($ivar_helper_module) - - unsafe impl ClassType for $for { - $(#[inherits($($inheritance_rest),+)])? - type Super = $superclass; - - type Mutability = $mutability; - - const NAME: &'static str = $name_const; - } - - $($impls)* - } - }; - - // No ivar helper - { - $(#[$m:meta])* - $v:vis struct $name:ident { - $($fields:tt)* - } - - unsafe impl ClassType for $for:ty { - $(#[inherits($($inheritance_rest:ty),+)])? - type Super = $superclass:ty; - - type Mutability = $mutability:ty; - - const NAME: &'static str = $name_const:expr; + impl DeclaredClass for $for_declared:ty { + $(type Ivars = $ivars:ty;)? } $($impls:tt)* } => { - $crate::__emit_struct_and_ivars! { - ($(#[$m])*) - ($v) - ($name) - () - ($($fields)*) - ( - // Superclasses are deallocated by calling `[super dealloc]`. - __superclass: $crate::__macro_helpers::ManuallyDrop<$superclass>, - ) + $(#[$m])* + #[repr(C)] + $v struct $name { + // Superclasses are deallocated by calling `[super dealloc]`. + __superclass: $crate::__macro_helpers::ManuallyDrop<$superclass>, + // Include ivars for proper auto traits. + __ivars: $crate::__macro_helpers::PhantomData<::Ivars>, } - $crate::__declare_class_inner! { - () - - unsafe impl ClassType for $for { - $(#[inherits($($inheritance_rest),+)])? - type Super = $superclass; + $crate::__extern_class_impl_traits! { + // SAFETY: Upheld by caller + unsafe impl () for $for_class { + INHERITS = [$superclass, $($($inheritance_rest,)+)? $crate::runtime::AnyObject]; - type Mutability = $mutability; + fn as_super(&self) { + &*self.__superclass + } - const NAME: &'static str = $name_const; + fn as_super_mut(&mut self) { + &mut *self.__superclass + } } - - $($impls)* } - }; - - // Allow declaring class with no instance variables - { - $(#[$m:meta])* - $v:vis struct $name:ident; - unsafe impl ClassType for $for:ty { - $(#[inherits($($inheritance_rest:ty),+)])? - type Super = $superclass:ty; + // Anonymous block to hide the shared statics + const _: () = { + static mut __OBJC2_CLASS: $crate::__macro_helpers::MaybeUninit<&'static $crate::runtime::AnyClass> = $crate::__macro_helpers::MaybeUninit::uninit(); + static mut __OBJC2_IVAR_OFFSET: $crate::__macro_helpers::MaybeUninit<$crate::__macro_helpers::isize> = $crate::__macro_helpers::MaybeUninit::uninit(); + static mut __OBJC2_DROP_FLAG_OFFSET: $crate::__macro_helpers::MaybeUninit<$crate::__macro_helpers::isize> = $crate::__macro_helpers::MaybeUninit::uninit(); - type Mutability = $mutability:ty; - - const NAME: &'static str = $name_const:expr; - } - - $($impls:tt)* - } => { - $crate::__emit_struct_and_ivars! { - ($(#[$m])*) - ($v) - ($name) - () - () - ( - // Superclasses are deallocated by calling `[super dealloc]`. - __superclass: $crate::__macro_helpers::ManuallyDrop<$superclass>, - ) - } - - $crate::__declare_class_inner! { - () - - unsafe impl ClassType for $for { - $(#[inherits($($inheritance_rest),+)])? + // Creation + unsafe impl ClassType for $for_class { type Super = $superclass; - type Mutability = $mutability; + const NAME: &'static $crate::__macro_helpers::str = $name_const; - const NAME: &'static str = $name_const; - } + fn class() -> &'static $crate::runtime::AnyClass { + $crate::__macro_helpers::assert_mutability_matches_superclass_mutability::(); - $($impls)* - } - }; -} + // TODO: Use `core::cell::LazyCell` + static REGISTER_CLASS: $crate::__macro_helpers::Once = $crate::__macro_helpers::Once::new(); -#[doc(hidden)] -#[macro_export] -macro_rules! __declare_class_inner { - { - ($($ivar_helper_module:ident)?) + REGISTER_CLASS.call_once(|| { + let mut __objc2_builder = $crate::__macro_helpers::ClassBuilderHelper::::new(); - unsafe impl ClassType for $for:ty { - $(#[inherits($($inheritance_rest:ty),+)])? - type Super = $superclass:ty; + // Implement protocols and methods + $crate::__declare_class_register_impls! { + (__objc2_builder) + $($impls)* + } - type Mutability = $mutability:ty; + let (__objc2_cls, __objc2_ivar_offset, __objc2_drop_flag_offset) = __objc2_builder.register(); - const NAME: &'static str = $name_const:expr; - } + // SAFETY: Modification is ensured by `Once` to happen + // before any access to the variables. + unsafe { + __OBJC2_CLASS.write(__objc2_cls); + __OBJC2_IVAR_OFFSET.write(__objc2_ivar_offset); + __OBJC2_DROP_FLAG_OFFSET.write(__objc2_drop_flag_offset); + } + }); - $($impls:tt)* - } => { - $crate::__extern_class_impl_traits! { - // SAFETY: Upheld by caller - unsafe impl () for $for { - INHERITS = [$superclass, $($($inheritance_rest,)+)? $crate::runtime::AnyObject]; + // SAFETY: We just registered the class, so is now available + unsafe { __OBJC2_CLASS.assume_init() } + } - fn as_super(&self) { + #[inline] + fn as_super(&self) -> &Self::Super { &*self.__superclass } - fn as_super_mut(&mut self) { + #[inline] + fn as_super_mut(&mut self) -> &mut Self::Super { &mut *self.__superclass } } - } - // Creation - unsafe impl ClassType for $for { - type Super = $superclass; - type Mutability = $mutability; - const NAME: &'static $crate::__macro_helpers::str = $name_const; - - fn class() -> &'static $crate::runtime::AnyClass { - $crate::__macro_helpers::assert_mutability_matches_superclass_mutability::(); - - // TODO: Use `core::cell::LazyCell` - static REGISTER_CLASS: $crate::__macro_helpers::Once = $crate::__macro_helpers::Once::new(); - - REGISTER_CLASS.call_once(|| { - let mut __objc2_builder = $crate::__macro_helpers::ClassBuilderHelper::::new(); - - $($ivar_helper_module::__objc2_declare_ivars(&mut __objc2_builder);)? - - // See the following links for more details: - // - - // - - // - - unsafe extern "C" fn __objc2_dealloc(__objc2_self: *mut $for, __objc2_cmd: $crate::runtime::Sel) { - // SAFETY: Ivars are explicitly designed to always - // be valid to drop, and since this is the - // `dealloc` method, we know the ivars are never - // going to be touched again. - // - // This also runs any `Drop` impl that the type may - // have. - unsafe { $crate::__macro_helpers::drop_in_place(__objc2_self) }; - - // The superclass' "marker" that this stores is - // wrapped in `ManuallyDrop`, instead we drop it by - // calling the superclass' `dealloc` method. - // - // Note: ARC does this automatically, which means - // most Objective-C code in the wild don't contain - // this; but we _are_ ARC, so we must do this. - unsafe { - $crate::__macro_helpers::MsgSend::send_super_message_static( - __objc2_self, - __objc2_cmd, // Reuse the selector - (), // No arguments - ) - } - } - - if $crate::__macro_helpers::needs_drop::() { - unsafe { - __objc2_builder.add_method( - $crate::sel!(dealloc), - __objc2_dealloc as unsafe extern "C" fn(_, _), - ); - } - } + unsafe impl DeclaredClass for $for_declared { + type Ivars = $crate::__select_ivars!($($ivars)?); - // Implement protocols and methods - $crate::__declare_class_register_impls! { - (__objc2_builder) - $($impls)* - } - - let _cls = __objc2_builder.register(); - }); - - // We just registered the class, so it should be available - $crate::runtime::AnyClass::get(::NAME).unwrap() - } + #[inline] + fn __ivars_offset() -> $crate::__macro_helpers::isize { + // SAFETY: Accessing the offset is guaranteed to only be + // done after the class has been initialized. + unsafe { __OBJC2_IVAR_OFFSET.assume_init() } + } - #[inline] - fn as_super(&self) -> &Self::Super { - &*self.__superclass - } + #[inline] + fn __drop_flag_offset() -> $crate::__macro_helpers::isize { + // SAFETY: Same as above. + unsafe { __OBJC2_DROP_FLAG_OFFSET.assume_init() } + } - #[inline] - fn as_super_mut(&mut self) -> &mut Self::Super { - &mut *self.__superclass + const __INNER: () = (); } - } + }; // Methods $crate::__declare_class_output_impls! { @@ -640,6 +501,18 @@ macro_rules! __select_name { }; } +#[doc(hidden)] +#[macro_export] +macro_rules! __select_ivars { + ($ivars:ty) => { + $ivars + }; + () => { + // Default ivars to empty tuple + () + }; +} + #[doc(hidden)] #[macro_export] macro_rules! __declare_class_output_impls { diff --git a/crates/objc2/src/macros/extern_methods.rs b/crates/objc2/src/macros/extern_methods.rs index 3fe32b354..3b9e893b0 100644 --- a/crates/objc2/src/macros/extern_methods.rs +++ b/crates/objc2/src/macros/extern_methods.rs @@ -69,7 +69,7 @@ /// use objc2::ffi::NSUInteger; /// use objc2::rc::{Allocated, Id}; /// use objc2::runtime::NSObject; -/// use objc2::{declare_class, extern_methods, mutability, ClassType}; +/// use objc2::{declare_class, extern_methods, mutability, ClassType, DeclaredClass}; /// /// // Shim /// type NSError = NSObject; @@ -83,6 +83,8 @@ /// const NAME: &'static str = "MyObject"; /// } /// +/// impl DeclaredClass for MyObject {} +/// /// unsafe impl MyObject { /// // ... Assume we've implemented all the methods used below /// } @@ -123,7 +125,7 @@ /// # use objc2::ffi::NSUInteger; /// # use objc2::rc::{Allocated, Id}; /// # use objc2::runtime::NSObject; -/// # use objc2::{declare_class, extern_methods, mutability, ClassType}; +/// # use objc2::{declare_class, extern_methods, mutability, ClassType, DeclaredClass}; /// # /// # // Shim /// # type NSError = NSObject; @@ -137,6 +139,8 @@ /// # const NAME: &'static str = "MyObject2"; /// # } /// # +/// # impl DeclaredClass for MyObject {} +/// # /// # unsafe impl MyObject { /// # // ... Assume we've implemented all the methods used below /// # } diff --git a/crates/objc2/src/macros/mod.rs b/crates/objc2/src/macros/mod.rs index a5adb07a9..8a5b57a49 100644 --- a/crates/objc2/src/macros/mod.rs +++ b/crates/objc2/src/macros/mod.rs @@ -1,5 +1,4 @@ mod __attribute_helpers; -mod __field_helpers; mod __method_msg_send; mod __msg_send_parse; mod __rewrite_self_param; @@ -872,7 +871,7 @@ macro_rules! __class_inner { /// use objc2::msg_send; /// # /// # use objc2::runtime::NSObject; -/// # use objc2::{declare_class, mutability, ClassType}; +/// # use objc2::{declare_class, mutability, ClassType, DeclaredClass}; /// # /// # declare_class!( /// # struct MyObject; @@ -882,6 +881,8 @@ macro_rules! __class_inner { /// # type Mutability = mutability::InteriorMutable; /// # const NAME: &'static str = "MyObject"; /// # } +/// # +/// # impl DeclaredClass for MyObject {} /// # ); /// /// let obj: &MyObject; // Some object that implements ClassType @@ -1187,6 +1188,34 @@ macro_rules! msg_send_bool { /// ``` #[macro_export] macro_rules! msg_send_id { + [super($obj:expr), $($selector_and_arguments:tt)+] => { + $crate::__msg_send_parse! { + (send_super_message_id_static_error) + () + () + ($($selector_and_arguments)+) + (send_super_message_id_static) + + ($crate::__msg_send_id_helper) + ($obj) + () // No retain semantics + (MsgSendSuperId) + } + }; + [super($obj:expr, $superclass:expr), $($selector_and_arguments:tt)+] => { + $crate::__msg_send_parse! { + (send_super_message_id_error) + () + () + ($($selector_and_arguments)+) + (send_super_message_id) + + ($crate::__msg_send_id_helper) + ($obj, $superclass) + () // No retain semantics + (MsgSendSuperId) + } + }; [$obj:expr, new $(,)?] => ({ let sel = $crate::sel!(new); let result; @@ -1216,6 +1245,7 @@ macro_rules! msg_send_id { ($crate::__msg_send_id_helper) ($obj) () // No retain semantics + (MsgSendId) } }; } @@ -1225,8 +1255,9 @@ macro_rules! msg_send_id { #[macro_export] macro_rules! __msg_send_id_helper { { - ($obj:expr) + ($($fn_args:tt)+) ($($retain_semantics:ident)?) + ($trait:ident) ($fn:ident) (retain) () @@ -1236,8 +1267,9 @@ macro_rules! __msg_send_id_helper { ) }}; { - ($obj:expr) + ($($fn_args:tt)+) ($($retain_semantics:ident)?) + ($trait:ident) ($fn:ident) (release) () @@ -1247,8 +1279,9 @@ macro_rules! __msg_send_id_helper { ) }}; { - ($obj:expr) + ($($fn_args:tt)+) ($($retain_semantics:ident)?) + ($trait:ident) ($fn:ident) (autorelease) () @@ -1258,8 +1291,9 @@ macro_rules! __msg_send_id_helper { ) }}; { - ($obj:expr) + ($($fn_args:tt)+) ($($retain_semantics:ident)?) + ($trait:ident) ($fn:ident) (dealloc) () @@ -1269,21 +1303,23 @@ macro_rules! __msg_send_id_helper { ) }}; { - ($obj:expr) + ($($fn_args:tt)+) ($retain_semantics:ident) + ($trait:ident) ($fn:ident) ($($selector:tt)*) ($($argument:expr,)*) } => ({ - <$crate::__macro_helpers::$retain_semantics as $crate::__macro_helpers::MsgSendId<_, _>>::$fn( - $obj, + <$crate::__macro_helpers::$retain_semantics as $crate::__macro_helpers::$trait<_, _>>::$fn( + $($fn_args)+, $crate::sel!($($selector)*), ($($argument,)*), ) }); { - ($obj:expr) + ($($fn_args:tt)+) () + ($trait:ident) ($fn:ident) ($($selector:tt)*) ($($argument:expr,)*) @@ -1295,8 +1331,8 @@ macro_rules! __msg_send_id_helper { let result; result = <$crate::__macro_helpers::RetainSemantics<{ $crate::__macro_helpers::retain_semantics(__SELECTOR_DATA) - }> as $crate::__macro_helpers::MsgSendId<_, _>>::$fn( - $obj, + }> as $crate::__macro_helpers::$trait<_, _>>::$fn( + $($fn_args)+, $crate::__sel_inner!( __SELECTOR_DATA, $crate::__hash_idents!($($selector)*) diff --git a/crates/objc2/src/rc/allocated.rs b/crates/objc2/src/rc/allocated.rs index fee507913..ec704f9b4 100644 --- a/crates/objc2/src/rc/allocated.rs +++ b/crates/objc2/src/rc/allocated.rs @@ -1,10 +1,14 @@ use core::fmt; use core::marker::PhantomData; use core::mem::ManuallyDrop; +use core::ptr::NonNull; +use crate::__macro_helpers::declared_ivars::initialize_ivars; use crate::mutability::IsMutable; use crate::runtime::{objc_release_fast, AnyObject}; -use crate::Message; +use crate::{DeclaredClass, Message}; + +use super::PartialInit; /// An Objective-C object that has been allocated, but not initialized. /// @@ -123,6 +127,34 @@ impl Allocated { let this = ManuallyDrop::new(this); this.ptr as *mut T } + + /// Initialize the instance variables for this object. + /// + /// TODO + // + // Note: This is intentionally _not_ an associated method, even though + // `Allocated` will become `MethodReceiver` in the future. + #[inline] + #[track_caller] + pub fn set_ivars(self, ivars: T::Ivars) -> PartialInit + where + T: DeclaredClass, + { + let ptr: NonNull = match NonNull::new(ManuallyDrop::new(self).ptr as *mut _) { + Some(ptr) => ptr, + // TODO: Should we just return a NULL PartialInit here??? + None => panic!("tried to initialize instance variables on NULL allocated object"), + }; + + // SAFETY: The pointer came from `self`, so it is valid. + unsafe { initialize_ivars::(ptr, ivars) }; + + // SAFETY: + // - The pointer came from a `ManuallyDrop>`, which means + // that we've now transfered ownership over +1 retain count. + // - The instance variables for this class have been intialized above. + unsafe { PartialInit::new(ptr) } + } } impl Drop for Allocated { diff --git a/crates/objc2/src/rc/id.rs b/crates/objc2/src/rc/id.rs index 7398c9c2d..3714462de 100644 --- a/crates/objc2/src/rc/id.rs +++ b/crates/objc2/src/rc/id.rs @@ -837,7 +837,7 @@ mod tests { use crate::mutability::{Immutable, Mutable}; use crate::rc::{__RcTestObject, __ThreadTestData, autoreleasepool}; use crate::runtime::{AnyObject, NSObject}; - use crate::{declare_class, msg_send}; + use crate::{declare_class, msg_send, DeclaredClass}; #[test] fn auto_traits() { @@ -851,6 +851,8 @@ mod tests { type Mutability = $mutability; const NAME: &'static str = concat!(stringify!($name), "Test"); } + + impl DeclaredClass for $name {} ); }; } @@ -906,7 +908,7 @@ mod tests { drop(obj); expected.release += 1; - expected.dealloc += 1; + expected.drop += 1; expected.assert_current(); } @@ -932,7 +934,7 @@ mod tests { expected.assert_current(); }); expected.release += 1; - expected.dealloc += 1; + expected.drop += 1; expected.assert_current(); } @@ -970,7 +972,7 @@ mod tests { drop(cloned); expected.release += 1; - expected.dealloc += 1; + expected.drop += 1; expected.assert_current(); } diff --git a/crates/objc2/src/rc/id_traits.rs b/crates/objc2/src/rc/id_traits.rs index 4ab267273..2bef09a79 100644 --- a/crates/objc2/src/rc/id_traits.rs +++ b/crates/objc2/src/rc/id_traits.rs @@ -130,7 +130,7 @@ mod tests { use super::*; use crate::mutability::Mutable; use crate::runtime::NSObject; - use crate::{declare_class, msg_send_id, ClassType}; + use crate::{declare_class, msg_send_id, ClassType, DeclaredClass}; declare_class!( #[derive(PartialEq, Eq, Hash, Debug)] @@ -141,6 +141,8 @@ mod tests { type Mutability = Mutable; const NAME: &'static str = "MyCustomCollection"; } + + impl DeclaredClass for Collection {} ); impl DefaultId for Collection { diff --git a/crates/objc2/src/rc/mod.rs b/crates/objc2/src/rc/mod.rs index 4c6dc0953..39c89eb5b 100644 --- a/crates/objc2/src/rc/mod.rs +++ b/crates/objc2/src/rc/mod.rs @@ -53,6 +53,7 @@ mod autorelease; mod id; mod id_forwarding_impls; mod id_traits; +mod partial_init; mod test_object; mod weak_id; @@ -62,6 +63,7 @@ pub use self::autorelease::{ }; pub use self::id::Id; pub use self::id_traits::{DefaultId, IdFromIterator, IdIntoIterator}; +pub use self::partial_init::PartialInit; #[doc(hidden)] pub use self::test_object::{__RcTestObject, __ThreadTestData}; pub use self::weak_id::WeakId; diff --git a/crates/objc2/src/rc/partial_init.rs b/crates/objc2/src/rc/partial_init.rs new file mode 100644 index 000000000..8b101f554 --- /dev/null +++ b/crates/objc2/src/rc/partial_init.rs @@ -0,0 +1,67 @@ +use core::fmt; +use core::marker::PhantomData; +use core::mem::ManuallyDrop; +use core::ptr::NonNull; + +use crate::runtime::objc_release_fast; +use crate::Message; + +/// A marker type that can be used to indicate that the object has been +/// initialized in the superclass, but not the current class. +/// +/// This is returned by `msg_send_id!` `super` calls. +// +// Internally, this is very similar to `rc::Allocated`, except that we have +// different guarantees on the validity of the object. +// +// TODO: We don't want to guarantee the layout of this just yet, as we may be +// able to move a drop flag to the stack! +#[repr(transparent)] +#[derive(Debug)] +pub struct PartialInit { + /// The partially initialized object. + /// + /// Variance is same as `Id`. + ptr: NonNull, + /// Necessary for dropck, as with `Id`. + p: PhantomData, +} + +impl PartialInit { + /// # Safety + /// + /// The caller must ensure the given object has +1 retain count, and that + /// the superclass initializer for the object behind the pointer has been + /// run, while the object itself hasn't yet been initialized. + #[inline] + pub(crate) unsafe fn new(ptr: NonNull) -> Self { + Self { + ptr, + p: PhantomData, + } + } + + #[inline] + pub(crate) fn into_ptr(this: Self) -> *mut T { + let this = ManuallyDrop::new(this); + this.ptr.as_ptr() + } +} + +impl Drop for PartialInit { + #[inline] + fn drop(&mut self) { + // SAFETY: Partially initialized objects can always safely be + // released, since destructors are written to take into account that + // the object may not have been fully initialized. + // + // Rest is same as `Id`. + unsafe { objc_release_fast(self.ptr.as_ptr().cast()) }; + } +} + +impl fmt::Pointer for PartialInit { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Pointer::fmt(&self.ptr.as_ptr(), f) + } +} diff --git a/crates/objc2/src/rc/test_object.rs b/crates/objc2/src/rc/test_object.rs index 202de9997..98bc46f41 100644 --- a/crates/objc2/src/rc/test_object.rs +++ b/crates/objc2/src/rc/test_object.rs @@ -4,7 +4,7 @@ use core::ptr; use super::{Allocated, Id}; use crate::mutability::Immutable; use crate::runtime::{NSObject, NSZone}; -use crate::{declare_class, msg_send, msg_send_id, ClassType}; +use crate::{declare_class, msg_send, msg_send_id, ClassType, DeclaredClass}; // TODO: Put tests that use this in another crate #[derive(Debug, Clone, Default, PartialEq, Eq)] @@ -12,7 +12,7 @@ use crate::{declare_class, msg_send, msg_send_id, ClassType}; #[doc(hidden)] pub struct __ThreadTestData { pub alloc: usize, - pub dealloc: usize, + pub drop: usize, pub init: usize, pub retain: usize, pub copy: usize, @@ -70,6 +70,8 @@ declare_class!( const NAME: &'static str = "__RcTestObject"; } + impl DeclaredClass for __RcTestObject {} + unsafe impl __RcTestObject { #[method_id(newReturningNull)] fn new_returning_null() -> Option> { @@ -106,10 +108,11 @@ declare_class!( ptr::null_mut() } - #[method(init)] - unsafe fn init(this: *mut Self) -> *mut Self { + #[method_id(init)] + unsafe fn init(this: Allocated) -> Id { TEST_DATA.with(|data| data.borrow_mut().init += 1); - unsafe { msg_send![super(this), init] } + let this = this.set_ivars(()); + unsafe { msg_send_id![super(this), init] } } #[method_id(initReturningNull)] @@ -286,7 +289,7 @@ declare_class!( impl Drop for __RcTestObject { fn drop(&mut self) { - TEST_DATA.with(|data| data.borrow_mut().dealloc += 1); + TEST_DATA.with(|data| data.borrow_mut().drop += 1); } } @@ -311,6 +314,8 @@ declare_class!( type Mutability = Immutable; const NAME: &'static str = "RcTestObjectSubclass"; } + + impl DeclaredClass for RcTestObjectSubclass {} ); #[cfg_attr(not(test), allow(unused))] @@ -357,7 +362,7 @@ mod tests { drop(res); $expected.release += 1; - $expected.dealloc += 1; + $expected.drop += 1; $expected.assert_current(); } } @@ -429,7 +434,7 @@ mod tests { drop(res); $expected.release += 1; - $expected.dealloc += 1; + $expected.drop += 1; $expected.assert_current(); // Errors @@ -449,7 +454,7 @@ mod tests { drop(res); $expected.release += 1; - $expected.dealloc += 1; + $expected.drop += 1; $expected.assert_current(); } } @@ -474,11 +479,11 @@ mod tests { expected.alloc -= 1; expected.release -= 1; - expected.dealloc -= 1; test_error_id!(expected, 0, initAndShouldError, { expected.alloc += 1; expected.release += 1; - expected.dealloc += 1; + // Drop flag ensures newly allocated objects do not drop + // expected.drop += 1; __RcTestObject::alloc() }); } @@ -499,7 +504,8 @@ mod tests { drop(res); expected.release += 1; - expected.dealloc += 1; + // Drop flag ensures uninitialized do not drop + // expected.drop += 1; expected.assert_current(); // Errors @@ -521,7 +527,7 @@ mod tests { drop(res); expected.release += 1; - expected.dealloc += 1; + expected.drop += 1; expected.assert_current(); } diff --git a/crates/objc2/src/rc/weak_id.rs b/crates/objc2/src/rc/weak_id.rs index 9f13e1211..48bd5f42f 100644 --- a/crates/objc2/src/rc/weak_id.rs +++ b/crates/objc2/src/rc/weak_id.rs @@ -210,7 +210,7 @@ mod tests { drop(obj); drop(strong); expected.release += 2; - expected.dealloc += 1; + expected.drop += 1; expected.assert_current(); if cfg!(not(feature = "gnustep-1-7")) { diff --git a/crates/objc2/src/runtime/bool.rs b/crates/objc2/src/runtime/bool.rs index 74b4bf9c0..e97a3b355 100644 --- a/crates/objc2/src/runtime/bool.rs +++ b/crates/objc2/src/runtime/bool.rs @@ -10,7 +10,9 @@ use crate::ffi; /// soon as possible. /// /// This is FFI-safe and can be used directly with `msg_send!` and `extern` -/// functions. +/// functions as a substitute for `BOOL` in Objective-C. If your Objective-C +/// code uses C99 `_Bool`, you should use a `#[repr(transparent)]` wrapper +/// around `bool` instead. /// /// Note that this is able to contain more states than `bool` on some /// platforms, but these cases should not be relied on! diff --git a/crates/objc2/src/runtime/message_receiver.rs b/crates/objc2/src/runtime/message_receiver.rs index bc1dc6b4e..d2cce6a72 100644 --- a/crates/objc2/src/runtime/message_receiver.rs +++ b/crates/objc2/src/runtime/message_receiver.rs @@ -510,7 +510,7 @@ mod tests { use crate::rc::{Allocated, Id}; use crate::runtime::NSObject; use crate::test_utils; - use crate::{declare_class, msg_send, msg_send_id, ClassType}; + use crate::{declare_class, msg_send, msg_send_id, ClassType, DeclaredClass}; declare_class!( struct MutableObject; @@ -520,6 +520,8 @@ mod tests { type Mutability = mutability::Mutable; const NAME: &'static str = "TestMutableObject"; } + + impl DeclaredClass for MutableObject {} ); #[allow(unused)] diff --git a/crates/objc2/src/runtime/protocol_object.rs b/crates/objc2/src/runtime/protocol_object.rs index ae8c8d085..46ff46c29 100644 --- a/crates/objc2/src/runtime/protocol_object.rs +++ b/crates/objc2/src/runtime/protocol_object.rs @@ -194,7 +194,7 @@ mod tests { use super::*; use crate::mutability::Mutable; use crate::runtime::{NSObject, NSObjectProtocol}; - use crate::{declare_class, extern_methods, extern_protocol, ClassType}; + use crate::{declare_class, extern_methods, extern_protocol, ClassType, DeclaredClass}; extern_protocol!( unsafe trait Foo { @@ -254,6 +254,8 @@ mod tests { const NAME: &'static str = "ProtocolTestsDummyClass"; } + impl DeclaredClass for DummyClass {} + unsafe impl NSObjectProtocol for DummyClass {} ); @@ -350,7 +352,7 @@ mod tests { assert_eq!( format!("{obj:?}"), format!( - "DummyClass {{ __superclass: {:?} }}", + "DummyClass {{ __superclass: {:?}, __ivars: PhantomData<()> }}", ManuallyDrop::new(foobar) ), ); diff --git a/crates/objc2/src/top_level_traits.rs b/crates/objc2/src/top_level_traits.rs index 8f00b8b22..cf4a979a2 100644 --- a/crates/objc2/src/top_level_traits.rs +++ b/crates/objc2/src/top_level_traits.rs @@ -1,3 +1,6 @@ +use core::ptr::NonNull; + +use crate::__macro_helpers::declared_ivars::get_initialized_ivar_ptr; use crate::encode::RefEncode; use crate::msg_send_id; use crate::mutability::{IsAllocableAnyThread, IsRetainable, Mutability}; @@ -307,6 +310,51 @@ pub unsafe trait ClassType: Message { // TODO: `fn mtm(&self) -> MainThreadMarker where T::Mutability: MainThreadOnly` } +/// TODO +/// +/// # Safety +/// +/// The ivar offset must be implemented correctly. +pub unsafe trait DeclaredClass: ClassType { + /// TODO + type Ivars: Sized; + + // TODO: Add `ivars_ptr(this: NonNull) -> NonNull`? + + /// TODO + #[inline] + fn ivars(&self) -> &Self::Ivars { + let ptr: NonNull = NonNull::from(self); + // SAFETY: The pointer is valid and initialized. + let ivars = unsafe { get_initialized_ivar_ptr(ptr) }; + // SAFETY: The lifetime of the instance variable is tied to the object. + unsafe { ivars.as_ref() } + } + + /// TODO + #[inline] + fn ivars_mut(&mut self) -> &mut Self::Ivars { + let ptr: NonNull = NonNull::from(self); + // SAFETY: The pointer is valid and initialized. + let mut ivars = unsafe { get_initialized_ivar_ptr(ptr) }; + // SAFETY: The lifetime of the instance variable is tied to the object. + // + // Mutability is safe since the object itself is mutable. See + // `ClassType::as_super_mut` for why this is safe without + // `Self: IsMutable`. + unsafe { ivars.as_mut() } + } + + #[doc(hidden)] + fn __ivars_offset() -> isize; + + #[doc(hidden)] + fn __drop_flag_offset() -> isize; + + #[doc(hidden)] + const __INNER: (); +} + /// Marks types that represent specific protocols. /// /// This is the protocol equivalent of [`ClassType`]. diff --git a/crates/objc2/tests/declare_class.rs b/crates/objc2/tests/declare_class.rs index 08a9d0622..c5933d8b2 100644 --- a/crates/objc2/tests/declare_class.rs +++ b/crates/objc2/tests/declare_class.rs @@ -1,17 +1,15 @@ #![deny(deprecated, unreachable_code)] use core::ptr::{self, NonNull}; -use objc2::declare::IvarEncode; use objc2::mutability::Immutable; use objc2::rc::Id; use objc2::runtime::NSObject; -use objc2::{declare_class, extern_methods, sel, ClassType}; +use objc2::{declare_class, extern_methods, sel, ClassType, DeclaredClass}; // Test that adding the `deprecated` attribute does not mean that warnings // when using the method internally are output. declare_class!( - // Also ensure that empty fields still work - struct DeclareClassDepreactedMethod {} + struct DeclareClassDepreactedMethod; unsafe impl ClassType for DeclareClassDepreactedMethod { type Super = NSObject; @@ -19,6 +17,8 @@ declare_class!( const NAME: &'static str = "DeclareClassDepreactedMethod"; } + impl DeclaredClass for DeclareClassDepreactedMethod {} + #[deprecated] unsafe impl DeclareClassDepreactedMethod { #[method(deprecatedOnImpl)] @@ -50,6 +50,8 @@ declare_class!( const NAME: &'static str = "DeclareClassCfg"; } + impl DeclaredClass for DeclareClassCfg {} + unsafe impl DeclareClassCfg { #[cfg(debug_assertions)] #[method(changesOnCfg1)] @@ -192,6 +194,8 @@ declare_class!( const NAME: &'static str = "TestMultipleColonSelector"; } + impl DeclaredClass for TestMultipleColonSelector {} + unsafe impl TestMultipleColonSelector { #[method(test::arg3:)] fn _test_class(arg1: i32, arg2: i32, arg3: i32) -> i32 { @@ -265,6 +269,8 @@ declare_class!( const NAME: &'static str = "DeclareClassAllTheBool"; } + impl DeclaredClass for DeclareClassAllTheBool {} + unsafe impl DeclareClassAllTheBool { #[method(returnsBool)] fn returns_bool() -> bool { @@ -328,6 +334,8 @@ declare_class!( const NAME: &'static str = "DeclareClassUnreachable"; } + impl DeclaredClass for DeclareClassUnreachable {} + // Ensure none of these warn unsafe impl DeclareClassUnreachable { #[method(unreachable)] @@ -367,27 +375,6 @@ fn test_unreachable() { let _ = DeclareClassUnreachable::class(); } -#[test] -#[should_panic = "failed to add ivar _ivar"] -fn test_duplicate_ivar() { - declare_class!( - struct DeclareClassDuplicateIvar { - ivar1: IvarEncode, - ivar2: IvarEncode, - } - - mod ivars; - - unsafe impl ClassType for DeclareClassDuplicateIvar { - type Super = NSObject; - type Mutability = Immutable; - const NAME: &'static str = "DeclareClassDuplicateIvar"; - } - ); - - let _ = DeclareClassDuplicateIvar::class(); -} - declare_class!( #[derive(Debug)] struct OutParam; @@ -398,6 +385,8 @@ declare_class!( const NAME: &'static str = "OutParam"; } + impl DeclaredClass for OutParam {} + unsafe impl OutParam { #[method(unsupported1:)] fn _unsupported1(_param: &mut Id) {} @@ -486,6 +475,8 @@ fn test_pointer_receiver_allowed() { const NAME: &'static str = "PointerReceiver"; } + impl DeclaredClass for PointerReceiver {} + unsafe impl PointerReceiver { #[method(constPtr)] fn const_ptr(_this: *const Self) {} diff --git a/crates/objc2/tests/declare_class_self.rs b/crates/objc2/tests/declare_class_self.rs index 6915e5f0f..6355e8429 100644 --- a/crates/objc2/tests/declare_class_self.rs +++ b/crates/objc2/tests/declare_class_self.rs @@ -3,7 +3,7 @@ //! do it in a context where `Self` works. use objc2::rc::{Allocated, Id}; use objc2::runtime::NSObject; -use objc2::{declare_class, mutability, ClassType}; +use objc2::{declare_class, mutability, ClassType, DeclaredClass}; trait GetSameType { type SameType: ?Sized; @@ -37,6 +37,8 @@ declare_class!( const NAME: &'static str = "MyTestObject"; } + impl DeclaredClass for MyTestObject {} + unsafe impl MyTestObject { #[method_id(initWith:)] fn init( diff --git a/crates/objc2/tests/macros_mainthreadmarker.rs b/crates/objc2/tests/macros_mainthreadmarker.rs index dff31e4c4..bf67b8614 100644 --- a/crates/objc2/tests/macros_mainthreadmarker.rs +++ b/crates/objc2/tests/macros_mainthreadmarker.rs @@ -1,6 +1,9 @@ use objc2::rc::Id; use objc2::runtime::{NSObject, NSObjectProtocol}; -use objc2::{declare_class, extern_methods, extern_protocol, mutability, ClassType, ProtocolType}; +use objc2::{ + declare_class, extern_methods, extern_protocol, mutability, ClassType, DeclaredClass, + ProtocolType, +}; extern_protocol!( #[allow(clippy::missing_safety_doc)] @@ -27,6 +30,8 @@ declare_class!( const NAME: &'static str = "MainThreadMarkerTest"; } + impl DeclaredClass for Cls {} + unsafe impl Proto for Cls { #[method(myMethod:)] fn _my_mainthreadonly_method(arg: i32) -> i32 { diff --git a/crates/objc2/tests/no_prelude.rs b/crates/objc2/tests/no_prelude.rs index cf79c10f5..c09ab224d 100644 --- a/crates/objc2/tests/no_prelude.rs +++ b/crates/objc2/tests/no_prelude.rs @@ -9,7 +9,7 @@ extern crate objc2 as new_objc2; -use new_objc2::{ClassType, ProtocolType}; +use new_objc2::{ClassType, DeclaredClass, ProtocolType}; mod core {} mod std {} @@ -82,14 +82,16 @@ type ExactSizeIterator = BogusType; type SliceConcatExt = BogusType; type ToString = BogusType; +type PhantomData = BogusType; + // Test begin below this line -type PhantomData = T; +pub struct MyCustomIvars { + ivars: i32, +} new_objc2::declare_class!( - pub struct CustomObject { - field1: PhantomData, - } + pub struct CustomObject; unsafe impl ClassType for CustomObject { type Super = new_objc2::runtime::NSObject; @@ -97,6 +99,10 @@ new_objc2::declare_class!( const NAME: &'static str = "CustomObject"; } + impl DeclaredClass for CustomObject { + type Ivars = MyCustomIvars; + } + unsafe impl CustomObject { #[method(a)] fn _a() {} diff --git a/crates/objc2/tests/track_caller.rs b/crates/objc2/tests/track_caller.rs index f50b32984..29bc8a47c 100644 --- a/crates/objc2/tests/track_caller.rs +++ b/crates/objc2/tests/track_caller.rs @@ -9,7 +9,7 @@ use std::sync::Mutex; use objc2::encode::Encode; use objc2::rc::{Allocated, Id, __RcTestObject}; use objc2::runtime::NSObject; -use objc2::{class, declare_class, msg_send, msg_send_id, mutability, ClassType}; +use objc2::{class, declare_class, msg_send, msg_send_id, mutability, ClassType, DeclaredClass}; static EXPECTED_MESSAGE: Mutex = Mutex::new(String::new()); static EXPECTED_LINE: Mutex = Mutex::new(0); @@ -202,6 +202,8 @@ declare_class!( const NAME: &'static str = "PanickingClass"; } + impl DeclaredClass for PanickingClass {} + unsafe impl PanickingClass { #[method(panic)] fn _panic() -> *mut Self { diff --git a/crates/objc2/tests/use_macros.rs b/crates/objc2/tests/use_macros.rs index 081b1e9f7..ce2ffe197 100644 --- a/crates/objc2/tests/use_macros.rs +++ b/crates/objc2/tests/use_macros.rs @@ -1,6 +1,6 @@ use objc2::mutability::Immutable; use objc2::runtime::{AnyClass, NSObject}; -use objc2::{class, declare_class, msg_send, sel, ClassType}; +use objc2::{class, declare_class, msg_send, sel, ClassType, DeclaredClass}; declare_class!( pub struct MyObject; @@ -10,6 +10,8 @@ declare_class!( type Mutability = Immutable; const NAME: &'static str = "MyObject"; } + + impl DeclaredClass for MyObject {} ); #[test] diff --git a/crates/test-assembly/crates/test_declare_class/expected/apple-aarch64.s b/crates/test-assembly/crates/test_declare_class/expected/apple-aarch64.s index 8bb3a2e77..f8a789469 100644 --- a/crates/test-assembly/crates/test_declare_class/expected/apple-aarch64.s +++ b/crates/test-assembly/crates/test_declare_class/expected/apple-aarch64.s @@ -4,255 +4,363 @@ SYM(core[CRATE_ID]::ptr::drop_in_place::<::call ret .p2align 2 -SYM(::call_once::<::class::{closure#0}>::{closure#0}, 0): - sub sp, sp, #64 - stp x22, x21, [sp, #16] - stp x20, x19, [sp, #32] - stp x29, x30, [sp, #48] - add x29, sp, #48 - ldr x8, [x0] - ldrb w9, [x8] - strb wzr, [x8] - cbz w9, LBB1_5 +SYM(objc2[CRATE_ID]::__macro_helpers::declared_ivars::dealloc::, 0): + sub sp, sp, #48 + stp x20, x19, [sp, #16] + stp x29, x30, [sp, #32] + add x29, sp, #32 + mov x19, x1 + mov x20, x0 Lloh0: - adrp x8, L_OBJC_CLASSLIST_REFERENCES_$_NSObject@GOTPAGE + adrp x8, SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)@PAGE Lloh1: - ldr x8, [x8, L_OBJC_CLASSLIST_REFERENCES_$_NSObject@GOTPAGEOFF] + ldr x8, [x8, SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)@PAGEOFF] + ldrb w8, [x0, x8] + cbz w8, LBB1_3 Lloh2: - ldr x2, [x8] + adrp x8, SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)@PAGE Lloh3: - adrp x0, l_anon.[ID].11@PAGE + ldr x8, [x8, SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)@PAGEOFF] + ldr x0, [x20, x8] + cbz x0, LBB1_3 + bl _objc_release +LBB1_3: Lloh4: - add x0, x0, l_anon.[ID].11@PAGEOFF - mov w1, #15 - bl SYM(objc2::declare::ClassBuilder::new::GENERATED_ID, 0) - cbz x0, LBB1_6 - str x0, [sp, #8] + adrp x8, L_OBJC_CLASSLIST_REFERENCES_$_NSObject@GOTPAGE Lloh5: - adrp x1, l_anon.[ID].12@PAGE + ldr x8, [x8, L_OBJC_CLASSLIST_REFERENCES_$_NSObject@GOTPAGEOFF] Lloh6: - add x1, x1, l_anon.[ID].12@PAGEOFF + ldr x8, [x8] + stp x20, x8, [sp] + mov x0, sp + mov x1, x19 + bl _objc_msgSendSuper + ldp x29, x30, [sp, #32] + ldp x20, x19, [sp, #16] + add sp, sp, #48 + ret + .loh AdrpLdr Lloh0, Lloh1 + .loh AdrpLdr Lloh2, Lloh3 + .loh AdrpLdrGotLdr Lloh4, Lloh5, Lloh6 + + .p2align 2 +SYM(::call_once::<::class::{closure#0}>::{closure#0}, 0): + sub sp, sp, #112 + stp x22, x21, [sp, #64] + stp x20, x19, [sp, #80] + stp x29, x30, [sp, #96] + add x29, sp, #96 + ldr x8, [x0] + ldrb w9, [x8] + strb wzr, [x8] + cbz w9, LBB2_7 Lloh7: - adrp x5, l_anon.[ID].15@PAGE + adrp x8, L_OBJC_CLASSLIST_REFERENCES_$_NSObject@GOTPAGE Lloh8: - add x5, x5, l_anon.[ID].15@PAGEOFF - add x0, sp, #8 - mov w2, #4 - mov w3, #1 - mov w4, #0 - bl SYM(objc2::declare::ClassBuilder::add_ivar_inner_mono::GENERATED_ID, 0) + ldr x8, [x8, L_OBJC_CLASSLIST_REFERENCES_$_NSObject@GOTPAGEOFF] Lloh9: - adrp x1, l_anon.[ID].13@PAGE + ldr x2, [x8] Lloh10: - add x1, x1, l_anon.[ID].13@PAGEOFF + adrp x0, l_anon.[ID].21@PAGE Lloh11: - adrp x19, l_anon.[ID].2@PAGE + add x0, x0, l_anon.[ID].21@PAGEOFF + mov w1, #15 + bl SYM(objc2::declare::ClassBuilder::new::GENERATED_ID, 0) + cbz x0, LBB2_8 + str x0, [sp, #24] Lloh12: - add x19, x19, l_anon.[ID].2@PAGEOFF - add x0, sp, #8 - mov w2, #4 - mov w3, #8 - mov w4, #3 - mov x5, x19 - bl SYM(objc2::declare::ClassBuilder::add_ivar_inner_mono::GENERATED_ID, 0) -Lloh13: adrp x8, L_OBJC_SELECTOR_REFERENCES_dealloc@GOTPAGE -Lloh14: +Lloh13: ldr x8, [x8, L_OBJC_SELECTOR_REFERENCES_dealloc@GOTPAGEOFF] -Lloh15: +Lloh14: ldr x1, [x8] +Lloh15: + adrp x19, l_anon.[ID].1@PAGE Lloh16: - adrp x20, l_anon.[ID].1@PAGE + add x19, x19, l_anon.[ID].1@PAGEOFF Lloh17: - add x20, x20, l_anon.[ID].1@PAGEOFF -Lloh18: adrp x21, l_anon.[ID].3@PAGE -Lloh19: +Lloh18: add x21, x21, l_anon.[ID].3@PAGEOFF +Lloh19: + adrp x5, SYM(objc2[CRATE_ID]::__macro_helpers::declared_ivars::dealloc::, 0)@PAGE Lloh20: - adrp x5, SYM(::class::{closure#0}::__objc2_dealloc, 0)@PAGE -Lloh21: - add x5, x5, SYM(::class::{closure#0}::__objc2_dealloc, 0)@PAGEOFF - add x0, sp, #8 - mov x2, x20 + add x5, x5, SYM(objc2[CRATE_ID]::__macro_helpers::declared_ivars::dealloc::, 0)@PAGEOFF + add x0, sp, #24 + mov x2, x19 mov x3, #0 mov x4, x21 bl SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) -Lloh22: + ldr x8, [sp, #24] + str x8, [sp, #8] +Lloh21: adrp x8, L_OBJC_SELECTOR_REFERENCES_init@GOTPAGE -Lloh23: +Lloh22: ldr x8, [x8, L_OBJC_SELECTOR_REFERENCES_init@GOTPAGEOFF] -Lloh24: +Lloh23: ldr x1, [x8] +Lloh24: + adrp x20, l_anon.[ID].2@PAGE Lloh25: - adrp x5, _init@PAGE + add x20, x20, l_anon.[ID].2@PAGEOFF Lloh26: + adrp x5, _init@PAGE +Lloh27: add x5, x5, _init@PAGEOFF add x0, sp, #8 - mov x2, x20 + mov x2, x19 mov x3, #0 - mov x4, x19 + mov x4, x20 bl SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) -Lloh27: - adrp x8, L_OBJC_SELECTOR_REFERENCES_d874ee9262978be2@PAGE Lloh28: - ldr x1, [x8, L_OBJC_SELECTOR_REFERENCES_d874ee9262978be2@PAGEOFF] + adrp x8, L_OBJC_SELECTOR_REFERENCES_ddead4cf1cfe35ab@PAGE Lloh29: - adrp x5, _class_method@PAGE + ldr x1, [x8, L_OBJC_SELECTOR_REFERENCES_ddead4cf1cfe35ab@PAGEOFF] Lloh30: + adrp x5, _class_method@PAGE +Lloh31: add x5, x5, _class_method@PAGEOFF add x0, sp, #8 - mov x2, x20 + mov x2, x19 mov x3, #0 mov x4, x21 bl SYM(objc2::declare::ClassBuilder::add_class_method_inner::GENERATED_ID, 0) -Lloh31: - adrp x8, L_OBJC_SELECTOR_REFERENCES_4539fd1dbda0cddc@PAGE Lloh32: - ldr x1, [x8, L_OBJC_SELECTOR_REFERENCES_4539fd1dbda0cddc@PAGEOFF] + adrp x8, L_OBJC_SELECTOR_REFERENCES_8ee1155e2a63c707@PAGE Lloh33: - adrp x5, _method@PAGE + ldr x1, [x8, L_OBJC_SELECTOR_REFERENCES_8ee1155e2a63c707@PAGEOFF] Lloh34: + adrp x5, _method@PAGE +Lloh35: add x5, x5, _method@PAGEOFF add x0, sp, #8 - mov x2, x20 + mov x2, x19 mov x3, #0 mov x4, x21 bl SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) -Lloh35: - adrp x8, L_OBJC_SELECTOR_REFERENCES_2b1b3a94e0ece2e5@PAGE Lloh36: - ldr x1, [x8, L_OBJC_SELECTOR_REFERENCES_2b1b3a94e0ece2e5@PAGEOFF] + adrp x8, L_OBJC_SELECTOR_REFERENCES_b1c6d8f625c88aa6@PAGE Lloh37: - adrp x21, l_anon.[ID].4@PAGE + ldr x1, [x8, L_OBJC_SELECTOR_REFERENCES_b1c6d8f625c88aa6@PAGEOFF] Lloh38: - add x21, x21, l_anon.[ID].4@PAGEOFF + adrp x21, l_anon.[ID].4@PAGE Lloh39: - adrp x5, _method_bool@PAGE + add x21, x21, l_anon.[ID].4@PAGEOFF Lloh40: + adrp x5, _method_bool@PAGE +Lloh41: add x5, x5, _method_bool@PAGEOFF add x0, sp, #8 mov x2, x21 mov w3, #1 mov x4, x21 bl SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) -Lloh41: - adrp x8, L_OBJC_SELECTOR_REFERENCES_f7f521670860b0ce@PAGE Lloh42: - ldr x1, [x8, L_OBJC_SELECTOR_REFERENCES_f7f521670860b0ce@PAGEOFF] + adrp x8, L_OBJC_SELECTOR_REFERENCES_f33da9321a226f33@PAGE Lloh43: - adrp x5, _method_id@PAGE + ldr x1, [x8, L_OBJC_SELECTOR_REFERENCES_f33da9321a226f33@PAGEOFF] Lloh44: + adrp x5, _method_id@PAGE +Lloh45: add x5, x5, _method_id@PAGEOFF add x0, sp, #8 - mov x2, x20 + mov x2, x19 mov x3, #0 - mov x4, x19 + mov x4, x20 bl SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) -Lloh45: - adrp x8, L_OBJC_SELECTOR_REFERENCES_6addfcf634c6232f@PAGE Lloh46: - ldr x1, [x8, L_OBJC_SELECTOR_REFERENCES_6addfcf634c6232f@PAGEOFF] + adrp x8, L_OBJC_SELECTOR_REFERENCES_e5d1ad528a5510d9@PAGE Lloh47: - adrp x5, _method_id_with_param@PAGE + ldr x1, [x8, L_OBJC_SELECTOR_REFERENCES_e5d1ad528a5510d9@PAGEOFF] Lloh48: + adrp x5, _method_id_with_param@PAGE +Lloh49: add x5, x5, _method_id_with_param@PAGEOFF add x0, sp, #8 mov x2, x21 mov w3, #1 - mov x4, x19 + mov x4, x20 bl SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) -Lloh49: - adrp x0, l_anon.[ID].17@PAGE Lloh50: - add x0, x0, l_anon.[ID].17@PAGEOFF + adrp x0, l_anon.[ID].24@PAGE +Lloh51: + add x0, x0, l_anon.[ID].24@PAGEOFF mov w1, #9 bl SYM(objc2::runtime::AnyProtocol::get::GENERATED_ID, 0) - cbz x0, LBB1_4 + cbz x0, LBB2_4 mov x1, x0 add x0, sp, #8 bl SYM(objc2::declare::ClassBuilder::add_protocol::GENERATED_ID, 0) -LBB1_4: -Lloh51: - adrp x8, L_OBJC_SELECTOR_REFERENCES_4a8c690dbc9d8166@PAGE +LBB2_4: Lloh52: - ldr x1, [x8, L_OBJC_SELECTOR_REFERENCES_4a8c690dbc9d8166@PAGEOFF] + adrp x8, L_OBJC_SELECTOR_REFERENCES_8daf9cd9e6dba6e3@PAGE Lloh53: - adrp x2, l_anon.[ID].7@PAGE + ldr x1, [x8, L_OBJC_SELECTOR_REFERENCES_8daf9cd9e6dba6e3@PAGEOFF] Lloh54: - add x2, x2, l_anon.[ID].7@PAGEOFF + adrp x2, l_anon.[ID].7@PAGE Lloh55: - adrp x4, l_anon.[ID].2@PAGE + add x2, x2, l_anon.[ID].7@PAGEOFF Lloh56: - add x4, x4, l_anon.[ID].2@PAGEOFF + adrp x4, l_anon.[ID].2@PAGE Lloh57: - adrp x5, _copyWithZone@PAGE + add x4, x4, l_anon.[ID].2@PAGEOFF Lloh58: + adrp x5, _copyWithZone@PAGE +Lloh59: add x5, x5, _copyWithZone@PAGEOFF add x0, sp, #8 mov w3, #1 bl SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) - ldr x0, [sp, #8] - bl SYM(objc2::declare::ClassBuilder::register::GENERATED_ID, 0) - ldp x29, x30, [sp, #48] - ldp x20, x19, [sp, #32] - ldp x22, x21, [sp, #16] - add sp, sp, #64 - ret -LBB1_5: -Lloh59: - adrp x0, l_anon.[ID].8@PAGE + ldr x8, [sp, #8] + str x8, [sp, #16] + mov w8, #16 Lloh60: - add x0, x0, l_anon.[ID].8@PAGEOFF + adrp x9, l_anon.[ID].11@PAGE Lloh61: - adrp x2, l_anon.[ID].10@PAGE + add x9, x9, l_anon.[ID].11@PAGEOFF + stp x8, x9, [sp, #32] + mov w8, #27 + strb w8, [sp, #24] Lloh62: - add x2, x2, l_anon.[ID].10@PAGEOFF - mov w1, #43 - bl SYM(core::panicking::panic::GENERATED_ID, 0) -LBB1_6: + adrp x20, l_anon.[ID].8@PAGE Lloh63: - adrp x0, l_anon.[ID].11@PAGE + add x20, x20, l_anon.[ID].8@PAGEOFF + add x0, sp, #16 + add x5, sp, #24 + mov x1, x20 + mov w2, #5 + mov w3, #16 + mov w4, #3 + bl SYM(objc2::declare::ClassBuilder::add_ivar_inner_mono::GENERATED_ID, 0) Lloh64: - add x0, x0, l_anon.[ID].11@PAGEOFF + adrp x1, l_anon.[ID].9@PAGE Lloh65: - adrp x2, l_anon.[ID].16@PAGE + add x1, x1, l_anon.[ID].9@PAGEOFF Lloh66: - add x2, x2, l_anon.[ID].16@PAGEOFF + adrp x5, l_anon.[ID].10@PAGE +Lloh67: + add x5, x5, l_anon.[ID].10@PAGEOFF + add x0, sp, #16 + mov w2, #9 + mov w3, #1 + mov w4, #0 + bl SYM(objc2::declare::ClassBuilder::add_ivar_inner_mono::GENERATED_ID, 0) + ldr x0, [sp, #16] + bl SYM(objc2::declare::ClassBuilder::register::GENERATED_ID, 0) + mov x19, x0 + mov x1, x20 + mov w2, #5 + bl SYM(objc2::runtime::AnyClass::instance_variable::GENERATED_ID, 0) + cbz x0, LBB2_9 + bl _ivar_getOffset + mov x20, x0 +Lloh68: + adrp x1, l_anon.[ID].9@PAGE +Lloh69: + add x1, x1, l_anon.[ID].9@PAGEOFF + mov x0, x19 + mov w2, #9 + bl SYM(objc2::runtime::AnyClass::instance_variable::GENERATED_ID, 0) + cbz x0, LBB2_10 + bl _ivar_getOffset +Lloh70: + adrp x8, __MergedGlobals@PAGE + str x19, [x8, __MergedGlobals@PAGEOFF] +Lloh71: + adrp x8, SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)@PAGE + str x20, [x8, SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)@PAGEOFF] +Lloh72: + adrp x8, SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)@PAGE + str x0, [x8, SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)@PAGEOFF] + ldp x29, x30, [sp, #96] + ldp x20, x19, [sp, #80] + ldp x22, x21, [sp, #64] + add sp, sp, #112 + ret +LBB2_7: +Lloh73: + adrp x0, l_anon.[ID].16@PAGE +Lloh74: + add x0, x0, l_anon.[ID].16@PAGEOFF +Lloh75: + adrp x2, l_anon.[ID].18@PAGE +Lloh76: + add x2, x2, l_anon.[ID].18@PAGEOFF + mov w1, #43 + bl SYM(core::panicking::panic::GENERATED_ID, 0) +LBB2_8: +Lloh77: + adrp x0, l_anon.[ID].21@PAGE +Lloh78: + add x0, x0, l_anon.[ID].21@PAGEOFF +Lloh79: + adrp x2, l_anon.[ID].23@PAGE +Lloh80: + add x2, x2, l_anon.[ID].23@PAGEOFF mov w1, #15 bl SYM(objc2::__macro_helpers::declare_class::failed_declaring_class::GENERATED_ID, 0) - .loh AdrpAdd Lloh3, Lloh4 - .loh AdrpLdrGotLdr Lloh0, Lloh1, Lloh2 - .loh AdrpAdd Lloh49, Lloh50 - .loh AdrpAdd Lloh47, Lloh48 - .loh AdrpLdr Lloh45, Lloh46 - .loh AdrpAdd Lloh43, Lloh44 - .loh AdrpLdr Lloh41, Lloh42 - .loh AdrpAdd Lloh39, Lloh40 - .loh AdrpAdd Lloh37, Lloh38 - .loh AdrpLdr Lloh35, Lloh36 - .loh AdrpAdd Lloh33, Lloh34 - .loh AdrpLdr Lloh31, Lloh32 - .loh AdrpAdd Lloh29, Lloh30 - .loh AdrpLdr Lloh27, Lloh28 - .loh AdrpAdd Lloh25, Lloh26 - .loh AdrpLdrGotLdr Lloh22, Lloh23, Lloh24 - .loh AdrpAdd Lloh20, Lloh21 - .loh AdrpAdd Lloh18, Lloh19 - .loh AdrpAdd Lloh16, Lloh17 - .loh AdrpLdrGotLdr Lloh13, Lloh14, Lloh15 - .loh AdrpAdd Lloh11, Lloh12 - .loh AdrpAdd Lloh9, Lloh10 - .loh AdrpAdd Lloh7, Lloh8 - .loh AdrpAdd Lloh5, Lloh6 - .loh AdrpAdd Lloh57, Lloh58 - .loh AdrpAdd Lloh55, Lloh56 - .loh AdrpAdd Lloh53, Lloh54 - .loh AdrpLdr Lloh51, Lloh52 - .loh AdrpAdd Lloh61, Lloh62 - .loh AdrpAdd Lloh59, Lloh60 - .loh AdrpAdd Lloh65, Lloh66 - .loh AdrpAdd Lloh63, Lloh64 +LBB2_9: +Lloh81: + adrp x0, l_anon.[ID].12@PAGE +Lloh82: + add x0, x0, l_anon.[ID].12@PAGEOFF +Lloh83: + adrp x2, l_anon.[ID].14@PAGE +Lloh84: + add x2, x2, l_anon.[ID].14@PAGEOFF + mov w1, #59 + bl SYM(core::option::expect_failed::GENERATED_ID, 0) +LBB2_10: +Lloh85: + adrp x0, l_anon.[ID].12@PAGE +Lloh86: + add x0, x0, l_anon.[ID].12@PAGEOFF +Lloh87: + adrp x2, l_anon.[ID].15@PAGE +Lloh88: + add x2, x2, l_anon.[ID].15@PAGEOFF + mov w1, #59 + bl SYM(core::option::expect_failed::GENERATED_ID, 0) + .loh AdrpAdd Lloh10, Lloh11 + .loh AdrpLdrGotLdr Lloh7, Lloh8, Lloh9 + .loh AdrpAdd Lloh50, Lloh51 + .loh AdrpAdd Lloh48, Lloh49 + .loh AdrpLdr Lloh46, Lloh47 + .loh AdrpAdd Lloh44, Lloh45 + .loh AdrpLdr Lloh42, Lloh43 + .loh AdrpAdd Lloh40, Lloh41 + .loh AdrpAdd Lloh38, Lloh39 + .loh AdrpLdr Lloh36, Lloh37 + .loh AdrpAdd Lloh34, Lloh35 + .loh AdrpLdr Lloh32, Lloh33 + .loh AdrpAdd Lloh30, Lloh31 + .loh AdrpLdr Lloh28, Lloh29 + .loh AdrpAdd Lloh26, Lloh27 + .loh AdrpAdd Lloh24, Lloh25 + .loh AdrpLdrGotLdr Lloh21, Lloh22, Lloh23 + .loh AdrpAdd Lloh19, Lloh20 + .loh AdrpAdd Lloh17, Lloh18 + .loh AdrpAdd Lloh15, Lloh16 + .loh AdrpLdrGotLdr Lloh12, Lloh13, Lloh14 + .loh AdrpAdd Lloh66, Lloh67 + .loh AdrpAdd Lloh64, Lloh65 + .loh AdrpAdd Lloh62, Lloh63 + .loh AdrpAdd Lloh60, Lloh61 + .loh AdrpAdd Lloh58, Lloh59 + .loh AdrpAdd Lloh56, Lloh57 + .loh AdrpAdd Lloh54, Lloh55 + .loh AdrpLdr Lloh52, Lloh53 + .loh AdrpAdd Lloh68, Lloh69 + .loh AdrpAdrp Lloh71, Lloh72 + .loh AdrpAdrp Lloh70, Lloh71 + .loh AdrpAdd Lloh75, Lloh76 + .loh AdrpAdd Lloh73, Lloh74 + .loh AdrpAdd Lloh79, Lloh80 + .loh AdrpAdd Lloh77, Lloh78 + .loh AdrpAdd Lloh83, Lloh84 + .loh AdrpAdd Lloh81, Lloh82 + .loh AdrpAdd Lloh87, Lloh88 + .loh AdrpAdd Lloh85, Lloh86 .p2align 2 SYM(<::call_once<::class::{closure#0}>::{closure#0} as core[CRATE_ID]::ops::function::FnOnce<(&std[CRATE_ID]::sync::once::OnceState,)>>::call_once::{shim:vtable#0}, 0): @@ -270,73 +378,54 @@ SYM(<::call_once<::class::REGISTER_CLASS, 0)@PAGE -Lloh68: - add x8, x8, SYM(::class::REGISTER_CLASS, 0)@PAGEOFF +Lloh89: + adrp x8, __MergedGlobals@PAGE+8 +Lloh90: + add x8, x8, __MergedGlobals@PAGEOFF+8 ldapr x8, [x8] cmp x8, #3 - b.ne LBB3_3 -Lloh69: - adrp x0, l_anon.[ID].11@PAGE -Lloh70: - add x0, x0, l_anon.[ID].11@PAGEOFF - mov w1, #15 - bl SYM(objc2::runtime::AnyClass::get::GENERATED_ID, 0) - cbz x0, LBB3_4 -LBB3_2: - ldp x29, x30, [sp, #16] - add sp, sp, #32 + b.ne LBB4_2 +Lloh91: + adrp x8, __MergedGlobals@PAGE +Lloh92: + ldr x0, [x8, __MergedGlobals@PAGEOFF] ret -LBB3_3: +LBB4_2: + sub sp, sp, #32 + stp x29, x30, [sp, #16] + add x29, sp, #16 mov w8, #1 strb w8, [sp, #7] add x8, sp, #7 str x8, [sp, #8] -Lloh71: - adrp x0, SYM(::class::REGISTER_CLASS, 0)@PAGE -Lloh72: - add x0, x0, SYM(::class::REGISTER_CLASS, 0)@PAGEOFF -Lloh73: +Lloh93: + adrp x0, __MergedGlobals@PAGE+8 +Lloh94: + add x0, x0, __MergedGlobals@PAGEOFF+8 +Lloh95: adrp x3, l_anon.[ID].0@PAGE -Lloh74: +Lloh96: add x3, x3, l_anon.[ID].0@PAGEOFF -Lloh75: - adrp x4, l_anon.[ID].16@PAGE -Lloh76: - add x4, x4, l_anon.[ID].16@PAGEOFF +Lloh97: + adrp x4, l_anon.[ID].23@PAGE +Lloh98: + add x4, x4, l_anon.[ID].23@PAGEOFF add x2, sp, #8 mov w1, #0 bl SYM(std::sys_common::once::queue::Once::call::GENERATED_ID, 0) -Lloh77: - adrp x0, l_anon.[ID].11@PAGE -Lloh78: - add x0, x0, l_anon.[ID].11@PAGEOFF - mov w1, #15 - bl SYM(objc2::runtime::AnyClass::get::GENERATED_ID, 0) - cbnz x0, LBB3_2 -LBB3_4: -Lloh79: - adrp x0, l_anon.[ID].8@PAGE -Lloh80: - add x0, x0, l_anon.[ID].8@PAGEOFF -Lloh81: - adrp x2, l_anon.[ID].16@PAGE -Lloh82: - add x2, x2, l_anon.[ID].16@PAGEOFF - mov w1, #43 - bl SYM(core::panicking::panic::GENERATED_ID, 0) - .loh AdrpAdd Lloh67, Lloh68 - .loh AdrpAdd Lloh69, Lloh70 - .loh AdrpAdd Lloh77, Lloh78 - .loh AdrpAdd Lloh75, Lloh76 - .loh AdrpAdd Lloh73, Lloh74 - .loh AdrpAdd Lloh71, Lloh72 - .loh AdrpAdd Lloh81, Lloh82 - .loh AdrpAdd Lloh79, Lloh80 + ldp x29, x30, [sp, #16] + add sp, sp, #32 +Lloh99: + adrp x8, __MergedGlobals@PAGE +Lloh100: + ldr x0, [x8, __MergedGlobals@PAGEOFF] + ret + .loh AdrpAdd Lloh89, Lloh90 + .loh AdrpLdr Lloh91, Lloh92 + .loh AdrpLdr Lloh99, Lloh100 + .loh AdrpAdd Lloh97, Lloh98 + .loh AdrpAdd Lloh95, Lloh96 + .loh AdrpAdd Lloh93, Lloh94 .globl _get_obj .p2align 2 @@ -344,216 +433,157 @@ _get_obj: stp x20, x19, [sp, #-32]! stp x29, x30, [sp, #16] add x29, sp, #16 -Lloh83: +Lloh101: adrp x8, L_OBJC_SELECTOR_REFERENCES_new@GOTPAGE -Lloh84: +Lloh102: ldr x8, [x8, L_OBJC_SELECTOR_REFERENCES_new@GOTPAGEOFF] -Lloh85: +Lloh103: ldr x19, [x8] bl _get_class mov x1, x19 ldp x29, x30, [sp, #16] ldp x20, x19, [sp], #32 b _objc_msgSend - .loh AdrpLdrGotLdr Lloh83, Lloh84, Lloh85 + .loh AdrpLdrGotLdr Lloh101, Lloh102, Lloh103 .globl _access_ivars .p2align 2 _access_ivars: - stp x22, x21, [sp, #-48]! - stp x20, x19, [sp, #16] - stp x29, x30, [sp, #32] - add x29, sp, #32 + stp x20, x19, [sp, #-32]! + stp x29, x30, [sp, #16] + add x29, sp, #16 bl _get_obj - mov x19, x0 -Lloh86: - adrp x1, l_anon.[ID].12@PAGE -Lloh87: - add x1, x1, l_anon.[ID].12@PAGEOFF - mov w2, #4 - bl SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - bl _ivar_getOffset - ldrb w20, [x19, x0] -Lloh88: - adrp x1, l_anon.[ID].13@PAGE -Lloh89: - add x1, x1, l_anon.[ID].13@PAGEOFF - mov x0, x19 - mov w2, #4 - bl SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - bl _ivar_getOffset - ldr x21, [x19, x0] - mov x0, x19 +Lloh104: + adrp x8, SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)@PAGE +Lloh105: + ldr x8, [x8, SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)@PAGEOFF] + add x8, x0, x8 + ldr x19, [x8] + ldrb w20, [x8, #8] bl _objc_release mov x0, x20 - mov x1, x21 - ldp x29, x30, [sp, #32] - ldp x20, x19, [sp, #16] - ldp x22, x21, [sp], #48 + mov x1, x19 + ldp x29, x30, [sp, #16] + ldp x20, x19, [sp], #32 ret - .loh AdrpAdd Lloh88, Lloh89 - .loh AdrpAdd Lloh86, Lloh87 + .loh AdrpLdr Lloh104, Lloh105 .globl SYM(::class, 0) .p2align 2 SYM(::class, 0): - sub sp, sp, #32 - stp x29, x30, [sp, #16] - add x29, sp, #16 -Lloh90: - adrp x8, SYM(::class::REGISTER_CLASS, 0)@PAGE -Lloh91: - add x8, x8, SYM(::class::REGISTER_CLASS, 0)@PAGEOFF +Lloh106: + adrp x8, __MergedGlobals@PAGE+8 +Lloh107: + add x8, x8, __MergedGlobals@PAGEOFF+8 ldapr x8, [x8] cmp x8, #3 - b.ne LBB6_3 -Lloh92: - adrp x0, l_anon.[ID].11@PAGE -Lloh93: - add x0, x0, l_anon.[ID].11@PAGEOFF - mov w1, #15 - bl SYM(objc2::runtime::AnyClass::get::GENERATED_ID, 0) - cbz x0, LBB6_4 -LBB6_2: - ldp x29, x30, [sp, #16] - add sp, sp, #32 + b.ne LBB7_2 +Lloh108: + adrp x8, __MergedGlobals@PAGE +Lloh109: + ldr x0, [x8, __MergedGlobals@PAGEOFF] ret -LBB6_3: +LBB7_2: + sub sp, sp, #32 + stp x29, x30, [sp, #16] + add x29, sp, #16 mov w8, #1 strb w8, [sp, #7] add x8, sp, #7 str x8, [sp, #8] -Lloh94: - adrp x0, SYM(::class::REGISTER_CLASS, 0)@PAGE -Lloh95: - add x0, x0, SYM(::class::REGISTER_CLASS, 0)@PAGEOFF -Lloh96: +Lloh110: + adrp x0, __MergedGlobals@PAGE+8 +Lloh111: + add x0, x0, __MergedGlobals@PAGEOFF+8 +Lloh112: adrp x3, l_anon.[ID].0@PAGE -Lloh97: +Lloh113: add x3, x3, l_anon.[ID].0@PAGEOFF -Lloh98: - adrp x4, l_anon.[ID].16@PAGE -Lloh99: - add x4, x4, l_anon.[ID].16@PAGEOFF +Lloh114: + adrp x4, l_anon.[ID].23@PAGE +Lloh115: + add x4, x4, l_anon.[ID].23@PAGEOFF add x2, sp, #8 mov w1, #0 bl SYM(std::sys_common::once::queue::Once::call::GENERATED_ID, 0) -Lloh100: - adrp x0, l_anon.[ID].11@PAGE -Lloh101: - add x0, x0, l_anon.[ID].11@PAGEOFF - mov w1, #15 - bl SYM(objc2::runtime::AnyClass::get::GENERATED_ID, 0) - cbnz x0, LBB6_2 -LBB6_4: -Lloh102: - adrp x0, l_anon.[ID].8@PAGE -Lloh103: - add x0, x0, l_anon.[ID].8@PAGEOFF -Lloh104: - adrp x2, l_anon.[ID].16@PAGE -Lloh105: - add x2, x2, l_anon.[ID].16@PAGEOFF - mov w1, #43 - bl SYM(core::panicking::panic::GENERATED_ID, 0) - .loh AdrpAdd Lloh90, Lloh91 - .loh AdrpAdd Lloh92, Lloh93 - .loh AdrpAdd Lloh100, Lloh101 - .loh AdrpAdd Lloh98, Lloh99 - .loh AdrpAdd Lloh96, Lloh97 - .loh AdrpAdd Lloh94, Lloh95 - .loh AdrpAdd Lloh104, Lloh105 - .loh AdrpAdd Lloh102, Lloh103 - - .p2align 2 -SYM(::class::{closure#0}::__objc2_dealloc, 0): - sub sp, sp, #48 - stp x20, x19, [sp, #16] - stp x29, x30, [sp, #32] - add x29, sp, #32 - mov x19, x1 - mov x20, x0 -Lloh106: - adrp x1, l_anon.[ID].13@PAGE -Lloh107: - add x1, x1, l_anon.[ID].13@PAGEOFF - mov w2, #4 - bl SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - bl _ivar_getOffset - ldr x0, [x20, x0] - cbz x0, LBB7_2 - bl _objc_release -LBB7_2: -Lloh108: - adrp x8, L_OBJC_CLASSLIST_REFERENCES_$_NSObject@GOTPAGE -Lloh109: - ldr x8, [x8, L_OBJC_CLASSLIST_REFERENCES_$_NSObject@GOTPAGEOFF] -Lloh110: - ldr x8, [x8] - stp x20, x8, [sp] - mov x0, sp - mov x1, x19 - bl _objc_msgSendSuper - ldp x29, x30, [sp, #32] - ldp x20, x19, [sp, #16] - add sp, sp, #48 + ldp x29, x30, [sp, #16] + add sp, sp, #32 +Lloh116: + adrp x8, __MergedGlobals@PAGE +Lloh117: + ldr x0, [x8, __MergedGlobals@PAGEOFF] ret .loh AdrpAdd Lloh106, Lloh107 - .loh AdrpLdrGotLdr Lloh108, Lloh109, Lloh110 + .loh AdrpLdr Lloh108, Lloh109 + .loh AdrpLdr Lloh116, Lloh117 + .loh AdrpAdd Lloh114, Lloh115 + .loh AdrpAdd Lloh112, Lloh113 + .loh AdrpAdd Lloh110, Lloh111 .globl _init .p2align 2 _init: - sub sp, sp, #48 - stp x20, x19, [sp, #16] - stp x29, x30, [sp, #32] - add x29, sp, #32 -Lloh111: - adrp x8, L_OBJC_SELECTOR_REFERENCES_init@GOTPAGE -Lloh112: - ldr x8, [x8, L_OBJC_SELECTOR_REFERENCES_init@GOTPAGEOFF] -Lloh113: - ldr x1, [x8] -Lloh114: + sub sp, sp, #64 + stp x29, x30, [sp, #48] + add x29, sp, #48 + cbz x0, LBB8_2 +Lloh118: + adrp x8, SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)@PAGE +Lloh119: + ldr x8, [x8, SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)@PAGEOFF] + add x8, x0, x8 + str xzr, [x8] + mov w9, #42 + strb w9, [x8, #8] +Lloh120: + adrp x8, SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)@PAGE +Lloh121: + ldr x8, [x8, SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)@PAGEOFF] + mov w9, #1 + strb w9, [x0, x8] +Lloh122: + adrp x8, L_OBJC_SELECTOR_REFERENCES_74641ed6f72d2d44@PAGE +Lloh123: + ldr x1, [x8, L_OBJC_SELECTOR_REFERENCES_74641ed6f72d2d44@PAGEOFF] +Lloh124: adrp x8, L_OBJC_CLASSLIST_REFERENCES_$_NSObject@GOTPAGE -Lloh115: +Lloh125: ldr x8, [x8, L_OBJC_CLASSLIST_REFERENCES_$_NSObject@GOTPAGEOFF] -Lloh116: +Lloh126: ldr x8, [x8] stp x0, x8, [sp] mov x0, sp bl _objc_msgSendSuper - mov x19, x0 - cbz x0, LBB8_2 -Lloh117: - adrp x1, l_anon.[ID].12@PAGE -Lloh118: - add x1, x1, l_anon.[ID].12@PAGEOFF - mov x0, x19 - mov w2, #4 - bl SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - bl _ivar_getOffset - mov w8, #42 - strb w8, [x19, x0] -Lloh119: - adrp x1, l_anon.[ID].13@PAGE -Lloh120: - add x1, x1, l_anon.[ID].13@PAGEOFF - mov x0, x19 - mov w2, #4 - bl SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - bl _ivar_getOffset - str xzr, [x19, x0] -LBB8_2: - mov x0, x19 - ldp x29, x30, [sp, #32] - ldp x20, x19, [sp, #16] - add sp, sp, #48 + ldp x29, x30, [sp, #48] + add sp, sp, #64 ret - .loh AdrpLdrGotLdr Lloh114, Lloh115, Lloh116 - .loh AdrpLdrGotLdr Lloh111, Lloh112, Lloh113 - .loh AdrpAdd Lloh119, Lloh120 - .loh AdrpAdd Lloh117, Lloh118 +LBB8_2: +Lloh127: + adrp x8, l_anon.[ID].20@PAGE +Lloh128: + add x8, x8, l_anon.[ID].20@PAGEOFF + mov w9, #1 + stp x8, x9, [sp] +Lloh129: + adrp x8, l_anon.[ID].1@PAGE +Lloh130: + add x8, x8, l_anon.[ID].1@PAGEOFF + stp xzr, xzr, [sp, #24] + str x8, [sp, #16] +Lloh131: + adrp x1, l_anon.[ID].25@PAGE +Lloh132: + add x1, x1, l_anon.[ID].25@PAGEOFF + mov x0, sp + bl SYM(core::panicking::panic_fmt::GENERATED_ID, 0) + .loh AdrpLdrGotLdr Lloh124, Lloh125, Lloh126 + .loh AdrpAdrp Lloh122, Lloh124 + .loh AdrpLdr Lloh122, Lloh123 + .loh AdrpLdr Lloh120, Lloh121 + .loh AdrpLdr Lloh118, Lloh119 + .loh AdrpAdd Lloh131, Lloh132 + .loh AdrpAdd Lloh129, Lloh130 + .loh AdrpAdd Lloh127, Lloh128 .globl _class_method .p2align 2 @@ -574,25 +604,19 @@ _method_bool: .globl _method_id .p2align 2 _method_id: - stp x20, x19, [sp, #-32]! - stp x29, x30, [sp, #16] - add x29, sp, #16 - mov x19, x0 -Lloh121: - adrp x1, l_anon.[ID].13@PAGE -Lloh122: - add x1, x1, l_anon.[ID].13@PAGEOFF - mov w2, #4 - bl SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - bl _ivar_getOffset - ldr x0, [x19, x0] +Lloh133: + adrp x8, SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)@PAGE +Lloh134: + ldr x8, [x8, SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)@PAGEOFF] + ldr x0, [x0, x8] cbz x0, LBB12_2 + stp x29, x30, [sp, #-16]! + mov x29, sp bl _objc_retain + ldp x29, x30, [sp], #16 LBB12_2: - ldp x29, x30, [sp, #16] - ldp x20, x19, [sp], #32 b _objc_autoreleaseReturnValue - .loh AdrpAdd Lloh121, Lloh122 + .loh AdrpLdr Lloh133, Lloh134 .globl _method_id_with_param .p2align 2 @@ -606,15 +630,11 @@ _method_id_with_param: bl SYM(objc2::runtime::nsobject::NSObject::new::GENERATED_ID, 0) mov x19, x0 cbz w21, LBB13_5 -Lloh123: - adrp x1, l_anon.[ID].13@PAGE -Lloh124: - add x1, x1, l_anon.[ID].13@PAGEOFF - mov x0, x20 - mov w2, #4 - bl SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - bl _ivar_getOffset - ldr x0, [x20, x0] +Lloh135: + adrp x8, SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)@PAGE +Lloh136: + ldr x8, [x8, SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)@PAGEOFF] + ldr x0, [x20, x8] cbz x0, LBB13_3 bl _objc_retain mov x20, x0 @@ -631,69 +651,128 @@ LBB13_5: ldp x20, x19, [sp, #16] ldp x22, x21, [sp], #48 b _objc_autoreleaseReturnValue - .loh AdrpAdd Lloh123, Lloh124 + .loh AdrpLdr Lloh135, Lloh136 .globl _copyWithZone .p2align 2 _copyWithZone: - stp x22, x21, [sp, #-48]! - stp x20, x19, [sp, #16] - stp x29, x30, [sp, #32] - add x29, sp, #32 + sub sp, sp, #112 + stp x22, x21, [sp, #64] + stp x20, x19, [sp, #80] + stp x29, x30, [sp, #96] + add x29, sp, #96 mov x20, x0 - bl _get_obj +Lloh137: + adrp x8, L_OBJC_SELECTOR_REFERENCES_alloc@GOTPAGE +Lloh138: + ldr x8, [x8, L_OBJC_SELECTOR_REFERENCES_alloc@GOTPAGEOFF] +Lloh139: + ldr x19, [x8] +Lloh140: + adrp x8, __MergedGlobals@PAGE+8 +Lloh141: + add x8, x8, __MergedGlobals@PAGEOFF+8 + ldapr x8, [x8] + cmp x8, #3 + b.ne LBB14_5 +LBB14_1: +Lloh142: + adrp x8, __MergedGlobals@PAGE +Lloh143: + ldr x0, [x8, __MergedGlobals@PAGEOFF] + mov x1, x19 + bl _objc_msgSend mov x19, x0 - cbz x0, LBB14_5 -Lloh125: - adrp x21, l_anon.[ID].12@PAGE -Lloh126: - add x21, x21, l_anon.[ID].12@PAGEOFF - mov x0, x20 - mov x1, x21 - mov w2, #4 - bl SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - bl _ivar_getOffset - ldrb w22, [x20, x0] - mov x0, x19 - mov x1, x21 - mov w2, #4 - bl SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - bl _ivar_getOffset - strb w22, [x19, x0] -Lloh127: - adrp x1, l_anon.[ID].13@PAGE -Lloh128: - add x1, x1, l_anon.[ID].13@PAGEOFF - mov x0, x20 - mov w2, #4 - bl SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - bl _ivar_getOffset - ldr x0, [x20, x0] + adrp x21, SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)@PAGE + ldr x8, [x21, SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)@PAGEOFF] + add x8, x20, x8 + ldrb w20, [x8, #8] + ldr x0, [x8] cbz x0, LBB14_3 bl _objc_retain - mov x20, x0 - b LBB14_4 LBB14_3: - mov x20, #0 -LBB14_4: -Lloh129: - adrp x1, l_anon.[ID].13@PAGE -Lloh130: - add x1, x1, l_anon.[ID].13@PAGEOFF - mov x0, x19 - mov w2, #4 - bl SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - bl _ivar_getOffset - str x20, [x19, x0] -LBB14_5: - mov x0, x19 - ldp x29, x30, [sp, #32] - ldp x20, x19, [sp, #16] - ldp x22, x21, [sp], #48 + cbz x19, LBB14_6 + ldr x8, [x21, SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)@PAGEOFF] + add x8, x19, x8 + str x0, [x8] + strb w20, [x8, #8] +Lloh144: + adrp x8, SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)@PAGE +Lloh145: + ldr x8, [x8, SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)@PAGEOFF] + mov w9, #1 + strb w9, [x19, x8] +Lloh146: + adrp x8, L_OBJC_SELECTOR_REFERENCES_a4c8ca93c4279f29@PAGE +Lloh147: + ldr x1, [x8, L_OBJC_SELECTOR_REFERENCES_a4c8ca93c4279f29@PAGEOFF] +Lloh148: + adrp x8, L_OBJC_CLASSLIST_REFERENCES_$_NSObject@GOTPAGE +Lloh149: + ldr x8, [x8, L_OBJC_CLASSLIST_REFERENCES_$_NSObject@GOTPAGEOFF] +Lloh150: + ldr x8, [x8] + stp x19, x8, [sp, #16] + add x0, sp, #16 + bl _objc_msgSendSuper + ldp x29, x30, [sp, #96] + ldp x20, x19, [sp, #80] + ldp x22, x21, [sp, #64] + add sp, sp, #112 ret - .loh AdrpAdd Lloh127, Lloh128 - .loh AdrpAdd Lloh125, Lloh126 - .loh AdrpAdd Lloh129, Lloh130 +LBB14_5: + mov w8, #1 + strb w8, [sp, #15] + add x8, sp, #15 + str x8, [sp, #16] +Lloh151: + adrp x0, __MergedGlobals@PAGE+8 +Lloh152: + add x0, x0, __MergedGlobals@PAGEOFF+8 +Lloh153: + adrp x3, l_anon.[ID].0@PAGE +Lloh154: + add x3, x3, l_anon.[ID].0@PAGEOFF +Lloh155: + adrp x4, l_anon.[ID].23@PAGE +Lloh156: + add x4, x4, l_anon.[ID].23@PAGEOFF + add x2, sp, #16 + mov w1, #0 + bl SYM(std::sys_common::once::queue::Once::call::GENERATED_ID, 0) + b LBB14_1 +LBB14_6: +Lloh157: + adrp x8, l_anon.[ID].20@PAGE +Lloh158: + add x8, x8, l_anon.[ID].20@PAGEOFF + mov w9, #1 + stp x8, x9, [sp, #16] +Lloh159: + adrp x8, l_anon.[ID].1@PAGE +Lloh160: + add x8, x8, l_anon.[ID].1@PAGEOFF + stp xzr, xzr, [sp, #40] + str x8, [sp, #32] +Lloh161: + adrp x1, l_anon.[ID].26@PAGE +Lloh162: + add x1, x1, l_anon.[ID].26@PAGEOFF + add x0, sp, #16 + bl SYM(core::panicking::panic_fmt::GENERATED_ID, 0) + .loh AdrpAdd Lloh140, Lloh141 + .loh AdrpLdrGotLdr Lloh137, Lloh138, Lloh139 + .loh AdrpLdr Lloh142, Lloh143 + .loh AdrpLdrGotLdr Lloh148, Lloh149, Lloh150 + .loh AdrpAdrp Lloh146, Lloh148 + .loh AdrpLdr Lloh146, Lloh147 + .loh AdrpLdr Lloh144, Lloh145 + .loh AdrpAdd Lloh155, Lloh156 + .loh AdrpAdd Lloh153, Lloh154 + .loh AdrpAdd Lloh151, Lloh152 + .loh AdrpAdd Lloh161, Lloh162 + .loh AdrpAdd Lloh159, Lloh160 + .loh AdrpAdd Lloh157, Lloh158 .section __DATA,__const .p2align 3, 0x0 @@ -745,148 +824,229 @@ l_anon.[ID].7: .section __TEXT,__const l_anon.[ID].8: - .ascii "called `Option::unwrap()` on a `None` value" + .ascii "ivars" l_anon.[ID].9: - .ascii "$RUSTC/library/std/src/sync/once.rs" + .ascii "drop_flag" - .section __DATA,__const .p2align 3, 0x0 l_anon.[ID].10: - .quad l_anon.[ID].9 - .asciz "p\000\000\000\000\000\000\000\225\000\000\0002\000\000" + .byte 5 + .space 39 - .section __TEXT,__const + .p2align 3, 0x0 l_anon.[ID].11: - .ascii "CustomClassName" + .byte 9 + .space 39 - .section __TEXT,__literal4,4byte_literals l_anon.[ID].12: - .ascii "_foo" + .ascii "failed retrieving instance variable on newly declared class" l_anon.[ID].13: - .ascii "_obj" + .ascii "$WORKSPACE/objc2/src/__macro_helpers/declared_ivars.rs" - .section __TEXT,__const + .section __DATA,__const + .p2align 3, 0x0 l_anon.[ID].14: - .ascii "crates/$DIR/lib.rs" + .quad l_anon.[ID].13 + .asciz "T\000\000\000\000\000\000\000\363\000\000\000\016\000\000" .p2align 3, 0x0 l_anon.[ID].15: - .byte 5 - .space 39 + .quad l_anon.[ID].13 + .asciz "T\000\000\000\000\000\000\000\377\000\000\000\016\000\000" + + .section __TEXT,__const +l_anon.[ID].16: + .ascii "called `Option::unwrap()` on a `None` value" + +l_anon.[ID].17: + .ascii "$RUSTC/library/std/src/sync/once.rs" .section __DATA,__const .p2align 3, 0x0 -l_anon.[ID].16: - .quad l_anon.[ID].14 - .asciz "5\000\000\000\000\000\000\000\f\000\000\000\001\000\000" +l_anon.[ID].18: + .quad l_anon.[ID].17 + .asciz "p\000\000\000\000\000\000\000\225\000\000\0002\000\000" -.zerofill __DATA,__bss,SYM(::class::REGISTER_CLASS, 0),8,3 .section __TEXT,__const -l_anon.[ID].17: +l_anon.[ID].19: + .ascii "tried to initialize instance variables on NULL allocated object" + + .section __DATA,__const + .p2align 3, 0x0 +l_anon.[ID].20: + .quad l_anon.[ID].19 + .asciz "?\000\000\000\000\000\000" + + .section __TEXT,__const +l_anon.[ID].21: + .ascii "CustomClassName" + +l_anon.[ID].22: + .ascii "crates/$DIR/lib.rs" + + .globl SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0) +.zerofill __DATA,__common,SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0),8,3 + .globl SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0) +.zerofill __DATA,__common,SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0),8,3 + .section __DATA,__const + .p2align 3, 0x0 +l_anon.[ID].23: + .quad l_anon.[ID].22 + .asciz "5\000\000\000\000\000\000\000\021\000\000\000\001\000\000" + + .section __TEXT,__const +l_anon.[ID].24: .ascii "NSCopying" .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_d874ee9262978be2 -L_OBJC_METH_VAR_NAME_d874ee9262978be2: + .globl L_OBJC_METH_VAR_NAME_ddead4cf1cfe35ab +L_OBJC_METH_VAR_NAME_ddead4cf1cfe35ab: .asciz "classMethod" .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_d874ee9262978be2 + .globl L_OBJC_SELECTOR_REFERENCES_ddead4cf1cfe35ab .p2align 3, 0x0 -L_OBJC_SELECTOR_REFERENCES_d874ee9262978be2: - .quad L_OBJC_METH_VAR_NAME_d874ee9262978be2 +L_OBJC_SELECTOR_REFERENCES_ddead4cf1cfe35ab: + .quad L_OBJC_METH_VAR_NAME_ddead4cf1cfe35ab .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_d874ee9262978be2 + .globl L_OBJC_IMAGE_INFO_ddead4cf1cfe35ab .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_d874ee9262978be2: +L_OBJC_IMAGE_INFO_ddead4cf1cfe35ab: .asciz "\000\000\000\000@\000\000" .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_4539fd1dbda0cddc -L_OBJC_METH_VAR_NAME_4539fd1dbda0cddc: + .globl L_OBJC_METH_VAR_NAME_8ee1155e2a63c707 +L_OBJC_METH_VAR_NAME_8ee1155e2a63c707: .asciz "method" .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_4539fd1dbda0cddc + .globl L_OBJC_SELECTOR_REFERENCES_8ee1155e2a63c707 .p2align 3, 0x0 -L_OBJC_SELECTOR_REFERENCES_4539fd1dbda0cddc: - .quad L_OBJC_METH_VAR_NAME_4539fd1dbda0cddc +L_OBJC_SELECTOR_REFERENCES_8ee1155e2a63c707: + .quad L_OBJC_METH_VAR_NAME_8ee1155e2a63c707 .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_4539fd1dbda0cddc + .globl L_OBJC_IMAGE_INFO_8ee1155e2a63c707 .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_4539fd1dbda0cddc: +L_OBJC_IMAGE_INFO_8ee1155e2a63c707: .asciz "\000\000\000\000@\000\000" .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_2b1b3a94e0ece2e5 -L_OBJC_METH_VAR_NAME_2b1b3a94e0ece2e5: + .globl L_OBJC_METH_VAR_NAME_b1c6d8f625c88aa6 +L_OBJC_METH_VAR_NAME_b1c6d8f625c88aa6: .asciz "methodBool:" .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_2b1b3a94e0ece2e5 + .globl L_OBJC_SELECTOR_REFERENCES_b1c6d8f625c88aa6 .p2align 3, 0x0 -L_OBJC_SELECTOR_REFERENCES_2b1b3a94e0ece2e5: - .quad L_OBJC_METH_VAR_NAME_2b1b3a94e0ece2e5 +L_OBJC_SELECTOR_REFERENCES_b1c6d8f625c88aa6: + .quad L_OBJC_METH_VAR_NAME_b1c6d8f625c88aa6 .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_2b1b3a94e0ece2e5 + .globl L_OBJC_IMAGE_INFO_b1c6d8f625c88aa6 .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_2b1b3a94e0ece2e5: +L_OBJC_IMAGE_INFO_b1c6d8f625c88aa6: .asciz "\000\000\000\000@\000\000" .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_f7f521670860b0ce -L_OBJC_METH_VAR_NAME_f7f521670860b0ce: + .globl L_OBJC_METH_VAR_NAME_f33da9321a226f33 +L_OBJC_METH_VAR_NAME_f33da9321a226f33: .asciz "methodId" .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_f7f521670860b0ce + .globl L_OBJC_SELECTOR_REFERENCES_f33da9321a226f33 .p2align 3, 0x0 -L_OBJC_SELECTOR_REFERENCES_f7f521670860b0ce: - .quad L_OBJC_METH_VAR_NAME_f7f521670860b0ce +L_OBJC_SELECTOR_REFERENCES_f33da9321a226f33: + .quad L_OBJC_METH_VAR_NAME_f33da9321a226f33 .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_f7f521670860b0ce + .globl L_OBJC_IMAGE_INFO_f33da9321a226f33 .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_f7f521670860b0ce: +L_OBJC_IMAGE_INFO_f33da9321a226f33: .asciz "\000\000\000\000@\000\000" .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_6addfcf634c6232f -L_OBJC_METH_VAR_NAME_6addfcf634c6232f: + .globl L_OBJC_METH_VAR_NAME_e5d1ad528a5510d9 +L_OBJC_METH_VAR_NAME_e5d1ad528a5510d9: .asciz "methodIdWithParam:" .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_6addfcf634c6232f + .globl L_OBJC_SELECTOR_REFERENCES_e5d1ad528a5510d9 .p2align 3, 0x0 -L_OBJC_SELECTOR_REFERENCES_6addfcf634c6232f: - .quad L_OBJC_METH_VAR_NAME_6addfcf634c6232f +L_OBJC_SELECTOR_REFERENCES_e5d1ad528a5510d9: + .quad L_OBJC_METH_VAR_NAME_e5d1ad528a5510d9 .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_6addfcf634c6232f + .globl L_OBJC_IMAGE_INFO_e5d1ad528a5510d9 .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_6addfcf634c6232f: +L_OBJC_IMAGE_INFO_e5d1ad528a5510d9: .asciz "\000\000\000\000@\000\000" .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_4a8c690dbc9d8166 -L_OBJC_METH_VAR_NAME_4a8c690dbc9d8166: + .globl L_OBJC_METH_VAR_NAME_8daf9cd9e6dba6e3 +L_OBJC_METH_VAR_NAME_8daf9cd9e6dba6e3: .asciz "copyWithZone:" .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_4a8c690dbc9d8166 + .globl L_OBJC_SELECTOR_REFERENCES_8daf9cd9e6dba6e3 + .p2align 3, 0x0 +L_OBJC_SELECTOR_REFERENCES_8daf9cd9e6dba6e3: + .quad L_OBJC_METH_VAR_NAME_8daf9cd9e6dba6e3 + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_8daf9cd9e6dba6e3 + .p2align 2, 0x0 +L_OBJC_IMAGE_INFO_8daf9cd9e6dba6e3: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__const + .p2align 3, 0x0 +l_anon.[ID].25: + .quad l_anon.[ID].22 + .asciz "5\000\000\000\000\000\000\000#\000\000\000\035\000\000" + + .section __TEXT,__objc_methname,cstring_literals + .globl L_OBJC_METH_VAR_NAME_74641ed6f72d2d44 +L_OBJC_METH_VAR_NAME_74641ed6f72d2d44: + .asciz "init" + + .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip + .globl L_OBJC_SELECTOR_REFERENCES_74641ed6f72d2d44 + .p2align 3, 0x0 +L_OBJC_SELECTOR_REFERENCES_74641ed6f72d2d44: + .quad L_OBJC_METH_VAR_NAME_74641ed6f72d2d44 + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_74641ed6f72d2d44 + .p2align 2, 0x0 +L_OBJC_IMAGE_INFO_74641ed6f72d2d44: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__const + .p2align 3, 0x0 +l_anon.[ID].26: + .quad l_anon.[ID].22 + .asciz "5\000\000\000\000\000\000\000N\000\000\000\033\000\000" + + .section __TEXT,__objc_methname,cstring_literals + .globl L_OBJC_METH_VAR_NAME_a4c8ca93c4279f29 +L_OBJC_METH_VAR_NAME_a4c8ca93c4279f29: + .asciz "init" + + .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip + .globl L_OBJC_SELECTOR_REFERENCES_a4c8ca93c4279f29 .p2align 3, 0x0 -L_OBJC_SELECTOR_REFERENCES_4a8c690dbc9d8166: - .quad L_OBJC_METH_VAR_NAME_4a8c690dbc9d8166 +L_OBJC_SELECTOR_REFERENCES_a4c8ca93c4279f29: + .quad L_OBJC_METH_VAR_NAME_a4c8ca93c4279f29 .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_4a8c690dbc9d8166 + .globl L_OBJC_IMAGE_INFO_a4c8ca93c4279f29 .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_4a8c690dbc9d8166: +L_OBJC_IMAGE_INFO_a4c8ca93c4279f29: .asciz "\000\000\000\000@\000\000" +.zerofill __DATA,__bss,__MergedGlobals,16,3 .subsections_via_symbols diff --git a/crates/test-assembly/crates/test_declare_class/expected/apple-armv7.s b/crates/test-assembly/crates/test_declare_class/expected/apple-armv7.s index fe42bf1e7..4b5663e69 100644 --- a/crates/test-assembly/crates/test_declare_class/expected/apple-armv7.s +++ b/crates/test-assembly/crates/test_declare_class/expected/apple-armv7.s @@ -7,223 +7,341 @@ SYM(core[CRATE_ID]::ptr::drop_in_place::<::call .p2align 2 .code 32 -SYM(::call_once::<::class::{closure#0}>::{closure#0}, 0): +SYM(objc2[CRATE_ID]::__macro_helpers::declared_ivars::dealloc::, 0): push {r4, r5, r7, lr} add r7, sp, #8 + sub sp, sp, #8 + mov r5, r0 + movw r0, :lower16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)-(LPC1_0+8)) + movt r0, :upper16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)-(LPC1_0+8)) + mov r4, r1 +LPC1_0: + ldr r0, [pc, r0] + ldrb r0, [r5, r0] + cmp r0, #0 + beq LBB1_3 + movw r0, :lower16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-(LPC1_1+8)) + movt r0, :upper16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-(LPC1_1+8)) +LPC1_1: + ldr r0, [pc, r0] + ldr r0, [r5, r0] + cmp r0, #0 + beq LBB1_3 + bl _objc_release +LBB1_3: + movw r0, :lower16:(LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-(LPC1_2+8)) + mov r1, r4 + movt r0, :upper16:(LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-(LPC1_2+8)) + str r5, [sp] +LPC1_2: + ldr r0, [pc, r0] + ldr r0, [r0] + str r0, [sp, #4] + mov r0, sp + bl _objc_msgSendSuper + sub sp, r7, #8 + pop {r4, r5, r7, pc} + + .p2align 2 + .code 32 +SYM(::call_once::<::class::{closure#0}>::{closure#0}, 0): + push {r4, r5, r6, r7, lr} + add r7, sp, #12 push {r8, r10, r11} - sub sp, sp, #12 + sub sp, sp, #36 ldr r0, [r0] mov r2, #0 ldrb r1, [r0] strb r2, [r0] cmp r1, #0 - beq LBB1_5 - movw r1, :lower16:(LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-(LPC1_0+8)) - movt r1, :upper16:(LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-(LPC1_0+8)) - movw r0, :lower16:(l_anon.[ID].11-(LPC1_1+8)) -LPC1_0: + beq LBB2_7 + movw r1, :lower16:(LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-(LPC2_0+8)) + movt r1, :upper16:(LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-(LPC2_0+8)) + movw r0, :lower16:(l_anon.[ID].21-(LPC2_1+8)) +LPC2_0: ldr r1, [pc, r1] - movt r0, :upper16:(l_anon.[ID].11-(LPC1_1+8)) -LPC1_1: + movt r0, :upper16:(l_anon.[ID].21-(LPC2_1+8)) +LPC2_1: add r0, pc, r0 ldr r2, [r1] mov r1, #15 bl SYM(objc2::declare::ClassBuilder::new::GENERATED_ID, 0) cmp r0, #0 - beq LBB1_6 - movw r1, :lower16:(L_anon.[ID].12-(LPC1_2+8)) - add r4, sp, #8 - movt r1, :upper16:(L_anon.[ID].12-(LPC1_2+8)) - movw r3, :lower16:(l_anon.[ID].15-(LPC1_3+8)) - movt r3, :upper16:(l_anon.[ID].15-(LPC1_3+8)) -LPC1_2: - add r1, pc, r1 -LPC1_3: + beq LBB2_8 + movw r1, :lower16:(LL_OBJC_SELECTOR_REFERENCES_dealloc$non_lazy_ptr-(LPC2_2+8)) + add r11, sp, #16 + movt r1, :upper16:(LL_OBJC_SELECTOR_REFERENCES_dealloc$non_lazy_ptr-(LPC2_2+8)) + movw r6, :lower16:(l_anon.[ID].3-(LPC2_3+8)) +LPC2_2: + ldr r1, [pc, r1] + movt r6, :upper16:(l_anon.[ID].3-(LPC2_3+8)) + movw r4, :lower16:(l_anon.[ID].1-(LPC2_4+8)) +LPC2_3: + add r6, pc, r6 + movt r4, :upper16:(l_anon.[ID].1-(LPC2_4+8)) + movw r3, :lower16:(SYM(objc2[CRATE_ID]::__macro_helpers::declared_ivars::dealloc::, 0)-(LPC2_5+8)) + movt r3, :upper16:(SYM(objc2[CRATE_ID]::__macro_helpers::declared_ivars::dealloc::, 0)-(LPC2_5+8)) +LPC2_4: + add r4, pc, r4 + ldr r1, [r1] +LPC2_5: add r3, pc, r3 - mov r2, #0 - str r0, [sp, #8] - mov r0, r4 - strd r2, r3, [sp] - mov r2, #4 - mov r3, #1 - bl SYM(objc2::declare::ClassBuilder::add_ivar_inner_mono::GENERATED_ID, 0) - movw r8, :lower16:(l_anon.[ID].2-(LPC1_4+8)) - mov r0, #2 - movt r8, :upper16:(l_anon.[ID].2-(LPC1_4+8)) - movw r1, :lower16:(L_anon.[ID].13-(LPC1_5+8)) - movt r1, :upper16:(L_anon.[ID].13-(LPC1_5+8)) -LPC1_4: - add r8, pc, r8 -LPC1_5: - add r1, pc, r1 - stm sp, {r0, r8} - mov r0, r4 - mov r2, #4 - mov r3, #4 - bl SYM(objc2::declare::ClassBuilder::add_ivar_inner_mono::GENERATED_ID, 0) - movw r0, :lower16:(LL_OBJC_SELECTOR_REFERENCES_dealloc$non_lazy_ptr-(LPC1_6+8)) + str r0, [sp, #16] + mov r0, r11 + str r6, [sp] + mov r2, r4 + str r3, [sp, #4] mov r3, #0 - movt r0, :upper16:(LL_OBJC_SELECTOR_REFERENCES_dealloc$non_lazy_ptr-(LPC1_6+8)) - movw r10, :lower16:(l_anon.[ID].3-(LPC1_7+8)) -LPC1_6: - ldr r0, [pc, r0] - movt r10, :upper16:(l_anon.[ID].3-(LPC1_7+8)) -LPC1_7: - add r10, pc, r10 - ldr r1, [r0] - movw r11, :lower16:(SYM(::class::{closure#0}::__objc2_dealloc, 0)-(LPC1_8+8)) - movt r11, :upper16:(SYM(::class::{closure#0}::__objc2_dealloc, 0)-(LPC1_8+8)) - movw r5, :lower16:(l_anon.[ID].1-(LPC1_9+8)) - movt r5, :upper16:(l_anon.[ID].1-(LPC1_9+8)) -LPC1_8: - add r11, pc, r11 -LPC1_9: - add r5, pc, r5 - mov r0, r4 - strd r10, r11, [sp] - mov r2, r5 + mov r8, #0 bl SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) - movw r0, :lower16:(LL_OBJC_SELECTOR_REFERENCES_init$non_lazy_ptr-(LPC1_10+8)) - mov r2, r5 - movt r0, :upper16:(LL_OBJC_SELECTOR_REFERENCES_init$non_lazy_ptr-(LPC1_10+8)) - mov r3, #0 -LPC1_10: + movw r0, :lower16:(LL_OBJC_SELECTOR_REFERENCES_init$non_lazy_ptr-(LPC2_6+8)) + add r5, sp, #8 + movt r0, :upper16:(LL_OBJC_SELECTOR_REFERENCES_init$non_lazy_ptr-(LPC2_6+8)) + mov r2, r4 +LPC2_6: ldr r0, [pc, r0] ldr r1, [r0] - movw r9, :lower16:(_init-(LPC1_11+8)) - movt r9, :upper16:(_init-(LPC1_11+8)) - mov r0, r4 -LPC1_11: - add r9, pc, r9 - strd r8, r9, [sp] + movw r10, :lower16:(l_anon.[ID].2-(LPC2_7+8)) + movt r10, :upper16:(l_anon.[ID].2-(LPC2_7+8)) + ldr r0, [sp, #16] + movw r3, :lower16:(_init-(LPC2_8+8)) +LPC2_7: + add r10, pc, r10 + movt r3, :upper16:(_init-(LPC2_8+8)) + str r0, [sp, #8] +LPC2_8: + add r3, pc, r3 + str r10, [sp] + str r3, [sp, #4] + mov r0, r5 + mov r3, #0 bl SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) - movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_d874ee9262978be2-(LPC1_12+8)) - mov r0, r4 - movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_d874ee9262978be2-(LPC1_12+8)) - mov r2, r5 -LPC1_12: + movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_ddead4cf1cfe35ab-(LPC2_9+8)) + mov r0, r5 + movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_ddead4cf1cfe35ab-(LPC2_9+8)) + mov r2, r4 +LPC2_9: ldr r1, [pc, r1] - movw r11, :lower16:(_class_method-(LPC1_13+8)) - movt r11, :upper16:(_class_method-(LPC1_13+8)) + movw r3, :lower16:(_class_method-(LPC2_10+8)) + movt r3, :upper16:(_class_method-(LPC2_10+8)) + str r6, [sp] +LPC2_10: + add r3, pc, r3 + str r3, [sp, #4] mov r3, #0 -LPC1_13: - add r11, pc, r11 - strd r10, r11, [sp] bl SYM(objc2::declare::ClassBuilder::add_class_method_inner::GENERATED_ID, 0) - movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_4539fd1dbda0cddc-(LPC1_14+8)) - mov r0, r4 - movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_4539fd1dbda0cddc-(LPC1_14+8)) - mov r2, r5 -LPC1_14: + movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_8ee1155e2a63c707-(LPC2_11+8)) + mov r0, r5 + movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_8ee1155e2a63c707-(LPC2_11+8)) + mov r2, r4 +LPC2_11: ldr r1, [pc, r1] - movw r11, :lower16:(_method-(LPC1_15+8)) - movt r11, :upper16:(_method-(LPC1_15+8)) + movw r3, :lower16:(_method-(LPC2_12+8)) + movt r3, :upper16:(_method-(LPC2_12+8)) + str r6, [sp] +LPC2_12: + add r3, pc, r3 + str r3, [sp, #4] mov r3, #0 -LPC1_15: - add r11, pc, r11 - strd r10, r11, [sp] bl SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) - movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_2b1b3a94e0ece2e5-(LPC1_16+8)) - mov r0, r4 - movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_2b1b3a94e0ece2e5-(LPC1_16+8)) -LPC1_16: + movw r6, :lower16:(l_anon.[ID].4-(LPC2_13+8)) + mov r0, r5 + movt r6, :upper16:(l_anon.[ID].4-(LPC2_13+8)) + movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_b1c6d8f625c88aa6-(LPC2_14+8)) + movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_b1c6d8f625c88aa6-(LPC2_14+8)) +LPC2_13: + add r6, pc, r6 +LPC2_14: ldr r1, [pc, r1] - movw r3, :lower16:(_method_bool-(LPC1_17+8)) - movt r3, :upper16:(_method_bool-(LPC1_17+8)) - movw r10, :lower16:(l_anon.[ID].4-(LPC1_18+8)) - movt r10, :upper16:(l_anon.[ID].4-(LPC1_18+8)) -LPC1_17: + movw r3, :lower16:(_method_bool-(LPC2_15+8)) + movt r3, :upper16:(_method_bool-(LPC2_15+8)) + str r6, [sp] +LPC2_15: add r3, pc, r3 -LPC1_18: - add r10, pc, r10 - str r10, [sp] str r3, [sp, #4] + mov r2, r6 mov r3, #1 - mov r2, r10 bl SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) - movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_f7f521670860b0ce-(LPC1_19+8)) - mov r0, r4 - movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_f7f521670860b0ce-(LPC1_19+8)) - mov r2, r5 -LPC1_19: + movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_f33da9321a226f33-(LPC2_16+8)) + mov r0, r5 + movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_f33da9321a226f33-(LPC2_16+8)) + mov r2, r4 +LPC2_16: ldr r1, [pc, r1] - movw r9, :lower16:(_method_id-(LPC1_20+8)) - movt r9, :upper16:(_method_id-(LPC1_20+8)) + movw r3, :lower16:(_method_id-(LPC2_17+8)) + movt r3, :upper16:(_method_id-(LPC2_17+8)) + str r10, [sp] +LPC2_17: + add r3, pc, r3 + str r3, [sp, #4] mov r3, #0 -LPC1_20: - add r9, pc, r9 - strd r8, r9, [sp] bl SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) - movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_6addfcf634c6232f-(LPC1_21+8)) - mov r0, r4 - movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_6addfcf634c6232f-(LPC1_21+8)) - mov r2, r10 -LPC1_21: + movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_e5d1ad528a5510d9-(LPC2_18+8)) + mov r0, r5 + movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_e5d1ad528a5510d9-(LPC2_18+8)) + mov r2, r6 +LPC2_18: ldr r1, [pc, r1] - movw r9, :lower16:(_method_id_with_param-(LPC1_22+8)) - movt r9, :upper16:(_method_id_with_param-(LPC1_22+8)) + movw r3, :lower16:(_method_id_with_param-(LPC2_19+8)) + movt r3, :upper16:(_method_id_with_param-(LPC2_19+8)) + str r10, [sp] +LPC2_19: + add r3, pc, r3 + str r3, [sp, #4] mov r3, #1 -LPC1_22: - add r9, pc, r9 - strd r8, r9, [sp] bl SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) - movw r0, :lower16:(l_anon.[ID].17-(LPC1_23+8)) + movw r0, :lower16:(l_anon.[ID].24-(LPC2_20+8)) mov r1, #9 - movt r0, :upper16:(l_anon.[ID].17-(LPC1_23+8)) -LPC1_23: + movt r0, :upper16:(l_anon.[ID].24-(LPC2_20+8)) +LPC2_20: add r0, pc, r0 bl SYM(objc2::runtime::AnyProtocol::get::GENERATED_ID, 0) cmp r0, #0 - beq LBB1_4 + beq LBB2_4 mov r1, r0 add r0, sp, #8 bl SYM(objc2::declare::ClassBuilder::add_protocol::GENERATED_ID, 0) -LBB1_4: - movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_4a8c690dbc9d8166-(LPC1_24+8)) +LBB2_4: + movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_8daf9cd9e6dba6e3-(LPC2_21+8)) add r0, sp, #8 - movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_4a8c690dbc9d8166-(LPC1_24+8)) - mov r3, #1 -LPC1_24: + movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_8daf9cd9e6dba6e3-(LPC2_21+8)) +LPC2_21: ldr r1, [pc, r1] - movw r2, :lower16:(l_anon.[ID].7-(LPC1_25+8)) - movt r2, :upper16:(l_anon.[ID].7-(LPC1_25+8)) - movw r9, :lower16:(_copyWithZone-(LPC1_26+8)) - movt r9, :upper16:(_copyWithZone-(LPC1_26+8)) -LPC1_25: + movw r2, :lower16:(l_anon.[ID].7-(LPC2_22+8)) + movt r2, :upper16:(l_anon.[ID].7-(LPC2_22+8)) + movw r3, :lower16:(_copyWithZone-(LPC2_23+8)) + movt r3, :upper16:(_copyWithZone-(LPC2_23+8)) +LPC2_22: add r2, pc, r2 -LPC1_26: - add r9, pc, r9 - strd r8, r9, [sp] +LPC2_23: + add r3, pc, r3 + str r10, [sp] + str r3, [sp, #4] + mov r3, #1 bl SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) ldr r0, [sp, #8] + movw r5, :lower16:(l_anon.[ID].8-(LPC2_24+8)) + movt r5, :upper16:(l_anon.[ID].8-(LPC2_24+8)) + movw r1, :lower16:(l_anon.[ID].11-(LPC2_25+8)) + movt r1, :upper16:(l_anon.[ID].11-(LPC2_25+8)) + str r0, [sp, #12] + mov r0, #8 +LPC2_24: + add r5, pc, r5 + add r4, sp, #12 +LPC2_25: + add r1, pc, r1 + str r0, [sp, #20] + mov r0, #27 + str r1, [sp, #28] + mov r10, #2 + strb r0, [sp, #16] + mov r0, r4 + mov r1, r5 + mov r2, #5 + mov r3, #8 + str r8, [sp, #24] + strd r10, r11, [sp] + bl SYM(objc2::declare::ClassBuilder::add_ivar_inner_mono::GENERATED_ID, 0) + movw r1, :lower16:(l_anon.[ID].9-(LPC2_26+8)) + mov r0, r4 + movt r1, :upper16:(l_anon.[ID].9-(LPC2_26+8)) + movw r9, :lower16:(l_anon.[ID].10-(LPC2_27+8)) + movt r9, :upper16:(l_anon.[ID].10-(LPC2_27+8)) +LPC2_26: + add r1, pc, r1 +LPC2_27: + add r9, pc, r9 + mov r2, #9 + mov r3, #1 + strd r8, r9, [sp] + bl SYM(objc2::declare::ClassBuilder::add_ivar_inner_mono::GENERATED_ID, 0) + ldr r0, [sp, #12] bl SYM(objc2::declare::ClassBuilder::register::GENERATED_ID, 0) - sub sp, r7, #20 + mov r1, r5 + mov r2, #5 + mov r4, r0 + bl SYM(objc2::runtime::AnyClass::instance_variable::GENERATED_ID, 0) + cmp r0, #0 + beq LBB2_9 + bl _ivar_getOffset + movw r1, :lower16:(l_anon.[ID].9-(LPC2_28+8)) + mov r5, r0 + movt r1, :upper16:(l_anon.[ID].9-(LPC2_28+8)) + mov r0, r4 +LPC2_28: + add r1, pc, r1 + mov r2, #9 + bl SYM(objc2::runtime::AnyClass::instance_variable::GENERATED_ID, 0) + cmp r0, #0 + beq LBB2_10 + bl _ivar_getOffset + movw r1, :lower16:(__MergedGlobals-(LPC2_29+8)) + movt r1, :upper16:(__MergedGlobals-(LPC2_29+8)) + movw r2, :lower16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-(LPC2_30+8)) + movt r2, :upper16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-(LPC2_30+8)) + movw r3, :lower16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)-(LPC2_31+8)) + movt r3, :upper16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)-(LPC2_31+8)) +LPC2_29: + add r1, pc, r1 +LPC2_30: + add r2, pc, r2 +LPC2_31: + add r3, pc, r3 + str r4, [r1] + str r5, [r2] + str r0, [r3] + sub sp, r7, #24 pop {r8, r10, r11} - pop {r4, r5, r7, pc} -LBB1_5: - movw r0, :lower16:(l_anon.[ID].8-(LPC1_27+8)) + pop {r4, r5, r6, r7, pc} +LBB2_7: + movw r0, :lower16:(l_anon.[ID].16-(LPC2_32+8)) mov r1, #43 - movt r0, :upper16:(l_anon.[ID].8-(LPC1_27+8)) - movw r2, :lower16:(l_anon.[ID].10-(LPC1_28+8)) - movt r2, :upper16:(l_anon.[ID].10-(LPC1_28+8)) -LPC1_27: + movt r0, :upper16:(l_anon.[ID].16-(LPC2_32+8)) + movw r2, :lower16:(l_anon.[ID].18-(LPC2_33+8)) + movt r2, :upper16:(l_anon.[ID].18-(LPC2_33+8)) +LPC2_32: add r0, pc, r0 -LPC1_28: +LPC2_33: add r2, pc, r2 mov lr, pc b SYM(core::panicking::panic::GENERATED_ID, 0) -LBB1_6: - movw r0, :lower16:(l_anon.[ID].11-(LPC1_29+8)) +LBB2_8: + movw r0, :lower16:(l_anon.[ID].21-(LPC2_34+8)) mov r1, #15 - movt r0, :upper16:(l_anon.[ID].11-(LPC1_29+8)) - movw r2, :lower16:(l_anon.[ID].16-(LPC1_30+8)) - movt r2, :upper16:(l_anon.[ID].16-(LPC1_30+8)) -LPC1_29: + movt r0, :upper16:(l_anon.[ID].21-(LPC2_34+8)) + movw r2, :lower16:(l_anon.[ID].23-(LPC2_35+8)) + movt r2, :upper16:(l_anon.[ID].23-(LPC2_35+8)) +LPC2_34: add r0, pc, r0 -LPC1_30: +LPC2_35: add r2, pc, r2 mov lr, pc b SYM(objc2::__macro_helpers::declare_class::failed_declaring_class::GENERATED_ID, 0) +LBB2_9: + movw r0, :lower16:(l_anon.[ID].12-(LPC2_36+8)) + mov r1, #59 + movt r0, :upper16:(l_anon.[ID].12-(LPC2_36+8)) + movw r2, :lower16:(l_anon.[ID].14-(LPC2_37+8)) + movt r2, :upper16:(l_anon.[ID].14-(LPC2_37+8)) +LPC2_36: + add r0, pc, r0 +LPC2_37: + add r2, pc, r2 + mov lr, pc + b SYM(core::option::expect_failed::GENERATED_ID, 0) +LBB2_10: + movw r0, :lower16:(l_anon.[ID].12-(LPC2_38+8)) + mov r1, #59 + movt r0, :upper16:(l_anon.[ID].12-(LPC2_38+8)) + movw r2, :lower16:(l_anon.[ID].15-(LPC2_39+8)) + movt r2, :upper16:(l_anon.[ID].15-(LPC2_39+8)) +LPC2_38: + add r0, pc, r0 +LPC2_39: + add r2, pc, r2 + mov lr, pc + b SYM(core::option::expect_failed::GENERATED_ID, 0) .p2align 2 .code 32 @@ -242,61 +360,44 @@ SYM(<::call_once<::class::REGISTER_CLASS, 0)-(LPC3_0+8)) - movt r0, :upper16:(SYM(::class::REGISTER_CLASS, 0)-(LPC3_0+8)) -LPC3_0: - add r0, pc, r0 - ldr r0, [r0] - dmb ish - cmp r0, #3 - bne LBB3_3 -LBB3_1: - movw r0, :lower16:(l_anon.[ID].11-(LPC3_4+8)) - mov r1, #15 - movt r0, :upper16:(l_anon.[ID].11-(LPC3_4+8)) -LPC3_4: - add r0, pc, r0 - bl SYM(objc2::runtime::AnyClass::get::GENERATED_ID, 0) - cmp r0, #0 - movne sp, r7 - popne {r7, pc} -LBB3_2: - movw r0, :lower16:(l_anon.[ID].8-(LPC3_5+8)) - mov r1, #43 - movt r0, :upper16:(l_anon.[ID].8-(LPC3_5+8)) - movw r2, :lower16:(l_anon.[ID].16-(LPC3_6+8)) - movt r2, :upper16:(l_anon.[ID].16-(LPC3_6+8)) -LPC3_5: - add r0, pc, r0 -LPC3_6: - add r2, pc, r2 - mov lr, pc - b SYM(core::panicking::panic::GENERATED_ID, 0) -LBB3_3: - movw r0, :lower16:(SYM(::class::REGISTER_CLASS, 0)-(LPC3_1+8)) + movw r1, :lower16:(l_anon.[ID].23-(LPC4_1+8)) mov r2, #1 - movt r0, :upper16:(SYM(::class::REGISTER_CLASS, 0)-(LPC3_1+8)) - movw r3, :lower16:(l_anon.[ID].0-(LPC3_2+8)) - movt r3, :upper16:(l_anon.[ID].0-(LPC3_2+8)) - movw r1, :lower16:(l_anon.[ID].16-(LPC3_3+8)) - movt r1, :upper16:(l_anon.[ID].16-(LPC3_3+8)) + movt r1, :upper16:(l_anon.[ID].23-(LPC4_1+8)) + movw r3, :lower16:(l_anon.[ID].0-(LPC4_2+8)) + movt r3, :upper16:(l_anon.[ID].0-(LPC4_2+8)) strb r2, [r7, #-5] sub r2, r7, #5 -LPC3_3: +LPC4_1: add r1, pc, r1 str r2, [r7, #-4] -LPC3_1: - add r0, pc, r0 -LPC3_2: +LPC4_2: add r3, pc, r3 + add r0, r0, #4 sub r2, r7, #4 str r1, [sp] mov r1, #0 bl SYM(std::sys_common::once::queue::Once::call::GENERATED_ID, 0) - b LBB3_1 + mov sp, r7 + pop {r7, lr} + b LBB4_1 .globl _get_obj .p2align 2 @@ -304,9 +405,9 @@ LPC3_2: _get_obj: push {r4, r7, lr} add r7, sp, #4 - movw r0, :lower16:(LL_OBJC_SELECTOR_REFERENCES_new$non_lazy_ptr-(LPC4_0+8)) - movt r0, :upper16:(LL_OBJC_SELECTOR_REFERENCES_new$non_lazy_ptr-(LPC4_0+8)) -LPC4_0: + movw r0, :lower16:(LL_OBJC_SELECTOR_REFERENCES_new$non_lazy_ptr-(LPC5_0+8)) + movt r0, :upper16:(LL_OBJC_SELECTOR_REFERENCES_new$non_lazy_ptr-(LPC5_0+8)) +LPC5_0: ldr r0, [pc, r0] ldr r4, [r0] bl _get_class @@ -318,173 +419,123 @@ LPC4_0: .p2align 2 .code 32 _access_ivars: - push {r4, r5, r6, r7, lr} - add r7, sp, #12 + push {r4, r5, r7, lr} + add r7, sp, #8 bl _get_obj - movw r1, :lower16:(L_anon.[ID].12-(LPC5_0+8)) - mov r2, #4 - movt r1, :upper16:(L_anon.[ID].12-(LPC5_0+8)) - mov r4, r0 -LPC5_0: - add r1, pc, r1 - bl SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - bl _ivar_getOffset - ldrb r5, [r4, r0] - movw r1, :lower16:(L_anon.[ID].13-(LPC5_1+8)) - movt r1, :upper16:(L_anon.[ID].13-(LPC5_1+8)) -LPC5_1: - add r1, pc, r1 - mov r0, r4 - mov r2, #4 - bl SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - bl _ivar_getOffset - ldr r6, [r4, r0] - mov r0, r4 + movw r1, :lower16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-(LPC6_0+8)) + mov r2, r0 + movt r1, :upper16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-(LPC6_0+8)) +LPC6_0: + ldr r1, [pc, r1] + ldr r4, [r2, r1]! + ldrb r5, [r2, #4] bl _objc_release mov r0, r5 - mov r1, r6 - pop {r4, r5, r6, r7, pc} + mov r1, r4 + pop {r4, r5, r7, pc} .globl SYM(::class, 0) .p2align 2 .code 32 SYM(::class, 0): + movw r0, :lower16:(__MergedGlobals-(LPC7_0+8)) + movt r0, :upper16:(__MergedGlobals-(LPC7_0+8)) +LPC7_0: + add r0, pc, r0 + ldr r1, [r0, #4] + dmb ish + cmp r1, #3 + bne LBB7_2 +LBB7_1: + movw r0, :lower16:(__MergedGlobals-(LPC7_3+8)) + movt r0, :upper16:(__MergedGlobals-(LPC7_3+8)) +LPC7_3: + ldr r0, [pc, r0] + bx lr +LBB7_2: push {r7, lr} mov r7, sp sub sp, sp, #12 - movw r0, :lower16:(SYM(::class::REGISTER_CLASS, 0)-(LPC6_0+8)) - movt r0, :upper16:(SYM(::class::REGISTER_CLASS, 0)-(LPC6_0+8)) -LPC6_0: - add r0, pc, r0 - ldr r0, [r0] - dmb ish - cmp r0, #3 - bne LBB6_3 -LBB6_1: - movw r0, :lower16:(l_anon.[ID].11-(LPC6_4+8)) - mov r1, #15 - movt r0, :upper16:(l_anon.[ID].11-(LPC6_4+8)) -LPC6_4: - add r0, pc, r0 - bl SYM(objc2::runtime::AnyClass::get::GENERATED_ID, 0) - cmp r0, #0 - movne sp, r7 - popne {r7, pc} -LBB6_2: - movw r0, :lower16:(l_anon.[ID].8-(LPC6_5+8)) - mov r1, #43 - movt r0, :upper16:(l_anon.[ID].8-(LPC6_5+8)) - movw r2, :lower16:(l_anon.[ID].16-(LPC6_6+8)) - movt r2, :upper16:(l_anon.[ID].16-(LPC6_6+8)) -LPC6_5: - add r0, pc, r0 -LPC6_6: - add r2, pc, r2 - mov lr, pc - b SYM(core::panicking::panic::GENERATED_ID, 0) -LBB6_3: - movw r0, :lower16:(SYM(::class::REGISTER_CLASS, 0)-(LPC6_1+8)) + movw r1, :lower16:(l_anon.[ID].23-(LPC7_1+8)) mov r2, #1 - movt r0, :upper16:(SYM(::class::REGISTER_CLASS, 0)-(LPC6_1+8)) - movw r3, :lower16:(l_anon.[ID].0-(LPC6_2+8)) - movt r3, :upper16:(l_anon.[ID].0-(LPC6_2+8)) - movw r1, :lower16:(l_anon.[ID].16-(LPC6_3+8)) - movt r1, :upper16:(l_anon.[ID].16-(LPC6_3+8)) + movt r1, :upper16:(l_anon.[ID].23-(LPC7_1+8)) + movw r3, :lower16:(l_anon.[ID].0-(LPC7_2+8)) + movt r3, :upper16:(l_anon.[ID].0-(LPC7_2+8)) strb r2, [r7, #-5] sub r2, r7, #5 -LPC6_3: +LPC7_1: add r1, pc, r1 str r2, [r7, #-4] -LPC6_1: - add r0, pc, r0 -LPC6_2: +LPC7_2: add r3, pc, r3 + add r0, r0, #4 sub r2, r7, #4 str r1, [sp] mov r1, #0 bl SYM(std::sys_common::once::queue::Once::call::GENERATED_ID, 0) - b LBB6_1 - - .p2align 2 - .code 32 -SYM(::class::{closure#0}::__objc2_dealloc, 0): - push {r4, r5, r7, lr} - add r7, sp, #8 - sub sp, sp, #8 - mov r4, r1 - movw r1, :lower16:(L_anon.[ID].13-(LPC7_0+8)) - movt r1, :upper16:(L_anon.[ID].13-(LPC7_0+8)) - mov r2, #4 -LPC7_0: - add r1, pc, r1 - mov r5, r0 - bl SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - bl _ivar_getOffset - ldr r0, [r5, r0] - cmp r0, #0 - beq LBB7_2 - bl _objc_release -LBB7_2: - movw r0, :lower16:(LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-(LPC7_1+8)) - mov r1, r4 - movt r0, :upper16:(LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-(LPC7_1+8)) - str r5, [sp] -LPC7_1: - ldr r0, [pc, r0] - ldr r0, [r0] - str r0, [sp, #4] - mov r0, sp - bl _objc_msgSendSuper - sub sp, r7, #8 - pop {r4, r5, r7, pc} + mov sp, r7 + pop {r7, lr} + b LBB7_1 .globl _init .p2align 2 .code 32 _init: - push {r4, r7, lr} - add r7, sp, #4 - sub sp, sp, #8 - movw r1, :lower16:(LL_OBJC_SELECTOR_REFERENCES_init$non_lazy_ptr-(LPC8_0+8)) - movt r1, :upper16:(LL_OBJC_SELECTOR_REFERENCES_init$non_lazy_ptr-(LPC8_0+8)) - movw r2, :lower16:(LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-(LPC8_1+8)) + push {r7, lr} + mov r7, sp + sub sp, sp, #24 + cmp r0, #0 + beq LBB8_2 + movw r1, :lower16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-(LPC8_0+8)) + mov r2, #0 + movt r1, :upper16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-(LPC8_0+8)) + mov r3, r0 LPC8_0: ldr r1, [pc, r1] - movt r2, :upper16:(LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-(LPC8_1+8)) + str r2, [r3, r1]! + mov r1, #42 + strb r1, [r3, #4] + movw r1, :lower16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)-(LPC8_1+8)) + movt r1, :upper16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)-(LPC8_1+8)) + mov r3, #1 LPC8_1: + ldr r1, [pc, r1] + movw r2, :lower16:(LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-(LPC8_2+8)) + movt r2, :upper16:(LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-(LPC8_2+8)) +LPC8_2: ldr r2, [pc, r2] - ldr r1, [r1] + strb r3, [r0, r1] + movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_74641ed6f72d2d44-(LPC8_3+8)) + movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_74641ed6f72d2d44-(LPC8_3+8)) +LPC8_3: + ldr r1, [pc, r1] ldr r2, [r2] stm sp, {r0, r2} mov r0, sp bl _objc_msgSendSuper - mov r4, r0 - cmp r0, #0 - beq LBB8_2 - movw r1, :lower16:(L_anon.[ID].12-(LPC8_2+8)) - mov r0, r4 - movt r1, :upper16:(L_anon.[ID].12-(LPC8_2+8)) - mov r2, #4 -LPC8_2: - add r1, pc, r1 - bl SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - bl _ivar_getOffset - movw r1, :lower16:(L_anon.[ID].13-(LPC8_3+8)) - mov r2, #42 - movt r1, :upper16:(L_anon.[ID].13-(LPC8_3+8)) - strb r2, [r4, r0] -LPC8_3: - add r1, pc, r1 - mov r0, r4 - mov r2, #4 - bl SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - bl _ivar_getOffset - mov r1, #0 - str r1, [r4, r0] + mov sp, r7 + pop {r7, pc} LBB8_2: - mov r0, r4 - sub sp, r7, #4 - pop {r4, r7, pc} + movw r0, :lower16:(l_anon.[ID].20-(LPC8_4+8)) + mov r3, #0 + movt r0, :upper16:(l_anon.[ID].20-(LPC8_4+8)) + movw r9, :lower16:(l_anon.[ID].1-(LPC8_5+8)) + movt r9, :upper16:(l_anon.[ID].1-(LPC8_5+8)) + movw r1, :lower16:(l_anon.[ID].25-(LPC8_6+8)) + movt r1, :upper16:(l_anon.[ID].25-(LPC8_6+8)) +LPC8_4: + add r0, pc, r0 +LPC8_6: + add r1, pc, r1 +LPC8_5: + add r9, pc, r9 + mov r2, #1 + stm sp, {r0, r2, r9} + mov r0, sp + str r3, [sp, #16] + str r3, [sp, #12] + mov lr, pc + b SYM(core::panicking::panic_fmt::GENERATED_ID, 0) .globl _class_method .p2align 2 @@ -510,25 +561,20 @@ _method_bool: .p2align 2 .code 32 _method_id: - push {r4, r7, lr} - add r7, sp, #4 - movw r1, :lower16:(L_anon.[ID].13-(LPC12_0+8)) - mov r2, #4 - movt r1, :upper16:(L_anon.[ID].13-(LPC12_0+8)) - mov r4, r0 + movw r1, :lower16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-(LPC12_0+8)) + movt r1, :upper16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-(LPC12_0+8)) LPC12_0: - add r1, pc, r1 - bl SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - bl _ivar_getOffset - ldr r0, [r4, r0] + ldr r1, [pc, r1] + ldr r0, [r0, r1] cmp r0, #0 beq LBB12_2 + push {r7, lr} + mov r7, sp bl _objc_retain - pop {r4, r7, lr} + pop {r7, lr} b _objc_autoreleaseReturnValue LBB12_2: mov r0, #0 - pop {r4, r7, lr} b _objc_autoreleaseReturnValue .globl _method_id_with_param @@ -543,14 +589,10 @@ _method_id_with_param: mov r4, r0 cmp r6, #0 beq LBB13_3 - movw r1, :lower16:(L_anon.[ID].13-(LPC13_0+8)) - mov r0, r5 - movt r1, :upper16:(L_anon.[ID].13-(LPC13_0+8)) - mov r2, #4 + movw r0, :lower16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-(LPC13_0+8)) + movt r0, :upper16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-(LPC13_0+8)) LPC13_0: - add r1, pc, r1 - bl SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - bl _ivar_getOffset + ldr r0, [pc, r0] ldr r0, [r5, r0] cmp r0, #0 beq LBB13_4 @@ -575,60 +617,117 @@ LBB13_5: .p2align 2 .code 32 _copyWithZone: - push {r4, r5, r6, r7, lr} - add r7, sp, #12 - push {r8} - mov r5, r0 - bl _get_obj + push {r4, r5, r7, lr} + add r7, sp, #8 + sub sp, sp, #32 + movw r1, :lower16:(LL_OBJC_SELECTOR_REFERENCES_alloc$non_lazy_ptr-(LPC14_0+8)) mov r4, r0 - cmp r0, #0 - beq LBB14_5 - movw r8, :lower16:(L_anon.[ID].12-(LPC14_0+8)) - mov r0, r5 - movt r8, :upper16:(L_anon.[ID].12-(LPC14_0+8)) - mov r2, #4 + movt r1, :upper16:(LL_OBJC_SELECTOR_REFERENCES_alloc$non_lazy_ptr-(LPC14_0+8)) + movw r0, :lower16:(__MergedGlobals-(LPC14_1+8)) + movt r0, :upper16:(__MergedGlobals-(LPC14_1+8)) LPC14_0: - add r8, pc, r8 - mov r1, r8 - bl SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - bl _ivar_getOffset - ldrb r6, [r5, r0] - mov r0, r4 - mov r1, r8 - mov r2, #4 - bl SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - bl _ivar_getOffset - movw r1, :lower16:(L_anon.[ID].13-(LPC14_1+8)) - mov r2, #4 - movt r1, :upper16:(L_anon.[ID].13-(LPC14_1+8)) - strb r6, [r4, r0] + ldr r1, [pc, r1] LPC14_1: - add r1, pc, r1 - mov r0, r5 - bl SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - bl _ivar_getOffset - ldr r0, [r5, r0] + add r0, pc, r0 + ldr r5, [r1] + ldr r1, [r0, #4] + dmb ish + cmp r1, #3 + bne LBB14_6 +LBB14_1: + movw r0, :lower16:(__MergedGlobals-(LPC14_4+8)) + mov r1, r5 + movt r0, :upper16:(__MergedGlobals-(LPC14_4+8)) +LPC14_4: + ldr r0, [pc, r0] + bl _objc_msgSend + mov r5, r0 + movw r0, :lower16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-(LPC14_5+8)) + movt r0, :upper16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-(LPC14_5+8)) +LPC14_5: + ldr r0, [pc, r0] + ldr r0, [r4, r0]! + ldrb r4, [r4, #4] cmp r0, #0 - beq LBB14_3 + beq LBB14_4 bl _objc_retain - mov r5, r0 - b LBB14_4 + cmp r5, #0 + beq LBB14_5 LBB14_3: - mov r5, #0 + movw r1, :lower16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-(LPC14_6+8)) + mov r2, r5 + movt r1, :upper16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-(LPC14_6+8)) +LPC14_6: + ldr r1, [pc, r1] + str r0, [r2, r1]! + mov r1, #1 + strb r4, [r2, #4] + movw r0, :lower16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)-(LPC14_7+8)) + movt r0, :upper16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)-(LPC14_7+8)) +LPC14_7: + ldr r0, [pc, r0] + movw r2, :lower16:(LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-(LPC14_8+8)) + movt r2, :upper16:(LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-(LPC14_8+8)) +LPC14_8: + ldr r2, [pc, r2] + strb r1, [r5, r0] + movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_a4c8ca93c4279f29-(LPC14_9+8)) + movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_a4c8ca93c4279f29-(LPC14_9+8)) + ldr r0, [r2] +LPC14_9: + ldr r1, [pc, r1] + str r0, [sp, #12] + add r0, sp, #8 + str r5, [sp, #8] + bl _objc_msgSendSuper + sub sp, r7, #8 + pop {r4, r5, r7, pc} LBB14_4: - movw r1, :lower16:(L_anon.[ID].13-(LPC14_2+8)) - mov r0, r4 - movt r1, :upper16:(L_anon.[ID].13-(LPC14_2+8)) - mov r2, #4 + mov r0, #0 + cmp r5, #0 + bne LBB14_3 +LBB14_5: + movw r0, :lower16:(l_anon.[ID].20-(LPC14_10+8)) + mov r3, #0 + movt r0, :upper16:(l_anon.[ID].20-(LPC14_10+8)) + movw r2, :lower16:(l_anon.[ID].1-(LPC14_11+8)) + movt r2, :upper16:(l_anon.[ID].1-(LPC14_11+8)) + movw r1, :lower16:(l_anon.[ID].26-(LPC14_12+8)) + movt r1, :upper16:(l_anon.[ID].26-(LPC14_12+8)) +LPC14_10: + add r0, pc, r0 + str r0, [sp, #8] +LPC14_12: + add r1, pc, r1 + add r0, sp, #8 + mov r5, #1 +LPC14_11: + add r2, pc, r2 + str r3, [sp, #24] + str r5, [sp, #12] + str r3, [sp, #20] + str r2, [sp, #16] + mov lr, pc + b SYM(core::panicking::panic_fmt::GENERATED_ID, 0) +LBB14_6: + movw r1, :lower16:(l_anon.[ID].23-(LPC14_2+8)) + mov r2, #1 + movt r1, :upper16:(l_anon.[ID].23-(LPC14_2+8)) + movw r3, :lower16:(l_anon.[ID].0-(LPC14_3+8)) + movt r3, :upper16:(l_anon.[ID].0-(LPC14_3+8)) + strb r2, [sp, #7] + add r2, sp, #7 LPC14_2: add r1, pc, r1 - bl SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - bl _ivar_getOffset - str r5, [r4, r0] -LBB14_5: - mov r0, r4 - pop {r8} - pop {r4, r5, r6, r7, pc} + str r2, [sp, #8] +LPC14_3: + add r3, pc, r3 + add r0, r0, #4 + add r2, sp, #8 + str r1, [sp] + mov r1, #0 + bl SYM(std::sys_common::once::queue::Once::call::GENERATED_ID, 0) + b LBB14_1 .section __DATA,__const .p2align 2, 0x0 @@ -680,155 +779,239 @@ l_anon.[ID].7: .section __TEXT,__const l_anon.[ID].8: - .ascii "called `Option::unwrap()` on a `None` value" + .ascii "ivars" l_anon.[ID].9: - .ascii "$RUSTC/library/std/src/sync/once.rs" + .ascii "drop_flag" - .section __DATA,__const .p2align 2, 0x0 l_anon.[ID].10: - .long l_anon.[ID].9 - .asciz "p\000\000\000\225\000\000\0002\000\000" + .byte 5 + .space 19 - .section __TEXT,__const + .p2align 2, 0x0 l_anon.[ID].11: - .ascii "CustomClassName" + .byte 7 + .space 19 - .section __TEXT,__literal4,4byte_literals -L_anon.[ID].12: - .ascii "_foo" +l_anon.[ID].12: + .ascii "failed retrieving instance variable on newly declared class" -L_anon.[ID].13: - .ascii "_obj" +l_anon.[ID].13: + .ascii "$WORKSPACE/objc2/src/__macro_helpers/declared_ivars.rs" - .section __TEXT,__const + .section __DATA,__const + .p2align 2, 0x0 l_anon.[ID].14: - .ascii "crates/$DIR/lib.rs" + .long l_anon.[ID].13 + .asciz "T\000\000\000\363\000\000\000\016\000\000" .p2align 2, 0x0 l_anon.[ID].15: - .byte 5 - .space 19 + .long l_anon.[ID].13 + .asciz "T\000\000\000\377\000\000\000\016\000\000" + + .section __TEXT,__const +l_anon.[ID].16: + .ascii "called `Option::unwrap()` on a `None` value" + +l_anon.[ID].17: + .ascii "$RUSTC/library/std/src/sync/once.rs" .section __DATA,__const .p2align 2, 0x0 -l_anon.[ID].16: - .long l_anon.[ID].14 - .asciz "5\000\000\000\f\000\000\000\001\000\000" +l_anon.[ID].18: + .long l_anon.[ID].17 + .asciz "p\000\000\000\225\000\000\0002\000\000" -.zerofill __DATA,__bss,SYM(::class::REGISTER_CLASS, 0),4,2 .section __TEXT,__const -l_anon.[ID].17: +l_anon.[ID].19: + .ascii "tried to initialize instance variables on NULL allocated object" + + .section __DATA,__const + .p2align 2, 0x0 +l_anon.[ID].20: + .long l_anon.[ID].19 + .asciz "?\000\000" + + .section __TEXT,__const +l_anon.[ID].21: + .ascii "CustomClassName" + +l_anon.[ID].22: + .ascii "crates/$DIR/lib.rs" + + .globl SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0) +.zerofill __DATA,__common,SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0),4,2 + .globl SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0) +.zerofill __DATA,__common,SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0),4,2 + .section __DATA,__const + .p2align 2, 0x0 +l_anon.[ID].23: + .long l_anon.[ID].22 + .asciz "5\000\000\000\021\000\000\000\001\000\000" + + .section __TEXT,__const +l_anon.[ID].24: .ascii "NSCopying" .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_d874ee9262978be2 -L_OBJC_METH_VAR_NAME_d874ee9262978be2: + .globl L_OBJC_METH_VAR_NAME_ddead4cf1cfe35ab +L_OBJC_METH_VAR_NAME_ddead4cf1cfe35ab: .asciz "classMethod" .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_d874ee9262978be2 + .globl L_OBJC_SELECTOR_REFERENCES_ddead4cf1cfe35ab .p2align 2, 0x0 -L_OBJC_SELECTOR_REFERENCES_d874ee9262978be2: - .long L_OBJC_METH_VAR_NAME_d874ee9262978be2 +L_OBJC_SELECTOR_REFERENCES_ddead4cf1cfe35ab: + .long L_OBJC_METH_VAR_NAME_ddead4cf1cfe35ab .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_d874ee9262978be2 + .globl L_OBJC_IMAGE_INFO_ddead4cf1cfe35ab .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_d874ee9262978be2: +L_OBJC_IMAGE_INFO_ddead4cf1cfe35ab: .asciz "\000\000\000\000@\000\000" .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_4539fd1dbda0cddc -L_OBJC_METH_VAR_NAME_4539fd1dbda0cddc: + .globl L_OBJC_METH_VAR_NAME_8ee1155e2a63c707 +L_OBJC_METH_VAR_NAME_8ee1155e2a63c707: .asciz "method" .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_4539fd1dbda0cddc + .globl L_OBJC_SELECTOR_REFERENCES_8ee1155e2a63c707 .p2align 2, 0x0 -L_OBJC_SELECTOR_REFERENCES_4539fd1dbda0cddc: - .long L_OBJC_METH_VAR_NAME_4539fd1dbda0cddc +L_OBJC_SELECTOR_REFERENCES_8ee1155e2a63c707: + .long L_OBJC_METH_VAR_NAME_8ee1155e2a63c707 .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_4539fd1dbda0cddc + .globl L_OBJC_IMAGE_INFO_8ee1155e2a63c707 .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_4539fd1dbda0cddc: +L_OBJC_IMAGE_INFO_8ee1155e2a63c707: .asciz "\000\000\000\000@\000\000" .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_2b1b3a94e0ece2e5 -L_OBJC_METH_VAR_NAME_2b1b3a94e0ece2e5: + .globl L_OBJC_METH_VAR_NAME_b1c6d8f625c88aa6 +L_OBJC_METH_VAR_NAME_b1c6d8f625c88aa6: .asciz "methodBool:" .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_2b1b3a94e0ece2e5 + .globl L_OBJC_SELECTOR_REFERENCES_b1c6d8f625c88aa6 .p2align 2, 0x0 -L_OBJC_SELECTOR_REFERENCES_2b1b3a94e0ece2e5: - .long L_OBJC_METH_VAR_NAME_2b1b3a94e0ece2e5 +L_OBJC_SELECTOR_REFERENCES_b1c6d8f625c88aa6: + .long L_OBJC_METH_VAR_NAME_b1c6d8f625c88aa6 .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_2b1b3a94e0ece2e5 + .globl L_OBJC_IMAGE_INFO_b1c6d8f625c88aa6 .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_2b1b3a94e0ece2e5: +L_OBJC_IMAGE_INFO_b1c6d8f625c88aa6: .asciz "\000\000\000\000@\000\000" .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_f7f521670860b0ce -L_OBJC_METH_VAR_NAME_f7f521670860b0ce: + .globl L_OBJC_METH_VAR_NAME_f33da9321a226f33 +L_OBJC_METH_VAR_NAME_f33da9321a226f33: .asciz "methodId" .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_f7f521670860b0ce + .globl L_OBJC_SELECTOR_REFERENCES_f33da9321a226f33 .p2align 2, 0x0 -L_OBJC_SELECTOR_REFERENCES_f7f521670860b0ce: - .long L_OBJC_METH_VAR_NAME_f7f521670860b0ce +L_OBJC_SELECTOR_REFERENCES_f33da9321a226f33: + .long L_OBJC_METH_VAR_NAME_f33da9321a226f33 .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_f7f521670860b0ce + .globl L_OBJC_IMAGE_INFO_f33da9321a226f33 .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_f7f521670860b0ce: +L_OBJC_IMAGE_INFO_f33da9321a226f33: .asciz "\000\000\000\000@\000\000" .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_6addfcf634c6232f -L_OBJC_METH_VAR_NAME_6addfcf634c6232f: + .globl L_OBJC_METH_VAR_NAME_e5d1ad528a5510d9 +L_OBJC_METH_VAR_NAME_e5d1ad528a5510d9: .asciz "methodIdWithParam:" .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_6addfcf634c6232f + .globl L_OBJC_SELECTOR_REFERENCES_e5d1ad528a5510d9 .p2align 2, 0x0 -L_OBJC_SELECTOR_REFERENCES_6addfcf634c6232f: - .long L_OBJC_METH_VAR_NAME_6addfcf634c6232f +L_OBJC_SELECTOR_REFERENCES_e5d1ad528a5510d9: + .long L_OBJC_METH_VAR_NAME_e5d1ad528a5510d9 .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_6addfcf634c6232f + .globl L_OBJC_IMAGE_INFO_e5d1ad528a5510d9 .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_6addfcf634c6232f: +L_OBJC_IMAGE_INFO_e5d1ad528a5510d9: .asciz "\000\000\000\000@\000\000" .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_4a8c690dbc9d8166 -L_OBJC_METH_VAR_NAME_4a8c690dbc9d8166: + .globl L_OBJC_METH_VAR_NAME_8daf9cd9e6dba6e3 +L_OBJC_METH_VAR_NAME_8daf9cd9e6dba6e3: .asciz "copyWithZone:" .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_4a8c690dbc9d8166 + .globl L_OBJC_SELECTOR_REFERENCES_8daf9cd9e6dba6e3 .p2align 2, 0x0 -L_OBJC_SELECTOR_REFERENCES_4a8c690dbc9d8166: - .long L_OBJC_METH_VAR_NAME_4a8c690dbc9d8166 +L_OBJC_SELECTOR_REFERENCES_8daf9cd9e6dba6e3: + .long L_OBJC_METH_VAR_NAME_8daf9cd9e6dba6e3 .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_4a8c690dbc9d8166 + .globl L_OBJC_IMAGE_INFO_8daf9cd9e6dba6e3 .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_4a8c690dbc9d8166: +L_OBJC_IMAGE_INFO_8daf9cd9e6dba6e3: .asciz "\000\000\000\000@\000\000" + .section __DATA,__const + .p2align 2, 0x0 +l_anon.[ID].25: + .long l_anon.[ID].22 + .asciz "5\000\000\000#\000\000\000\035\000\000" + + .section __TEXT,__objc_methname,cstring_literals + .globl L_OBJC_METH_VAR_NAME_74641ed6f72d2d44 +L_OBJC_METH_VAR_NAME_74641ed6f72d2d44: + .asciz "init" + + .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip + .globl L_OBJC_SELECTOR_REFERENCES_74641ed6f72d2d44 + .p2align 2, 0x0 +L_OBJC_SELECTOR_REFERENCES_74641ed6f72d2d44: + .long L_OBJC_METH_VAR_NAME_74641ed6f72d2d44 + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_74641ed6f72d2d44 + .p2align 2, 0x0 +L_OBJC_IMAGE_INFO_74641ed6f72d2d44: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__const + .p2align 2, 0x0 +l_anon.[ID].26: + .long l_anon.[ID].22 + .asciz "5\000\000\000N\000\000\000\033\000\000" + + .section __TEXT,__objc_methname,cstring_literals + .globl L_OBJC_METH_VAR_NAME_a4c8ca93c4279f29 +L_OBJC_METH_VAR_NAME_a4c8ca93c4279f29: + .asciz "init" + + .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip + .globl L_OBJC_SELECTOR_REFERENCES_a4c8ca93c4279f29 + .p2align 2, 0x0 +L_OBJC_SELECTOR_REFERENCES_a4c8ca93c4279f29: + .long L_OBJC_METH_VAR_NAME_a4c8ca93c4279f29 + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_a4c8ca93c4279f29 + .p2align 2, 0x0 +L_OBJC_IMAGE_INFO_a4c8ca93c4279f29: + .asciz "\000\000\000\000@\000\000" + +.zerofill __DATA,__bss,__MergedGlobals,8,2 .section __DATA,__nl_symbol_ptr,non_lazy_symbol_pointers .p2align 2, 0x0 LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr: .indirect_symbol L_OBJC_CLASSLIST_REFERENCES_$_NSObject .long 0 +LL_OBJC_SELECTOR_REFERENCES_alloc$non_lazy_ptr: + .indirect_symbol L_OBJC_SELECTOR_REFERENCES_alloc + .long 0 LL_OBJC_SELECTOR_REFERENCES_dealloc$non_lazy_ptr: .indirect_symbol L_OBJC_SELECTOR_REFERENCES_dealloc .long 0 diff --git a/crates/test-assembly/crates/test_declare_class/expected/apple-armv7s.s b/crates/test-assembly/crates/test_declare_class/expected/apple-armv7s.s index 69350aaec..2008f0d59 100644 --- a/crates/test-assembly/crates/test_declare_class/expected/apple-armv7s.s +++ b/crates/test-assembly/crates/test_declare_class/expected/apple-armv7s.s @@ -7,223 +7,341 @@ SYM(core[CRATE_ID]::ptr::drop_in_place::<::call .p2align 2 .code 32 -SYM(::call_once::<::class::{closure#0}>::{closure#0}, 0): +SYM(objc2[CRATE_ID]::__macro_helpers::declared_ivars::dealloc::, 0): push {r4, r5, r7, lr} add r7, sp, #8 + sub sp, sp, #8 + mov r5, r0 + movw r0, :lower16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)-(LPC1_0+8)) + movt r0, :upper16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)-(LPC1_0+8)) + mov r4, r1 +LPC1_0: + ldr r0, [pc, r0] + ldrb r0, [r5, r0] + cmp r0, #0 + beq LBB1_3 + movw r0, :lower16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-(LPC1_1+8)) + movt r0, :upper16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-(LPC1_1+8)) +LPC1_1: + ldr r0, [pc, r0] + ldr r0, [r5, r0] + cmp r0, #0 + beq LBB1_3 + bl _objc_release +LBB1_3: + movw r0, :lower16:(LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-(LPC1_2+8)) + mov r1, r4 + movt r0, :upper16:(LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-(LPC1_2+8)) + str r5, [sp] +LPC1_2: + ldr r0, [pc, r0] + ldr r0, [r0] + str r0, [sp, #4] + mov r0, sp + bl _objc_msgSendSuper + sub sp, r7, #8 + pop {r4, r5, r7, pc} + + .p2align 2 + .code 32 +SYM(::call_once::<::class::{closure#0}>::{closure#0}, 0): + push {r4, r5, r6, r7, lr} + add r7, sp, #12 push {r8, r10, r11} - sub sp, sp, #12 + sub sp, sp, #36 ldr r0, [r0] mov r2, #0 ldrb r1, [r0] strb r2, [r0] cmp r1, #0 - beq LBB1_5 - movw r1, :lower16:(LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-(LPC1_0+8)) - movt r1, :upper16:(LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-(LPC1_0+8)) - movw r0, :lower16:(l_anon.[ID].11-(LPC1_1+8)) -LPC1_0: + beq LBB2_7 + movw r1, :lower16:(LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-(LPC2_0+8)) + movt r1, :upper16:(LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-(LPC2_0+8)) + movw r0, :lower16:(l_anon.[ID].21-(LPC2_1+8)) +LPC2_0: ldr r1, [pc, r1] - movt r0, :upper16:(l_anon.[ID].11-(LPC1_1+8)) -LPC1_1: + movt r0, :upper16:(l_anon.[ID].21-(LPC2_1+8)) +LPC2_1: add r0, pc, r0 ldr r2, [r1] mov r1, #15 bl SYM(objc2::declare::ClassBuilder::new::GENERATED_ID, 0) cmp r0, #0 - beq LBB1_6 - movw r1, :lower16:(L_anon.[ID].12-(LPC1_2+8)) - mov r2, #0 - movt r1, :upper16:(L_anon.[ID].12-(LPC1_2+8)) - movw r3, :lower16:(l_anon.[ID].15-(LPC1_3+8)) - movt r3, :upper16:(l_anon.[ID].15-(LPC1_3+8)) - add r4, sp, #8 -LPC1_3: + beq LBB2_8 + movw r1, :lower16:(LL_OBJC_SELECTOR_REFERENCES_dealloc$non_lazy_ptr-(LPC2_2+8)) + add r11, sp, #16 + movt r1, :upper16:(LL_OBJC_SELECTOR_REFERENCES_dealloc$non_lazy_ptr-(LPC2_2+8)) + movw r4, :lower16:(l_anon.[ID].1-(LPC2_3+8)) +LPC2_2: + ldr r1, [pc, r1] + movt r4, :upper16:(l_anon.[ID].1-(LPC2_3+8)) + movw r6, :lower16:(l_anon.[ID].3-(LPC2_4+8)) +LPC2_3: + add r4, pc, r4 + movt r6, :upper16:(l_anon.[ID].3-(LPC2_4+8)) + movw r3, :lower16:(SYM(objc2[CRATE_ID]::__macro_helpers::declared_ivars::dealloc::, 0)-(LPC2_5+8)) + movt r3, :upper16:(SYM(objc2[CRATE_ID]::__macro_helpers::declared_ivars::dealloc::, 0)-(LPC2_5+8)) + ldr r1, [r1] +LPC2_4: + add r6, pc, r6 +LPC2_5: add r3, pc, r3 - str r0, [sp, #8] - strd r2, r3, [sp] -LPC1_2: - add r1, pc, r1 - mov r0, r4 - mov r2, #4 - mov r3, #1 - bl SYM(objc2::declare::ClassBuilder::add_ivar_inner_mono::GENERATED_ID, 0) - movw r8, :lower16:(l_anon.[ID].2-(LPC1_4+8)) - mov r0, #2 - movt r8, :upper16:(l_anon.[ID].2-(LPC1_4+8)) - movw r1, :lower16:(L_anon.[ID].13-(LPC1_5+8)) - movt r1, :upper16:(L_anon.[ID].13-(LPC1_5+8)) -LPC1_4: - add r8, pc, r8 - stm sp, {r0, r8} -LPC1_5: - add r1, pc, r1 - mov r0, r4 - mov r2, #4 - mov r3, #4 - bl SYM(objc2::declare::ClassBuilder::add_ivar_inner_mono::GENERATED_ID, 0) - movw r0, :lower16:(LL_OBJC_SELECTOR_REFERENCES_dealloc$non_lazy_ptr-(LPC1_6+8)) + str r0, [sp, #16] + mov r0, r11 + str r6, [sp] + mov r2, r4 + str r3, [sp, #4] mov r3, #0 - movt r0, :upper16:(LL_OBJC_SELECTOR_REFERENCES_dealloc$non_lazy_ptr-(LPC1_6+8)) - movw r11, :lower16:(SYM(::class::{closure#0}::__objc2_dealloc, 0)-(LPC1_7+8)) -LPC1_6: - ldr r0, [pc, r0] - movt r11, :upper16:(SYM(::class::{closure#0}::__objc2_dealloc, 0)-(LPC1_7+8)) -LPC1_7: - add r11, pc, r11 - ldr r1, [r0] - movw r10, :lower16:(l_anon.[ID].3-(LPC1_8+8)) - movt r10, :upper16:(l_anon.[ID].3-(LPC1_8+8)) - movw r5, :lower16:(l_anon.[ID].1-(LPC1_9+8)) - movt r5, :upper16:(l_anon.[ID].1-(LPC1_9+8)) -LPC1_8: - add r10, pc, r10 -LPC1_9: - add r5, pc, r5 - mov r0, r4 - mov r2, r5 - strd r10, r11, [sp] + mov r8, #0 bl SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) - movw r0, :lower16:(LL_OBJC_SELECTOR_REFERENCES_init$non_lazy_ptr-(LPC1_10+8)) - mov r2, r5 - movt r0, :upper16:(LL_OBJC_SELECTOR_REFERENCES_init$non_lazy_ptr-(LPC1_10+8)) - mov r3, #0 -LPC1_10: + movw r0, :lower16:(LL_OBJC_SELECTOR_REFERENCES_init$non_lazy_ptr-(LPC2_6+8)) + add r5, sp, #8 + movt r0, :upper16:(LL_OBJC_SELECTOR_REFERENCES_init$non_lazy_ptr-(LPC2_6+8)) + ldr r2, [sp, #16] +LPC2_6: ldr r0, [pc, r0] + movw r10, :lower16:(l_anon.[ID].2-(LPC2_7+8)) + movt r10, :upper16:(l_anon.[ID].2-(LPC2_7+8)) +LPC2_7: + add r10, pc, r10 ldr r1, [r0] - movw r9, :lower16:(_init-(LPC1_11+8)) - movt r9, :upper16:(_init-(LPC1_11+8)) - mov r0, r4 -LPC1_11: - add r9, pc, r9 - strd r8, r9, [sp] + movw r3, :lower16:(_init-(LPC2_8+8)) + movt r3, :upper16:(_init-(LPC2_8+8)) + str r2, [sp, #8] +LPC2_8: + add r3, pc, r3 + str r10, [sp] + str r3, [sp, #4] + mov r0, r5 + mov r2, r4 + mov r3, #0 bl SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) - movw r11, :lower16:(_class_method-(LPC1_12+8)) - mov r0, r4 - movt r11, :upper16:(_class_method-(LPC1_12+8)) - movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_d874ee9262978be2-(LPC1_13+8)) - movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_d874ee9262978be2-(LPC1_13+8)) -LPC1_12: - add r11, pc, r11 -LPC1_13: + movw r3, :lower16:(_class_method-(LPC2_9+8)) + mov r0, r5 + movt r3, :upper16:(_class_method-(LPC2_9+8)) + movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_ddead4cf1cfe35ab-(LPC2_10+8)) + movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_ddead4cf1cfe35ab-(LPC2_10+8)) +LPC2_9: + add r3, pc, r3 +LPC2_10: ldr r1, [pc, r1] - mov r2, r5 + mov r2, r4 + str r6, [sp] + str r3, [sp, #4] mov r3, #0 - strd r10, r11, [sp] bl SYM(objc2::declare::ClassBuilder::add_class_method_inner::GENERATED_ID, 0) - movw r11, :lower16:(_method-(LPC1_14+8)) - mov r0, r4 - movt r11, :upper16:(_method-(LPC1_14+8)) - movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_4539fd1dbda0cddc-(LPC1_15+8)) - movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_4539fd1dbda0cddc-(LPC1_15+8)) -LPC1_14: - add r11, pc, r11 -LPC1_15: + movw r3, :lower16:(_method-(LPC2_11+8)) + mov r0, r5 + movt r3, :upper16:(_method-(LPC2_11+8)) + movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_8ee1155e2a63c707-(LPC2_12+8)) + movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_8ee1155e2a63c707-(LPC2_12+8)) +LPC2_11: + add r3, pc, r3 +LPC2_12: ldr r1, [pc, r1] - mov r2, r5 + mov r2, r4 + str r6, [sp] + str r3, [sp, #4] mov r3, #0 - strd r10, r11, [sp] bl SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) - movw r3, :lower16:(_method_bool-(LPC1_16+8)) - mov r0, r4 - movt r3, :upper16:(_method_bool-(LPC1_16+8)) - movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_2b1b3a94e0ece2e5-(LPC1_17+8)) - movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_2b1b3a94e0ece2e5-(LPC1_17+8)) -LPC1_16: + movw r3, :lower16:(_method_bool-(LPC2_13+8)) + mov r0, r5 + movt r3, :upper16:(_method_bool-(LPC2_13+8)) + movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_b1c6d8f625c88aa6-(LPC2_14+8)) + movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_b1c6d8f625c88aa6-(LPC2_14+8)) +LPC2_13: add r3, pc, r3 -LPC1_17: +LPC2_14: ldr r1, [pc, r1] - movw r10, :lower16:(l_anon.[ID].4-(LPC1_18+8)) - movt r10, :upper16:(l_anon.[ID].4-(LPC1_18+8)) -LPC1_18: - add r10, pc, r10 - str r10, [sp] - mov r2, r10 + movw r6, :lower16:(l_anon.[ID].4-(LPC2_15+8)) + movt r6, :upper16:(l_anon.[ID].4-(LPC2_15+8)) +LPC2_15: + add r6, pc, r6 + str r6, [sp] + mov r2, r6 str r3, [sp, #4] mov r3, #1 bl SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) - movw r9, :lower16:(_method_id-(LPC1_19+8)) - mov r0, r4 - movt r9, :upper16:(_method_id-(LPC1_19+8)) - movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_f7f521670860b0ce-(LPC1_20+8)) - movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_f7f521670860b0ce-(LPC1_20+8)) -LPC1_19: - add r9, pc, r9 -LPC1_20: + movw r3, :lower16:(_method_id-(LPC2_16+8)) + mov r0, r5 + movt r3, :upper16:(_method_id-(LPC2_16+8)) + movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_f33da9321a226f33-(LPC2_17+8)) + movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_f33da9321a226f33-(LPC2_17+8)) +LPC2_16: + add r3, pc, r3 +LPC2_17: ldr r1, [pc, r1] - mov r2, r5 + mov r2, r4 + str r10, [sp] + str r3, [sp, #4] mov r3, #0 - strd r8, r9, [sp] bl SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) - movw r9, :lower16:(_method_id_with_param-(LPC1_21+8)) - mov r0, r4 - movt r9, :upper16:(_method_id_with_param-(LPC1_21+8)) - movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_6addfcf634c6232f-(LPC1_22+8)) - movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_6addfcf634c6232f-(LPC1_22+8)) -LPC1_21: - add r9, pc, r9 -LPC1_22: + movw r3, :lower16:(_method_id_with_param-(LPC2_18+8)) + mov r0, r5 + movt r3, :upper16:(_method_id_with_param-(LPC2_18+8)) + movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_e5d1ad528a5510d9-(LPC2_19+8)) + movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_e5d1ad528a5510d9-(LPC2_19+8)) +LPC2_18: + add r3, pc, r3 +LPC2_19: ldr r1, [pc, r1] - mov r2, r10 + mov r2, r6 + str r10, [sp] + str r3, [sp, #4] mov r3, #1 - strd r8, r9, [sp] bl SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) - movw r0, :lower16:(l_anon.[ID].17-(LPC1_23+8)) + movw r0, :lower16:(l_anon.[ID].24-(LPC2_20+8)) mov r1, #9 - movt r0, :upper16:(l_anon.[ID].17-(LPC1_23+8)) -LPC1_23: + movt r0, :upper16:(l_anon.[ID].24-(LPC2_20+8)) +LPC2_20: add r0, pc, r0 bl SYM(objc2::runtime::AnyProtocol::get::GENERATED_ID, 0) cmp r0, #0 - beq LBB1_4 + beq LBB2_4 mov r1, r0 add r0, sp, #8 bl SYM(objc2::declare::ClassBuilder::add_protocol::GENERATED_ID, 0) -LBB1_4: - movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_4a8c690dbc9d8166-(LPC1_24+8)) +LBB2_4: + movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_8daf9cd9e6dba6e3-(LPC2_21+8)) add r0, sp, #8 - movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_4a8c690dbc9d8166-(LPC1_24+8)) - mov r3, #1 -LPC1_24: + movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_8daf9cd9e6dba6e3-(LPC2_21+8)) +LPC2_21: ldr r1, [pc, r1] - movw r2, :lower16:(l_anon.[ID].7-(LPC1_25+8)) - movt r2, :upper16:(l_anon.[ID].7-(LPC1_25+8)) - movw r9, :lower16:(_copyWithZone-(LPC1_26+8)) - movt r9, :upper16:(_copyWithZone-(LPC1_26+8)) -LPC1_25: + movw r2, :lower16:(l_anon.[ID].7-(LPC2_22+8)) + movt r2, :upper16:(l_anon.[ID].7-(LPC2_22+8)) + movw r3, :lower16:(_copyWithZone-(LPC2_23+8)) + movt r3, :upper16:(_copyWithZone-(LPC2_23+8)) +LPC2_22: add r2, pc, r2 -LPC1_26: - add r9, pc, r9 - strd r8, r9, [sp] +LPC2_23: + add r3, pc, r3 + str r10, [sp] + str r3, [sp, #4] + mov r3, #1 bl SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) ldr r0, [sp, #8] + movw r5, :lower16:(l_anon.[ID].8-(LPC2_24+8)) + movt r5, :upper16:(l_anon.[ID].8-(LPC2_24+8)) + movw r1, :lower16:(l_anon.[ID].11-(LPC2_25+8)) + movt r1, :upper16:(l_anon.[ID].11-(LPC2_25+8)) +LPC2_24: + add r5, pc, r5 + str r0, [sp, #12] + mov r0, #27 +LPC2_25: + add r1, pc, r1 + strb r0, [sp, #16] + mov r0, #8 + add r4, sp, #12 + str r0, [sp, #20] + mov r10, #2 + str r1, [sp, #28] + mov r0, r4 + mov r1, r5 + mov r2, #5 + mov r3, #8 + str r8, [sp, #24] + strd r10, r11, [sp] + bl SYM(objc2::declare::ClassBuilder::add_ivar_inner_mono::GENERATED_ID, 0) + movw r1, :lower16:(l_anon.[ID].9-(LPC2_26+8)) + mov r0, r4 + movt r1, :upper16:(l_anon.[ID].9-(LPC2_26+8)) + movw r9, :lower16:(l_anon.[ID].10-(LPC2_27+8)) + movt r9, :upper16:(l_anon.[ID].10-(LPC2_27+8)) +LPC2_26: + add r1, pc, r1 +LPC2_27: + add r9, pc, r9 + mov r2, #9 + mov r3, #1 + strd r8, r9, [sp] + bl SYM(objc2::declare::ClassBuilder::add_ivar_inner_mono::GENERATED_ID, 0) + ldr r0, [sp, #12] bl SYM(objc2::declare::ClassBuilder::register::GENERATED_ID, 0) - sub sp, r7, #20 + mov r1, r5 + mov r2, #5 + mov r4, r0 + bl SYM(objc2::runtime::AnyClass::instance_variable::GENERATED_ID, 0) + cmp r0, #0 + beq LBB2_9 + bl _ivar_getOffset + movw r1, :lower16:(l_anon.[ID].9-(LPC2_28+8)) + mov r5, r0 + movt r1, :upper16:(l_anon.[ID].9-(LPC2_28+8)) + mov r0, r4 +LPC2_28: + add r1, pc, r1 + mov r2, #9 + bl SYM(objc2::runtime::AnyClass::instance_variable::GENERATED_ID, 0) + cmp r0, #0 + beq LBB2_10 + bl _ivar_getOffset + movw r1, :lower16:(__MergedGlobals-(LPC2_29+8)) + movt r1, :upper16:(__MergedGlobals-(LPC2_29+8)) + movw r2, :lower16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-(LPC2_30+8)) + movt r2, :upper16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-(LPC2_30+8)) + movw r3, :lower16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)-(LPC2_31+8)) + movt r3, :upper16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)-(LPC2_31+8)) +LPC2_29: + add r1, pc, r1 +LPC2_30: + add r2, pc, r2 +LPC2_31: + add r3, pc, r3 + str r4, [r1] + str r5, [r2] + str r0, [r3] + sub sp, r7, #24 pop {r8, r10, r11} - pop {r4, r5, r7, pc} -LBB1_5: - movw r0, :lower16:(l_anon.[ID].8-(LPC1_27+8)) + pop {r4, r5, r6, r7, pc} +LBB2_7: + movw r0, :lower16:(l_anon.[ID].16-(LPC2_32+8)) mov r1, #43 - movt r0, :upper16:(l_anon.[ID].8-(LPC1_27+8)) - movw r2, :lower16:(l_anon.[ID].10-(LPC1_28+8)) - movt r2, :upper16:(l_anon.[ID].10-(LPC1_28+8)) -LPC1_27: + movt r0, :upper16:(l_anon.[ID].16-(LPC2_32+8)) + movw r2, :lower16:(l_anon.[ID].18-(LPC2_33+8)) + movt r2, :upper16:(l_anon.[ID].18-(LPC2_33+8)) +LPC2_32: add r0, pc, r0 -LPC1_28: +LPC2_33: add r2, pc, r2 mov lr, pc b SYM(core::panicking::panic::GENERATED_ID, 0) -LBB1_6: - movw r0, :lower16:(l_anon.[ID].11-(LPC1_29+8)) +LBB2_8: + movw r0, :lower16:(l_anon.[ID].21-(LPC2_34+8)) mov r1, #15 - movt r0, :upper16:(l_anon.[ID].11-(LPC1_29+8)) - movw r2, :lower16:(l_anon.[ID].16-(LPC1_30+8)) - movt r2, :upper16:(l_anon.[ID].16-(LPC1_30+8)) -LPC1_29: + movt r0, :upper16:(l_anon.[ID].21-(LPC2_34+8)) + movw r2, :lower16:(l_anon.[ID].23-(LPC2_35+8)) + movt r2, :upper16:(l_anon.[ID].23-(LPC2_35+8)) +LPC2_34: add r0, pc, r0 -LPC1_30: +LPC2_35: add r2, pc, r2 mov lr, pc b SYM(objc2::__macro_helpers::declare_class::failed_declaring_class::GENERATED_ID, 0) +LBB2_9: + movw r0, :lower16:(l_anon.[ID].12-(LPC2_36+8)) + mov r1, #59 + movt r0, :upper16:(l_anon.[ID].12-(LPC2_36+8)) + movw r2, :lower16:(l_anon.[ID].14-(LPC2_37+8)) + movt r2, :upper16:(l_anon.[ID].14-(LPC2_37+8)) +LPC2_36: + add r0, pc, r0 +LPC2_37: + add r2, pc, r2 + mov lr, pc + b SYM(core::option::expect_failed::GENERATED_ID, 0) +LBB2_10: + movw r0, :lower16:(l_anon.[ID].12-(LPC2_38+8)) + mov r1, #59 + movt r0, :upper16:(l_anon.[ID].12-(LPC2_38+8)) + movw r2, :lower16:(l_anon.[ID].15-(LPC2_39+8)) + movt r2, :upper16:(l_anon.[ID].15-(LPC2_39+8)) +LPC2_38: + add r0, pc, r0 +LPC2_39: + add r2, pc, r2 + mov lr, pc + b SYM(core::option::expect_failed::GENERATED_ID, 0) .p2align 2 .code 32 @@ -242,61 +360,44 @@ SYM(<::call_once<::class::REGISTER_CLASS, 0)-(LPC3_0+8)) - movt r0, :upper16:(SYM(::class::REGISTER_CLASS, 0)-(LPC3_0+8)) -LPC3_0: - add r0, pc, r0 - ldr r0, [r0] - dmb ish - cmp r0, #3 - bne LBB3_3 -LBB3_1: - movw r0, :lower16:(l_anon.[ID].11-(LPC3_4+8)) - mov r1, #15 - movt r0, :upper16:(l_anon.[ID].11-(LPC3_4+8)) -LPC3_4: - add r0, pc, r0 - bl SYM(objc2::runtime::AnyClass::get::GENERATED_ID, 0) - cmp r0, #0 - movne sp, r7 - popne {r7, pc} -LBB3_2: - movw r0, :lower16:(l_anon.[ID].8-(LPC3_5+8)) - mov r1, #43 - movt r0, :upper16:(l_anon.[ID].8-(LPC3_5+8)) - movw r2, :lower16:(l_anon.[ID].16-(LPC3_6+8)) - movt r2, :upper16:(l_anon.[ID].16-(LPC3_6+8)) -LPC3_5: - add r0, pc, r0 -LPC3_6: - add r2, pc, r2 - mov lr, pc - b SYM(core::panicking::panic::GENERATED_ID, 0) -LBB3_3: - movw r0, :lower16:(SYM(::class::REGISTER_CLASS, 0)-(LPC3_1+8)) + movw r1, :lower16:(l_anon.[ID].23-(LPC4_1+8)) mov r2, #1 - movt r0, :upper16:(SYM(::class::REGISTER_CLASS, 0)-(LPC3_1+8)) - movw r3, :lower16:(l_anon.[ID].0-(LPC3_2+8)) - movt r3, :upper16:(l_anon.[ID].0-(LPC3_2+8)) - movw r1, :lower16:(l_anon.[ID].16-(LPC3_3+8)) - movt r1, :upper16:(l_anon.[ID].16-(LPC3_3+8)) - strb r2, [r7, #-5] -LPC3_3: + movt r1, :upper16:(l_anon.[ID].23-(LPC4_1+8)) + movw r3, :lower16:(l_anon.[ID].0-(LPC4_2+8)) + movt r3, :upper16:(l_anon.[ID].0-(LPC4_2+8)) +LPC4_1: add r1, pc, r1 + strb r2, [r7, #-5] sub r2, r7, #5 - str r2, [r7, #-4] -LPC3_1: - add r0, pc, r0 - str r1, [sp] -LPC3_2: +LPC4_2: add r3, pc, r3 + add r0, r0, #4 + str r2, [r7, #-4] sub r2, r7, #4 + str r1, [sp] mov r1, #0 bl SYM(std::sys_common::once::queue::Once::call::GENERATED_ID, 0) - b LBB3_1 + mov sp, r7 + pop {r7, lr} + b LBB4_1 .globl _get_obj .p2align 2 @@ -304,9 +405,9 @@ LPC3_2: _get_obj: push {r4, r7, lr} add r7, sp, #4 - movw r0, :lower16:(LL_OBJC_SELECTOR_REFERENCES_new$non_lazy_ptr-(LPC4_0+8)) - movt r0, :upper16:(LL_OBJC_SELECTOR_REFERENCES_new$non_lazy_ptr-(LPC4_0+8)) -LPC4_0: + movw r0, :lower16:(LL_OBJC_SELECTOR_REFERENCES_new$non_lazy_ptr-(LPC5_0+8)) + movt r0, :upper16:(LL_OBJC_SELECTOR_REFERENCES_new$non_lazy_ptr-(LPC5_0+8)) +LPC5_0: ldr r0, [pc, r0] ldr r4, [r0] bl _get_class @@ -318,173 +419,124 @@ LPC4_0: .p2align 2 .code 32 _access_ivars: - push {r4, r5, r6, r7, lr} - add r7, sp, #12 + push {r4, r5, r7, lr} + add r7, sp, #8 bl _get_obj - movw r1, :lower16:(L_anon.[ID].12-(LPC5_0+8)) - mov r2, #4 - movt r1, :upper16:(L_anon.[ID].12-(LPC5_0+8)) - mov r4, r0 -LPC5_0: - add r1, pc, r1 - bl SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - bl _ivar_getOffset - movw r1, :lower16:(L_anon.[ID].13-(LPC5_1+8)) - mov r2, #4 - movt r1, :upper16:(L_anon.[ID].13-(LPC5_1+8)) - ldrb r5, [r4, r0] -LPC5_1: - add r1, pc, r1 - mov r0, r4 - bl SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - bl _ivar_getOffset - ldr r6, [r4, r0] - mov r0, r4 + movw r1, :lower16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-(LPC6_0+8)) + mov r2, r0 + movt r1, :upper16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-(LPC6_0+8)) +LPC6_0: + ldr r1, [pc, r1] + ldr r4, [r2, r1]! + ldrb r5, [r2, #4] bl _objc_release mov r0, r5 - mov r1, r6 - pop {r4, r5, r6, r7, pc} + mov r1, r4 + pop {r4, r5, r7, pc} .globl SYM(::class, 0) .p2align 2 .code 32 SYM(::class, 0): + movw r0, :lower16:(__MergedGlobals-(LPC7_0+8)) + movt r0, :upper16:(__MergedGlobals-(LPC7_0+8)) +LPC7_0: + add r0, pc, r0 + ldr r1, [r0, #4] + dmb ish + cmp r1, #3 + bne LBB7_2 +LBB7_1: + movw r0, :lower16:(__MergedGlobals-(LPC7_3+8)) + movt r0, :upper16:(__MergedGlobals-(LPC7_3+8)) +LPC7_3: + ldr r0, [pc, r0] + bx lr +LBB7_2: push {r7, lr} mov r7, sp sub sp, sp, #12 - movw r0, :lower16:(SYM(::class::REGISTER_CLASS, 0)-(LPC6_0+8)) - movt r0, :upper16:(SYM(::class::REGISTER_CLASS, 0)-(LPC6_0+8)) -LPC6_0: - add r0, pc, r0 - ldr r0, [r0] - dmb ish - cmp r0, #3 - bne LBB6_3 -LBB6_1: - movw r0, :lower16:(l_anon.[ID].11-(LPC6_4+8)) - mov r1, #15 - movt r0, :upper16:(l_anon.[ID].11-(LPC6_4+8)) -LPC6_4: - add r0, pc, r0 - bl SYM(objc2::runtime::AnyClass::get::GENERATED_ID, 0) - cmp r0, #0 - movne sp, r7 - popne {r7, pc} -LBB6_2: - movw r0, :lower16:(l_anon.[ID].8-(LPC6_5+8)) - mov r1, #43 - movt r0, :upper16:(l_anon.[ID].8-(LPC6_5+8)) - movw r2, :lower16:(l_anon.[ID].16-(LPC6_6+8)) - movt r2, :upper16:(l_anon.[ID].16-(LPC6_6+8)) -LPC6_5: - add r0, pc, r0 -LPC6_6: - add r2, pc, r2 - mov lr, pc - b SYM(core::panicking::panic::GENERATED_ID, 0) -LBB6_3: - movw r0, :lower16:(SYM(::class::REGISTER_CLASS, 0)-(LPC6_1+8)) + movw r1, :lower16:(l_anon.[ID].23-(LPC7_1+8)) mov r2, #1 - movt r0, :upper16:(SYM(::class::REGISTER_CLASS, 0)-(LPC6_1+8)) - movw r3, :lower16:(l_anon.[ID].0-(LPC6_2+8)) - movt r3, :upper16:(l_anon.[ID].0-(LPC6_2+8)) - movw r1, :lower16:(l_anon.[ID].16-(LPC6_3+8)) - movt r1, :upper16:(l_anon.[ID].16-(LPC6_3+8)) - strb r2, [r7, #-5] -LPC6_3: + movt r1, :upper16:(l_anon.[ID].23-(LPC7_1+8)) + movw r3, :lower16:(l_anon.[ID].0-(LPC7_2+8)) + movt r3, :upper16:(l_anon.[ID].0-(LPC7_2+8)) +LPC7_1: add r1, pc, r1 + strb r2, [r7, #-5] sub r2, r7, #5 - str r2, [r7, #-4] -LPC6_1: - add r0, pc, r0 - str r1, [sp] -LPC6_2: +LPC7_2: add r3, pc, r3 + add r0, r0, #4 + str r2, [r7, #-4] sub r2, r7, #4 + str r1, [sp] mov r1, #0 bl SYM(std::sys_common::once::queue::Once::call::GENERATED_ID, 0) - b LBB6_1 - - .p2align 2 - .code 32 -SYM(::class::{closure#0}::__objc2_dealloc, 0): - push {r4, r5, r7, lr} - add r7, sp, #8 - sub sp, sp, #8 - mov r4, r1 - movw r1, :lower16:(L_anon.[ID].13-(LPC7_0+8)) - movt r1, :upper16:(L_anon.[ID].13-(LPC7_0+8)) - mov r2, #4 -LPC7_0: - add r1, pc, r1 - mov r5, r0 - bl SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - bl _ivar_getOffset - ldr r0, [r5, r0] - cmp r0, #0 - beq LBB7_2 - bl _objc_release -LBB7_2: - movw r0, :lower16:(LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-(LPC7_1+8)) - mov r1, r4 - movt r0, :upper16:(LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-(LPC7_1+8)) - str r5, [sp] -LPC7_1: - ldr r0, [pc, r0] - ldr r0, [r0] - str r0, [sp, #4] - mov r0, sp - bl _objc_msgSendSuper - sub sp, r7, #8 - pop {r4, r5, r7, pc} + mov sp, r7 + pop {r7, lr} + b LBB7_1 .globl _init .p2align 2 .code 32 _init: - push {r4, r7, lr} - add r7, sp, #4 - sub sp, sp, #8 - movw r1, :lower16:(LL_OBJC_SELECTOR_REFERENCES_init$non_lazy_ptr-(LPC8_0+8)) - movt r1, :upper16:(LL_OBJC_SELECTOR_REFERENCES_init$non_lazy_ptr-(LPC8_0+8)) - movw r2, :lower16:(LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-(LPC8_1+8)) + push {r7, lr} + mov r7, sp + sub sp, sp, #24 + cmp r0, #0 + beq LBB8_2 + movw r1, :lower16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-(LPC8_0+8)) + mov r2, #0 + movt r1, :upper16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-(LPC8_0+8)) + mov r3, r0 LPC8_0: ldr r1, [pc, r1] - movt r2, :upper16:(LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-(LPC8_1+8)) + str r2, [r3, r1]! + mov r1, #42 + strb r1, [r3, #4] + movw r1, :lower16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)-(LPC8_1+8)) + movt r1, :upper16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)-(LPC8_1+8)) + mov r3, #1 LPC8_1: + ldr r1, [pc, r1] + movw r2, :lower16:(LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-(LPC8_2+8)) + movt r2, :upper16:(LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-(LPC8_2+8)) +LPC8_2: ldr r2, [pc, r2] - ldr r1, [r1] + strb r3, [r0, r1] + movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_74641ed6f72d2d44-(LPC8_3+8)) + movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_74641ed6f72d2d44-(LPC8_3+8)) +LPC8_3: + ldr r1, [pc, r1] ldr r2, [r2] stm sp, {r0, r2} mov r0, sp bl _objc_msgSendSuper - mov r4, r0 - cmp r0, #0 - beq LBB8_2 - movw r1, :lower16:(L_anon.[ID].12-(LPC8_2+8)) - mov r0, r4 - movt r1, :upper16:(L_anon.[ID].12-(LPC8_2+8)) - mov r2, #4 -LPC8_2: - add r1, pc, r1 - bl SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - bl _ivar_getOffset - movw r1, :lower16:(L_anon.[ID].13-(LPC8_3+8)) - mov r2, #42 - movt r1, :upper16:(L_anon.[ID].13-(LPC8_3+8)) - strb r2, [r4, r0] -LPC8_3: - add r1, pc, r1 - mov r0, r4 - mov r2, #4 - bl SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - bl _ivar_getOffset - mov r1, #0 - str r1, [r4, r0] + mov sp, r7 + pop {r7, pc} LBB8_2: - mov r0, r4 - sub sp, r7, #4 - pop {r4, r7, pc} + movw r9, :lower16:(l_anon.[ID].1-(LPC8_4+8)) + mov r0, #1 + movt r9, :upper16:(l_anon.[ID].1-(LPC8_4+8)) + movw r1, :lower16:(l_anon.[ID].25-(LPC8_5+8)) + movt r1, :upper16:(l_anon.[ID].25-(LPC8_5+8)) + movw r2, :lower16:(l_anon.[ID].20-(LPC8_6+8)) + movt r2, :upper16:(l_anon.[ID].20-(LPC8_6+8)) + mov r3, #0 +LPC8_4: + add r9, pc, r9 +LPC8_6: + add r2, pc, r2 + stmib sp, {r0, r9} +LPC8_5: + add r1, pc, r1 + mov r0, sp + str r3, [sp, #16] + str r3, [sp, #12] + str r2, [sp] + mov lr, pc + b SYM(core::panicking::panic_fmt::GENERATED_ID, 0) .globl _class_method .p2align 2 @@ -510,26 +562,22 @@ _method_bool: .p2align 2 .code 32 _method_id: - push {r4, r7, lr} - add r7, sp, #4 - movw r1, :lower16:(L_anon.[ID].13-(LPC12_0+8)) - mov r2, #4 - movt r1, :upper16:(L_anon.[ID].13-(LPC12_0+8)) - mov r4, r0 + push {r7, lr} + mov r7, sp + movw r1, :lower16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-(LPC12_0+8)) + movt r1, :upper16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-(LPC12_0+8)) LPC12_0: - add r1, pc, r1 - bl SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - bl _ivar_getOffset - ldr r0, [r4, r0] + ldr r1, [pc, r1] + ldr r0, [r0, r1] cmp r0, #0 beq LBB12_2 bl _objc_retain bl _objc_autoreleaseReturnValue - pop {r4, r7, pc} + pop {r7, pc} LBB12_2: mov r0, #0 bl _objc_autoreleaseReturnValue - pop {r4, r7, pc} + pop {r7, pc} .globl _method_id_with_param .p2align 2 @@ -543,14 +591,10 @@ _method_id_with_param: mov r4, r0 cmp r6, #0 beq LBB13_3 - movw r1, :lower16:(L_anon.[ID].13-(LPC13_0+8)) - mov r0, r5 - movt r1, :upper16:(L_anon.[ID].13-(LPC13_0+8)) - mov r2, #4 + movw r0, :lower16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-(LPC13_0+8)) + movt r0, :upper16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-(LPC13_0+8)) LPC13_0: - add r1, pc, r1 - bl SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - bl _ivar_getOffset + ldr r0, [pc, r0] ldr r0, [r5, r0] cmp r0, #0 beq LBB13_4 @@ -575,60 +619,117 @@ LBB13_5: .p2align 2 .code 32 _copyWithZone: - push {r4, r5, r6, r7, lr} - add r7, sp, #12 - push {r8} - mov r5, r0 - bl _get_obj + push {r4, r5, r7, lr} + add r7, sp, #8 + sub sp, sp, #32 + movw r1, :lower16:(LL_OBJC_SELECTOR_REFERENCES_alloc$non_lazy_ptr-(LPC14_0+8)) mov r4, r0 - cmp r0, #0 - beq LBB14_5 - movw r8, :lower16:(L_anon.[ID].12-(LPC14_0+8)) - mov r0, r5 - movt r8, :upper16:(L_anon.[ID].12-(LPC14_0+8)) - mov r2, #4 + movt r1, :upper16:(LL_OBJC_SELECTOR_REFERENCES_alloc$non_lazy_ptr-(LPC14_0+8)) + movw r0, :lower16:(__MergedGlobals-(LPC14_1+8)) LPC14_0: - add r8, pc, r8 - mov r1, r8 - bl SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - bl _ivar_getOffset - ldrb r6, [r5, r0] - mov r0, r4 - mov r1, r8 - mov r2, #4 - bl SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - bl _ivar_getOffset - movw r1, :lower16:(L_anon.[ID].13-(LPC14_1+8)) - mov r2, #4 - movt r1, :upper16:(L_anon.[ID].13-(LPC14_1+8)) - strb r6, [r4, r0] + ldr r1, [pc, r1] + movt r0, :upper16:(__MergedGlobals-(LPC14_1+8)) LPC14_1: - add r1, pc, r1 - mov r0, r5 - bl SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - bl _ivar_getOffset - ldr r0, [r5, r0] + add r0, pc, r0 + ldr r5, [r1] + ldr r1, [r0, #4] + dmb ish + cmp r1, #3 + bne LBB14_6 +LBB14_1: + movw r0, :lower16:(__MergedGlobals-(LPC14_4+8)) + mov r1, r5 + movt r0, :upper16:(__MergedGlobals-(LPC14_4+8)) +LPC14_4: + ldr r0, [pc, r0] + bl _objc_msgSend + mov r5, r0 + movw r0, :lower16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-(LPC14_5+8)) + movt r0, :upper16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-(LPC14_5+8)) +LPC14_5: + ldr r0, [pc, r0] + ldr r0, [r4, r0]! + ldrb r4, [r4, #4] cmp r0, #0 - beq LBB14_3 + beq LBB14_4 bl _objc_retain - mov r5, r0 - b LBB14_4 + cmp r5, #0 + beq LBB14_5 LBB14_3: - mov r5, #0 + movw r1, :lower16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-(LPC14_6+8)) + mov r2, r5 + movt r1, :upper16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-(LPC14_6+8)) +LPC14_6: + ldr r1, [pc, r1] + str r0, [r2, r1]! + mov r1, #1 + strb r4, [r2, #4] + movw r0, :lower16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)-(LPC14_7+8)) + movt r0, :upper16:(SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)-(LPC14_7+8)) +LPC14_7: + ldr r0, [pc, r0] + movw r2, :lower16:(LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-(LPC14_8+8)) + movt r2, :upper16:(LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-(LPC14_8+8)) +LPC14_8: + ldr r2, [pc, r2] + strb r1, [r5, r0] + movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_a4c8ca93c4279f29-(LPC14_9+8)) + movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_a4c8ca93c4279f29-(LPC14_9+8)) + ldr r0, [r2] +LPC14_9: + ldr r1, [pc, r1] + str r5, [sp, #8] + str r0, [sp, #12] + add r0, sp, #8 + bl _objc_msgSendSuper + sub sp, r7, #8 + pop {r4, r5, r7, pc} LBB14_4: - movw r1, :lower16:(L_anon.[ID].13-(LPC14_2+8)) - mov r0, r4 - movt r1, :upper16:(L_anon.[ID].13-(LPC14_2+8)) - mov r2, #4 + mov r0, #0 + cmp r5, #0 + bne LBB14_3 +LBB14_5: + movw r0, :lower16:(l_anon.[ID].1-(LPC14_10+8)) + mov r3, #0 + movt r0, :upper16:(l_anon.[ID].1-(LPC14_10+8)) + movw r1, :lower16:(l_anon.[ID].26-(LPC14_11+8)) + movt r1, :upper16:(l_anon.[ID].26-(LPC14_11+8)) + movw r2, :lower16:(l_anon.[ID].20-(LPC14_12+8)) + movt r2, :upper16:(l_anon.[ID].20-(LPC14_12+8)) +LPC14_10: + add r0, pc, r0 +LPC14_12: + add r2, pc, r2 + mov r5, #1 + str r0, [sp, #16] +LPC14_11: + add r1, pc, r1 + add r0, sp, #8 + str r3, [sp, #24] + str r5, [sp, #12] + str r3, [sp, #20] + str r2, [sp, #8] + mov lr, pc + b SYM(core::panicking::panic_fmt::GENERATED_ID, 0) +LBB14_6: + movw r1, :lower16:(l_anon.[ID].23-(LPC14_2+8)) + mov r2, #1 + movt r1, :upper16:(l_anon.[ID].23-(LPC14_2+8)) + movw r3, :lower16:(l_anon.[ID].0-(LPC14_3+8)) + movt r3, :upper16:(l_anon.[ID].0-(LPC14_3+8)) LPC14_2: add r1, pc, r1 - bl SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - bl _ivar_getOffset - str r5, [r4, r0] -LBB14_5: - mov r0, r4 - pop {r8} - pop {r4, r5, r6, r7, pc} + strb r2, [sp, #7] + add r2, sp, #7 +LPC14_3: + add r3, pc, r3 + add r0, r0, #4 + str r2, [sp, #8] + add r2, sp, #8 + str r1, [sp] + mov r1, #0 + bl SYM(std::sys_common::once::queue::Once::call::GENERATED_ID, 0) + b LBB14_1 .section __DATA,__const .p2align 2, 0x0 @@ -680,155 +781,239 @@ l_anon.[ID].7: .section __TEXT,__const l_anon.[ID].8: - .ascii "called `Option::unwrap()` on a `None` value" + .ascii "ivars" l_anon.[ID].9: - .ascii "$RUSTC/library/std/src/sync/once.rs" + .ascii "drop_flag" - .section __DATA,__const .p2align 2, 0x0 l_anon.[ID].10: - .long l_anon.[ID].9 - .asciz "p\000\000\000\225\000\000\0002\000\000" + .byte 5 + .space 19 - .section __TEXT,__const + .p2align 2, 0x0 l_anon.[ID].11: - .ascii "CustomClassName" + .byte 7 + .space 19 - .section __TEXT,__literal4,4byte_literals -L_anon.[ID].12: - .ascii "_foo" +l_anon.[ID].12: + .ascii "failed retrieving instance variable on newly declared class" -L_anon.[ID].13: - .ascii "_obj" +l_anon.[ID].13: + .ascii "$WORKSPACE/objc2/src/__macro_helpers/declared_ivars.rs" - .section __TEXT,__const + .section __DATA,__const + .p2align 2, 0x0 l_anon.[ID].14: - .ascii "crates/$DIR/lib.rs" + .long l_anon.[ID].13 + .asciz "T\000\000\000\363\000\000\000\016\000\000" .p2align 2, 0x0 l_anon.[ID].15: - .byte 5 - .space 19 + .long l_anon.[ID].13 + .asciz "T\000\000\000\377\000\000\000\016\000\000" + + .section __TEXT,__const +l_anon.[ID].16: + .ascii "called `Option::unwrap()` on a `None` value" + +l_anon.[ID].17: + .ascii "$RUSTC/library/std/src/sync/once.rs" .section __DATA,__const .p2align 2, 0x0 -l_anon.[ID].16: - .long l_anon.[ID].14 - .asciz "5\000\000\000\f\000\000\000\001\000\000" +l_anon.[ID].18: + .long l_anon.[ID].17 + .asciz "p\000\000\000\225\000\000\0002\000\000" -.zerofill __DATA,__bss,SYM(::class::REGISTER_CLASS, 0),4,2 .section __TEXT,__const -l_anon.[ID].17: +l_anon.[ID].19: + .ascii "tried to initialize instance variables on NULL allocated object" + + .section __DATA,__const + .p2align 2, 0x0 +l_anon.[ID].20: + .long l_anon.[ID].19 + .asciz "?\000\000" + + .section __TEXT,__const +l_anon.[ID].21: + .ascii "CustomClassName" + +l_anon.[ID].22: + .ascii "crates/$DIR/lib.rs" + + .globl SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0) +.zerofill __DATA,__common,SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0),4,2 + .globl SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0) +.zerofill __DATA,__common,SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0),4,2 + .section __DATA,__const + .p2align 2, 0x0 +l_anon.[ID].23: + .long l_anon.[ID].22 + .asciz "5\000\000\000\021\000\000\000\001\000\000" + + .section __TEXT,__const +l_anon.[ID].24: .ascii "NSCopying" .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_d874ee9262978be2 -L_OBJC_METH_VAR_NAME_d874ee9262978be2: + .globl L_OBJC_METH_VAR_NAME_ddead4cf1cfe35ab +L_OBJC_METH_VAR_NAME_ddead4cf1cfe35ab: .asciz "classMethod" .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_d874ee9262978be2 + .globl L_OBJC_SELECTOR_REFERENCES_ddead4cf1cfe35ab .p2align 2, 0x0 -L_OBJC_SELECTOR_REFERENCES_d874ee9262978be2: - .long L_OBJC_METH_VAR_NAME_d874ee9262978be2 +L_OBJC_SELECTOR_REFERENCES_ddead4cf1cfe35ab: + .long L_OBJC_METH_VAR_NAME_ddead4cf1cfe35ab .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_d874ee9262978be2 + .globl L_OBJC_IMAGE_INFO_ddead4cf1cfe35ab .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_d874ee9262978be2: +L_OBJC_IMAGE_INFO_ddead4cf1cfe35ab: .asciz "\000\000\000\000@\000\000" .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_4539fd1dbda0cddc -L_OBJC_METH_VAR_NAME_4539fd1dbda0cddc: + .globl L_OBJC_METH_VAR_NAME_8ee1155e2a63c707 +L_OBJC_METH_VAR_NAME_8ee1155e2a63c707: .asciz "method" .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_4539fd1dbda0cddc + .globl L_OBJC_SELECTOR_REFERENCES_8ee1155e2a63c707 .p2align 2, 0x0 -L_OBJC_SELECTOR_REFERENCES_4539fd1dbda0cddc: - .long L_OBJC_METH_VAR_NAME_4539fd1dbda0cddc +L_OBJC_SELECTOR_REFERENCES_8ee1155e2a63c707: + .long L_OBJC_METH_VAR_NAME_8ee1155e2a63c707 .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_4539fd1dbda0cddc + .globl L_OBJC_IMAGE_INFO_8ee1155e2a63c707 .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_4539fd1dbda0cddc: +L_OBJC_IMAGE_INFO_8ee1155e2a63c707: .asciz "\000\000\000\000@\000\000" .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_2b1b3a94e0ece2e5 -L_OBJC_METH_VAR_NAME_2b1b3a94e0ece2e5: + .globl L_OBJC_METH_VAR_NAME_b1c6d8f625c88aa6 +L_OBJC_METH_VAR_NAME_b1c6d8f625c88aa6: .asciz "methodBool:" .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_2b1b3a94e0ece2e5 + .globl L_OBJC_SELECTOR_REFERENCES_b1c6d8f625c88aa6 .p2align 2, 0x0 -L_OBJC_SELECTOR_REFERENCES_2b1b3a94e0ece2e5: - .long L_OBJC_METH_VAR_NAME_2b1b3a94e0ece2e5 +L_OBJC_SELECTOR_REFERENCES_b1c6d8f625c88aa6: + .long L_OBJC_METH_VAR_NAME_b1c6d8f625c88aa6 .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_2b1b3a94e0ece2e5 + .globl L_OBJC_IMAGE_INFO_b1c6d8f625c88aa6 .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_2b1b3a94e0ece2e5: +L_OBJC_IMAGE_INFO_b1c6d8f625c88aa6: .asciz "\000\000\000\000@\000\000" .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_f7f521670860b0ce -L_OBJC_METH_VAR_NAME_f7f521670860b0ce: + .globl L_OBJC_METH_VAR_NAME_f33da9321a226f33 +L_OBJC_METH_VAR_NAME_f33da9321a226f33: .asciz "methodId" .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_f7f521670860b0ce + .globl L_OBJC_SELECTOR_REFERENCES_f33da9321a226f33 .p2align 2, 0x0 -L_OBJC_SELECTOR_REFERENCES_f7f521670860b0ce: - .long L_OBJC_METH_VAR_NAME_f7f521670860b0ce +L_OBJC_SELECTOR_REFERENCES_f33da9321a226f33: + .long L_OBJC_METH_VAR_NAME_f33da9321a226f33 .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_f7f521670860b0ce + .globl L_OBJC_IMAGE_INFO_f33da9321a226f33 .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_f7f521670860b0ce: +L_OBJC_IMAGE_INFO_f33da9321a226f33: .asciz "\000\000\000\000@\000\000" .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_6addfcf634c6232f -L_OBJC_METH_VAR_NAME_6addfcf634c6232f: + .globl L_OBJC_METH_VAR_NAME_e5d1ad528a5510d9 +L_OBJC_METH_VAR_NAME_e5d1ad528a5510d9: .asciz "methodIdWithParam:" .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_6addfcf634c6232f + .globl L_OBJC_SELECTOR_REFERENCES_e5d1ad528a5510d9 .p2align 2, 0x0 -L_OBJC_SELECTOR_REFERENCES_6addfcf634c6232f: - .long L_OBJC_METH_VAR_NAME_6addfcf634c6232f +L_OBJC_SELECTOR_REFERENCES_e5d1ad528a5510d9: + .long L_OBJC_METH_VAR_NAME_e5d1ad528a5510d9 .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_6addfcf634c6232f + .globl L_OBJC_IMAGE_INFO_e5d1ad528a5510d9 .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_6addfcf634c6232f: +L_OBJC_IMAGE_INFO_e5d1ad528a5510d9: .asciz "\000\000\000\000@\000\000" .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_4a8c690dbc9d8166 -L_OBJC_METH_VAR_NAME_4a8c690dbc9d8166: + .globl L_OBJC_METH_VAR_NAME_8daf9cd9e6dba6e3 +L_OBJC_METH_VAR_NAME_8daf9cd9e6dba6e3: .asciz "copyWithZone:" .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_4a8c690dbc9d8166 + .globl L_OBJC_SELECTOR_REFERENCES_8daf9cd9e6dba6e3 .p2align 2, 0x0 -L_OBJC_SELECTOR_REFERENCES_4a8c690dbc9d8166: - .long L_OBJC_METH_VAR_NAME_4a8c690dbc9d8166 +L_OBJC_SELECTOR_REFERENCES_8daf9cd9e6dba6e3: + .long L_OBJC_METH_VAR_NAME_8daf9cd9e6dba6e3 .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_4a8c690dbc9d8166 + .globl L_OBJC_IMAGE_INFO_8daf9cd9e6dba6e3 .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_4a8c690dbc9d8166: +L_OBJC_IMAGE_INFO_8daf9cd9e6dba6e3: .asciz "\000\000\000\000@\000\000" + .section __DATA,__const + .p2align 2, 0x0 +l_anon.[ID].25: + .long l_anon.[ID].22 + .asciz "5\000\000\000#\000\000\000\035\000\000" + + .section __TEXT,__objc_methname,cstring_literals + .globl L_OBJC_METH_VAR_NAME_74641ed6f72d2d44 +L_OBJC_METH_VAR_NAME_74641ed6f72d2d44: + .asciz "init" + + .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip + .globl L_OBJC_SELECTOR_REFERENCES_74641ed6f72d2d44 + .p2align 2, 0x0 +L_OBJC_SELECTOR_REFERENCES_74641ed6f72d2d44: + .long L_OBJC_METH_VAR_NAME_74641ed6f72d2d44 + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_74641ed6f72d2d44 + .p2align 2, 0x0 +L_OBJC_IMAGE_INFO_74641ed6f72d2d44: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__const + .p2align 2, 0x0 +l_anon.[ID].26: + .long l_anon.[ID].22 + .asciz "5\000\000\000N\000\000\000\033\000\000" + + .section __TEXT,__objc_methname,cstring_literals + .globl L_OBJC_METH_VAR_NAME_a4c8ca93c4279f29 +L_OBJC_METH_VAR_NAME_a4c8ca93c4279f29: + .asciz "init" + + .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip + .globl L_OBJC_SELECTOR_REFERENCES_a4c8ca93c4279f29 + .p2align 2, 0x0 +L_OBJC_SELECTOR_REFERENCES_a4c8ca93c4279f29: + .long L_OBJC_METH_VAR_NAME_a4c8ca93c4279f29 + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_a4c8ca93c4279f29 + .p2align 2, 0x0 +L_OBJC_IMAGE_INFO_a4c8ca93c4279f29: + .asciz "\000\000\000\000@\000\000" + +.zerofill __DATA,__bss,__MergedGlobals,8,2 .section __DATA,__nl_symbol_ptr,non_lazy_symbol_pointers .p2align 2, 0x0 LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr: .indirect_symbol L_OBJC_CLASSLIST_REFERENCES_$_NSObject .long 0 +LL_OBJC_SELECTOR_REFERENCES_alloc$non_lazy_ptr: + .indirect_symbol L_OBJC_SELECTOR_REFERENCES_alloc + .long 0 LL_OBJC_SELECTOR_REFERENCES_dealloc$non_lazy_ptr: .indirect_symbol L_OBJC_SELECTOR_REFERENCES_dealloc .long 0 diff --git a/crates/test-assembly/crates/test_declare_class/expected/apple-old-x86.s b/crates/test-assembly/crates/test_declare_class/expected/apple-old-x86.s index 5cd9cfd8f..f44bb2648 100644 --- a/crates/test-assembly/crates/test_declare_class/expected/apple-old-x86.s +++ b/crates/test-assembly/crates/test_declare_class/expected/apple-old-x86.s @@ -8,179 +8,271 @@ SYM(core[CRATE_ID]::ptr::drop_in_place::<::call ret .p2align 4, 0x90 -SYM(::call_once::<::class::{closure#0}>::{closure#0}, 0): +SYM(objc2[CRATE_ID]::__macro_helpers::declared_ivars::dealloc::, 0): push ebp mov ebp, esp push ebx push edi push esi - sub esp, 12 + sub esp, 28 call L1$pb L1$pb: + pop ebx + mov esi, dword ptr [ebp + 12] + mov edi, dword ptr [ebp + 8] + mov eax, dword ptr [ebx + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)-L1$pb] + cmp byte ptr [edi + eax], 0 + je LBB1_3 + mov eax, dword ptr [ebx + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-L1$pb] + mov eax, dword ptr [edi + eax] + test eax, eax + je LBB1_3 + mov dword ptr [esp], eax + call _objc_release +LBB1_3: + mov eax, dword ptr [ebx + LL_OBJC_CLASS_REFERENCES_NSObject$non_lazy_ptr-L1$pb] + mov eax, dword ptr [eax] + mov dword ptr [ebp - 20], edi + mov dword ptr [ebp - 16], eax + mov dword ptr [esp + 4], esi + lea eax, [ebp - 20] + mov dword ptr [esp], eax + call _objc_msgSendSuper + add esp, 28 pop esi + pop edi + pop ebx + pop ebp + ret + + .p2align 4, 0x90 +SYM(::call_once::<::class::{closure#0}>::{closure#0}, 0): + push ebp + mov ebp, esp + push ebx + push edi + push esi + sub esp, 28 + call L2$pb +L2$pb: + pop ebx mov eax, dword ptr [ebp + 8] mov eax, dword ptr [eax] cmp byte ptr [eax], 0 mov byte ptr [eax], 0 - je LBB1_5 - mov eax, dword ptr [esi + LL_OBJC_CLASS_REFERENCES_NSObject$non_lazy_ptr-L1$pb] + je LBB2_10 + mov eax, dword ptr [ebx + LL_OBJC_CLASS_REFERENCES_NSObject$non_lazy_ptr-L2$pb] sub esp, 4 - lea edi, [esi + l_anon.[ID].11-L1$pb] + lea esi, [ebx + l_anon.[ID].21-L2$pb] push dword ptr [eax] push 15 - push edi + push esi call SYM(objc2::declare::ClassBuilder::new::GENERATED_ID, 0) add esp, 16 test eax, eax - je LBB1_6 - mov dword ptr [ebp - 16], eax + je LBB2_11 + mov dword ptr [ebp - 40], eax + mov eax, dword ptr [ebx + LL_OBJC_SELECTOR_REFERENCES_dealloc$non_lazy_ptr-L2$pb] sub esp, 8 - lea eax, [esi + l_anon.[ID].15-L1$pb] - lea ecx, [esi + L_anon.[ID].12-L1$pb] - lea ebx, [ebp - 16] - push eax - push 0 - push 1 - push 4 - push ecx - push ebx - call SYM(objc2::declare::ClassBuilder::add_ivar_inner_mono::GENERATED_ID, 0) - add esp, 24 - lea ecx, [esi + l_anon.[ID].2-L1$pb] - lea eax, [esi + L_anon.[ID].13-L1$pb] - push ecx - push 2 - push 4 - push 4 - push eax - push ebx - call SYM(objc2::declare::ClassBuilder::add_ivar_inner_mono::GENERATED_ID, 0) - add esp, 32 - mov eax, dword ptr [esi + LL_OBJC_SELECTOR_REFERENCES_dealloc$non_lazy_ptr-L1$pb] - sub esp, 8 - lea ecx, [esi + SYM(::class::{closure#0}::__objc2_dealloc, 0)-L1$pb] - lea edi, [esi + l_anon.[ID].3-L1$pb] - lea edx, [esi + l_anon.[ID].1-L1$pb] + lea ecx, [ebx + SYM(objc2[CRATE_ID]::__macro_helpers::declared_ivars::dealloc::, 0)-L2$pb] + lea edi, [ebx + l_anon.[ID].3-L2$pb] + lea esi, [ebx + l_anon.[ID].1-L2$pb] + lea edx, [ebp - 40] push ecx push edi push 0 - push edx - mov edi, edx + push esi push dword ptr [eax] - push ebx + push edx call SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) add esp, 32 - mov eax, dword ptr [esi + LL_OBJC_SELECTOR_REFERENCES_init$non_lazy_ptr-L1$pb] + mov eax, dword ptr [ebp - 40] + mov dword ptr [ebp - 16], eax + mov eax, dword ptr [ebx + LL_OBJC_SELECTOR_REFERENCES_init$non_lazy_ptr-L2$pb] sub esp, 8 - lea ecx, [esi + _init-L1$pb] - push ecx - lea ecx, [esi + l_anon.[ID].2-L1$pb] + lea ecx, [ebx + _init-L2$pb] + lea edx, [ebx + l_anon.[ID].2-L2$pb] + lea edi, [ebp - 16] push ecx + push edx push 0 - push edi + push esi push dword ptr [eax] - push ebx + push edi call SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) add esp, 24 - lea eax, [esi + _class_method-L1$pb] + lea eax, [ebx + _class_method-L2$pb] push eax - lea eax, [esi + l_anon.[ID].3-L1$pb] + lea eax, [ebx + l_anon.[ID].3-L2$pb] push eax push 0 + push esi + push dword ptr [ebx + L_OBJC_SELECTOR_REFERENCES_ddead4cf1cfe35ab-L2$pb] push edi - push dword ptr [esi + L_OBJC_SELECTOR_REFERENCES_d874ee9262978be2-L1$pb] - push ebx call SYM(objc2::declare::ClassBuilder::add_class_method_inner::GENERATED_ID, 0) add esp, 24 - lea eax, [esi + _method-L1$pb] + lea eax, [ebx + _method-L2$pb] push eax - lea eax, [esi + l_anon.[ID].3-L1$pb] + lea eax, [ebx + l_anon.[ID].3-L2$pb] push eax push 0 + push esi + push dword ptr [ebx + L_OBJC_SELECTOR_REFERENCES_8ee1155e2a63c707-L2$pb] push edi - push dword ptr [esi + L_OBJC_SELECTOR_REFERENCES_4539fd1dbda0cddc-L1$pb] - push ebx call SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) add esp, 24 - lea eax, [esi + _method_bool-L1$pb] - lea ecx, [esi + l_anon.[ID].4-L1$pb] + lea eax, [ebx + _method_bool-L2$pb] + lea esi, [ebx + l_anon.[ID].4-L2$pb] push eax - push ecx + push esi push 1 - push ecx - push dword ptr [esi + L_OBJC_SELECTOR_REFERENCES_2b1b3a94e0ece2e5-L1$pb] - push ebx + push esi + push dword ptr [ebx + L_OBJC_SELECTOR_REFERENCES_b1c6d8f625c88aa6-L2$pb] + push edi call SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) add esp, 24 - lea eax, [esi + _method_id-L1$pb] + lea eax, [ebx + _method_id-L2$pb] + push eax + lea eax, [ebx + l_anon.[ID].2-L2$pb] push eax - lea edi, [esi + l_anon.[ID].2-L1$pb] - push edi push 0 - lea eax, [esi + l_anon.[ID].1-L1$pb] + lea eax, [ebx + l_anon.[ID].1-L2$pb] push eax - push dword ptr [esi + L_OBJC_SELECTOR_REFERENCES_f7f521670860b0ce-L1$pb] - push ebx + push dword ptr [ebx + L_OBJC_SELECTOR_REFERENCES_f33da9321a226f33-L2$pb] + push edi call SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) add esp, 24 - lea eax, [esi + _method_id_with_param-L1$pb] + lea eax, [ebx + _method_id_with_param-L2$pb] push eax - push edi - push 1 - lea eax, [esi + l_anon.[ID].4-L1$pb] + lea eax, [ebx + l_anon.[ID].2-L2$pb] push eax - push dword ptr [esi + L_OBJC_SELECTOR_REFERENCES_6addfcf634c6232f-L1$pb] - push ebx + push 1 + push esi + push dword ptr [ebx + L_OBJC_SELECTOR_REFERENCES_e5d1ad528a5510d9-L2$pb] + push edi call SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) add esp, 24 - lea eax, [esi + l_anon.[ID].17-L1$pb] + lea eax, [ebx + l_anon.[ID].24-L2$pb] push 9 push eax call SYM(objc2::runtime::AnyProtocol::get::GENERATED_ID, 0) add esp, 16 test eax, eax - je LBB1_4 + je LBB2_4 sub esp, 8 push eax - push ebx + push edi call SYM(objc2::declare::ClassBuilder::add_protocol::GENERATED_ID, 0) add esp, 16 -LBB1_4: +LBB2_4: sub esp, 8 - lea eax, [esi + _copyWithZone-L1$pb] - lea ecx, [esi + l_anon.[ID].7-L1$pb] + lea eax, [ebx + _copyWithZone-L2$pb] + lea ecx, [ebx + l_anon.[ID].7-L2$pb] push eax - lea eax, [esi + l_anon.[ID].2-L1$pb] + lea eax, [ebx + l_anon.[ID].2-L2$pb] push eax push 1 push ecx - push dword ptr [esi + L_OBJC_SELECTOR_REFERENCES_4a8c690dbc9d8166-L1$pb] - push ebx + push dword ptr [ebx + L_OBJC_SELECTOR_REFERENCES_8daf9cd9e6dba6e3-L2$pb] + push edi call SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) + add esp, 32 + mov eax, dword ptr [ebp - 16] + mov dword ptr [ebp - 20], eax + mov dword ptr [ebp - 32], 0 + mov dword ptr [ebp - 36], 8 + lea eax, [ebx + l_anon.[ID].11-L2$pb] + mov dword ptr [ebp - 28], eax + mov byte ptr [ebp - 40], 27 + sub esp, 8 + lea edi, [ebx + l_anon.[ID].8-L2$pb] + lea esi, [ebp - 20] + lea eax, [ebp - 40] + push eax + push 2 + push 8 + push 5 + push edi + push esi + call SYM(objc2::declare::ClassBuilder::add_ivar_inner_mono::GENERATED_ID, 0) + add esp, 24 + lea eax, [ebx + l_anon.[ID].10-L2$pb] + lea ecx, [ebx + l_anon.[ID].9-L2$pb] + push eax + push 0 + push 1 + push 9 + push ecx + push esi + call SYM(objc2::declare::ClassBuilder::add_ivar_inner_mono::GENERATED_ID, 0) add esp, 20 - push dword ptr [ebp - 16] + push dword ptr [ebp - 20] call SYM(objc2::declare::ClassBuilder::register::GENERATED_ID, 0) + add esp, 16 + mov esi, eax + sub esp, 4 + push 5 + push edi + push eax + call SYM(objc2::runtime::AnyClass::instance_variable::GENERATED_ID, 0) + add esp, 16 + test eax, eax + je LBB2_5 + sub esp, 12 + push eax + call _ivar_getOffset + add esp, 16 + mov edi, eax + sub esp, 4 + push 9 + lea eax, [ebx + l_anon.[ID].9-L2$pb] + push eax + push esi + call SYM(objc2::runtime::AnyClass::instance_variable::GENERATED_ID, 0) + add esp, 16 + test eax, eax + je LBB2_8 + sub esp, 12 + push eax + call _ivar_getOffset + add esp, 16 + mov dword ptr [ebx + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_CLASS, 0).0-L2$pb], esi + mov dword ptr [ebx + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-L2$pb], edi + mov dword ptr [ebx + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)-L2$pb], eax add esp, 28 pop esi pop edi pop ebx pop ebp ret -LBB1_5: +LBB2_10: sub esp, 4 - lea eax, [esi + l_anon.[ID].10-L1$pb] - lea ecx, [esi + l_anon.[ID].8-L1$pb] + lea eax, [ebx + l_anon.[ID].18-L2$pb] + lea ecx, [ebx + l_anon.[ID].16-L2$pb] push eax push 43 push ecx call SYM(core::panicking::panic::GENERATED_ID, 0) -LBB1_6: +LBB2_11: sub esp, 4 - lea eax, [esi + l_anon.[ID].16-L1$pb] + lea eax, [ebx + l_anon.[ID].23-L2$pb] push eax push 15 - push edi + push esi call SYM(objc2::__macro_helpers::declare_class::failed_declaring_class::GENERATED_ID, 0) +LBB2_5: + sub esp, 4 + lea eax, [ebx + l_anon.[ID].14-L2$pb] + jmp LBB2_6 +LBB2_8: + sub esp, 4 + lea eax, [ebx + l_anon.[ID].15-L2$pb] +LBB2_6: + lea ecx, [ebx + l_anon.[ID].12-L2$pb] + push eax + push 59 + push ecx + call SYM(core::option::expect_failed::GENERATED_ID, 0) .p2align 4, 0x90 SYM(<::call_once<::class::{closure#0}>::{closure#0} as core[CRATE_ID]::ops::function::FnOnce<(&std[CRATE_ID]::sync::once::OnceState,)>>::call_once::{shim:vtable#0}, 0): @@ -205,35 +297,28 @@ _get_class: push edi push esi sub esp, 16 - call L3$pb -L3$pb: + call L4$pb +L4$pb: pop esi - mov eax, dword ptr [esi + SYM(::class::REGISTER_CLASS, 0)-L3$pb] + mov eax, dword ptr [esi + SYM(::class::REGISTER_CLASS, 0)-L4$pb] cmp eax, 3 - jne LBB3_1 -LBB3_2: - sub esp, 8 - lea eax, [esi + l_anon.[ID].11-L3$pb] - push 15 - push eax - call SYM(objc2::runtime::AnyClass::get::GENERATED_ID, 0) - add esp, 16 - test eax, eax - je LBB3_4 + jne LBB4_1 +LBB4_2: + mov eax, dword ptr [esi + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_CLASS, 0).0-L4$pb] add esp, 16 pop esi pop edi pop ebp ret -LBB3_1: +LBB4_1: mov byte ptr [ebp - 9], 1 lea eax, [ebp - 9] mov dword ptr [ebp - 16], eax sub esp, 12 - lea eax, [esi + l_anon.[ID].16-L3$pb] - lea ecx, [esi + l_anon.[ID].0-L3$pb] + lea eax, [esi + l_anon.[ID].23-L4$pb] + lea ecx, [esi + l_anon.[ID].0-L4$pb] lea edx, [ebp - 16] - lea edi, [esi + SYM(::class::REGISTER_CLASS, 0)-L3$pb] + lea edi, [esi + SYM(::class::REGISTER_CLASS, 0)-L4$pb] push eax push ecx push edx @@ -241,15 +326,7 @@ LBB3_1: push edi call SYM(std::sys_common::once::queue::Once::call::GENERATED_ID, 0) add esp, 32 - jmp LBB3_2 -LBB3_4: - sub esp, 4 - lea eax, [esi + l_anon.[ID].16-L3$pb] - lea ecx, [esi + l_anon.[ID].8-L3$pb] - push eax - push 43 - push ecx - call SYM(core::panicking::panic::GENERATED_ID, 0) + jmp LBB4_2 .globl _get_obj .p2align 4, 0x90 @@ -258,10 +335,10 @@ _get_obj: mov ebp, esp push esi push eax - call L4$pb -L4$pb: + call L5$pb +L5$pb: pop eax - mov eax, dword ptr [eax + LL_OBJC_SELECTOR_REFERENCES_new$non_lazy_ptr-L4$pb] + mov eax, dword ptr [eax + LL_OBJC_SELECTOR_REFERENCES_new$non_lazy_ptr-L5$pb] mov esi, dword ptr [eax] call _get_class sub esp, 8 @@ -279,37 +356,21 @@ _access_ivars: push ebp mov ebp, esp push ebx - push edi push esi - sub esp, 12 - call L5$pb -L5$pb: - pop edi + sub esp, 16 + call L6$pb +L6$pb: + pop esi call _get_obj - mov esi, eax - lea eax, [edi + L_anon.[ID].12-L5$pb] - mov dword ptr [esp + 4], eax - mov dword ptr [esp], esi - mov dword ptr [esp + 8], 4 - call SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) + mov ecx, dword ptr [esi + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-L6$pb] + movzx ebx, byte ptr [eax + ecx + 4] + mov esi, dword ptr [eax + ecx] mov dword ptr [esp], eax - call _ivar_getOffset - movzx ebx, byte ptr [esi + eax] - lea eax, [edi + L_anon.[ID].13-L5$pb] - mov dword ptr [esp + 4], eax - mov dword ptr [esp], esi - mov dword ptr [esp + 8], 4 - call SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - mov dword ptr [esp], eax - call _ivar_getOffset - mov edi, dword ptr [esi + eax] - mov dword ptr [esp], esi call _objc_release mov eax, ebx - mov edx, edi - add esp, 12 + mov edx, esi + add esp, 16 pop esi - pop edi pop ebx pop ebp ret @@ -322,35 +383,28 @@ SYM(::class::REGISTER_CLASS, 0)-L6$pb] + mov eax, dword ptr [esi + SYM(::class::REGISTER_CLASS, 0)-L7$pb] cmp eax, 3 - jne LBB6_1 -LBB6_2: - sub esp, 8 - lea eax, [esi + l_anon.[ID].11-L6$pb] - push 15 - push eax - call SYM(objc2::runtime::AnyClass::get::GENERATED_ID, 0) - add esp, 16 - test eax, eax - je LBB6_4 + jne LBB7_1 +LBB7_2: + mov eax, dword ptr [esi + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_CLASS, 0).0-L7$pb] add esp, 16 pop esi pop edi pop ebp ret -LBB6_1: +LBB7_1: mov byte ptr [ebp - 9], 1 lea eax, [ebp - 9] mov dword ptr [ebp - 16], eax sub esp, 12 - lea eax, [esi + l_anon.[ID].16-L6$pb] - lea ecx, [esi + l_anon.[ID].0-L6$pb] + lea eax, [esi + l_anon.[ID].23-L7$pb] + lea ecx, [esi + l_anon.[ID].0-L7$pb] lea edx, [ebp - 16] - lea edi, [esi + SYM(::class::REGISTER_CLASS, 0)-L6$pb] + lea edi, [esi + SYM(::class::REGISTER_CLASS, 0)-L7$pb] push eax push ecx push edx @@ -358,113 +412,52 @@ LBB6_1: push edi call SYM(std::sys_common::once::queue::Once::call::GENERATED_ID, 0) add esp, 32 - jmp LBB6_2 -LBB6_4: - sub esp, 4 - lea eax, [esi + l_anon.[ID].16-L6$pb] - lea ecx, [esi + l_anon.[ID].8-L6$pb] - push eax - push 43 - push ecx - call SYM(core::panicking::panic::GENERATED_ID, 0) - - .p2align 4, 0x90 -SYM(::class::{closure#0}::__objc2_dealloc, 0): - push ebp - mov ebp, esp - push ebx - push edi - push esi - sub esp, 28 - call L7$pb -L7$pb: - pop ebx - mov esi, dword ptr [ebp + 12] - mov edi, dword ptr [ebp + 8] - lea eax, [ebx + L_anon.[ID].13-L7$pb] - mov dword ptr [esp + 4], eax - mov dword ptr [esp], edi - mov dword ptr [esp + 8], 4 - call SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - mov dword ptr [esp], eax - call _ivar_getOffset - mov eax, dword ptr [edi + eax] - test eax, eax - je LBB7_2 - mov dword ptr [esp], eax - call _objc_release -LBB7_2: - mov eax, dword ptr [ebx + LL_OBJC_CLASS_REFERENCES_NSObject$non_lazy_ptr-L7$pb] - mov eax, dword ptr [eax] - mov dword ptr [ebp - 20], edi - mov dword ptr [ebp - 16], eax - mov dword ptr [esp + 4], esi - lea eax, [ebp - 20] - mov dword ptr [esp], eax - call _objc_msgSendSuper - add esp, 28 - pop esi - pop edi - pop ebx - pop ebp - ret + jmp LBB7_2 .globl _init .p2align 4, 0x90 _init: push ebp mov ebp, esp - push edi - push esi - sub esp, 16 + sub esp, 24 call L8$pb L8$pb: - pop edi - mov eax, dword ptr [ebp + 8] - mov ecx, dword ptr [edi + LL_OBJC_SELECTOR_REFERENCES_init$non_lazy_ptr-L8$pb] - mov ecx, dword ptr [ecx] - mov edx, dword ptr [edi + LL_OBJC_CLASS_REFERENCES_NSObject$non_lazy_ptr-L8$pb] - mov edx, dword ptr [edx] - mov dword ptr [ebp - 16], eax - mov dword ptr [ebp - 12], edx + pop eax + mov ecx, dword ptr [ebp + 8] + test ecx, ecx + je LBB8_2 + mov edx, dword ptr [eax + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-L8$pb] + mov dword ptr [ecx + edx], 0 + mov byte ptr [ecx + edx + 4], 42 + mov edx, dword ptr [eax + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)-L8$pb] + mov byte ptr [ecx + edx], 1 + mov edx, dword ptr [eax + L_OBJC_SELECTOR_REFERENCES_74641ed6f72d2d44-L8$pb] + mov eax, dword ptr [eax + LL_OBJC_CLASS_REFERENCES_NSObject$non_lazy_ptr-L8$pb] + mov eax, dword ptr [eax] + mov dword ptr [ebp - 24], ecx + mov dword ptr [ebp - 20], eax sub esp, 8 - lea eax, [ebp - 16] - push ecx + lea eax, [ebp - 24] + push edx push eax call _objc_msgSendSuper - add esp, 16 - mov esi, eax - test eax, eax - je LBB8_2 - sub esp, 4 - lea eax, [edi + L_anon.[ID].12-L8$pb] - push 4 - push eax - push esi - call SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - add esp, 4 - push eax - call _ivar_getOffset - add esp, 16 - mov byte ptr [esi + eax], 42 - sub esp, 4 - lea eax, [edi + L_anon.[ID].13-L8$pb] - push 4 - push eax - push esi - call SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - add esp, 4 - push eax - call _ivar_getOffset - add esp, 16 - mov dword ptr [esi + eax], 0 -LBB8_2: - mov eax, esi - add esp, 16 - pop esi - pop edi + add esp, 40 pop ebp ret +LBB8_2: + lea ecx, [eax + l_anon.[ID].20-L8$pb] + mov dword ptr [ebp - 24], ecx + mov dword ptr [ebp - 20], 1 + mov dword ptr [ebp - 8], 0 + lea ecx, [eax + l_anon.[ID].1-L8$pb] + mov dword ptr [ebp - 16], ecx + mov dword ptr [ebp - 12], 0 + sub esp, 8 + lea eax, [eax + l_anon.[ID].25-L8$pb] + lea ecx, [ebp - 24] + push eax + push ecx + call SYM(core::panicking::panic_fmt::GENERATED_ID, 0) .globl _class_method .p2align 4, 0x90 @@ -498,20 +491,13 @@ _method_bool: _method_id: push ebp mov ebp, esp - push esi - sub esp, 20 + sub esp, 8 call L12$pb L12$pb: pop eax - mov esi, dword ptr [ebp + 8] - lea eax, [eax + L_anon.[ID].13-L12$pb] - mov dword ptr [esp + 4], eax - mov dword ptr [esp], esi - mov dword ptr [esp + 8], 4 - call SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - mov dword ptr [esp], eax - call _ivar_getOffset - mov eax, dword ptr [esi + eax] + mov ecx, dword ptr [ebp + 8] + mov eax, dword ptr [eax + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-L12$pb] + mov eax, dword ptr [ecx + eax] test eax, eax je LBB12_1 mov dword ptr [esp], eax @@ -522,8 +508,7 @@ LBB12_1: LBB12_3: mov dword ptr [esp], eax call _objc_autoreleaseReturnValue - add esp, 20 - pop esi + add esp, 8 pop ebp ret @@ -532,26 +517,19 @@ LBB12_3: _method_id_with_param: push ebp mov ebp, esp - push ebx push edi push esi - sub esp, 12 + sub esp, 16 call L13$pb L13$pb: - pop ebx + pop edi call SYM(objc2::runtime::nsobject::NSObject::new::GENERATED_ID, 0) mov esi, eax cmp byte ptr [ebp + 16], 0 je LBB13_5 - mov edi, dword ptr [ebp + 8] - lea eax, [ebx + L_anon.[ID].13-L13$pb] - mov dword ptr [esp + 4], eax - mov dword ptr [esp], edi - mov dword ptr [esp + 8], 4 - call SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - mov dword ptr [esp], eax - call _ivar_getOffset - mov eax, dword ptr [edi + eax] + mov eax, dword ptr [ebp + 8] + mov ecx, dword ptr [edi + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-L13$pb] + mov eax, dword ptr [eax + ecx] test eax, eax je LBB13_2 mov dword ptr [esp], eax @@ -567,10 +545,9 @@ LBB13_4: LBB13_5: mov dword ptr [esp], esi call _objc_autoreleaseReturnValue - add esp, 12 + add esp, 16 pop esi pop edi - pop ebx pop ebp ret @@ -585,62 +562,90 @@ _copyWithZone: sub esp, 28 call L14$pb L14$pb: - pop ebx - call _get_obj + pop edi + mov ebx, dword ptr [ebp + 8] + mov eax, dword ptr [edi + LL_OBJC_SELECTOR_REFERENCES_alloc$non_lazy_ptr-L14$pb] + mov esi, dword ptr [eax] + mov eax, dword ptr [edi + SYM(::class::REGISTER_CLASS, 0)-L14$pb] + cmp eax, 3 + jne LBB14_1 +LBB14_2: + sub esp, 8 + push esi + push dword ptr [edi + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_CLASS, 0).0-L14$pb] + call _objc_msgSend + add esp, 16 mov esi, eax + mov eax, dword ptr [edi + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-L14$pb] + mov ecx, ebx + movzx ebx, byte ptr [ebx + eax + 4] + mov eax, dword ptr [ecx + eax] test eax, eax - je LBB14_5 - mov edi, dword ptr [ebp + 8] - lea ecx, [ebx + L_anon.[ID].12-L14$pb] - mov dword ptr [esp + 4], ecx - mov dword ptr [esp], edi - mov dword ptr [esp + 8], 4 - call SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - mov dword ptr [esp], eax - call _ivar_getOffset - movzx eax, byte ptr [edi + eax] - mov byte ptr [ebp - 13], al - lea eax, [ebx + L_anon.[ID].12-L14$pb] - mov dword ptr [esp + 4], eax - mov dword ptr [esp], esi - mov dword ptr [esp + 8], 4 - call SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - mov dword ptr [esp], eax - call _ivar_getOffset - movzx ecx, byte ptr [ebp - 13] - mov byte ptr [esi + eax], cl - lea ebx, [ebx + L_anon.[ID].13-L14$pb] - mov dword ptr [esp + 4], ebx - mov dword ptr [esp], edi - mov dword ptr [esp + 8], 4 - call SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - mov dword ptr [esp], eax - call _ivar_getOffset - mov eax, dword ptr [edi + eax] - test eax, eax - je LBB14_2 - mov dword ptr [esp], eax + je LBB14_3 + sub esp, 12 + push eax call _objc_retain - mov edi, eax - jmp LBB14_4 -LBB14_2: - xor edi, edi -LBB14_4: - mov dword ptr [esp + 4], ebx - mov dword ptr [esp], esi - mov dword ptr [esp + 8], 4 - call SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - mov dword ptr [esp], eax - call _ivar_getOffset - mov dword ptr [esi + eax], edi -LBB14_5: - mov eax, esi - add esp, 28 + add esp, 16 + test esi, esi + je LBB14_7 +LBB14_6: + mov ecx, dword ptr [edi + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-L14$pb] + mov dword ptr [esi + ecx], eax + mov byte ptr [esi + ecx + 4], bl + mov eax, dword ptr [edi + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)-L14$pb] + mov byte ptr [esi + eax], 1 + mov eax, dword ptr [edi + L_OBJC_SELECTOR_REFERENCES_a4c8ca93c4279f29-L14$pb] + mov ecx, dword ptr [edi + LL_OBJC_CLASS_REFERENCES_NSObject$non_lazy_ptr-L14$pb] + mov ecx, dword ptr [ecx] + mov dword ptr [ebp - 40], esi + mov dword ptr [ebp - 36], ecx + sub esp, 8 + lea ecx, [ebp - 40] + push eax + push ecx + call _objc_msgSendSuper + add esp, 44 pop esi pop edi pop ebx pop ebp ret +LBB14_3: + xor eax, eax + test esi, esi + jne LBB14_6 +LBB14_7: + lea eax, [edi + l_anon.[ID].20-L14$pb] + mov dword ptr [ebp - 40], eax + mov dword ptr [ebp - 36], 1 + mov dword ptr [ebp - 24], 0 + lea eax, [edi + l_anon.[ID].1-L14$pb] + mov dword ptr [ebp - 32], eax + mov dword ptr [ebp - 28], 0 + sub esp, 8 + lea eax, [edi + l_anon.[ID].26-L14$pb] + lea ecx, [ebp - 40] + push eax + push ecx + call SYM(core::panicking::panic_fmt::GENERATED_ID, 0) +LBB14_1: + mov byte ptr [ebp - 13], 1 + lea eax, [ebp - 13] + mov dword ptr [ebp - 40], eax + sub esp, 12 + lea eax, [edi + l_anon.[ID].23-L14$pb] + lea ecx, [edi + l_anon.[ID].0-L14$pb] + lea edx, [ebp - 40] + lea ebx, [edi + SYM(::class::REGISTER_CLASS, 0)-L14$pb] + push eax + push ecx + push edx + push 0 + push ebx + mov ebx, dword ptr [ebp + 8] + call SYM(std::sys_common::once::queue::Once::call::GENERATED_ID, 0) + add esp, 32 + jmp LBB14_2 .section __DATA,__const .p2align 2, 0x0 @@ -692,154 +697,239 @@ l_anon.[ID].7: .section __TEXT,__const l_anon.[ID].8: - .ascii "called `Option::unwrap()` on a `None` value" + .ascii "ivars" l_anon.[ID].9: - .ascii "$RUSTC/library/std/src/sync/once.rs" + .ascii "drop_flag" - .section __DATA,__const .p2align 2, 0x0 l_anon.[ID].10: - .long l_anon.[ID].9 - .asciz "p\000\000\000\225\000\000\0002\000\000" + .byte 5 + .space 19 - .section __TEXT,__const + .p2align 2, 0x0 l_anon.[ID].11: - .ascii "CustomClassName" + .byte 7 + .space 19 - .section __TEXT,__literal4,4byte_literals -L_anon.[ID].12: - .ascii "_foo" +l_anon.[ID].12: + .ascii "failed retrieving instance variable on newly declared class" -L_anon.[ID].13: - .ascii "_obj" +l_anon.[ID].13: + .ascii "$WORKSPACE/objc2/src/__macro_helpers/declared_ivars.rs" - .section __TEXT,__const + .section __DATA,__const + .p2align 2, 0x0 l_anon.[ID].14: - .ascii "crates/$DIR/lib.rs" + .long l_anon.[ID].13 + .asciz "T\000\000\000\363\000\000\000\016\000\000" .p2align 2, 0x0 l_anon.[ID].15: - .byte 5 - .space 19 + .long l_anon.[ID].13 + .asciz "T\000\000\000\377\000\000\000\016\000\000" + + .section __TEXT,__const +l_anon.[ID].16: + .ascii "called `Option::unwrap()` on a `None` value" + +l_anon.[ID].17: + .ascii "$RUSTC/library/std/src/sync/once.rs" .section __DATA,__const .p2align 2, 0x0 -l_anon.[ID].16: - .long l_anon.[ID].14 - .asciz "5\000\000\000\f\000\000\000\001\000\000" +l_anon.[ID].18: + .long l_anon.[ID].17 + .asciz "p\000\000\000\225\000\000\0002\000\000" + + .section __TEXT,__const +l_anon.[ID].19: + .ascii "tried to initialize instance variables on NULL allocated object" + + .section __DATA,__const + .p2align 2, 0x0 +l_anon.[ID].20: + .long l_anon.[ID].19 + .asciz "?\000\000" + + .section __TEXT,__const +l_anon.[ID].21: + .ascii "CustomClassName" + +l_anon.[ID].22: + .ascii "crates/$DIR/lib.rs" + +.zerofill __DATA,__bss,SYM(test_declare_class[CRATE_ID]::_::__OBJC2_CLASS, 0).0,4,2 + .globl SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0) +.zerofill __DATA,__common,SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0),4,2 + .globl SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0) +.zerofill __DATA,__common,SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0),4,2 + .section __DATA,__const + .p2align 2, 0x0 +l_anon.[ID].23: + .long l_anon.[ID].22 + .asciz "5\000\000\000\021\000\000\000\001\000\000" .zerofill __DATA,__bss,SYM(::class::REGISTER_CLASS, 0),4,2 .section __TEXT,__const -l_anon.[ID].17: +l_anon.[ID].24: .ascii "NSCopying" .section __TEXT,__cstring,cstring_literals - .globl L_OBJC_METH_VAR_NAME_d874ee9262978be2 -L_OBJC_METH_VAR_NAME_d874ee9262978be2: + .globl L_OBJC_METH_VAR_NAME_ddead4cf1cfe35ab +L_OBJC_METH_VAR_NAME_ddead4cf1cfe35ab: .asciz "classMethod" .section __OBJC,__message_refs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_d874ee9262978be2 + .globl L_OBJC_SELECTOR_REFERENCES_ddead4cf1cfe35ab .p2align 2, 0x0 -L_OBJC_SELECTOR_REFERENCES_d874ee9262978be2: - .long L_OBJC_METH_VAR_NAME_d874ee9262978be2 +L_OBJC_SELECTOR_REFERENCES_ddead4cf1cfe35ab: + .long L_OBJC_METH_VAR_NAME_ddead4cf1cfe35ab .section __OBJC,__image_info - .globl L_OBJC_IMAGE_INFO_d874ee9262978be2 + .globl L_OBJC_IMAGE_INFO_ddead4cf1cfe35ab .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_d874ee9262978be2: +L_OBJC_IMAGE_INFO_ddead4cf1cfe35ab: .asciz "\000\000\000\000@\000\000" .section __TEXT,__cstring,cstring_literals - .globl L_OBJC_METH_VAR_NAME_4539fd1dbda0cddc -L_OBJC_METH_VAR_NAME_4539fd1dbda0cddc: + .globl L_OBJC_METH_VAR_NAME_8ee1155e2a63c707 +L_OBJC_METH_VAR_NAME_8ee1155e2a63c707: .asciz "method" .section __OBJC,__message_refs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_4539fd1dbda0cddc + .globl L_OBJC_SELECTOR_REFERENCES_8ee1155e2a63c707 .p2align 2, 0x0 -L_OBJC_SELECTOR_REFERENCES_4539fd1dbda0cddc: - .long L_OBJC_METH_VAR_NAME_4539fd1dbda0cddc +L_OBJC_SELECTOR_REFERENCES_8ee1155e2a63c707: + .long L_OBJC_METH_VAR_NAME_8ee1155e2a63c707 .section __OBJC,__image_info - .globl L_OBJC_IMAGE_INFO_4539fd1dbda0cddc + .globl L_OBJC_IMAGE_INFO_8ee1155e2a63c707 .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_4539fd1dbda0cddc: +L_OBJC_IMAGE_INFO_8ee1155e2a63c707: .asciz "\000\000\000\000@\000\000" .section __TEXT,__cstring,cstring_literals - .globl L_OBJC_METH_VAR_NAME_2b1b3a94e0ece2e5 -L_OBJC_METH_VAR_NAME_2b1b3a94e0ece2e5: + .globl L_OBJC_METH_VAR_NAME_b1c6d8f625c88aa6 +L_OBJC_METH_VAR_NAME_b1c6d8f625c88aa6: .asciz "methodBool:" .section __OBJC,__message_refs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_2b1b3a94e0ece2e5 + .globl L_OBJC_SELECTOR_REFERENCES_b1c6d8f625c88aa6 .p2align 2, 0x0 -L_OBJC_SELECTOR_REFERENCES_2b1b3a94e0ece2e5: - .long L_OBJC_METH_VAR_NAME_2b1b3a94e0ece2e5 +L_OBJC_SELECTOR_REFERENCES_b1c6d8f625c88aa6: + .long L_OBJC_METH_VAR_NAME_b1c6d8f625c88aa6 .section __OBJC,__image_info - .globl L_OBJC_IMAGE_INFO_2b1b3a94e0ece2e5 + .globl L_OBJC_IMAGE_INFO_b1c6d8f625c88aa6 .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_2b1b3a94e0ece2e5: +L_OBJC_IMAGE_INFO_b1c6d8f625c88aa6: .asciz "\000\000\000\000@\000\000" .section __TEXT,__cstring,cstring_literals - .globl L_OBJC_METH_VAR_NAME_f7f521670860b0ce -L_OBJC_METH_VAR_NAME_f7f521670860b0ce: + .globl L_OBJC_METH_VAR_NAME_f33da9321a226f33 +L_OBJC_METH_VAR_NAME_f33da9321a226f33: .asciz "methodId" .section __OBJC,__message_refs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_f7f521670860b0ce + .globl L_OBJC_SELECTOR_REFERENCES_f33da9321a226f33 .p2align 2, 0x0 -L_OBJC_SELECTOR_REFERENCES_f7f521670860b0ce: - .long L_OBJC_METH_VAR_NAME_f7f521670860b0ce +L_OBJC_SELECTOR_REFERENCES_f33da9321a226f33: + .long L_OBJC_METH_VAR_NAME_f33da9321a226f33 .section __OBJC,__image_info - .globl L_OBJC_IMAGE_INFO_f7f521670860b0ce + .globl L_OBJC_IMAGE_INFO_f33da9321a226f33 .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_f7f521670860b0ce: +L_OBJC_IMAGE_INFO_f33da9321a226f33: .asciz "\000\000\000\000@\000\000" .section __TEXT,__cstring,cstring_literals - .globl L_OBJC_METH_VAR_NAME_6addfcf634c6232f -L_OBJC_METH_VAR_NAME_6addfcf634c6232f: + .globl L_OBJC_METH_VAR_NAME_e5d1ad528a5510d9 +L_OBJC_METH_VAR_NAME_e5d1ad528a5510d9: .asciz "methodIdWithParam:" .section __OBJC,__message_refs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_6addfcf634c6232f + .globl L_OBJC_SELECTOR_REFERENCES_e5d1ad528a5510d9 .p2align 2, 0x0 -L_OBJC_SELECTOR_REFERENCES_6addfcf634c6232f: - .long L_OBJC_METH_VAR_NAME_6addfcf634c6232f +L_OBJC_SELECTOR_REFERENCES_e5d1ad528a5510d9: + .long L_OBJC_METH_VAR_NAME_e5d1ad528a5510d9 .section __OBJC,__image_info - .globl L_OBJC_IMAGE_INFO_6addfcf634c6232f + .globl L_OBJC_IMAGE_INFO_e5d1ad528a5510d9 .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_6addfcf634c6232f: +L_OBJC_IMAGE_INFO_e5d1ad528a5510d9: .asciz "\000\000\000\000@\000\000" .section __TEXT,__cstring,cstring_literals - .globl L_OBJC_METH_VAR_NAME_4a8c690dbc9d8166 -L_OBJC_METH_VAR_NAME_4a8c690dbc9d8166: + .globl L_OBJC_METH_VAR_NAME_8daf9cd9e6dba6e3 +L_OBJC_METH_VAR_NAME_8daf9cd9e6dba6e3: .asciz "copyWithZone:" .section __OBJC,__message_refs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_4a8c690dbc9d8166 + .globl L_OBJC_SELECTOR_REFERENCES_8daf9cd9e6dba6e3 .p2align 2, 0x0 -L_OBJC_SELECTOR_REFERENCES_4a8c690dbc9d8166: - .long L_OBJC_METH_VAR_NAME_4a8c690dbc9d8166 +L_OBJC_SELECTOR_REFERENCES_8daf9cd9e6dba6e3: + .long L_OBJC_METH_VAR_NAME_8daf9cd9e6dba6e3 .section __OBJC,__image_info - .globl L_OBJC_IMAGE_INFO_4a8c690dbc9d8166 + .globl L_OBJC_IMAGE_INFO_8daf9cd9e6dba6e3 .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_4a8c690dbc9d8166: +L_OBJC_IMAGE_INFO_8daf9cd9e6dba6e3: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__const + .p2align 2, 0x0 +l_anon.[ID].25: + .long l_anon.[ID].22 + .asciz "5\000\000\000#\000\000\000\035\000\000" + + .section __TEXT,__cstring,cstring_literals + .globl L_OBJC_METH_VAR_NAME_74641ed6f72d2d44 +L_OBJC_METH_VAR_NAME_74641ed6f72d2d44: + .asciz "init" + + .section __OBJC,__message_refs,literal_pointers,no_dead_strip + .globl L_OBJC_SELECTOR_REFERENCES_74641ed6f72d2d44 + .p2align 2, 0x0 +L_OBJC_SELECTOR_REFERENCES_74641ed6f72d2d44: + .long L_OBJC_METH_VAR_NAME_74641ed6f72d2d44 + + .section __OBJC,__image_info + .globl L_OBJC_IMAGE_INFO_74641ed6f72d2d44 + .p2align 2, 0x0 +L_OBJC_IMAGE_INFO_74641ed6f72d2d44: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__const + .p2align 2, 0x0 +l_anon.[ID].26: + .long l_anon.[ID].22 + .asciz "5\000\000\000N\000\000\000\033\000\000" + + .section __TEXT,__cstring,cstring_literals + .globl L_OBJC_METH_VAR_NAME_a4c8ca93c4279f29 +L_OBJC_METH_VAR_NAME_a4c8ca93c4279f29: + .asciz "init" + + .section __OBJC,__message_refs,literal_pointers,no_dead_strip + .globl L_OBJC_SELECTOR_REFERENCES_a4c8ca93c4279f29 + .p2align 2, 0x0 +L_OBJC_SELECTOR_REFERENCES_a4c8ca93c4279f29: + .long L_OBJC_METH_VAR_NAME_a4c8ca93c4279f29 + + .section __OBJC,__image_info + .globl L_OBJC_IMAGE_INFO_a4c8ca93c4279f29 + .p2align 2, 0x0 +L_OBJC_IMAGE_INFO_a4c8ca93c4279f29: .asciz "\000\000\000\000@\000\000" .section __IMPORT,__pointers,non_lazy_symbol_pointers LL_OBJC_CLASS_REFERENCES_NSObject$non_lazy_ptr: .indirect_symbol L_OBJC_CLASS_REFERENCES_NSObject .long 0 +LL_OBJC_SELECTOR_REFERENCES_alloc$non_lazy_ptr: + .indirect_symbol L_OBJC_SELECTOR_REFERENCES_alloc + .long 0 LL_OBJC_SELECTOR_REFERENCES_dealloc$non_lazy_ptr: .indirect_symbol L_OBJC_SELECTOR_REFERENCES_dealloc .long 0 diff --git a/crates/test-assembly/crates/test_declare_class/expected/apple-x86.s b/crates/test-assembly/crates/test_declare_class/expected/apple-x86.s index 079d17352..17e71230f 100644 --- a/crates/test-assembly/crates/test_declare_class/expected/apple-x86.s +++ b/crates/test-assembly/crates/test_declare_class/expected/apple-x86.s @@ -8,179 +8,271 @@ SYM(core[CRATE_ID]::ptr::drop_in_place::<::call ret .p2align 4, 0x90 -SYM(::call_once::<::class::{closure#0}>::{closure#0}, 0): +SYM(objc2[CRATE_ID]::__macro_helpers::declared_ivars::dealloc::, 0): push ebp mov ebp, esp push ebx push edi push esi - sub esp, 12 + sub esp, 28 call L1$pb L1$pb: + pop ebx + mov esi, dword ptr [ebp + 12] + mov edi, dword ptr [ebp + 8] + mov eax, dword ptr [ebx + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)-L1$pb] + cmp byte ptr [edi + eax], 0 + je LBB1_3 + mov eax, dword ptr [ebx + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-L1$pb] + mov eax, dword ptr [edi + eax] + test eax, eax + je LBB1_3 + mov dword ptr [esp], eax + call _objc_release +LBB1_3: + mov eax, dword ptr [ebx + LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-L1$pb] + mov eax, dword ptr [eax] + mov dword ptr [ebp - 20], edi + mov dword ptr [ebp - 16], eax + mov dword ptr [esp + 4], esi + lea eax, [ebp - 20] + mov dword ptr [esp], eax + call _objc_msgSendSuper + add esp, 28 pop esi + pop edi + pop ebx + pop ebp + ret + + .p2align 4, 0x90 +SYM(::call_once::<::class::{closure#0}>::{closure#0}, 0): + push ebp + mov ebp, esp + push ebx + push edi + push esi + sub esp, 28 + call L2$pb +L2$pb: + pop ebx mov eax, dword ptr [ebp + 8] mov eax, dword ptr [eax] cmp byte ptr [eax], 0 mov byte ptr [eax], 0 - je LBB1_5 - mov eax, dword ptr [esi + LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-L1$pb] + je LBB2_10 + mov eax, dword ptr [ebx + LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-L2$pb] sub esp, 4 - lea edi, [esi + l_anon.[ID].11-L1$pb] + lea esi, [ebx + l_anon.[ID].21-L2$pb] push dword ptr [eax] push 15 - push edi + push esi call SYM(objc2::declare::ClassBuilder::new::GENERATED_ID, 0) add esp, 16 test eax, eax - je LBB1_6 - mov dword ptr [ebp - 16], eax + je LBB2_11 + mov dword ptr [ebp - 40], eax + mov eax, dword ptr [ebx + LL_OBJC_SELECTOR_REFERENCES_dealloc$non_lazy_ptr-L2$pb] sub esp, 8 - lea eax, [esi + l_anon.[ID].15-L1$pb] - lea ecx, [esi + L_anon.[ID].12-L1$pb] - lea ebx, [ebp - 16] - push eax - push 0 - push 1 - push 4 - push ecx - push ebx - call SYM(objc2::declare::ClassBuilder::add_ivar_inner_mono::GENERATED_ID, 0) - add esp, 24 - lea ecx, [esi + l_anon.[ID].2-L1$pb] - lea eax, [esi + L_anon.[ID].13-L1$pb] - push ecx - push 2 - push 4 - push 4 - push eax - push ebx - call SYM(objc2::declare::ClassBuilder::add_ivar_inner_mono::GENERATED_ID, 0) - add esp, 32 - mov eax, dword ptr [esi + LL_OBJC_SELECTOR_REFERENCES_dealloc$non_lazy_ptr-L1$pb] - sub esp, 8 - lea ecx, [esi + SYM(::class::{closure#0}::__objc2_dealloc, 0)-L1$pb] - lea edi, [esi + l_anon.[ID].3-L1$pb] - lea edx, [esi + l_anon.[ID].1-L1$pb] + lea ecx, [ebx + SYM(objc2[CRATE_ID]::__macro_helpers::declared_ivars::dealloc::, 0)-L2$pb] + lea edi, [ebx + l_anon.[ID].3-L2$pb] + lea esi, [ebx + l_anon.[ID].1-L2$pb] + lea edx, [ebp - 40] push ecx push edi push 0 - push edx - mov edi, edx + push esi push dword ptr [eax] - push ebx + push edx call SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) add esp, 32 - mov eax, dword ptr [esi + LL_OBJC_SELECTOR_REFERENCES_init$non_lazy_ptr-L1$pb] + mov eax, dword ptr [ebp - 40] + mov dword ptr [ebp - 16], eax + mov eax, dword ptr [ebx + LL_OBJC_SELECTOR_REFERENCES_init$non_lazy_ptr-L2$pb] sub esp, 8 - lea ecx, [esi + _init-L1$pb] - push ecx - lea ecx, [esi + l_anon.[ID].2-L1$pb] + lea ecx, [ebx + _init-L2$pb] + lea edx, [ebx + l_anon.[ID].2-L2$pb] + lea edi, [ebp - 16] push ecx + push edx push 0 - push edi + push esi push dword ptr [eax] - push ebx + push edi call SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) add esp, 24 - lea eax, [esi + _class_method-L1$pb] + lea eax, [ebx + _class_method-L2$pb] push eax - lea eax, [esi + l_anon.[ID].3-L1$pb] + lea eax, [ebx + l_anon.[ID].3-L2$pb] push eax push 0 + push esi + push dword ptr [ebx + L_OBJC_SELECTOR_REFERENCES_ddead4cf1cfe35ab-L2$pb] push edi - push dword ptr [esi + L_OBJC_SELECTOR_REFERENCES_d874ee9262978be2-L1$pb] - push ebx call SYM(objc2::declare::ClassBuilder::add_class_method_inner::GENERATED_ID, 0) add esp, 24 - lea eax, [esi + _method-L1$pb] + lea eax, [ebx + _method-L2$pb] push eax - lea eax, [esi + l_anon.[ID].3-L1$pb] + lea eax, [ebx + l_anon.[ID].3-L2$pb] push eax push 0 + push esi + push dword ptr [ebx + L_OBJC_SELECTOR_REFERENCES_8ee1155e2a63c707-L2$pb] push edi - push dword ptr [esi + L_OBJC_SELECTOR_REFERENCES_4539fd1dbda0cddc-L1$pb] - push ebx call SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) add esp, 24 - lea eax, [esi + _method_bool-L1$pb] - lea ecx, [esi + l_anon.[ID].4-L1$pb] + lea eax, [ebx + _method_bool-L2$pb] + lea esi, [ebx + l_anon.[ID].4-L2$pb] push eax - push ecx + push esi push 1 - push ecx - push dword ptr [esi + L_OBJC_SELECTOR_REFERENCES_2b1b3a94e0ece2e5-L1$pb] - push ebx + push esi + push dword ptr [ebx + L_OBJC_SELECTOR_REFERENCES_b1c6d8f625c88aa6-L2$pb] + push edi call SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) add esp, 24 - lea eax, [esi + _method_id-L1$pb] + lea eax, [ebx + _method_id-L2$pb] + push eax + lea eax, [ebx + l_anon.[ID].2-L2$pb] push eax - lea edi, [esi + l_anon.[ID].2-L1$pb] - push edi push 0 - lea eax, [esi + l_anon.[ID].1-L1$pb] + lea eax, [ebx + l_anon.[ID].1-L2$pb] push eax - push dword ptr [esi + L_OBJC_SELECTOR_REFERENCES_f7f521670860b0ce-L1$pb] - push ebx + push dword ptr [ebx + L_OBJC_SELECTOR_REFERENCES_f33da9321a226f33-L2$pb] + push edi call SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) add esp, 24 - lea eax, [esi + _method_id_with_param-L1$pb] + lea eax, [ebx + _method_id_with_param-L2$pb] push eax - push edi - push 1 - lea eax, [esi + l_anon.[ID].4-L1$pb] + lea eax, [ebx + l_anon.[ID].2-L2$pb] push eax - push dword ptr [esi + L_OBJC_SELECTOR_REFERENCES_6addfcf634c6232f-L1$pb] - push ebx + push 1 + push esi + push dword ptr [ebx + L_OBJC_SELECTOR_REFERENCES_e5d1ad528a5510d9-L2$pb] + push edi call SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) add esp, 24 - lea eax, [esi + l_anon.[ID].17-L1$pb] + lea eax, [ebx + l_anon.[ID].24-L2$pb] push 9 push eax call SYM(objc2::runtime::AnyProtocol::get::GENERATED_ID, 0) add esp, 16 test eax, eax - je LBB1_4 + je LBB2_4 sub esp, 8 push eax - push ebx + push edi call SYM(objc2::declare::ClassBuilder::add_protocol::GENERATED_ID, 0) add esp, 16 -LBB1_4: +LBB2_4: sub esp, 8 - lea eax, [esi + _copyWithZone-L1$pb] - lea ecx, [esi + l_anon.[ID].7-L1$pb] + lea eax, [ebx + _copyWithZone-L2$pb] + lea ecx, [ebx + l_anon.[ID].7-L2$pb] push eax - lea eax, [esi + l_anon.[ID].2-L1$pb] + lea eax, [ebx + l_anon.[ID].2-L2$pb] push eax push 1 push ecx - push dword ptr [esi + L_OBJC_SELECTOR_REFERENCES_4a8c690dbc9d8166-L1$pb] - push ebx + push dword ptr [ebx + L_OBJC_SELECTOR_REFERENCES_8daf9cd9e6dba6e3-L2$pb] + push edi call SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) + add esp, 32 + mov eax, dword ptr [ebp - 16] + mov dword ptr [ebp - 20], eax + mov dword ptr [ebp - 32], 0 + mov dword ptr [ebp - 36], 8 + lea eax, [ebx + l_anon.[ID].11-L2$pb] + mov dword ptr [ebp - 28], eax + mov byte ptr [ebp - 40], 27 + sub esp, 8 + lea edi, [ebx + l_anon.[ID].8-L2$pb] + lea esi, [ebp - 20] + lea eax, [ebp - 40] + push eax + push 2 + push 8 + push 5 + push edi + push esi + call SYM(objc2::declare::ClassBuilder::add_ivar_inner_mono::GENERATED_ID, 0) + add esp, 24 + lea eax, [ebx + l_anon.[ID].10-L2$pb] + lea ecx, [ebx + l_anon.[ID].9-L2$pb] + push eax + push 0 + push 1 + push 9 + push ecx + push esi + call SYM(objc2::declare::ClassBuilder::add_ivar_inner_mono::GENERATED_ID, 0) add esp, 20 - push dword ptr [ebp - 16] + push dword ptr [ebp - 20] call SYM(objc2::declare::ClassBuilder::register::GENERATED_ID, 0) + add esp, 16 + mov esi, eax + sub esp, 4 + push 5 + push edi + push eax + call SYM(objc2::runtime::AnyClass::instance_variable::GENERATED_ID, 0) + add esp, 16 + test eax, eax + je LBB2_5 + sub esp, 12 + push eax + call _ivar_getOffset + add esp, 16 + mov edi, eax + sub esp, 4 + push 9 + lea eax, [ebx + l_anon.[ID].9-L2$pb] + push eax + push esi + call SYM(objc2::runtime::AnyClass::instance_variable::GENERATED_ID, 0) + add esp, 16 + test eax, eax + je LBB2_8 + sub esp, 12 + push eax + call _ivar_getOffset + add esp, 16 + mov dword ptr [ebx + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_CLASS, 0).0-L2$pb], esi + mov dword ptr [ebx + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-L2$pb], edi + mov dword ptr [ebx + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)-L2$pb], eax add esp, 28 pop esi pop edi pop ebx pop ebp ret -LBB1_5: +LBB2_10: sub esp, 4 - lea eax, [esi + l_anon.[ID].10-L1$pb] - lea ecx, [esi + l_anon.[ID].8-L1$pb] + lea eax, [ebx + l_anon.[ID].18-L2$pb] + lea ecx, [ebx + l_anon.[ID].16-L2$pb] push eax push 43 push ecx call SYM(core::panicking::panic::GENERATED_ID, 0) -LBB1_6: +LBB2_11: sub esp, 4 - lea eax, [esi + l_anon.[ID].16-L1$pb] + lea eax, [ebx + l_anon.[ID].23-L2$pb] push eax push 15 - push edi + push esi call SYM(objc2::__macro_helpers::declare_class::failed_declaring_class::GENERATED_ID, 0) +LBB2_5: + sub esp, 4 + lea eax, [ebx + l_anon.[ID].14-L2$pb] + jmp LBB2_6 +LBB2_8: + sub esp, 4 + lea eax, [ebx + l_anon.[ID].15-L2$pb] +LBB2_6: + lea ecx, [ebx + l_anon.[ID].12-L2$pb] + push eax + push 59 + push ecx + call SYM(core::option::expect_failed::GENERATED_ID, 0) .p2align 4, 0x90 SYM(<::call_once<::class::{closure#0}>::{closure#0} as core[CRATE_ID]::ops::function::FnOnce<(&std[CRATE_ID]::sync::once::OnceState,)>>::call_once::{shim:vtable#0}, 0): @@ -205,35 +297,28 @@ _get_class: push edi push esi sub esp, 16 - call L3$pb -L3$pb: + call L4$pb +L4$pb: pop esi - mov eax, dword ptr [esi + SYM(::class::REGISTER_CLASS, 0)-L3$pb] + mov eax, dword ptr [esi + SYM(::class::REGISTER_CLASS, 0)-L4$pb] cmp eax, 3 - jne LBB3_1 -LBB3_2: - sub esp, 8 - lea eax, [esi + l_anon.[ID].11-L3$pb] - push 15 - push eax - call SYM(objc2::runtime::AnyClass::get::GENERATED_ID, 0) - add esp, 16 - test eax, eax - je LBB3_4 + jne LBB4_1 +LBB4_2: + mov eax, dword ptr [esi + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_CLASS, 0).0-L4$pb] add esp, 16 pop esi pop edi pop ebp ret -LBB3_1: +LBB4_1: mov byte ptr [ebp - 9], 1 lea eax, [ebp - 9] mov dword ptr [ebp - 16], eax sub esp, 12 - lea eax, [esi + l_anon.[ID].16-L3$pb] - lea ecx, [esi + l_anon.[ID].0-L3$pb] + lea eax, [esi + l_anon.[ID].23-L4$pb] + lea ecx, [esi + l_anon.[ID].0-L4$pb] lea edx, [ebp - 16] - lea edi, [esi + SYM(::class::REGISTER_CLASS, 0)-L3$pb] + lea edi, [esi + SYM(::class::REGISTER_CLASS, 0)-L4$pb] push eax push ecx push edx @@ -241,15 +326,7 @@ LBB3_1: push edi call SYM(std::sys_common::once::queue::Once::call::GENERATED_ID, 0) add esp, 32 - jmp LBB3_2 -LBB3_4: - sub esp, 4 - lea eax, [esi + l_anon.[ID].16-L3$pb] - lea ecx, [esi + l_anon.[ID].8-L3$pb] - push eax - push 43 - push ecx - call SYM(core::panicking::panic::GENERATED_ID, 0) + jmp LBB4_2 .globl _get_obj .p2align 4, 0x90 @@ -258,10 +335,10 @@ _get_obj: mov ebp, esp push esi push eax - call L4$pb -L4$pb: + call L5$pb +L5$pb: pop eax - mov eax, dword ptr [eax + LL_OBJC_SELECTOR_REFERENCES_new$non_lazy_ptr-L4$pb] + mov eax, dword ptr [eax + LL_OBJC_SELECTOR_REFERENCES_new$non_lazy_ptr-L5$pb] mov esi, dword ptr [eax] call _get_class sub esp, 8 @@ -279,37 +356,21 @@ _access_ivars: push ebp mov ebp, esp push ebx - push edi push esi - sub esp, 12 - call L5$pb -L5$pb: - pop edi + sub esp, 16 + call L6$pb +L6$pb: + pop esi call _get_obj - mov esi, eax - lea eax, [edi + L_anon.[ID].12-L5$pb] - mov dword ptr [esp + 4], eax - mov dword ptr [esp], esi - mov dword ptr [esp + 8], 4 - call SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) + mov ecx, dword ptr [esi + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-L6$pb] + movzx ebx, byte ptr [eax + ecx + 4] + mov esi, dword ptr [eax + ecx] mov dword ptr [esp], eax - call _ivar_getOffset - movzx ebx, byte ptr [esi + eax] - lea eax, [edi + L_anon.[ID].13-L5$pb] - mov dword ptr [esp + 4], eax - mov dword ptr [esp], esi - mov dword ptr [esp + 8], 4 - call SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - mov dword ptr [esp], eax - call _ivar_getOffset - mov edi, dword ptr [esi + eax] - mov dword ptr [esp], esi call _objc_release mov eax, ebx - mov edx, edi - add esp, 12 + mov edx, esi + add esp, 16 pop esi - pop edi pop ebx pop ebp ret @@ -322,35 +383,28 @@ SYM(::class::REGISTER_CLASS, 0)-L6$pb] + mov eax, dword ptr [esi + SYM(::class::REGISTER_CLASS, 0)-L7$pb] cmp eax, 3 - jne LBB6_1 -LBB6_2: - sub esp, 8 - lea eax, [esi + l_anon.[ID].11-L6$pb] - push 15 - push eax - call SYM(objc2::runtime::AnyClass::get::GENERATED_ID, 0) - add esp, 16 - test eax, eax - je LBB6_4 + jne LBB7_1 +LBB7_2: + mov eax, dword ptr [esi + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_CLASS, 0).0-L7$pb] add esp, 16 pop esi pop edi pop ebp ret -LBB6_1: +LBB7_1: mov byte ptr [ebp - 9], 1 lea eax, [ebp - 9] mov dword ptr [ebp - 16], eax sub esp, 12 - lea eax, [esi + l_anon.[ID].16-L6$pb] - lea ecx, [esi + l_anon.[ID].0-L6$pb] + lea eax, [esi + l_anon.[ID].23-L7$pb] + lea ecx, [esi + l_anon.[ID].0-L7$pb] lea edx, [ebp - 16] - lea edi, [esi + SYM(::class::REGISTER_CLASS, 0)-L6$pb] + lea edi, [esi + SYM(::class::REGISTER_CLASS, 0)-L7$pb] push eax push ecx push edx @@ -358,113 +412,52 @@ LBB6_1: push edi call SYM(std::sys_common::once::queue::Once::call::GENERATED_ID, 0) add esp, 32 - jmp LBB6_2 -LBB6_4: - sub esp, 4 - lea eax, [esi + l_anon.[ID].16-L6$pb] - lea ecx, [esi + l_anon.[ID].8-L6$pb] - push eax - push 43 - push ecx - call SYM(core::panicking::panic::GENERATED_ID, 0) - - .p2align 4, 0x90 -SYM(::class::{closure#0}::__objc2_dealloc, 0): - push ebp - mov ebp, esp - push ebx - push edi - push esi - sub esp, 28 - call L7$pb -L7$pb: - pop ebx - mov esi, dword ptr [ebp + 12] - mov edi, dword ptr [ebp + 8] - lea eax, [ebx + L_anon.[ID].13-L7$pb] - mov dword ptr [esp + 4], eax - mov dword ptr [esp], edi - mov dword ptr [esp + 8], 4 - call SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - mov dword ptr [esp], eax - call _ivar_getOffset - mov eax, dword ptr [edi + eax] - test eax, eax - je LBB7_2 - mov dword ptr [esp], eax - call _objc_release -LBB7_2: - mov eax, dword ptr [ebx + LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-L7$pb] - mov eax, dword ptr [eax] - mov dword ptr [ebp - 20], edi - mov dword ptr [ebp - 16], eax - mov dword ptr [esp + 4], esi - lea eax, [ebp - 20] - mov dword ptr [esp], eax - call _objc_msgSendSuper - add esp, 28 - pop esi - pop edi - pop ebx - pop ebp - ret + jmp LBB7_2 .globl _init .p2align 4, 0x90 _init: push ebp mov ebp, esp - push edi - push esi - sub esp, 16 + sub esp, 24 call L8$pb L8$pb: - pop edi - mov eax, dword ptr [ebp + 8] - mov ecx, dword ptr [edi + LL_OBJC_SELECTOR_REFERENCES_init$non_lazy_ptr-L8$pb] - mov ecx, dword ptr [ecx] - mov edx, dword ptr [edi + LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-L8$pb] - mov edx, dword ptr [edx] - mov dword ptr [ebp - 16], eax - mov dword ptr [ebp - 12], edx + pop eax + mov ecx, dword ptr [ebp + 8] + test ecx, ecx + je LBB8_2 + mov edx, dword ptr [eax + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-L8$pb] + mov dword ptr [ecx + edx], 0 + mov byte ptr [ecx + edx + 4], 42 + mov edx, dword ptr [eax + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)-L8$pb] + mov byte ptr [ecx + edx], 1 + mov edx, dword ptr [eax + L_OBJC_SELECTOR_REFERENCES_74641ed6f72d2d44-L8$pb] + mov eax, dword ptr [eax + LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-L8$pb] + mov eax, dword ptr [eax] + mov dword ptr [ebp - 24], ecx + mov dword ptr [ebp - 20], eax sub esp, 8 - lea eax, [ebp - 16] - push ecx + lea eax, [ebp - 24] + push edx push eax call _objc_msgSendSuper - add esp, 16 - mov esi, eax - test eax, eax - je LBB8_2 - sub esp, 4 - lea eax, [edi + L_anon.[ID].12-L8$pb] - push 4 - push eax - push esi - call SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - add esp, 4 - push eax - call _ivar_getOffset - add esp, 16 - mov byte ptr [esi + eax], 42 - sub esp, 4 - lea eax, [edi + L_anon.[ID].13-L8$pb] - push 4 - push eax - push esi - call SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - add esp, 4 - push eax - call _ivar_getOffset - add esp, 16 - mov dword ptr [esi + eax], 0 -LBB8_2: - mov eax, esi - add esp, 16 - pop esi - pop edi + add esp, 40 pop ebp ret +LBB8_2: + lea ecx, [eax + l_anon.[ID].20-L8$pb] + mov dword ptr [ebp - 24], ecx + mov dword ptr [ebp - 20], 1 + mov dword ptr [ebp - 8], 0 + lea ecx, [eax + l_anon.[ID].1-L8$pb] + mov dword ptr [ebp - 16], ecx + mov dword ptr [ebp - 12], 0 + sub esp, 8 + lea eax, [eax + l_anon.[ID].25-L8$pb] + lea ecx, [ebp - 24] + push eax + push ecx + call SYM(core::panicking::panic_fmt::GENERATED_ID, 0) .globl _class_method .p2align 4, 0x90 @@ -498,20 +491,13 @@ _method_bool: _method_id: push ebp mov ebp, esp - push esi - sub esp, 20 + sub esp, 8 call L12$pb L12$pb: pop eax - mov esi, dword ptr [ebp + 8] - lea eax, [eax + L_anon.[ID].13-L12$pb] - mov dword ptr [esp + 4], eax - mov dword ptr [esp], esi - mov dword ptr [esp + 8], 4 - call SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - mov dword ptr [esp], eax - call _ivar_getOffset - mov eax, dword ptr [esi + eax] + mov ecx, dword ptr [ebp + 8] + mov eax, dword ptr [eax + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-L12$pb] + mov eax, dword ptr [ecx + eax] test eax, eax je LBB12_1 mov dword ptr [esp], eax @@ -522,8 +508,7 @@ LBB12_1: LBB12_3: mov dword ptr [esp], eax call _objc_autoreleaseReturnValue - add esp, 20 - pop esi + add esp, 8 pop ebp ret @@ -532,26 +517,19 @@ LBB12_3: _method_id_with_param: push ebp mov ebp, esp - push ebx push edi push esi - sub esp, 12 + sub esp, 16 call L13$pb L13$pb: - pop ebx + pop edi call SYM(objc2::runtime::nsobject::NSObject::new::GENERATED_ID, 0) mov esi, eax cmp byte ptr [ebp + 16], 0 je LBB13_5 - mov edi, dword ptr [ebp + 8] - lea eax, [ebx + L_anon.[ID].13-L13$pb] - mov dword ptr [esp + 4], eax - mov dword ptr [esp], edi - mov dword ptr [esp + 8], 4 - call SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - mov dword ptr [esp], eax - call _ivar_getOffset - mov eax, dword ptr [edi + eax] + mov eax, dword ptr [ebp + 8] + mov ecx, dword ptr [edi + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-L13$pb] + mov eax, dword ptr [eax + ecx] test eax, eax je LBB13_2 mov dword ptr [esp], eax @@ -567,10 +545,9 @@ LBB13_4: LBB13_5: mov dword ptr [esp], esi call _objc_autoreleaseReturnValue - add esp, 12 + add esp, 16 pop esi pop edi - pop ebx pop ebp ret @@ -585,62 +562,90 @@ _copyWithZone: sub esp, 28 call L14$pb L14$pb: - pop ebx - call _get_obj + pop edi + mov ebx, dword ptr [ebp + 8] + mov eax, dword ptr [edi + LL_OBJC_SELECTOR_REFERENCES_alloc$non_lazy_ptr-L14$pb] + mov esi, dword ptr [eax] + mov eax, dword ptr [edi + SYM(::class::REGISTER_CLASS, 0)-L14$pb] + cmp eax, 3 + jne LBB14_1 +LBB14_2: + sub esp, 8 + push esi + push dword ptr [edi + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_CLASS, 0).0-L14$pb] + call _objc_msgSend + add esp, 16 mov esi, eax + mov eax, dword ptr [edi + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-L14$pb] + mov ecx, ebx + movzx ebx, byte ptr [ebx + eax + 4] + mov eax, dword ptr [ecx + eax] test eax, eax - je LBB14_5 - mov edi, dword ptr [ebp + 8] - lea ecx, [ebx + L_anon.[ID].12-L14$pb] - mov dword ptr [esp + 4], ecx - mov dword ptr [esp], edi - mov dword ptr [esp + 8], 4 - call SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - mov dword ptr [esp], eax - call _ivar_getOffset - movzx eax, byte ptr [edi + eax] - mov byte ptr [ebp - 13], al - lea eax, [ebx + L_anon.[ID].12-L14$pb] - mov dword ptr [esp + 4], eax - mov dword ptr [esp], esi - mov dword ptr [esp + 8], 4 - call SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - mov dword ptr [esp], eax - call _ivar_getOffset - movzx ecx, byte ptr [ebp - 13] - mov byte ptr [esi + eax], cl - lea ebx, [ebx + L_anon.[ID].13-L14$pb] - mov dword ptr [esp + 4], ebx - mov dword ptr [esp], edi - mov dword ptr [esp + 8], 4 - call SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - mov dword ptr [esp], eax - call _ivar_getOffset - mov eax, dword ptr [edi + eax] - test eax, eax - je LBB14_2 - mov dword ptr [esp], eax + je LBB14_3 + sub esp, 12 + push eax call _objc_retain - mov edi, eax - jmp LBB14_4 -LBB14_2: - xor edi, edi -LBB14_4: - mov dword ptr [esp + 4], ebx - mov dword ptr [esp], esi - mov dword ptr [esp + 8], 4 - call SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - mov dword ptr [esp], eax - call _ivar_getOffset - mov dword ptr [esi + eax], edi -LBB14_5: - mov eax, esi - add esp, 28 + add esp, 16 + test esi, esi + je LBB14_7 +LBB14_6: + mov ecx, dword ptr [edi + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)-L14$pb] + mov dword ptr [esi + ecx], eax + mov byte ptr [esi + ecx + 4], bl + mov eax, dword ptr [edi + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)-L14$pb] + mov byte ptr [esi + eax], 1 + mov eax, dword ptr [edi + L_OBJC_SELECTOR_REFERENCES_a4c8ca93c4279f29-L14$pb] + mov ecx, dword ptr [edi + LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr-L14$pb] + mov ecx, dword ptr [ecx] + mov dword ptr [ebp - 40], esi + mov dword ptr [ebp - 36], ecx + sub esp, 8 + lea ecx, [ebp - 40] + push eax + push ecx + call _objc_msgSendSuper + add esp, 44 pop esi pop edi pop ebx pop ebp ret +LBB14_3: + xor eax, eax + test esi, esi + jne LBB14_6 +LBB14_7: + lea eax, [edi + l_anon.[ID].20-L14$pb] + mov dword ptr [ebp - 40], eax + mov dword ptr [ebp - 36], 1 + mov dword ptr [ebp - 24], 0 + lea eax, [edi + l_anon.[ID].1-L14$pb] + mov dword ptr [ebp - 32], eax + mov dword ptr [ebp - 28], 0 + sub esp, 8 + lea eax, [edi + l_anon.[ID].26-L14$pb] + lea ecx, [ebp - 40] + push eax + push ecx + call SYM(core::panicking::panic_fmt::GENERATED_ID, 0) +LBB14_1: + mov byte ptr [ebp - 13], 1 + lea eax, [ebp - 13] + mov dword ptr [ebp - 40], eax + sub esp, 12 + lea eax, [edi + l_anon.[ID].23-L14$pb] + lea ecx, [edi + l_anon.[ID].0-L14$pb] + lea edx, [ebp - 40] + lea ebx, [edi + SYM(::class::REGISTER_CLASS, 0)-L14$pb] + push eax + push ecx + push edx + push 0 + push ebx + mov ebx, dword ptr [ebp + 8] + call SYM(std::sys_common::once::queue::Once::call::GENERATED_ID, 0) + add esp, 32 + jmp LBB14_2 .section __DATA,__const .p2align 2, 0x0 @@ -692,154 +697,239 @@ l_anon.[ID].7: .section __TEXT,__const l_anon.[ID].8: - .ascii "called `Option::unwrap()` on a `None` value" + .ascii "ivars" l_anon.[ID].9: - .ascii "$RUSTC/library/std/src/sync/once.rs" + .ascii "drop_flag" - .section __DATA,__const .p2align 2, 0x0 l_anon.[ID].10: - .long l_anon.[ID].9 - .asciz "p\000\000\000\225\000\000\0002\000\000" + .byte 5 + .space 19 - .section __TEXT,__const + .p2align 2, 0x0 l_anon.[ID].11: - .ascii "CustomClassName" + .byte 7 + .space 19 - .section __TEXT,__literal4,4byte_literals -L_anon.[ID].12: - .ascii "_foo" +l_anon.[ID].12: + .ascii "failed retrieving instance variable on newly declared class" -L_anon.[ID].13: - .ascii "_obj" +l_anon.[ID].13: + .ascii "$WORKSPACE/objc2/src/__macro_helpers/declared_ivars.rs" - .section __TEXT,__const + .section __DATA,__const + .p2align 2, 0x0 l_anon.[ID].14: - .ascii "crates/$DIR/lib.rs" + .long l_anon.[ID].13 + .asciz "T\000\000\000\363\000\000\000\016\000\000" .p2align 2, 0x0 l_anon.[ID].15: - .byte 5 - .space 19 + .long l_anon.[ID].13 + .asciz "T\000\000\000\377\000\000\000\016\000\000" + + .section __TEXT,__const +l_anon.[ID].16: + .ascii "called `Option::unwrap()` on a `None` value" + +l_anon.[ID].17: + .ascii "$RUSTC/library/std/src/sync/once.rs" .section __DATA,__const .p2align 2, 0x0 -l_anon.[ID].16: - .long l_anon.[ID].14 - .asciz "5\000\000\000\f\000\000\000\001\000\000" +l_anon.[ID].18: + .long l_anon.[ID].17 + .asciz "p\000\000\000\225\000\000\0002\000\000" + + .section __TEXT,__const +l_anon.[ID].19: + .ascii "tried to initialize instance variables on NULL allocated object" + + .section __DATA,__const + .p2align 2, 0x0 +l_anon.[ID].20: + .long l_anon.[ID].19 + .asciz "?\000\000" + + .section __TEXT,__const +l_anon.[ID].21: + .ascii "CustomClassName" + +l_anon.[ID].22: + .ascii "crates/$DIR/lib.rs" + +.zerofill __DATA,__bss,SYM(test_declare_class[CRATE_ID]::_::__OBJC2_CLASS, 0).0,4,2 + .globl SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0) +.zerofill __DATA,__common,SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0),4,2 + .globl SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0) +.zerofill __DATA,__common,SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0),4,2 + .section __DATA,__const + .p2align 2, 0x0 +l_anon.[ID].23: + .long l_anon.[ID].22 + .asciz "5\000\000\000\021\000\000\000\001\000\000" .zerofill __DATA,__bss,SYM(::class::REGISTER_CLASS, 0),4,2 .section __TEXT,__const -l_anon.[ID].17: +l_anon.[ID].24: .ascii "NSCopying" .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_d874ee9262978be2 -L_OBJC_METH_VAR_NAME_d874ee9262978be2: + .globl L_OBJC_METH_VAR_NAME_ddead4cf1cfe35ab +L_OBJC_METH_VAR_NAME_ddead4cf1cfe35ab: .asciz "classMethod" .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_d874ee9262978be2 + .globl L_OBJC_SELECTOR_REFERENCES_ddead4cf1cfe35ab .p2align 2, 0x0 -L_OBJC_SELECTOR_REFERENCES_d874ee9262978be2: - .long L_OBJC_METH_VAR_NAME_d874ee9262978be2 +L_OBJC_SELECTOR_REFERENCES_ddead4cf1cfe35ab: + .long L_OBJC_METH_VAR_NAME_ddead4cf1cfe35ab .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_d874ee9262978be2 + .globl L_OBJC_IMAGE_INFO_ddead4cf1cfe35ab .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_d874ee9262978be2: +L_OBJC_IMAGE_INFO_ddead4cf1cfe35ab: .asciz "\000\000\000\000@\000\000" .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_4539fd1dbda0cddc -L_OBJC_METH_VAR_NAME_4539fd1dbda0cddc: + .globl L_OBJC_METH_VAR_NAME_8ee1155e2a63c707 +L_OBJC_METH_VAR_NAME_8ee1155e2a63c707: .asciz "method" .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_4539fd1dbda0cddc + .globl L_OBJC_SELECTOR_REFERENCES_8ee1155e2a63c707 .p2align 2, 0x0 -L_OBJC_SELECTOR_REFERENCES_4539fd1dbda0cddc: - .long L_OBJC_METH_VAR_NAME_4539fd1dbda0cddc +L_OBJC_SELECTOR_REFERENCES_8ee1155e2a63c707: + .long L_OBJC_METH_VAR_NAME_8ee1155e2a63c707 .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_4539fd1dbda0cddc + .globl L_OBJC_IMAGE_INFO_8ee1155e2a63c707 .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_4539fd1dbda0cddc: +L_OBJC_IMAGE_INFO_8ee1155e2a63c707: .asciz "\000\000\000\000@\000\000" .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_2b1b3a94e0ece2e5 -L_OBJC_METH_VAR_NAME_2b1b3a94e0ece2e5: + .globl L_OBJC_METH_VAR_NAME_b1c6d8f625c88aa6 +L_OBJC_METH_VAR_NAME_b1c6d8f625c88aa6: .asciz "methodBool:" .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_2b1b3a94e0ece2e5 + .globl L_OBJC_SELECTOR_REFERENCES_b1c6d8f625c88aa6 .p2align 2, 0x0 -L_OBJC_SELECTOR_REFERENCES_2b1b3a94e0ece2e5: - .long L_OBJC_METH_VAR_NAME_2b1b3a94e0ece2e5 +L_OBJC_SELECTOR_REFERENCES_b1c6d8f625c88aa6: + .long L_OBJC_METH_VAR_NAME_b1c6d8f625c88aa6 .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_2b1b3a94e0ece2e5 + .globl L_OBJC_IMAGE_INFO_b1c6d8f625c88aa6 .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_2b1b3a94e0ece2e5: +L_OBJC_IMAGE_INFO_b1c6d8f625c88aa6: .asciz "\000\000\000\000@\000\000" .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_f7f521670860b0ce -L_OBJC_METH_VAR_NAME_f7f521670860b0ce: + .globl L_OBJC_METH_VAR_NAME_f33da9321a226f33 +L_OBJC_METH_VAR_NAME_f33da9321a226f33: .asciz "methodId" .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_f7f521670860b0ce + .globl L_OBJC_SELECTOR_REFERENCES_f33da9321a226f33 .p2align 2, 0x0 -L_OBJC_SELECTOR_REFERENCES_f7f521670860b0ce: - .long L_OBJC_METH_VAR_NAME_f7f521670860b0ce +L_OBJC_SELECTOR_REFERENCES_f33da9321a226f33: + .long L_OBJC_METH_VAR_NAME_f33da9321a226f33 .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_f7f521670860b0ce + .globl L_OBJC_IMAGE_INFO_f33da9321a226f33 .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_f7f521670860b0ce: +L_OBJC_IMAGE_INFO_f33da9321a226f33: .asciz "\000\000\000\000@\000\000" .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_6addfcf634c6232f -L_OBJC_METH_VAR_NAME_6addfcf634c6232f: + .globl L_OBJC_METH_VAR_NAME_e5d1ad528a5510d9 +L_OBJC_METH_VAR_NAME_e5d1ad528a5510d9: .asciz "methodIdWithParam:" .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_6addfcf634c6232f + .globl L_OBJC_SELECTOR_REFERENCES_e5d1ad528a5510d9 .p2align 2, 0x0 -L_OBJC_SELECTOR_REFERENCES_6addfcf634c6232f: - .long L_OBJC_METH_VAR_NAME_6addfcf634c6232f +L_OBJC_SELECTOR_REFERENCES_e5d1ad528a5510d9: + .long L_OBJC_METH_VAR_NAME_e5d1ad528a5510d9 .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_6addfcf634c6232f + .globl L_OBJC_IMAGE_INFO_e5d1ad528a5510d9 .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_6addfcf634c6232f: +L_OBJC_IMAGE_INFO_e5d1ad528a5510d9: .asciz "\000\000\000\000@\000\000" .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_4a8c690dbc9d8166 -L_OBJC_METH_VAR_NAME_4a8c690dbc9d8166: + .globl L_OBJC_METH_VAR_NAME_8daf9cd9e6dba6e3 +L_OBJC_METH_VAR_NAME_8daf9cd9e6dba6e3: .asciz "copyWithZone:" .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_4a8c690dbc9d8166 + .globl L_OBJC_SELECTOR_REFERENCES_8daf9cd9e6dba6e3 .p2align 2, 0x0 -L_OBJC_SELECTOR_REFERENCES_4a8c690dbc9d8166: - .long L_OBJC_METH_VAR_NAME_4a8c690dbc9d8166 +L_OBJC_SELECTOR_REFERENCES_8daf9cd9e6dba6e3: + .long L_OBJC_METH_VAR_NAME_8daf9cd9e6dba6e3 .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_4a8c690dbc9d8166 + .globl L_OBJC_IMAGE_INFO_8daf9cd9e6dba6e3 .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_4a8c690dbc9d8166: +L_OBJC_IMAGE_INFO_8daf9cd9e6dba6e3: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__const + .p2align 2, 0x0 +l_anon.[ID].25: + .long l_anon.[ID].22 + .asciz "5\000\000\000#\000\000\000\035\000\000" + + .section __TEXT,__objc_methname,cstring_literals + .globl L_OBJC_METH_VAR_NAME_74641ed6f72d2d44 +L_OBJC_METH_VAR_NAME_74641ed6f72d2d44: + .asciz "init" + + .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip + .globl L_OBJC_SELECTOR_REFERENCES_74641ed6f72d2d44 + .p2align 2, 0x0 +L_OBJC_SELECTOR_REFERENCES_74641ed6f72d2d44: + .long L_OBJC_METH_VAR_NAME_74641ed6f72d2d44 + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_74641ed6f72d2d44 + .p2align 2, 0x0 +L_OBJC_IMAGE_INFO_74641ed6f72d2d44: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__const + .p2align 2, 0x0 +l_anon.[ID].26: + .long l_anon.[ID].22 + .asciz "5\000\000\000N\000\000\000\033\000\000" + + .section __TEXT,__objc_methname,cstring_literals + .globl L_OBJC_METH_VAR_NAME_a4c8ca93c4279f29 +L_OBJC_METH_VAR_NAME_a4c8ca93c4279f29: + .asciz "init" + + .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip + .globl L_OBJC_SELECTOR_REFERENCES_a4c8ca93c4279f29 + .p2align 2, 0x0 +L_OBJC_SELECTOR_REFERENCES_a4c8ca93c4279f29: + .long L_OBJC_METH_VAR_NAME_a4c8ca93c4279f29 + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_a4c8ca93c4279f29 + .p2align 2, 0x0 +L_OBJC_IMAGE_INFO_a4c8ca93c4279f29: .asciz "\000\000\000\000@\000\000" .section __IMPORT,__pointers,non_lazy_symbol_pointers LL_OBJC_CLASSLIST_REFERENCES_$_NSObject$non_lazy_ptr: .indirect_symbol L_OBJC_CLASSLIST_REFERENCES_$_NSObject .long 0 +LL_OBJC_SELECTOR_REFERENCES_alloc$non_lazy_ptr: + .indirect_symbol L_OBJC_SELECTOR_REFERENCES_alloc + .long 0 LL_OBJC_SELECTOR_REFERENCES_dealloc$non_lazy_ptr: .indirect_symbol L_OBJC_SELECTOR_REFERENCES_dealloc .long 0 diff --git a/crates/test-assembly/crates/test_declare_class/expected/apple-x86_64.s b/crates/test-assembly/crates/test_declare_class/expected/apple-x86_64.s index 0c9c9cb7f..a60291154 100644 --- a/crates/test-assembly/crates/test_declare_class/expected/apple-x86_64.s +++ b/crates/test-assembly/crates/test_declare_class/expected/apple-x86_64.s @@ -7,6 +7,37 @@ SYM(core[CRATE_ID]::ptr::drop_in_place::<::call pop rbp ret + .p2align 4, 0x90 +SYM(objc2[CRATE_ID]::__macro_helpers::declared_ivars::dealloc::, 0): + push rbp + mov rbp, rsp + push r14 + push rbx + sub rsp, 16 + mov rbx, rsi + mov r14, rdi + mov rax, qword ptr [rip + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)] + cmp byte ptr [rdi + rax], 0 + je LBB1_3 + mov rax, qword ptr [rip + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)] + mov rdi, qword ptr [r14 + rax] + test rdi, rdi + je LBB1_3 + call _objc_release +LBB1_3: + mov rax, qword ptr [rip + L_OBJC_CLASSLIST_REFERENCES_$_NSObject@GOTPCREL] + mov rax, qword ptr [rax] + mov qword ptr [rbp - 32], r14 + mov qword ptr [rbp - 24], rax + lea rdi, [rbp - 32] + mov rsi, rbx + call _objc_msgSendSuper + add rsp, 16 + pop rbx + pop r14 + pop rbp + ret + .p2align 4, 0x90 SYM(::call_once::<::class::{closure#0}>::{closure#0}, 0): push rbp @@ -15,124 +46,165 @@ SYM(::call_once::<::class::{closure#0}::__objc2_dealloc, 0)] - mov rdi, rbx - mov rdx, r15 + lea r9, [rip + SYM(objc2[CRATE_ID]::__macro_helpers::declared_ivars::dealloc::, 0)] + lea rdi, [rbp - 88] + mov rdx, rbx xor ecx, ecx mov r8, r12 call SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) + mov rax, qword ptr [rbp - 88] + mov qword ptr [rbp - 40], rax mov rax, qword ptr [rip + L_OBJC_SELECTOR_REFERENCES_init@GOTPCREL] mov rsi, qword ptr [rax] + lea r14, [rip + l_anon.[ID].2] lea r9, [rip + _init] - mov rdi, rbx - mov rdx, r15 + lea r15, [rbp - 40] + mov rdi, r15 + mov rdx, rbx xor ecx, ecx mov r8, r14 call SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) - mov rsi, qword ptr [rip + L_OBJC_SELECTOR_REFERENCES_d874ee9262978be2] + mov rsi, qword ptr [rip + L_OBJC_SELECTOR_REFERENCES_ddead4cf1cfe35ab] lea r9, [rip + _class_method] - mov rdi, rbx - mov rdx, r15 + mov rdi, r15 + mov rdx, rbx xor ecx, ecx mov r8, r12 call SYM(objc2::declare::ClassBuilder::add_class_method_inner::GENERATED_ID, 0) - mov rsi, qword ptr [rip + L_OBJC_SELECTOR_REFERENCES_4539fd1dbda0cddc] + mov rsi, qword ptr [rip + L_OBJC_SELECTOR_REFERENCES_8ee1155e2a63c707] lea r9, [rip + _method] - mov rdi, rbx - mov rdx, r15 + mov rdi, r15 + mov rdx, rbx xor ecx, ecx mov r8, r12 call SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) - mov rsi, qword ptr [rip + L_OBJC_SELECTOR_REFERENCES_2b1b3a94e0ece2e5] + mov rsi, qword ptr [rip + L_OBJC_SELECTOR_REFERENCES_b1c6d8f625c88aa6] lea r12, [rip + l_anon.[ID].4] lea r9, [rip + _method_bool] mov ecx, 1 - mov rdi, rbx + mov rdi, r15 mov rdx, r12 mov r8, r12 call SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) - mov rsi, qword ptr [rip + L_OBJC_SELECTOR_REFERENCES_f7f521670860b0ce] + mov rsi, qword ptr [rip + L_OBJC_SELECTOR_REFERENCES_f33da9321a226f33] lea r9, [rip + _method_id] - mov rdi, rbx - mov rdx, r15 + mov rdi, r15 + mov rdx, rbx xor ecx, ecx mov r8, r14 call SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) - mov rsi, qword ptr [rip + L_OBJC_SELECTOR_REFERENCES_6addfcf634c6232f] + mov rsi, qword ptr [rip + L_OBJC_SELECTOR_REFERENCES_e5d1ad528a5510d9] lea r9, [rip + _method_id_with_param] mov ecx, 1 - mov rdi, rbx + mov rdi, r15 mov rdx, r12 mov r8, r14 call SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) - lea rdi, [rip + l_anon.[ID].17] + lea rdi, [rip + l_anon.[ID].24] mov esi, 9 call SYM(objc2::runtime::AnyProtocol::get::GENERATED_ID, 0) test rax, rax - je LBB1_4 + je LBB2_4 lea rdi, [rbp - 40] mov rsi, rax call SYM(objc2::declare::ClassBuilder::add_protocol::GENERATED_ID, 0) -LBB1_4: - mov rsi, qword ptr [rip + L_OBJC_SELECTOR_REFERENCES_4a8c690dbc9d8166] +LBB2_4: + mov rsi, qword ptr [rip + L_OBJC_SELECTOR_REFERENCES_8daf9cd9e6dba6e3] lea rdx, [rip + l_anon.[ID].7] lea r8, [rip + l_anon.[ID].2] lea r9, [rip + _copyWithZone] lea rdi, [rbp - 40] mov ecx, 1 call SYM(objc2::declare::ClassBuilder::add_method_inner::GENERATED_ID, 0) - mov rdi, qword ptr [rbp - 40] + mov rax, qword ptr [rbp - 40] + mov qword ptr [rbp - 48], rax + mov qword ptr [rbp - 80], 16 + lea rax, [rip + l_anon.[ID].11] + mov qword ptr [rbp - 72], rax + mov byte ptr [rbp - 88], 27 + lea r14, [rip + l_anon.[ID].8] + lea rbx, [rbp - 48] + lea r9, [rbp - 88] + mov edx, 5 + mov ecx, 16 + mov rdi, rbx + mov rsi, r14 + mov r8d, 3 + call SYM(objc2::declare::ClassBuilder::add_ivar_inner_mono::GENERATED_ID, 0) + lea rsi, [rip + l_anon.[ID].9] + lea r9, [rip + l_anon.[ID].10] + mov edx, 9 + mov ecx, 1 + mov rdi, rbx + xor r8d, r8d + call SYM(objc2::declare::ClassBuilder::add_ivar_inner_mono::GENERATED_ID, 0) + mov rdi, qword ptr [rbp - 48] call SYM(objc2::declare::ClassBuilder::register::GENERATED_ID, 0) - add rsp, 16 + mov rbx, rax + mov edx, 5 + mov rdi, rax + mov rsi, r14 + call SYM(objc2::runtime::AnyClass::instance_variable::GENERATED_ID, 0) + test rax, rax + je LBB2_9 + mov rdi, rax + call _ivar_getOffset + mov r14, rax + lea rsi, [rip + l_anon.[ID].9] + mov edx, 9 + mov rdi, rbx + call SYM(objc2::runtime::AnyClass::instance_variable::GENERATED_ID, 0) + test rax, rax + je LBB2_10 + mov rdi, rax + call _ivar_getOffset + mov qword ptr [rip + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_CLASS, 0).0], rbx + mov qword ptr [rip + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)], r14 + mov qword ptr [rip + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)], rax + add rsp, 64 pop rbx pop r12 pop r14 pop r15 pop rbp ret -LBB1_5: - lea rdi, [rip + l_anon.[ID].8] - lea rdx, [rip + l_anon.[ID].10] +LBB2_7: + lea rdi, [rip + l_anon.[ID].16] + lea rdx, [rip + l_anon.[ID].18] mov esi, 43 call SYM(core::panicking::panic::GENERATED_ID, 0) -LBB1_6: - lea rdi, [rip + l_anon.[ID].11] - lea rdx, [rip + l_anon.[ID].16] +LBB2_8: + lea rdi, [rip + l_anon.[ID].21] + lea rdx, [rip + l_anon.[ID].23] mov esi, 15 call SYM(objc2::__macro_helpers::declare_class::failed_declaring_class::GENERATED_ID, 0) +LBB2_9: + lea rdi, [rip + l_anon.[ID].12] + lea rdx, [rip + l_anon.[ID].14] + mov esi, 59 + call SYM(core::option::expect_failed::GENERATED_ID, 0) +LBB2_10: + lea rdi, [rip + l_anon.[ID].12] + lea rdx, [rip + l_anon.[ID].15] + mov esi, 59 + call SYM(core::option::expect_failed::GENERATED_ID, 0) .p2align 4, 0x90 SYM(<::call_once<::class::{closure#0}>::{closure#0} as core[CRATE_ID]::ops::function::FnOnce<(&std[CRATE_ID]::sync::once::OnceState,)>>::call_once::{shim:vtable#0}, 0): @@ -150,37 +222,28 @@ SYM(<::call_once<::class::REGISTER_CLASS, 0)] cmp rax, 3 - jne LBB3_1 -LBB3_2: - lea rdi, [rip + l_anon.[ID].11] - mov esi, 15 - call SYM(objc2::runtime::AnyClass::get::GENERATED_ID, 0) - test rax, rax - je LBB3_4 - add rsp, 16 - pop rbp + jne LBB4_1 + mov rax, qword ptr [rip + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_CLASS, 0).0] ret -LBB3_1: +LBB4_1: + push rbp + mov rbp, rsp + sub rsp, 16 mov byte ptr [rbp - 1], 1 lea rax, [rbp - 1] mov qword ptr [rbp - 16], rax lea rdi, [rip + SYM(::class::REGISTER_CLASS, 0)] lea rcx, [rip + l_anon.[ID].0] - lea r8, [rip + l_anon.[ID].16] + lea r8, [rip + l_anon.[ID].23] lea rdx, [rbp - 16] xor esi, esi call SYM(std::sys_common::once::queue::Once::call::GENERATED_ID, 0) - jmp LBB3_2 -LBB3_4: - lea rdi, [rip + l_anon.[ID].8] - lea rdx, [rip + l_anon.[ID].16] - mov esi, 43 - call SYM(core::panicking::panic::GENERATED_ID, 0) + add rsp, 16 + pop rbp + mov rax, qword ptr [rip + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_CLASS, 0).0] + ret .globl _get_obj .p2align 4, 0x90 @@ -204,102 +267,45 @@ _get_obj: _access_ivars: push rbp mov rbp, rsp - push r15 push r14 push rbx - push rax call _get_obj - mov rbx, rax - lea rsi, [rip + L_anon.[ID].12] - mov edx, 4 - mov rdi, rax - call SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) + mov rcx, qword ptr [rip + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)] + movzx ebx, byte ptr [rax + rcx + 8] + mov r14, qword ptr [rax + rcx] mov rdi, rax - call _ivar_getOffset - movzx r14d, byte ptr [rbx + rax] - lea rsi, [rip + L_anon.[ID].13] - mov edx, 4 - mov rdi, rbx - call SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - mov rdi, rax - call _ivar_getOffset - mov r15, qword ptr [rbx + rax] - mov rdi, rbx call _objc_release - mov eax, r14d - mov rdx, r15 - add rsp, 8 + mov eax, ebx + mov rdx, r14 pop rbx pop r14 - pop r15 pop rbp ret .globl SYM(::class, 0) .p2align 4, 0x90 SYM(::class, 0): - push rbp - mov rbp, rsp - sub rsp, 16 mov rax, qword ptr [rip + SYM(::class::REGISTER_CLASS, 0)] cmp rax, 3 - jne LBB6_1 -LBB6_2: - lea rdi, [rip + l_anon.[ID].11] - mov esi, 15 - call SYM(objc2::runtime::AnyClass::get::GENERATED_ID, 0) - test rax, rax - je LBB6_4 - add rsp, 16 - pop rbp + jne LBB7_1 + mov rax, qword ptr [rip + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_CLASS, 0).0] ret -LBB6_1: +LBB7_1: + push rbp + mov rbp, rsp + sub rsp, 16 mov byte ptr [rbp - 1], 1 lea rax, [rbp - 1] mov qword ptr [rbp - 16], rax lea rdi, [rip + SYM(::class::REGISTER_CLASS, 0)] lea rcx, [rip + l_anon.[ID].0] - lea r8, [rip + l_anon.[ID].16] + lea r8, [rip + l_anon.[ID].23] lea rdx, [rbp - 16] xor esi, esi call SYM(std::sys_common::once::queue::Once::call::GENERATED_ID, 0) - jmp LBB6_2 -LBB6_4: - lea rdi, [rip + l_anon.[ID].8] - lea rdx, [rip + l_anon.[ID].16] - mov esi, 43 - call SYM(core::panicking::panic::GENERATED_ID, 0) - - .p2align 4, 0x90 -SYM(::class::{closure#0}::__objc2_dealloc, 0): - push rbp - mov rbp, rsp - push r14 - push rbx - sub rsp, 16 - mov rbx, rsi - mov r14, rdi - lea rsi, [rip + L_anon.[ID].13] - mov edx, 4 - call SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - mov rdi, rax - call _ivar_getOffset - mov rdi, qword ptr [r14 + rax] - test rdi, rdi - je LBB7_2 - call _objc_release -LBB7_2: - mov rax, qword ptr [rip + L_OBJC_CLASSLIST_REFERENCES_$_NSObject@GOTPCREL] - mov rax, qword ptr [rax] - mov qword ptr [rbp - 32], r14 - mov qword ptr [rbp - 24], rax - lea rdi, [rbp - 32] - mov rsi, rbx - call _objc_msgSendSuper add rsp, 16 - pop rbx - pop r14 pop rbp + mov rax, qword ptr [rip + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_CLASS, 0).0] ret .globl _init @@ -307,39 +313,35 @@ LBB7_2: _init: push rbp mov rbp, rsp - push rbx - sub rsp, 24 - mov rax, qword ptr [rip + L_OBJC_SELECTOR_REFERENCES_init@GOTPCREL] - mov rsi, qword ptr [rax] + sub rsp, 48 + test rdi, rdi + je LBB8_2 + mov rax, qword ptr [rip + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)] + mov qword ptr [rdi + rax], 0 + mov byte ptr [rdi + rax + 8], 42 + mov rax, qword ptr [rip + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)] + mov byte ptr [rdi + rax], 1 + mov rsi, qword ptr [rip + L_OBJC_SELECTOR_REFERENCES_74641ed6f72d2d44] mov rax, qword ptr [rip + L_OBJC_CLASSLIST_REFERENCES_$_NSObject@GOTPCREL] mov rax, qword ptr [rax] - mov qword ptr [rbp - 24], rdi - mov qword ptr [rbp - 16], rax - lea rdi, [rbp - 24] + mov qword ptr [rbp - 48], rdi + mov qword ptr [rbp - 40], rax + lea rdi, [rbp - 48] call _objc_msgSendSuper - mov rbx, rax - test rax, rax - je LBB8_2 - lea rsi, [rip + L_anon.[ID].12] - mov edx, 4 - mov rdi, rbx - call SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - mov rdi, rax - call _ivar_getOffset - mov byte ptr [rbx + rax], 42 - lea rsi, [rip + L_anon.[ID].13] - mov edx, 4 - mov rdi, rbx - call SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - mov rdi, rax - call _ivar_getOffset - mov qword ptr [rbx + rax], 0 -LBB8_2: - mov rax, rbx - add rsp, 24 - pop rbx + add rsp, 48 pop rbp ret +LBB8_2: + lea rax, [rip + l_anon.[ID].20] + mov qword ptr [rbp - 48], rax + mov qword ptr [rbp - 40], 1 + mov qword ptr [rbp - 16], 0 + lea rax, [rip + l_anon.[ID].1] + mov qword ptr [rbp - 32], rax + mov qword ptr [rbp - 24], 0 + lea rsi, [rip + l_anon.[ID].25] + lea rdi, [rbp - 48] + call SYM(core::panicking::panic_fmt::GENERATED_ID, 0) .globl _class_method .p2align 4, 0x90 @@ -371,30 +373,18 @@ _method_bool: .globl _method_id .p2align 4, 0x90 _method_id: - push rbp - mov rbp, rsp - push rbx - push rax - mov rbx, rdi - lea rsi, [rip + L_anon.[ID].13] - mov edx, 4 - call SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - mov rdi, rax - call _ivar_getOffset - mov rdi, qword ptr [rbx + rax] + mov rax, qword ptr [rip + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)] + mov rdi, qword ptr [rdi + rax] test rdi, rdi je LBB12_1 + push rbp + mov rbp, rsp call _objc_retain mov rdi, rax - add rsp, 8 - pop rbx pop rbp jmp _objc_autoreleaseReturnValue LBB12_1: xor edi, edi - add rsp, 8 - pop rbx - pop rbp jmp _objc_autoreleaseReturnValue .globl _method_id_with_param @@ -412,12 +402,7 @@ _method_id_with_param: mov rbx, rax test r15b, r15b je LBB13_5 - lea rsi, [rip + L_anon.[ID].13] - mov edx, 4 - mov rdi, r14 - call SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - mov rdi, rax - call _ivar_getOffset + mov rax, qword ptr [rip + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)] mov rdi, qword ptr [r14 + rax] test rdi, rdi je LBB13_2 @@ -446,58 +431,72 @@ _copyWithZone: mov rbp, rsp push r15 push r14 - push r12 push rbx - mov r14, rdi - call _get_obj - mov rbx, rax - test rax, rax - je LBB14_5 - lea r15, [rip + L_anon.[ID].12] - mov edx, 4 - mov rdi, r14 - mov rsi, r15 - call SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - mov rdi, rax - call _ivar_getOffset - movzx r12d, byte ptr [r14 + rax] - mov edx, 4 - mov rdi, rbx - mov rsi, r15 - call SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - mov rdi, rax - call _ivar_getOffset - mov byte ptr [rbx + rax], r12b - lea rsi, [rip + L_anon.[ID].13] - mov edx, 4 - mov rdi, r14 - call SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - mov rdi, rax - call _ivar_getOffset - mov rdi, qword ptr [r14 + rax] + sub rsp, 56 + mov rbx, rdi + mov rax, qword ptr [rip + L_OBJC_SELECTOR_REFERENCES_alloc@GOTPCREL] + mov r14, qword ptr [rax] + mov rax, qword ptr [rip + SYM(::class::REGISTER_CLASS, 0)] + cmp rax, 3 + jne LBB14_1 +LBB14_2: + mov rdi, qword ptr [rip + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_CLASS, 0).0] + mov rsi, r14 + call _objc_msgSend + mov r14, rax + mov rax, qword ptr [rip + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)] + movzx r15d, byte ptr [rbx + rax + 8] + mov rdi, qword ptr [rbx + rax] test rdi, rdi - je LBB14_2 + je LBB14_3 call _objc_retain - mov r14, rax - jmp LBB14_4 -LBB14_2: - xor r14d, r14d -LBB14_4: - lea rsi, [rip + L_anon.[ID].13] - mov edx, 4 - mov rdi, rbx - call SYM(objc2::runtime::AnyObject::lookup_instance_variable_dynamically::GENERATED_ID, 0) - mov rdi, rax - call _ivar_getOffset - mov qword ptr [rbx + rax], r14 -LBB14_5: - mov rax, rbx + test r14, r14 + je LBB14_7 +LBB14_6: + mov rcx, qword ptr [rip + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0)] + mov qword ptr [r14 + rcx], rax + mov byte ptr [r14 + rcx + 8], r15b + mov rax, qword ptr [rip + SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0)] + mov byte ptr [r14 + rax], 1 + mov rsi, qword ptr [rip + L_OBJC_SELECTOR_REFERENCES_a4c8ca93c4279f29] + mov rax, qword ptr [rip + L_OBJC_CLASSLIST_REFERENCES_$_NSObject@GOTPCREL] + mov rax, qword ptr [rax] + mov qword ptr [rbp - 80], r14 + mov qword ptr [rbp - 72], rax + lea rdi, [rbp - 80] + call _objc_msgSendSuper + add rsp, 56 pop rbx - pop r12 pop r14 pop r15 pop rbp ret +LBB14_3: + xor eax, eax + test r14, r14 + jne LBB14_6 +LBB14_7: + lea rax, [rip + l_anon.[ID].20] + mov qword ptr [rbp - 80], rax + mov qword ptr [rbp - 72], 1 + mov qword ptr [rbp - 48], 0 + lea rax, [rip + l_anon.[ID].1] + mov qword ptr [rbp - 64], rax + mov qword ptr [rbp - 56], 0 + lea rsi, [rip + l_anon.[ID].26] + lea rdi, [rbp - 80] + call SYM(core::panicking::panic_fmt::GENERATED_ID, 0) +LBB14_1: + mov byte ptr [rbp - 25], 1 + lea rax, [rbp - 25] + mov qword ptr [rbp - 80], rax + lea rdi, [rip + SYM(::class::REGISTER_CLASS, 0)] + lea rcx, [rip + l_anon.[ID].0] + lea r8, [rip + l_anon.[ID].23] + lea rdx, [rbp - 80] + xor esi, esi + call SYM(std::sys_common::once::queue::Once::call::GENERATED_ID, 0) + jmp LBB14_2 .section __DATA,__const .p2align 3, 0x0 @@ -549,148 +548,230 @@ l_anon.[ID].7: .section __TEXT,__const l_anon.[ID].8: - .ascii "called `Option::unwrap()` on a `None` value" + .ascii "ivars" l_anon.[ID].9: - .ascii "$RUSTC/library/std/src/sync/once.rs" + .ascii "drop_flag" - .section __DATA,__const .p2align 3, 0x0 l_anon.[ID].10: - .quad l_anon.[ID].9 - .asciz "p\000\000\000\000\000\000\000\225\000\000\0002\000\000" + .byte 5 + .space 39 - .section __TEXT,__const + .p2align 3, 0x0 l_anon.[ID].11: - .ascii "CustomClassName" + .byte 9 + .space 39 - .section __TEXT,__literal4,4byte_literals -L_anon.[ID].12: - .ascii "_foo" +l_anon.[ID].12: + .ascii "failed retrieving instance variable on newly declared class" -L_anon.[ID].13: - .ascii "_obj" +l_anon.[ID].13: + .ascii "$WORKSPACE/objc2/src/__macro_helpers/declared_ivars.rs" - .section __TEXT,__const + .section __DATA,__const + .p2align 3, 0x0 l_anon.[ID].14: - .ascii "crates/$DIR/lib.rs" + .quad l_anon.[ID].13 + .asciz "T\000\000\000\000\000\000\000\363\000\000\000\016\000\000" .p2align 3, 0x0 l_anon.[ID].15: - .byte 5 - .space 39 + .quad l_anon.[ID].13 + .asciz "T\000\000\000\000\000\000\000\377\000\000\000\016\000\000" + + .section __TEXT,__const +l_anon.[ID].16: + .ascii "called `Option::unwrap()` on a `None` value" + +l_anon.[ID].17: + .ascii "$RUSTC/library/std/src/sync/once.rs" .section __DATA,__const .p2align 3, 0x0 -l_anon.[ID].16: - .quad l_anon.[ID].14 - .asciz "5\000\000\000\000\000\000\000\f\000\000\000\001\000\000" +l_anon.[ID].18: + .quad l_anon.[ID].17 + .asciz "p\000\000\000\000\000\000\000\225\000\000\0002\000\000" + + .section __TEXT,__const +l_anon.[ID].19: + .ascii "tried to initialize instance variables on NULL allocated object" + + .section __DATA,__const + .p2align 3, 0x0 +l_anon.[ID].20: + .quad l_anon.[ID].19 + .asciz "?\000\000\000\000\000\000" + + .section __TEXT,__const +l_anon.[ID].21: + .ascii "CustomClassName" + +l_anon.[ID].22: + .ascii "crates/$DIR/lib.rs" + +.zerofill __DATA,__bss,SYM(test_declare_class[CRATE_ID]::_::__OBJC2_CLASS, 0).0,8,3 + .globl SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0) +.zerofill __DATA,__common,SYM(test_declare_class[CRATE_ID]::_::__OBJC2_IVAR_OFFSET, 0),8,3 + .globl SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0) +.zerofill __DATA,__common,SYM(test_declare_class[CRATE_ID]::_::__OBJC2_DROP_FLAG_OFFSET, 0),8,3 + .section __DATA,__const + .p2align 3, 0x0 +l_anon.[ID].23: + .quad l_anon.[ID].22 + .asciz "5\000\000\000\000\000\000\000\021\000\000\000\001\000\000" .zerofill __DATA,__bss,SYM(::class::REGISTER_CLASS, 0),8,3 .section __TEXT,__const -l_anon.[ID].17: +l_anon.[ID].24: .ascii "NSCopying" .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_d874ee9262978be2 -L_OBJC_METH_VAR_NAME_d874ee9262978be2: + .globl L_OBJC_METH_VAR_NAME_ddead4cf1cfe35ab +L_OBJC_METH_VAR_NAME_ddead4cf1cfe35ab: .asciz "classMethod" .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_d874ee9262978be2 + .globl L_OBJC_SELECTOR_REFERENCES_ddead4cf1cfe35ab .p2align 3, 0x0 -L_OBJC_SELECTOR_REFERENCES_d874ee9262978be2: - .quad L_OBJC_METH_VAR_NAME_d874ee9262978be2 +L_OBJC_SELECTOR_REFERENCES_ddead4cf1cfe35ab: + .quad L_OBJC_METH_VAR_NAME_ddead4cf1cfe35ab .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_d874ee9262978be2 + .globl L_OBJC_IMAGE_INFO_ddead4cf1cfe35ab .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_d874ee9262978be2: +L_OBJC_IMAGE_INFO_ddead4cf1cfe35ab: .asciz "\000\000\000\000@\000\000" .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_4539fd1dbda0cddc -L_OBJC_METH_VAR_NAME_4539fd1dbda0cddc: + .globl L_OBJC_METH_VAR_NAME_8ee1155e2a63c707 +L_OBJC_METH_VAR_NAME_8ee1155e2a63c707: .asciz "method" .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_4539fd1dbda0cddc + .globl L_OBJC_SELECTOR_REFERENCES_8ee1155e2a63c707 .p2align 3, 0x0 -L_OBJC_SELECTOR_REFERENCES_4539fd1dbda0cddc: - .quad L_OBJC_METH_VAR_NAME_4539fd1dbda0cddc +L_OBJC_SELECTOR_REFERENCES_8ee1155e2a63c707: + .quad L_OBJC_METH_VAR_NAME_8ee1155e2a63c707 .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_4539fd1dbda0cddc + .globl L_OBJC_IMAGE_INFO_8ee1155e2a63c707 .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_4539fd1dbda0cddc: +L_OBJC_IMAGE_INFO_8ee1155e2a63c707: .asciz "\000\000\000\000@\000\000" .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_2b1b3a94e0ece2e5 -L_OBJC_METH_VAR_NAME_2b1b3a94e0ece2e5: + .globl L_OBJC_METH_VAR_NAME_b1c6d8f625c88aa6 +L_OBJC_METH_VAR_NAME_b1c6d8f625c88aa6: .asciz "methodBool:" .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_2b1b3a94e0ece2e5 + .globl L_OBJC_SELECTOR_REFERENCES_b1c6d8f625c88aa6 .p2align 3, 0x0 -L_OBJC_SELECTOR_REFERENCES_2b1b3a94e0ece2e5: - .quad L_OBJC_METH_VAR_NAME_2b1b3a94e0ece2e5 +L_OBJC_SELECTOR_REFERENCES_b1c6d8f625c88aa6: + .quad L_OBJC_METH_VAR_NAME_b1c6d8f625c88aa6 .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_2b1b3a94e0ece2e5 + .globl L_OBJC_IMAGE_INFO_b1c6d8f625c88aa6 .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_2b1b3a94e0ece2e5: +L_OBJC_IMAGE_INFO_b1c6d8f625c88aa6: .asciz "\000\000\000\000@\000\000" .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_f7f521670860b0ce -L_OBJC_METH_VAR_NAME_f7f521670860b0ce: + .globl L_OBJC_METH_VAR_NAME_f33da9321a226f33 +L_OBJC_METH_VAR_NAME_f33da9321a226f33: .asciz "methodId" .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_f7f521670860b0ce + .globl L_OBJC_SELECTOR_REFERENCES_f33da9321a226f33 .p2align 3, 0x0 -L_OBJC_SELECTOR_REFERENCES_f7f521670860b0ce: - .quad L_OBJC_METH_VAR_NAME_f7f521670860b0ce +L_OBJC_SELECTOR_REFERENCES_f33da9321a226f33: + .quad L_OBJC_METH_VAR_NAME_f33da9321a226f33 .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_f7f521670860b0ce + .globl L_OBJC_IMAGE_INFO_f33da9321a226f33 .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_f7f521670860b0ce: +L_OBJC_IMAGE_INFO_f33da9321a226f33: .asciz "\000\000\000\000@\000\000" .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_6addfcf634c6232f -L_OBJC_METH_VAR_NAME_6addfcf634c6232f: + .globl L_OBJC_METH_VAR_NAME_e5d1ad528a5510d9 +L_OBJC_METH_VAR_NAME_e5d1ad528a5510d9: .asciz "methodIdWithParam:" .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_6addfcf634c6232f + .globl L_OBJC_SELECTOR_REFERENCES_e5d1ad528a5510d9 .p2align 3, 0x0 -L_OBJC_SELECTOR_REFERENCES_6addfcf634c6232f: - .quad L_OBJC_METH_VAR_NAME_6addfcf634c6232f +L_OBJC_SELECTOR_REFERENCES_e5d1ad528a5510d9: + .quad L_OBJC_METH_VAR_NAME_e5d1ad528a5510d9 .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_6addfcf634c6232f + .globl L_OBJC_IMAGE_INFO_e5d1ad528a5510d9 .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_6addfcf634c6232f: +L_OBJC_IMAGE_INFO_e5d1ad528a5510d9: .asciz "\000\000\000\000@\000\000" .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_4a8c690dbc9d8166 -L_OBJC_METH_VAR_NAME_4a8c690dbc9d8166: + .globl L_OBJC_METH_VAR_NAME_8daf9cd9e6dba6e3 +L_OBJC_METH_VAR_NAME_8daf9cd9e6dba6e3: .asciz "copyWithZone:" .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_4a8c690dbc9d8166 + .globl L_OBJC_SELECTOR_REFERENCES_8daf9cd9e6dba6e3 + .p2align 3, 0x0 +L_OBJC_SELECTOR_REFERENCES_8daf9cd9e6dba6e3: + .quad L_OBJC_METH_VAR_NAME_8daf9cd9e6dba6e3 + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_8daf9cd9e6dba6e3 + .p2align 2, 0x0 +L_OBJC_IMAGE_INFO_8daf9cd9e6dba6e3: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__const + .p2align 3, 0x0 +l_anon.[ID].25: + .quad l_anon.[ID].22 + .asciz "5\000\000\000\000\000\000\000#\000\000\000\035\000\000" + + .section __TEXT,__objc_methname,cstring_literals + .globl L_OBJC_METH_VAR_NAME_74641ed6f72d2d44 +L_OBJC_METH_VAR_NAME_74641ed6f72d2d44: + .asciz "init" + + .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip + .globl L_OBJC_SELECTOR_REFERENCES_74641ed6f72d2d44 + .p2align 3, 0x0 +L_OBJC_SELECTOR_REFERENCES_74641ed6f72d2d44: + .quad L_OBJC_METH_VAR_NAME_74641ed6f72d2d44 + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_74641ed6f72d2d44 + .p2align 2, 0x0 +L_OBJC_IMAGE_INFO_74641ed6f72d2d44: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__const + .p2align 3, 0x0 +l_anon.[ID].26: + .quad l_anon.[ID].22 + .asciz "5\000\000\000\000\000\000\000N\000\000\000\033\000\000" + + .section __TEXT,__objc_methname,cstring_literals + .globl L_OBJC_METH_VAR_NAME_a4c8ca93c4279f29 +L_OBJC_METH_VAR_NAME_a4c8ca93c4279f29: + .asciz "init" + + .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip + .globl L_OBJC_SELECTOR_REFERENCES_a4c8ca93c4279f29 .p2align 3, 0x0 -L_OBJC_SELECTOR_REFERENCES_4a8c690dbc9d8166: - .quad L_OBJC_METH_VAR_NAME_4a8c690dbc9d8166 +L_OBJC_SELECTOR_REFERENCES_a4c8ca93c4279f29: + .quad L_OBJC_METH_VAR_NAME_a4c8ca93c4279f29 .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_4a8c690dbc9d8166 + .globl L_OBJC_IMAGE_INFO_a4c8ca93c4279f29 .p2align 2, 0x0 -L_OBJC_IMAGE_INFO_4a8c690dbc9d8166: +L_OBJC_IMAGE_INFO_a4c8ca93c4279f29: .asciz "\000\000\000\000@\000\000" .subsections_via_symbols diff --git a/crates/test-assembly/crates/test_declare_class/lib.rs b/crates/test-assembly/crates/test_declare_class/lib.rs index ea181ca05..9ec268633 100644 --- a/crates/test-assembly/crates/test_declare_class/lib.rs +++ b/crates/test-assembly/crates/test_declare_class/lib.rs @@ -1,22 +1,22 @@ //! Test assembly output of `declare_class!`. #![deny(unsafe_op_in_unsafe_fn)] #![cfg(feature = "apple")] -use core::ptr::{self}; +use core::ptr; use icrate::Foundation::{NSCopying, NSObject}; -use objc2::declare::{Ivar, IvarDrop, IvarEncode}; -use objc2::rc::Id; +use objc2::rc::{Allocated, Id}; use objc2::runtime::{AnyClass, NSZone}; -use objc2::{declare_class, msg_send, msg_send_id, mutability, ClassType}; +use objc2::{declare_class, msg_send_id, mutability, ClassType, DeclaredClass}; + +#[derive(Clone)] +pub struct Ivars { + foo: u8, + obj: Option>, +} declare_class!( #[no_mangle] - pub struct Custom { - foo: IvarEncode, - obj: IvarDrop>, "_obj">, - } - - mod ivars; + pub struct Custom; unsafe impl ClassType for Custom { type Super = NSObject; @@ -24,19 +24,16 @@ declare_class!( const NAME: &'static str = "CustomClassName"; } + impl DeclaredClass for Custom { + type Ivars = Ivars; + } + unsafe impl Custom { #[no_mangle] - #[method(init)] - unsafe fn init(this: *mut Self) -> *mut Self { - let this: Option<&mut Self> = unsafe { msg_send![super(this), init] }; - - this.map(|this| { - Ivar::write(&mut this.foo, 42); - Ivar::write(&mut this.obj, None); - let this: *mut Self = this; - this - }) - .unwrap_or_else(ptr::null_mut) + #[method_id(init)] + fn init(this: Allocated) -> Option> { + let this = this.set_ivars(Ivars { foo: 42, obj: None }); + unsafe { msg_send_id![super(this), init] } } #[no_mangle] @@ -56,7 +53,7 @@ declare_class!( #[no_mangle] #[method_id(methodId)] fn method_id(&self) -> Option> { - self.obj.clone() + self.ivars().obj.clone() } // Test that `objc_autoreleaseReturnValue` is tail-called @@ -66,7 +63,7 @@ declare_class!( // Explicitly create outside condition let obj = NSObject::new(); if param { - self.obj.clone() + self.ivars().obj.clone() } else { Some(obj) } @@ -77,14 +74,9 @@ declare_class!( #[no_mangle] #[method_id(copyWithZone:)] fn copyWithZone(&self, _zone: *const NSZone) -> Option> { - get_obj().map(|new| { - let hack = Id::as_ptr(&new) as *mut Self; - let hack = unsafe { &mut *hack }; - - Ivar::write(&mut hack.foo, *self.foo); - Ivar::write(&mut hack.obj, self.obj.clone()); - new - }) + let new = Self::alloc(); + let new = new.set_ivars(self.ivars().clone()); + unsafe { msg_send_id![super(new), init] } } } ); @@ -106,8 +98,9 @@ pub fn get_obj() -> Option> { pub fn access_ivars() -> (u8, *const NSObject) { let obj = unsafe { get_obj().unwrap_unchecked() }; ( - *obj.foo, - (*obj.obj) + obj.ivars().foo, + obj.ivars() + .obj .as_ref() .map(|obj| Id::as_ptr(&obj)) .unwrap_or_else(ptr::null), diff --git a/crates/test-ui/ui/declare_class_classtype_imported.rs b/crates/test-ui/ui/declare_class_classtype_imported.rs index 7ab550cd2..6fc85f270 100644 --- a/crates/test-ui/ui/declare_class_classtype_imported.rs +++ b/crates/test-ui/ui/declare_class_classtype_imported.rs @@ -10,6 +10,8 @@ declare_class!( type Mutability = mutability::InteriorMutable; const NAME: &'static str = "CustomObject"; } + + impl objc2::DeclaredClass for CustomObject {} ); fn main() {} diff --git a/crates/test-ui/ui/declare_class_classtype_imported.stderr b/crates/test-ui/ui/declare_class_classtype_imported.stderr index 38a59afb6..a60443068 100644 --- a/crates/test-ui/ui/declare_class_classtype_imported.stderr +++ b/crates/test-ui/ui/declare_class_classtype_imported.stderr @@ -7,5 +7,5 @@ error: no rules expected the token `objc2` note: while trying to match `ClassType` --> $WORKSPACE/crates/objc2/src/macros/declare_class.rs | - | unsafe impl ClassType for $for:ty { + | unsafe impl ClassType for $for_class:ty { | ^^^^^^^^^ diff --git a/crates/test-ui/ui/declare_class_delegate_not_mainthreadonly.rs b/crates/test-ui/ui/declare_class_delegate_not_mainthreadonly.rs index af10f877b..cb43b051e 100644 --- a/crates/test-ui/ui/declare_class_delegate_not_mainthreadonly.rs +++ b/crates/test-ui/ui/declare_class_delegate_not_mainthreadonly.rs @@ -4,7 +4,7 @@ use icrate::AppKit::{NSApplication, NSApplicationDelegate}; use icrate::Foundation::{MainThreadMarker, NSNotification, NSObject, NSObjectProtocol}; use objc2::rc::Id; use objc2::runtime::ProtocolObject; -use objc2::{declare_class, extern_methods, mutability, ClassType}; +use objc2::{declare_class, extern_methods, mutability, ClassType, DeclaredClass}; declare_class!( struct CustomObject; @@ -15,6 +15,8 @@ declare_class!( const NAME: &'static str = "CustomObject"; } + impl DeclaredClass for CustomObject {} + unsafe impl NSObjectProtocol for CustomObject {} unsafe impl NSApplicationDelegate for CustomObject { diff --git a/crates/test-ui/ui/declare_class_invalid_receiver.rs b/crates/test-ui/ui/declare_class_invalid_receiver.rs index 63ff3f45c..5cfb493f9 100644 --- a/crates/test-ui/ui/declare_class_invalid_receiver.rs +++ b/crates/test-ui/ui/declare_class_invalid_receiver.rs @@ -1,6 +1,6 @@ use objc2::rc::{Allocated, Id}; use objc2::runtime::{AnyClass, NSObject}; -use objc2::{declare_class, mutability, ClassType}; +use objc2::{declare_class, mutability, ClassType, DeclaredClass}; declare_class!( struct CustomObject; @@ -11,6 +11,8 @@ declare_class!( const NAME: &'static str = "CustomObject"; } + impl DeclaredClass for CustomObject {} + unsafe impl CustomObject { #[method(testBox)] fn test_box(self: Box) { diff --git a/crates/test-ui/ui/declare_class_invalid_syntax.rs b/crates/test-ui/ui/declare_class_invalid_syntax.rs index d7e38b188..e0757b960 100644 --- a/crates/test-ui/ui/declare_class_invalid_syntax.rs +++ b/crates/test-ui/ui/declare_class_invalid_syntax.rs @@ -1,9 +1,6 @@ -use std::marker::PhantomData; - -use objc2::declare::IvarEncode; use objc2::rc::Id; use objc2::runtime::NSObject; -use objc2::{declare_class, mutability, ClassType}; +use objc2::{declare_class, mutability, ClassType, DeclaredClass}; declare_class!( struct InvalidMethodDeclarations; @@ -14,6 +11,8 @@ declare_class!( const NAME: &'static str = "InvalidMethodDeclarations"; } + impl DeclaredClass for InvalidMethodDeclarations {} + unsafe impl InvalidMethodDeclarations { fn test_no_attribute() { unimplemented!() @@ -140,63 +139,27 @@ declare_class!( type Super = NSObject; type Mutability = mutability::InteriorMutable; } -); - -declare_class!( - struct InvalidField { - field: i32, - } - unsafe impl ClassType for InvalidField { - type Super = NSObject; - type Mutability = mutability::InteriorMutable; - const NAME: &'static str = "InvalidField"; - } + impl DeclaredClass for MissingName {} ); declare_class!( - struct UnnecessaryIvarModule; - - mod ivars; + struct MissingMutability; - unsafe impl ClassType for UnnecessaryIvarModule { + unsafe impl ClassType for MissingMutability { type Super = NSObject; - type Mutability = mutability::InteriorMutable; - const NAME: &'static str = "UnnecessaryIvarModule"; - } -); - -declare_class!( - struct UnnecessaryIvarModuleWithFields { - p: PhantomData, } - mod ivars; - - unsafe impl ClassType for UnnecessaryIvarModuleWithFields { - type Super = NSObject; - type Mutability = mutability::InteriorMutable; - const NAME: &'static str = "UnnecessaryIvarModuleWithFields"; - } + impl DeclaredClass for MissingMutability {} ); declare_class!( - struct MissingIvarModule { - field: IvarEncode, - } + struct MissingDeclaredClass; - unsafe impl ClassType for MissingIvarModule { + unsafe impl ClassType for MissingDeclaredClass { type Super = NSObject; type Mutability = mutability::InteriorMutable; - const NAME: &'static str = "MissingIvarModule"; - } -); - -declare_class!( - struct MissingMutability; - - unsafe impl ClassType for MissingMutability { - type Super = NSObject; + const NAME: &'static str = "MissingDeclaredClass"; } ); diff --git a/crates/test-ui/ui/declare_class_invalid_syntax.stderr b/crates/test-ui/ui/declare_class_invalid_syntax.stderr index fdc940454..17ecb6092 100644 --- a/crates/test-ui/ui/declare_class_invalid_syntax.stderr +++ b/crates/test-ui/ui/declare_class_invalid_syntax.stderr @@ -451,71 +451,29 @@ note: while trying to match `const` | const NAME: &'static str = $name_const:expr; | ^^^^^ -error: invalid type i32 in field field. Type must be either `PhantomData`, `IvarDrop`, `IvarBool` or `IvarEncode`. - --> ui/declare_class_invalid_syntax.rs - | - | / declare_class!( - | | struct InvalidField { - | | field: i32, - | | } -... | - | | } - | | ); - | |_^ - | - = note: this error originates in the macro `$crate::__parse_fields` which comes from the expansion of the macro `declare_class` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: no rules expected the token `mod` +error: no rules expected the token `}` --> ui/declare_class_invalid_syntax.rs | - | mod ivars; - | ^^^ no rules expected this token in macro call + | } + | ^ no rules expected this token in macro call | -note: while trying to match `unsafe` +note: while trying to match `type` --> $WORKSPACE/crates/objc2/src/macros/declare_class.rs | - | unsafe impl ClassType for $for:ty { - | ^^^^^^ - -error: no need to specify an ivar module when the type has no ivars - --> ui/declare_class_invalid_syntax.rs - | - | / declare_class!( - | | struct UnnecessaryIvarModuleWithFields { - | | p: PhantomData, - | | } -... | - | | } - | | ); - | |_^ - | - = note: this error originates in the macro `$crate::__parse_fields` which comes from the expansion of the macro `declare_class` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: must specify an ivar module when the type has ivars - --> ui/declare_class_invalid_syntax.rs - | - | / declare_class!( - | | struct MissingIvarModule { - | | field: IvarEncode, - | | } -... | - | | } - | | ); - | |_^ - | - = note: this error originates in the macro `$crate::__parse_fields` which comes from the expansion of the macro `declare_class` (in Nightly builds, run with -Z macro-backtrace for more info) + | type Mutability = $mutability:ty; + | ^^^^ -error: no rules expected the token `}` +error: unexpected end of macro invocation --> ui/declare_class_invalid_syntax.rs | | } - | ^ no rules expected this token in macro call + | ^ missing tokens in macro arguments | -note: while trying to match `type` +note: while trying to match `impl` --> $WORKSPACE/crates/objc2/src/macros/declare_class.rs | - | type Mutability = $mutability:ty; - | ^^^^ + | impl DeclaredClass for $for_declared:ty { + | ^^^^ error[E0599]: no function or associated item named `test_pattern` found for struct `InvalidMethodDeclarations` in the current scope --> ui/declare_class_invalid_syntax.rs diff --git a/crates/test-ui/ui/declare_class_invalid_type.rs b/crates/test-ui/ui/declare_class_invalid_type.rs index a34b00e1b..ce8c704bf 100644 --- a/crates/test-ui/ui/declare_class_invalid_type.rs +++ b/crates/test-ui/ui/declare_class_invalid_type.rs @@ -1,6 +1,6 @@ use objc2::rc::Id; use objc2::runtime::NSObject; -use objc2::{declare_class, mutability, ClassType}; +use objc2::{declare_class, mutability, ClassType, DeclaredClass}; declare_class!( struct CustomObject; @@ -11,6 +11,8 @@ declare_class!( const NAME: &'static str = "CustomObject"; } + impl DeclaredClass for CustomObject {} + unsafe impl CustomObject { #[method(test1)] fn test1() -> Id { diff --git a/crates/test-ui/ui/declare_class_invalid_type2.rs b/crates/test-ui/ui/declare_class_invalid_type2.rs index 18dcf5da3..fb1129632 100644 --- a/crates/test-ui/ui/declare_class_invalid_type2.rs +++ b/crates/test-ui/ui/declare_class_invalid_type2.rs @@ -1,6 +1,6 @@ use objc2::rc::{Allocated, Id}; use objc2::runtime::NSObject; -use objc2::{declare_class, mutability, ClassType}; +use objc2::{declare_class, mutability, ClassType, DeclaredClass}; declare_class!( struct CustomObject; @@ -11,6 +11,8 @@ declare_class!( const NAME: &'static str = "CustomObject"; } + impl DeclaredClass for CustomObject {} + unsafe impl CustomObject { #[method_id(initNotSameGenerics)] fn test_init_not_same_generics(this: Allocated) -> Id { diff --git a/crates/test-ui/ui/declare_class_invalid_type3.rs b/crates/test-ui/ui/declare_class_invalid_type3.rs deleted file mode 100644 index 99480de84..000000000 --- a/crates/test-ui/ui/declare_class_invalid_type3.rs +++ /dev/null @@ -1,19 +0,0 @@ -use objc2::declare::IvarEncode; -use objc2::runtime::NSObject; -use objc2::{declare_class, mutability, ClassType}; - -declare_class!( - struct CustomObject { - field: IvarEncode<(), "_field">, - } - - mod ivars; - - unsafe impl ClassType for CustomObject { - type Super = NSObject; - type Mutability = mutability::InteriorMutable; - const NAME: &'static str = "CustomObject"; - } -); - -fn main() {} diff --git a/crates/test-ui/ui/declare_class_invalid_type3.stderr b/crates/test-ui/ui/declare_class_invalid_type3.stderr deleted file mode 100644 index 9e0f48a51..000000000 --- a/crates/test-ui/ui/declare_class_invalid_type3.stderr +++ /dev/null @@ -1,29 +0,0 @@ -error[E0277]: the trait bound `(): Encode` is not satisfied - --> ui/declare_class_invalid_type3.rs - | - | / declare_class!( - | | struct CustomObject { - | | field: IvarEncode<(), "_field">, - | | } -... | - | | } - | | ); - | |_^ the trait `Encode` is not implemented for `()` - | - = help: the following other types implement trait `Encode`: - isize - i8 - i16 - i32 - i64 - usize - u8 - u16 - and $N others - = note: required for `objc2::declare::IvarEncode<()>` to implement `InnerIvarType` -note: required by a bound in `objc2::declare::IvarType::Type` - --> $WORKSPACE/crates/objc2/src/declare/ivar.rs - | - | type Type: InnerIvarType; - | ^^^^^^^^^^^^^ required by this bound in `IvarType::Type` - = note: this error originates in the macro `$crate::__parse_fields` which comes from the expansion of the macro `declare_class` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/crates/test-ui/ui/declare_class_mut_self_not_mutable.rs b/crates/test-ui/ui/declare_class_mut_self_not_mutable.rs index 96d865f7d..9505f8775 100644 --- a/crates/test-ui/ui/declare_class_mut_self_not_mutable.rs +++ b/crates/test-ui/ui/declare_class_mut_self_not_mutable.rs @@ -1,6 +1,6 @@ use objc2::rc::Id; use objc2::runtime::NSObject; -use objc2::{declare_class, mutability, ClassType}; +use objc2::{declare_class, mutability, ClassType, DeclaredClass}; declare_class!( struct CustomObject; @@ -11,6 +11,8 @@ declare_class!( const NAME: &'static str = "CustomObject"; } + impl DeclaredClass for CustomObject {} + unsafe impl CustomObject { #[method(initTest)] fn init_test(&mut self) -> &mut Self { diff --git a/crates/test-ui/ui/implement_protocol_missing_super.rs b/crates/test-ui/ui/implement_protocol_missing_super.rs index 7e2fd36ad..dbb131610 100644 --- a/crates/test-ui/ui/implement_protocol_missing_super.rs +++ b/crates/test-ui/ui/implement_protocol_missing_super.rs @@ -2,7 +2,7 @@ //! protocols like `NSObjectProtocol` to also be implemented. use icrate::AppKit::NSApplicationDelegate; use icrate::Foundation::NSObject; -use objc2::{declare_class, mutability, ClassType}; +use objc2::{declare_class, mutability, ClassType, DeclaredClass}; declare_class!( struct CustomObject; @@ -13,6 +13,8 @@ declare_class!( const NAME: &'static str = "CustomObject"; } + impl DeclaredClass for CustomObject {} + unsafe impl NSApplicationDelegate for CustomObject {} ); diff --git a/crates/test-ui/ui/main_thread_only_not_allocable.rs b/crates/test-ui/ui/main_thread_only_not_allocable.rs index 2b67f131a..b5b2a6f58 100644 --- a/crates/test-ui/ui/main_thread_only_not_allocable.rs +++ b/crates/test-ui/ui/main_thread_only_not_allocable.rs @@ -1,5 +1,5 @@ use objc2::runtime::NSObject; -use objc2::{declare_class, mutability, ClassType}; +use objc2::{declare_class, mutability, ClassType, DeclaredClass}; declare_class!( struct MyMainThreadOnlyClass; @@ -9,6 +9,8 @@ declare_class!( type Mutability = mutability::MainThreadOnly; const NAME: &'static str = "MyMainThreadOnlyClass"; } + + impl DeclaredClass for MyMainThreadOnlyClass {} ); fn main() { diff --git a/crates/test-ui/ui/msg_send_missing_comma.rs b/crates/test-ui/ui/msg_send_missing_comma.rs index e23c4fe87..7e7d2a0c9 100644 --- a/crates/test-ui/ui/msg_send_missing_comma.rs +++ b/crates/test-ui/ui/msg_send_missing_comma.rs @@ -12,5 +12,7 @@ fn main() { unsafe { msg_send_bool![obj, c:obj d:obj] }; + let _: Id = unsafe { msg_send_id![super(obj), e:obj f:obj] }; + let _: Id = unsafe { msg_send_id![super(obj, NSString::class()), e:obj f:obj] }; let _: Id = unsafe { msg_send_id![obj, e:obj f:obj] }; } diff --git a/crates/test-ui/ui/msg_send_missing_comma.stderr b/crates/test-ui/ui/msg_send_missing_comma.stderr index a70e62e01..6d911234a 100644 --- a/crates/test-ui/ui/msg_send_missing_comma.stderr +++ b/crates/test-ui/ui/msg_send_missing_comma.stderr @@ -48,6 +48,24 @@ error: use of deprecated function `main::__msg_send_missing_comma`: using msg_se | = note: this error originates in the macro `$crate::__comma_between_args_inner` which comes from the expansion of the macro `msg_send_bool` (in Nightly builds, run with -Z macro-backtrace for more info) +error: use of deprecated function `main::__msg_send_missing_comma`: using msg_send_id! without a comma between arguments is technically not valid macro syntax, and may break in a future version of Rust. You should use the following instead: + msg_send_id![super(obj), e: obj, f: obj] + --> ui/msg_send_missing_comma.rs + | + | let _: Id = unsafe { msg_send_id![super(obj), e:obj f:obj] }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in the macro `$crate::__comma_between_args_inner` which comes from the expansion of the macro `msg_send_id` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: use of deprecated function `main::__msg_send_missing_comma`: using msg_send_id! without a comma between arguments is technically not valid macro syntax, and may break in a future version of Rust. You should use the following instead: + msg_send_id![super(obj, NSString::class()), e: obj, f: obj] + --> ui/msg_send_missing_comma.rs + | + | let _: Id = unsafe { msg_send_id![super(obj, NSString::class()), e:obj f:obj] }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in the macro `$crate::__comma_between_args_inner` which comes from the expansion of the macro `msg_send_id` (in Nightly builds, run with -Z macro-backtrace for more info) + error: use of deprecated function `main::__msg_send_missing_comma`: using msg_send_id! without a comma between arguments is technically not valid macro syntax, and may break in a future version of Rust. You should use the following instead: msg_send_id![obj, e: obj, f: obj] --> ui/msg_send_missing_comma.rs diff --git a/crates/test-ui/ui/mutability_traits_unimplementable.rs b/crates/test-ui/ui/mutability_traits_unimplementable.rs index 96fe63505..8eedc6be9 100644 --- a/crates/test-ui/ui/mutability_traits_unimplementable.rs +++ b/crates/test-ui/ui/mutability_traits_unimplementable.rs @@ -1,6 +1,6 @@ //! Check that `mutability` traits are not implementable manually. use objc2::runtime::NSObject; -use objc2::{declare_class, mutability, ClassType}; +use objc2::{declare_class, mutability, ClassType, DeclaredClass}; declare_class!( struct CustomObject; @@ -10,6 +10,8 @@ declare_class!( type Mutability = mutability::InteriorMutable; const NAME: &'static str = "CustomObject"; } + + impl DeclaredClass for CustomObject {} ); unsafe impl mutability::IsMutable for CustomObject {} diff --git a/crates/test-ui/ui/wrong_optional.rs b/crates/test-ui/ui/wrong_optional.rs index 78203d187..721a430aa 100644 --- a/crates/test-ui/ui/wrong_optional.rs +++ b/crates/test-ui/ui/wrong_optional.rs @@ -1,6 +1,6 @@ use objc2::rc::Id; use objc2::runtime::NSObject; -use objc2::{declare_class, extern_class, extern_methods, mutability, ClassType}; +use objc2::{declare_class, extern_class, extern_methods, mutability, ClassType, DeclaredClass}; extern_class!( pub struct MyObject; @@ -38,6 +38,8 @@ declare_class!( const NAME: &'static str = "CustomObject1"; } + impl DeclaredClass for CustomObject1 {} + unsafe impl CustomObject1 { #[method(c)] #[optional] @@ -55,6 +57,8 @@ declare_class!( const NAME: &'static str = "CustomObject2"; } + impl DeclaredClass for CustomObject2 {} + unsafe impl CustomObject2 { #[optional] /// Doc comment diff --git a/crates/tests/src/test_declare_class_protocol.rs b/crates/tests/src/test_declare_class_protocol.rs index e408e296a..1a1c9cd67 100644 --- a/crates/tests/src/test_declare_class_protocol.rs +++ b/crates/tests/src/test_declare_class_protocol.rs @@ -3,7 +3,7 @@ use icrate::Foundation::NSCopying; use objc2::mutability::Immutable; use objc2::rc::Id; use objc2::runtime::{NSObject, NSZone}; -use objc2::{declare_class, ClassType, ProtocolType}; +use objc2::{declare_class, ClassType, DeclaredClass, ProtocolType}; #[test] #[should_panic = "could not create new class TestDeclareClassDuplicate. Perhaps a class with that name already exists?"] @@ -16,6 +16,8 @@ fn test_declare_class_duplicate() { type Mutability = Immutable; const NAME: &'static str = "TestDeclareClassDuplicate"; } + + impl DeclaredClass for Custom1 {} ); declare_class!( @@ -26,6 +28,8 @@ fn test_declare_class_duplicate() { type Mutability = Immutable; const NAME: &'static str = "TestDeclareClassDuplicate"; } + + impl DeclaredClass for Custom2 {} ); let _cls = Custom1::class(); @@ -44,6 +48,8 @@ fn test_declare_class_protocol() { const NAME: &'static str = "TestDeclareClassProtocolNotFound"; } + impl DeclaredClass for Custom {} + unsafe impl NSCopying for Custom { #[method_id(copyWithZone:)] fn copy_with_zone(&self, _zone: *const NSZone) -> Id { @@ -71,6 +77,8 @@ fn test_declare_class_invalid_method() { const NAME: &'static str = "TestDeclareClassInvalidMethod"; } + impl DeclaredClass for Custom {} + unsafe impl Custom { // Override `description` with a bad return type #[method(description)] @@ -96,6 +104,8 @@ fn test_declare_class_missing_protocol_method() { const NAME: &'static str = "TestDeclareClassMissingProtocolMethod"; } + impl DeclaredClass for Custom {} + unsafe impl NSCopying for Custom { // Missing required method } @@ -116,6 +126,8 @@ fn test_declare_class_invalid_protocol_method() { const NAME: &'static str = "TestDeclareClassInvalidProtocolMethod"; } + impl DeclaredClass for Custom {} + unsafe impl NSCopying for Custom { // Override with a bad return type #[method(copyWithZone:)] @@ -143,6 +155,8 @@ fn test_declare_class_extra_protocol_method() { const NAME: &'static str = "TestDeclareClassExtraProtocolMethod"; } + impl DeclaredClass for Custom {} + unsafe impl NSCopying for Custom { #[method_id(copyWithZone:)] fn copy_with_zone(&self, _zone: *const NSZone) -> Id {