diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d4c9fcae8..42de00017 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -378,12 +378,12 @@ jobs: # Not using --all-features because that would enable e.g. gnustep args: ${{ env.ARGS }} ${{ env.TESTARGS }} --features ${{ env.FEATURES }},${{ env.UNSTABLE_FEATURES }} - - name: Test static selectors + - name: Test static class and selectors if: ${{ !matrix.dinghy && (matrix.runtime || 'apple') == 'apple' }} uses: actions-rs/cargo@v1 with: command: test - args: ${{ env.ARGS }} ${{ env.TESTARGS }} --features unstable-static-sel + args: ${{ env.ARGS }} ${{ env.TESTARGS }} --features unstable-static-sel,unstable-static-class - name: Run assembly tests # Not run on GNUStep yet since a lot of function labels are mangled and diff --git a/objc2/Cargo.toml b/objc2/Cargo.toml index bb03c89e2..1d1099e73 100644 --- a/objc2/Cargo.toml +++ b/objc2/Cargo.toml @@ -51,6 +51,8 @@ malloc = ["malloc_buf"] # https://github.com/madsmtm/objc2/issues/new unstable-static-sel = ["objc2-proc-macros"] unstable-static-sel-inlined = ["unstable-static-sel"] +unstable-static-class = ["objc2-proc-macros"] +unstable-static-class-inlined = ["unstable-static-class"] # Uses nightly features to make AutoreleasePool zero-cost even in debug mode unstable-autoreleasesafe = [] diff --git a/objc2/examples/introspection.rs b/objc2/examples/introspection.rs index 9d71d8155..685cf09ce 100644 --- a/objc2/examples/introspection.rs +++ b/objc2/examples/introspection.rs @@ -4,6 +4,10 @@ use objc2::{class, msg_send, msg_send_id}; #[cfg(feature = "malloc")] use objc2::{sel, Encode}; +#[cfg(feature = "apple")] +#[link(name = "Foundation", kind = "framework")] +extern "C" {} + fn main() { // Get a class let cls = class!(NSObject); diff --git a/objc2/examples/talk_to_me.rs b/objc2/examples/talk_to_me.rs index 7e5b4ea1e..c2e5ac87a 100644 --- a/objc2/examples/talk_to_me.rs +++ b/objc2/examples/talk_to_me.rs @@ -12,6 +12,9 @@ use std::ffi::c_void; #[cfg(feature = "apple")] #[link(name = "AVFoundation", kind = "framework")] extern "C" {} +#[cfg(feature = "apple")] +#[link(name = "Foundation", kind = "framework")] +extern "C" {} const UTF8_ENCODING: NSUInteger = 4; diff --git a/objc2/src/lib.rs b/objc2/src/lib.rs index 026d69683..a5d281b7b 100644 --- a/objc2/src/lib.rs +++ b/objc2/src/lib.rs @@ -223,6 +223,11 @@ mod test_utils; #[doc(hidden)] pub mod __macro_helpers; +// Hack to make doctests work +#[cfg(all(feature = "apple", feature = "unstable-static-class"))] +#[link(name = "Foundation", kind = "framework")] +extern "C" {} + /// Hacky way to make GNUStep link properly to Foundation while testing. /// /// This is a temporary solution to make our CI work for now! diff --git a/objc2/src/macros.rs b/objc2/src/macros.rs index d6a691f6e..6cc8ad533 100644 --- a/objc2/src/macros.rs +++ b/objc2/src/macros.rs @@ -17,6 +17,15 @@ /// ``` #[macro_export] macro_rules! class { + ($name:ident) => {{ + $crate::__class_inner!($name) + }}; +} + +#[doc(hidden)] +#[macro_export] +#[cfg(not(feature = "unstable-static-class"))] +macro_rules! __class_inner { ($name:ident) => {{ use $crate::__macro_helpers::{concat, panic, stringify, CachedClass, None, Some}; static CACHED_CLASS: CachedClass = CachedClass::new(); @@ -25,7 +34,7 @@ macro_rules! class { let cls = unsafe { CACHED_CLASS.get(name) }; match cls { Some(cls) => cls, - None => panic!("Class with name {} could not be found", stringify!($name)), + None => panic!("Class with name {} could not be found", stringify!($name),), } }}; } @@ -165,18 +174,12 @@ macro_rules! __sel_inner { #[doc(hidden)] #[macro_export] -macro_rules! __sel_inner_statics_apple_generic { +macro_rules! __inner_statics_apple_generic { { + @image_info; $image_info_section:literal; - $var_name_section:literal; - $selector_ref_section:literal; - $data:ident, $($idents:ident)+ } => { - use $crate::__macro_helpers::{__hash_idents, u8, UnsafeCell}; - use $crate::ffi::__ImageInfo; - use $crate::runtime::Sel; - /// We always emit the image info tag, since we need it to: /// - End up in the same codegen unit as the other statics below. /// - End up in the final binary so it can be read by dyld. @@ -185,9 +188,22 @@ macro_rules! __sel_inner_statics_apple_generic { /// reports `__DATA/__objc_imageinfo has unexpectedly large size XXX`, /// but things still seems to work. #[link_section = $image_info_section] - #[export_name = concat!("\x01L_OBJC_IMAGE_INFO_", __hash_idents!($($idents)+))] + #[export_name = $crate::__macro_helpers::concat!( + "\x01L_OBJC_IMAGE_INFO_", + $crate::__macro_helpers::__hash_idents!($($idents)+) + )] #[used] // Make sure this reaches the linker - static _IMAGE_INFO: __ImageInfo = __ImageInfo::system(); + static _IMAGE_INFO: $crate::ffi::__ImageInfo = $crate::ffi::__ImageInfo::system(); + }; + { + @sel; + $var_name_section:literal; + $selector_ref_section:literal; + $data:ident, + $($idents:ident)+ + } => { + use $crate::__macro_helpers::{__hash_idents, u8, UnsafeCell}; + use $crate::runtime::Sel; const X: &[u8] = $data.as_bytes(); @@ -241,47 +257,108 @@ macro_rules! __sel_inner_statics_apple_generic { UnsafeCell::new(Sel::__internal_from_ptr(NAME_DATA.as_ptr().cast())) }; }; + { + @class; + $class_ref_section:literal; + $name:ident + } => { + use $crate::__macro_helpers::{concat, stringify, __hash_idents, UnsafeCell}; + use $crate::runtime::Class; + + // TODO + extern "C" { + // TODO: Weak linkage? + // https://stackoverflow.com/a/16936512 + // http://sealiesoftware.com/blog/archive/2010/4/8/Do-it-yourself_Objective-C_weak_import.html + #[link_name = concat!("OBJC_CLASS_$_", stringify!($name))] + static CLASS: Class; + } + + // TODO + #[link_section = $class_ref_section] + #[export_name = concat!("\x01L_OBJC_CLASSLIST_REFERENCES_$_", __hash_idents!($name))] + static mut REF: UnsafeCell<&Class> = unsafe { + UnsafeCell::new(&CLASS) + }; + }; } +// These sections are found by reading clang/LLVM sources #[doc(hidden)] #[macro_export] #[cfg(all(feature = "apple", not(all(target_os = "macos", target_arch = "x86"))))] -macro_rules! __sel_inner_statics { - ($($args:tt)*) => { - // Found by reading clang/LLVM sources - $crate::__sel_inner_statics_apple_generic! { +macro_rules! __inner_statics { + (@image_info $($args:tt)*) => { + $crate::__inner_statics_apple_generic! { + @image_info; "__DATA,__objc_imageinfo,regular,no_dead_strip"; + $($args)* + } + }; + (@sel $($args:tt)*) => { + $crate::__inner_statics_apple_generic! { + @sel; "__TEXT,__objc_methname,cstring_literals"; "__DATA,__objc_selrefs,literal_pointers,no_dead_strip"; $($args)* } }; + (@class $($args:tt)*) => { + $crate::__inner_statics_apple_generic! { + @class; + "__DATA,__objc_classrefs,regular,no_dead_strip"; + $($args)* + } + }; } #[doc(hidden)] #[macro_export] #[cfg(all(feature = "apple", target_os = "macos", target_arch = "x86"))] -macro_rules! __sel_inner_statics { - ($($args:tt)*) => { - $crate::__sel_inner_statics_apple_generic! { +macro_rules! __inner_statics { + (@image_info $($args:tt)*) => { + $crate::__inner_statics_apple_generic! { + @image_info; "__OBJC,__image_info,regular"; + $($args)* + } + }; + (@sel $($args:tt)*) => { + $crate::__inner_statics_apple_generic! { + @sel; "__TEXT,__cstring,cstring_literals"; "__OBJC,__message_refs,literal_pointers,no_dead_strip"; $($args)* } }; + (@class $($args:tt)*) => { + // TODO + $crate::__macro_helpers::compile_error!( + "The `\"unstable-static-class\"` feature is not yet supported on 32bit macOS!" + ) + // TODO: module info + }; } #[doc(hidden)] #[macro_export] #[cfg(not(feature = "apple"))] -macro_rules! __sel_inner_statics { - ($($args:tt)*) => { +macro_rules! __inner_statics { + (@image_info $($args:tt)*) => { + // TODO + }; + (@sel $($args:tt)*) => { // TODO $crate::__macro_helpers::compile_error!( "The `\"unstable-static-sel\"` feature is not yet supported on GNUStep!" ) }; + (@class $($args:tt)*) => { + // TODO + $crate::__macro_helpers::compile_error!( + "The `\"unstable-static-class\"` feature is not yet supported on GNUStep!" + ) + }; } #[doc(hidden)] @@ -291,8 +368,9 @@ macro_rules! __sel_inner_statics { not(feature = "unstable-static-sel-inlined") ))] macro_rules! __sel_inner { - ($($args:tt)*) => {{ - $crate::__sel_inner_statics!($($args)*); + ($data:ident, $($idents:ident)+) => {{ + $crate::__inner_statics!(@image_info $($idents)+); + $crate::__inner_statics!(@sel $data, $($idents)+); /// HACK: Wrap the access in a non-generic, `#[inline(never)]` /// function to make the compiler group it into the same codegen unit @@ -319,8 +397,44 @@ macro_rules! __sel_inner { #[macro_export] #[cfg(all(feature = "unstable-static-sel-inlined"))] macro_rules! __sel_inner { - ($($args:tt)*) => {{ - $crate::__sel_inner_statics!($($args)*); + ($data:ident, $($idents:ident)+) => {{ + $crate::__inner_statics!(@image_info $($idents)+); + $crate::__inner_statics!(@sel $data, $($idents)+); + + #[allow(unused_unsafe)] + // SAFETY: See above + unsafe { *REF.get() } + }}; +} + +#[doc(hidden)] +#[macro_export] +#[cfg(all( + feature = "unstable-static-class", + not(feature = "unstable-static-class-inlined") +))] +macro_rules! __class_inner { + ($name:ident) => {{ + $crate::__inner_statics!(@image_info $name); + $crate::__inner_statics!(@class $name); + + // SAFETY: Same as __sel_inner + #[inline(never)] + fn objc_static_workaround() -> &'static Class { + unsafe { *REF.get() } + } + + objc_static_workaround() + }}; +} + +#[doc(hidden)] +#[macro_export] +#[cfg(all(feature = "unstable-static-class-inlined"))] +macro_rules! __class_inner { + ($name:ident) => {{ + $crate::__inner_statics!(@image_info $name); + $crate::__inner_statics!(@class $name); #[allow(unused_unsafe)] // SAFETY: See above diff --git a/objc2/src/rc/test_object.rs b/objc2/src/rc/test_object.rs index 4f2ecf70d..ebc32c24e 100644 --- a/objc2/src/rc/test_object.rs +++ b/objc2/src/rc/test_object.rs @@ -145,10 +145,11 @@ impl RcTestObject { ); } - builder.register(); + let _cls = builder.register(); }); - class!(RcTestObject) + // Can't use `class!` here since `RcTestObject` is dynamically created. + Class::get("RcTestObject").unwrap() } pub(crate) fn new() -> Id { diff --git a/objc2/src/test_utils.rs b/objc2/src/test_utils.rs index 2a462b877..a7f187895 100644 --- a/objc2/src/test_utils.rs +++ b/objc2/src/test_utils.rs @@ -166,7 +166,8 @@ pub(crate) fn custom_class() -> &'static Class { builder.register(); }); - class!(CustomObject) + // Can't use `class!` here since `CustomObject` is dynamically created. + Class::get("CustomObject").unwrap() } pub(crate) fn custom_protocol() -> &'static Protocol { @@ -225,7 +226,7 @@ pub(crate) fn custom_subclass() -> &'static Class { builder.register(); }); - class!(CustomSubclassObject) + Class::get("CustomSubclassObject").unwrap() } pub(crate) fn custom_subclass_object() -> CustomObject { diff --git a/objc2/tests/id_retain_autoreleased.rs b/objc2/tests/id_retain_autoreleased.rs index 2640a4a73..325614540 100644 --- a/objc2/tests/id_retain_autoreleased.rs +++ b/objc2/tests/id_retain_autoreleased.rs @@ -4,6 +4,16 @@ use objc2::rc::{autoreleasepool, Id, Shared}; use objc2::runtime::Object; use objc2::{class, msg_send}; +#[cfg(feature = "gnustep-1-7")] +#[test] +fn ensure_linkage() { + unsafe { objc2::__gnustep_hack::get_class_to_force_linkage() }; +} + +#[cfg(feature = "apple")] +#[link(name = "Foundation", kind = "framework")] +extern "C" {} + fn retain_count(obj: &Object) -> usize { unsafe { msg_send![obj, retainCount] } } @@ -37,15 +47,6 @@ fn create_data(bytes: &[u8]) -> Id { #[test] fn test_retain_autoreleased() { - #[cfg(feature = "gnustep-1-7")] - unsafe { - objc2::__gnustep_hack::get_class_to_force_linkage() - }; - - #[cfg(feature = "apple")] - #[link(name = "Foundation", kind = "framework")] - extern "C" {} - autoreleasepool(|_| { // Run once to allow DYLD to resolve the symbol stubs. // Required for making `retain_autoreleased` work on x86_64. diff --git a/objc2/tests/no_prelude.rs b/objc2/tests/no_prelude.rs index 995cb7b4b..de3c7236e 100644 --- a/objc2/tests/no_prelude.rs +++ b/objc2/tests/no_prelude.rs @@ -9,6 +9,16 @@ extern crate objc2 as new_objc2; +#[cfg(feature = "gnustep-1-7")] +#[test] +fn ensure_linkage() { + unsafe { new_objc2::__gnustep_hack::get_class_to_force_linkage() }; +} + +#[cfg(feature = "apple")] +#[link(name = "Foundation", kind = "framework")] +extern "C" {} + mod core {} mod std {} mod libc {} diff --git a/objc2/tests/use_macros.rs b/objc2/tests/use_macros.rs index b58ebe190..eeb7613cf 100644 --- a/objc2/tests/use_macros.rs +++ b/objc2/tests/use_macros.rs @@ -7,6 +7,10 @@ fn ensure_linkage() { unsafe { objc2::__gnustep_hack::get_class_to_force_linkage() }; } +#[cfg(feature = "apple")] +#[link(name = "Foundation", kind = "framework")] +extern "C" {} + #[test] fn use_class_and_msg_send() { unsafe { diff --git a/tests/assembly/test_static_class/Cargo.toml b/tests/assembly/test_static_class/Cargo.toml new file mode 100644 index 000000000..46b8a1047 --- /dev/null +++ b/tests/assembly/test_static_class/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "test_static_class" +version = "0.1.0" +edition = "2021" +publish = false + +[lib] +path = "lib.rs" + +[dependencies] +objc2 = { path = "../../../objc2", default-features = false } + +[features] +default = ["apple", "std"] +std = ["objc2/std"] +# Runtime +apple = ["objc2/apple"] +gnustep-1-7 = ["objc2/gnustep-1-7"] +gnustep-1-8 = ["gnustep-1-7", "objc2/gnustep-1-8"] +gnustep-1-9 = ["gnustep-1-8", "objc2/gnustep-1-9"] +gnustep-2-0 = ["gnustep-1-9", "objc2/gnustep-2-0"] +gnustep-2-1 = ["gnustep-2-0", "objc2/gnustep-2-1"] + +# Hack to prevent the feature flag from being enabled in the entire project +assembly-features = ["objc2/unstable-static-class-inlined"] diff --git a/tests/assembly/test_static_class/expected/apple-aarch64.s b/tests/assembly/test_static_class/expected/apple-aarch64.s new file mode 100644 index 000000000..ddf3851ba --- /dev/null +++ b/tests/assembly/test_static_class/expected/apple-aarch64.s @@ -0,0 +1,152 @@ + .section __TEXT,__text,regular,pure_instructions + .globl _get_class + .p2align 2 +_get_class: +Lloh0: + adrp x8, L_OBJC_CLASSLIST_REFERENCES_$_e0796f2f86586929@PAGE +Lloh1: + ldr x0, [x8, L_OBJC_CLASSLIST_REFERENCES_$_e0796f2f86586929@PAGEOFF] + ret + .loh AdrpLdr Lloh0, Lloh1 + + .globl _get_same_class + .p2align 2 +_get_same_class: +Lloh2: + adrp x8, L_OBJC_CLASSLIST_REFERENCES_$_1121b6b8519ae283@PAGE +Lloh3: + ldr x0, [x8, L_OBJC_CLASSLIST_REFERENCES_$_1121b6b8519ae283@PAGEOFF] + ret + .loh AdrpLdr Lloh2, Lloh3 + + .globl _get_different_class + .p2align 2 +_get_different_class: +Lloh4: + adrp x8, L_OBJC_CLASSLIST_REFERENCES_$_7314246f93b118b1@PAGE +Lloh5: + ldr x0, [x8, L_OBJC_CLASSLIST_REFERENCES_$_7314246f93b118b1@PAGEOFF] + ret + .loh AdrpLdr Lloh4, Lloh5 + + .globl _unused_sel + .p2align 2 +_unused_sel: + ret + + .globl _use_fns + .p2align 2 +_use_fns: +Lloh6: + adrp x9, L_OBJC_CLASSLIST_REFERENCES_$_e0796f2f86586929@PAGE +Lloh7: + ldr x9, [x9, L_OBJC_CLASSLIST_REFERENCES_$_e0796f2f86586929@PAGEOFF] +Lloh8: + adrp x10, L_OBJC_CLASSLIST_REFERENCES_$_1121b6b8519ae283@PAGE +Lloh9: + ldr x10, [x10, L_OBJC_CLASSLIST_REFERENCES_$_1121b6b8519ae283@PAGEOFF] +Lloh10: + adrp x11, L_OBJC_CLASSLIST_REFERENCES_$_7314246f93b118b1@PAGE +Lloh11: + ldr x11, [x11, L_OBJC_CLASSLIST_REFERENCES_$_7314246f93b118b1@PAGEOFF] +Lloh12: + adrp x12, L_OBJC_CLASSLIST_REFERENCES_$_16e72be3e810c687@PAGE +Lloh13: + ldr x12, [x12, L_OBJC_CLASSLIST_REFERENCES_$_16e72be3e810c687@PAGEOFF] + stp x9, x10, [x8] + stp x11, x12, [x8, #16] + ret + .loh AdrpLdr Lloh12, Lloh13 + .loh AdrpLdr Lloh10, Lloh11 + .loh AdrpLdr Lloh8, Lloh9 + .loh AdrpLdr Lloh6, Lloh7 + + .globl _use_same_twice + .p2align 2 +_use_same_twice: +Lloh14: + adrp x9, L_OBJC_CLASSLIST_REFERENCES_$_e0796f2f86586929@PAGE +Lloh15: + ldr x9, [x9, L_OBJC_CLASSLIST_REFERENCES_$_e0796f2f86586929@PAGEOFF] + stp x9, x9, [x8] + ret + .loh AdrpLdr Lloh14, Lloh15 + + .globl _use_in_loop + .p2align 2 +_use_in_loop: + ret + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_e0796f2f86586929 + .p2align 2 +L_OBJC_IMAGE_INFO_e0796f2f86586929: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__objc_classrefs,regular,no_dead_strip + .globl L_OBJC_CLASSLIST_REFERENCES_$_e0796f2f86586929 + .p2align 3 +L_OBJC_CLASSLIST_REFERENCES_$_e0796f2f86586929: + .quad _OBJC_CLASS_$_NSObject + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_1121b6b8519ae283 + .p2align 2 +L_OBJC_IMAGE_INFO_1121b6b8519ae283: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__objc_classrefs,regular,no_dead_strip + .globl L_OBJC_CLASSLIST_REFERENCES_$_1121b6b8519ae283 + .p2align 3 +L_OBJC_CLASSLIST_REFERENCES_$_1121b6b8519ae283: + .quad _OBJC_CLASS_$_NSObject + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_7314246f93b118b1 + .p2align 2 +L_OBJC_IMAGE_INFO_7314246f93b118b1: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__objc_classrefs,regular,no_dead_strip + .globl L_OBJC_CLASSLIST_REFERENCES_$_7314246f93b118b1 + .p2align 3 +L_OBJC_CLASSLIST_REFERENCES_$_7314246f93b118b1: + .quad _OBJC_CLASS_$_NSString + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_f5b45e093b02d6c9 + .p2align 2 +L_OBJC_IMAGE_INFO_f5b45e093b02d6c9: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__objc_classrefs,regular,no_dead_strip + .globl L_OBJC_CLASSLIST_REFERENCES_$_f5b45e093b02d6c9 + .p2align 3 +L_OBJC_CLASSLIST_REFERENCES_$_f5b45e093b02d6c9: + .quad _OBJC_CLASS_$_NSData + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_16e72be3e810c687 + .p2align 2 +L_OBJC_IMAGE_INFO_16e72be3e810c687: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__objc_classrefs,regular,no_dead_strip + .globl L_OBJC_CLASSLIST_REFERENCES_$_16e72be3e810c687 + .p2align 3 +L_OBJC_CLASSLIST_REFERENCES_$_16e72be3e810c687: + .quad _OBJC_CLASS_$_NSException + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_4465b4c2c67ae674 + .p2align 2 +L_OBJC_IMAGE_INFO_4465b4c2c67ae674: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__objc_classrefs,regular,no_dead_strip + .globl L_OBJC_CLASSLIST_REFERENCES_$_4465b4c2c67ae674 + .p2align 3 +L_OBJC_CLASSLIST_REFERENCES_$_4465b4c2c67ae674: + .quad _OBJC_CLASS_$_NSLock + +.subsections_via_symbols diff --git a/tests/assembly/test_static_class/expected/apple-armv7.s b/tests/assembly/test_static_class/expected/apple-armv7.s new file mode 100644 index 000000000..f5290a3ef --- /dev/null +++ b/tests/assembly/test_static_class/expected/apple-armv7.s @@ -0,0 +1,154 @@ + .section __TEXT,__text,regular,pure_instructions + .syntax unified + .globl _get_class + .p2align 2 + .code 32 +_get_class: + movw r0, :lower16:(L_OBJC_CLASSLIST_REFERENCES_$_e0796f2f86586929-(LPC0_0+8)) + movt r0, :upper16:(L_OBJC_CLASSLIST_REFERENCES_$_e0796f2f86586929-(LPC0_0+8)) +LPC0_0: + ldr r0, [pc, r0] + bx lr + + .globl _get_same_class + .p2align 2 + .code 32 +_get_same_class: + movw r0, :lower16:(L_OBJC_CLASSLIST_REFERENCES_$_1121b6b8519ae283-(LPC1_0+8)) + movt r0, :upper16:(L_OBJC_CLASSLIST_REFERENCES_$_1121b6b8519ae283-(LPC1_0+8)) +LPC1_0: + ldr r0, [pc, r0] + bx lr + + .globl _get_different_class + .p2align 2 + .code 32 +_get_different_class: + movw r0, :lower16:(L_OBJC_CLASSLIST_REFERENCES_$_7314246f93b118b1-(LPC2_0+8)) + movt r0, :upper16:(L_OBJC_CLASSLIST_REFERENCES_$_7314246f93b118b1-(LPC2_0+8)) +LPC2_0: + ldr r0, [pc, r0] + bx lr + + .globl _unused_sel + .p2align 2 + .code 32 +_unused_sel: + bx lr + + .globl _use_fns + .p2align 2 + .code 32 +_use_fns: + movw r9, :lower16:(L_OBJC_CLASSLIST_REFERENCES_$_16e72be3e810c687-(LPC4_0+8)) + movt r9, :upper16:(L_OBJC_CLASSLIST_REFERENCES_$_16e72be3e810c687-(LPC4_0+8)) +LPC4_0: + ldr r9, [pc, r9] + movw r2, :lower16:(L_OBJC_CLASSLIST_REFERENCES_$_7314246f93b118b1-(LPC4_1+8)) + movt r2, :upper16:(L_OBJC_CLASSLIST_REFERENCES_$_7314246f93b118b1-(LPC4_1+8)) +LPC4_1: + ldr r2, [pc, r2] + movw r3, :lower16:(L_OBJC_CLASSLIST_REFERENCES_$_1121b6b8519ae283-(LPC4_2+8)) + movt r3, :upper16:(L_OBJC_CLASSLIST_REFERENCES_$_1121b6b8519ae283-(LPC4_2+8)) +LPC4_2: + ldr r3, [pc, r3] + movw r1, :lower16:(L_OBJC_CLASSLIST_REFERENCES_$_e0796f2f86586929-(LPC4_3+8)) + movt r1, :upper16:(L_OBJC_CLASSLIST_REFERENCES_$_e0796f2f86586929-(LPC4_3+8)) + str r2, [r0, #8] +LPC4_3: + ldr r1, [pc, r1] + str r9, [r0, #12] + stm r0, {r1, r3} + bx lr + + .globl _use_same_twice + .p2align 2 + .code 32 +_use_same_twice: + movw r1, :lower16:(L_OBJC_CLASSLIST_REFERENCES_$_e0796f2f86586929-(LPC5_0+8)) + movt r1, :upper16:(L_OBJC_CLASSLIST_REFERENCES_$_e0796f2f86586929-(LPC5_0+8)) +LPC5_0: + ldr r1, [pc, r1] + str r1, [r0] + str r1, [r0, #4] + bx lr + + .globl _use_in_loop + .p2align 2 + .code 32 +_use_in_loop: + bx lr + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_e0796f2f86586929 + .p2align 2 +L_OBJC_IMAGE_INFO_e0796f2f86586929: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__objc_classrefs,regular,no_dead_strip + .globl L_OBJC_CLASSLIST_REFERENCES_$_e0796f2f86586929 + .p2align 2 +L_OBJC_CLASSLIST_REFERENCES_$_e0796f2f86586929: + .long _OBJC_CLASS_$_NSObject + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_1121b6b8519ae283 + .p2align 2 +L_OBJC_IMAGE_INFO_1121b6b8519ae283: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__objc_classrefs,regular,no_dead_strip + .globl L_OBJC_CLASSLIST_REFERENCES_$_1121b6b8519ae283 + .p2align 2 +L_OBJC_CLASSLIST_REFERENCES_$_1121b6b8519ae283: + .long _OBJC_CLASS_$_NSObject + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_7314246f93b118b1 + .p2align 2 +L_OBJC_IMAGE_INFO_7314246f93b118b1: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__objc_classrefs,regular,no_dead_strip + .globl L_OBJC_CLASSLIST_REFERENCES_$_7314246f93b118b1 + .p2align 2 +L_OBJC_CLASSLIST_REFERENCES_$_7314246f93b118b1: + .long _OBJC_CLASS_$_NSString + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_f5b45e093b02d6c9 + .p2align 2 +L_OBJC_IMAGE_INFO_f5b45e093b02d6c9: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__objc_classrefs,regular,no_dead_strip + .globl L_OBJC_CLASSLIST_REFERENCES_$_f5b45e093b02d6c9 + .p2align 2 +L_OBJC_CLASSLIST_REFERENCES_$_f5b45e093b02d6c9: + .long _OBJC_CLASS_$_NSData + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_16e72be3e810c687 + .p2align 2 +L_OBJC_IMAGE_INFO_16e72be3e810c687: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__objc_classrefs,regular,no_dead_strip + .globl L_OBJC_CLASSLIST_REFERENCES_$_16e72be3e810c687 + .p2align 2 +L_OBJC_CLASSLIST_REFERENCES_$_16e72be3e810c687: + .long _OBJC_CLASS_$_NSException + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_4465b4c2c67ae674 + .p2align 2 +L_OBJC_IMAGE_INFO_4465b4c2c67ae674: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__objc_classrefs,regular,no_dead_strip + .globl L_OBJC_CLASSLIST_REFERENCES_$_4465b4c2c67ae674 + .p2align 2 +L_OBJC_CLASSLIST_REFERENCES_$_4465b4c2c67ae674: + .long _OBJC_CLASS_$_NSLock + +.subsections_via_symbols diff --git a/tests/assembly/test_static_class/expected/apple-armv7s.s b/tests/assembly/test_static_class/expected/apple-armv7s.s new file mode 100644 index 000000000..f5290a3ef --- /dev/null +++ b/tests/assembly/test_static_class/expected/apple-armv7s.s @@ -0,0 +1,154 @@ + .section __TEXT,__text,regular,pure_instructions + .syntax unified + .globl _get_class + .p2align 2 + .code 32 +_get_class: + movw r0, :lower16:(L_OBJC_CLASSLIST_REFERENCES_$_e0796f2f86586929-(LPC0_0+8)) + movt r0, :upper16:(L_OBJC_CLASSLIST_REFERENCES_$_e0796f2f86586929-(LPC0_0+8)) +LPC0_0: + ldr r0, [pc, r0] + bx lr + + .globl _get_same_class + .p2align 2 + .code 32 +_get_same_class: + movw r0, :lower16:(L_OBJC_CLASSLIST_REFERENCES_$_1121b6b8519ae283-(LPC1_0+8)) + movt r0, :upper16:(L_OBJC_CLASSLIST_REFERENCES_$_1121b6b8519ae283-(LPC1_0+8)) +LPC1_0: + ldr r0, [pc, r0] + bx lr + + .globl _get_different_class + .p2align 2 + .code 32 +_get_different_class: + movw r0, :lower16:(L_OBJC_CLASSLIST_REFERENCES_$_7314246f93b118b1-(LPC2_0+8)) + movt r0, :upper16:(L_OBJC_CLASSLIST_REFERENCES_$_7314246f93b118b1-(LPC2_0+8)) +LPC2_0: + ldr r0, [pc, r0] + bx lr + + .globl _unused_sel + .p2align 2 + .code 32 +_unused_sel: + bx lr + + .globl _use_fns + .p2align 2 + .code 32 +_use_fns: + movw r9, :lower16:(L_OBJC_CLASSLIST_REFERENCES_$_16e72be3e810c687-(LPC4_0+8)) + movt r9, :upper16:(L_OBJC_CLASSLIST_REFERENCES_$_16e72be3e810c687-(LPC4_0+8)) +LPC4_0: + ldr r9, [pc, r9] + movw r2, :lower16:(L_OBJC_CLASSLIST_REFERENCES_$_7314246f93b118b1-(LPC4_1+8)) + movt r2, :upper16:(L_OBJC_CLASSLIST_REFERENCES_$_7314246f93b118b1-(LPC4_1+8)) +LPC4_1: + ldr r2, [pc, r2] + movw r3, :lower16:(L_OBJC_CLASSLIST_REFERENCES_$_1121b6b8519ae283-(LPC4_2+8)) + movt r3, :upper16:(L_OBJC_CLASSLIST_REFERENCES_$_1121b6b8519ae283-(LPC4_2+8)) +LPC4_2: + ldr r3, [pc, r3] + movw r1, :lower16:(L_OBJC_CLASSLIST_REFERENCES_$_e0796f2f86586929-(LPC4_3+8)) + movt r1, :upper16:(L_OBJC_CLASSLIST_REFERENCES_$_e0796f2f86586929-(LPC4_3+8)) + str r2, [r0, #8] +LPC4_3: + ldr r1, [pc, r1] + str r9, [r0, #12] + stm r0, {r1, r3} + bx lr + + .globl _use_same_twice + .p2align 2 + .code 32 +_use_same_twice: + movw r1, :lower16:(L_OBJC_CLASSLIST_REFERENCES_$_e0796f2f86586929-(LPC5_0+8)) + movt r1, :upper16:(L_OBJC_CLASSLIST_REFERENCES_$_e0796f2f86586929-(LPC5_0+8)) +LPC5_0: + ldr r1, [pc, r1] + str r1, [r0] + str r1, [r0, #4] + bx lr + + .globl _use_in_loop + .p2align 2 + .code 32 +_use_in_loop: + bx lr + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_e0796f2f86586929 + .p2align 2 +L_OBJC_IMAGE_INFO_e0796f2f86586929: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__objc_classrefs,regular,no_dead_strip + .globl L_OBJC_CLASSLIST_REFERENCES_$_e0796f2f86586929 + .p2align 2 +L_OBJC_CLASSLIST_REFERENCES_$_e0796f2f86586929: + .long _OBJC_CLASS_$_NSObject + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_1121b6b8519ae283 + .p2align 2 +L_OBJC_IMAGE_INFO_1121b6b8519ae283: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__objc_classrefs,regular,no_dead_strip + .globl L_OBJC_CLASSLIST_REFERENCES_$_1121b6b8519ae283 + .p2align 2 +L_OBJC_CLASSLIST_REFERENCES_$_1121b6b8519ae283: + .long _OBJC_CLASS_$_NSObject + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_7314246f93b118b1 + .p2align 2 +L_OBJC_IMAGE_INFO_7314246f93b118b1: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__objc_classrefs,regular,no_dead_strip + .globl L_OBJC_CLASSLIST_REFERENCES_$_7314246f93b118b1 + .p2align 2 +L_OBJC_CLASSLIST_REFERENCES_$_7314246f93b118b1: + .long _OBJC_CLASS_$_NSString + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_f5b45e093b02d6c9 + .p2align 2 +L_OBJC_IMAGE_INFO_f5b45e093b02d6c9: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__objc_classrefs,regular,no_dead_strip + .globl L_OBJC_CLASSLIST_REFERENCES_$_f5b45e093b02d6c9 + .p2align 2 +L_OBJC_CLASSLIST_REFERENCES_$_f5b45e093b02d6c9: + .long _OBJC_CLASS_$_NSData + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_16e72be3e810c687 + .p2align 2 +L_OBJC_IMAGE_INFO_16e72be3e810c687: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__objc_classrefs,regular,no_dead_strip + .globl L_OBJC_CLASSLIST_REFERENCES_$_16e72be3e810c687 + .p2align 2 +L_OBJC_CLASSLIST_REFERENCES_$_16e72be3e810c687: + .long _OBJC_CLASS_$_NSException + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_4465b4c2c67ae674 + .p2align 2 +L_OBJC_IMAGE_INFO_4465b4c2c67ae674: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__objc_classrefs,regular,no_dead_strip + .globl L_OBJC_CLASSLIST_REFERENCES_$_4465b4c2c67ae674 + .p2align 2 +L_OBJC_CLASSLIST_REFERENCES_$_4465b4c2c67ae674: + .long _OBJC_CLASS_$_NSLock + +.subsections_via_symbols diff --git a/tests/assembly/test_static_class/expected/apple-old-x86.s b/tests/assembly/test_static_class/expected/apple-old-x86.s new file mode 100644 index 000000000..d3cea7aab --- /dev/null +++ b/tests/assembly/test_static_class/expected/apple-old-x86.s @@ -0,0 +1,3 @@ + .section __TEXT,__text,regular,pure_instructions + .intel_syntax noprefix +.subsections_via_symbols diff --git a/tests/assembly/test_static_class/expected/apple-x86.s b/tests/assembly/test_static_class/expected/apple-x86.s new file mode 100644 index 000000000..9edd358ea --- /dev/null +++ b/tests/assembly/test_static_class/expected/apple-x86.s @@ -0,0 +1,166 @@ + .section __TEXT,__text,regular,pure_instructions + .intel_syntax noprefix + .globl _get_class + .p2align 4, 0x90 +_get_class: + push ebp + mov ebp, esp + call L0$pb +L0$pb: + pop eax + mov eax, dword ptr [eax + L_OBJC_CLASSLIST_REFERENCES_$_e0796f2f86586929-L0$pb] + pop ebp + ret + + .globl _get_same_class + .p2align 4, 0x90 +_get_same_class: + push ebp + mov ebp, esp + call L1$pb +L1$pb: + pop eax + mov eax, dword ptr [eax + L_OBJC_CLASSLIST_REFERENCES_$_1121b6b8519ae283-L1$pb] + pop ebp + ret + + .globl _get_different_class + .p2align 4, 0x90 +_get_different_class: + push ebp + mov ebp, esp + call L2$pb +L2$pb: + pop eax + mov eax, dword ptr [eax + L_OBJC_CLASSLIST_REFERENCES_$_7314246f93b118b1-L2$pb] + pop ebp + ret + + .globl _unused_sel + .p2align 4, 0x90 +_unused_sel: + push ebp + mov ebp, esp + pop ebp + ret + + .globl _use_fns + .p2align 4, 0x90 +_use_fns: + push ebp + mov ebp, esp + push edi + push esi + call L4$pb +L4$pb: + pop ecx + mov eax, dword ptr [ebp + 8] + mov edx, dword ptr [ecx + L_OBJC_CLASSLIST_REFERENCES_$_e0796f2f86586929-L4$pb] + mov esi, dword ptr [ecx + L_OBJC_CLASSLIST_REFERENCES_$_1121b6b8519ae283-L4$pb] + mov edi, dword ptr [ecx + L_OBJC_CLASSLIST_REFERENCES_$_7314246f93b118b1-L4$pb] + mov ecx, dword ptr [ecx + L_OBJC_CLASSLIST_REFERENCES_$_16e72be3e810c687-L4$pb] + mov dword ptr [eax], edx + mov dword ptr [eax + 4], esi + mov dword ptr [eax + 8], edi + mov dword ptr [eax + 12], ecx + pop esi + pop edi + pop ebp + ret 4 + + .globl _use_same_twice + .p2align 4, 0x90 +_use_same_twice: + push ebp + mov ebp, esp + call L5$pb +L5$pb: + pop ecx + mov eax, dword ptr [ebp + 8] + mov ecx, dword ptr [ecx + L_OBJC_CLASSLIST_REFERENCES_$_e0796f2f86586929-L5$pb] + mov dword ptr [eax], ecx + mov dword ptr [eax + 4], ecx + pop ebp + ret 4 + + .globl _use_in_loop + .p2align 4, 0x90 +_use_in_loop: + push ebp + mov ebp, esp + pop ebp + ret + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_e0796f2f86586929 + .p2align 2 +L_OBJC_IMAGE_INFO_e0796f2f86586929: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__objc_classrefs,regular,no_dead_strip + .globl L_OBJC_CLASSLIST_REFERENCES_$_e0796f2f86586929 + .p2align 2 +L_OBJC_CLASSLIST_REFERENCES_$_e0796f2f86586929: + .long _OBJC_CLASS_$_NSObject + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_1121b6b8519ae283 + .p2align 2 +L_OBJC_IMAGE_INFO_1121b6b8519ae283: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__objc_classrefs,regular,no_dead_strip + .globl L_OBJC_CLASSLIST_REFERENCES_$_1121b6b8519ae283 + .p2align 2 +L_OBJC_CLASSLIST_REFERENCES_$_1121b6b8519ae283: + .long _OBJC_CLASS_$_NSObject + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_7314246f93b118b1 + .p2align 2 +L_OBJC_IMAGE_INFO_7314246f93b118b1: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__objc_classrefs,regular,no_dead_strip + .globl L_OBJC_CLASSLIST_REFERENCES_$_7314246f93b118b1 + .p2align 2 +L_OBJC_CLASSLIST_REFERENCES_$_7314246f93b118b1: + .long _OBJC_CLASS_$_NSString + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_f5b45e093b02d6c9 + .p2align 2 +L_OBJC_IMAGE_INFO_f5b45e093b02d6c9: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__objc_classrefs,regular,no_dead_strip + .globl L_OBJC_CLASSLIST_REFERENCES_$_f5b45e093b02d6c9 + .p2align 2 +L_OBJC_CLASSLIST_REFERENCES_$_f5b45e093b02d6c9: + .long _OBJC_CLASS_$_NSData + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_16e72be3e810c687 + .p2align 2 +L_OBJC_IMAGE_INFO_16e72be3e810c687: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__objc_classrefs,regular,no_dead_strip + .globl L_OBJC_CLASSLIST_REFERENCES_$_16e72be3e810c687 + .p2align 2 +L_OBJC_CLASSLIST_REFERENCES_$_16e72be3e810c687: + .long _OBJC_CLASS_$_NSException + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_4465b4c2c67ae674 + .p2align 2 +L_OBJC_IMAGE_INFO_4465b4c2c67ae674: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__objc_classrefs,regular,no_dead_strip + .globl L_OBJC_CLASSLIST_REFERENCES_$_4465b4c2c67ae674 + .p2align 2 +L_OBJC_CLASSLIST_REFERENCES_$_4465b4c2c67ae674: + .long _OBJC_CLASS_$_NSLock + +.subsections_via_symbols diff --git a/tests/assembly/test_static_class/expected/apple-x86_64.s b/tests/assembly/test_static_class/expected/apple-x86_64.s new file mode 100644 index 000000000..3659952b3 --- /dev/null +++ b/tests/assembly/test_static_class/expected/apple-x86_64.s @@ -0,0 +1,147 @@ + .section __TEXT,__text,regular,pure_instructions + .intel_syntax noprefix + .globl _get_class + .p2align 4, 0x90 +_get_class: + push rbp + mov rbp, rsp + mov rax, qword ptr [rip + L_OBJC_CLASSLIST_REFERENCES_$_e0796f2f86586929] + pop rbp + ret + + .globl _get_same_class + .p2align 4, 0x90 +_get_same_class: + push rbp + mov rbp, rsp + mov rax, qword ptr [rip + L_OBJC_CLASSLIST_REFERENCES_$_1121b6b8519ae283] + pop rbp + ret + + .globl _get_different_class + .p2align 4, 0x90 +_get_different_class: + push rbp + mov rbp, rsp + mov rax, qword ptr [rip + L_OBJC_CLASSLIST_REFERENCES_$_7314246f93b118b1] + pop rbp + ret + + .globl _unused_sel + .p2align 4, 0x90 +_unused_sel: + push rbp + mov rbp, rsp + pop rbp + ret + + .globl _use_fns + .p2align 4, 0x90 +_use_fns: + push rbp + mov rbp, rsp + mov rax, rdi + mov rcx, qword ptr [rip + L_OBJC_CLASSLIST_REFERENCES_$_e0796f2f86586929] + mov rdx, qword ptr [rip + L_OBJC_CLASSLIST_REFERENCES_$_1121b6b8519ae283] + mov rsi, qword ptr [rip + L_OBJC_CLASSLIST_REFERENCES_$_7314246f93b118b1] + mov rdi, qword ptr [rip + L_OBJC_CLASSLIST_REFERENCES_$_16e72be3e810c687] + mov qword ptr [rax], rcx + mov qword ptr [rax + 8], rdx + mov qword ptr [rax + 16], rsi + mov qword ptr [rax + 24], rdi + pop rbp + ret + + .globl _use_same_twice + .p2align 4, 0x90 +_use_same_twice: + push rbp + mov rbp, rsp + mov rax, rdi + mov rcx, qword ptr [rip + L_OBJC_CLASSLIST_REFERENCES_$_e0796f2f86586929] + mov qword ptr [rdi], rcx + mov qword ptr [rdi + 8], rcx + pop rbp + ret + + .globl _use_in_loop + .p2align 4, 0x90 +_use_in_loop: + push rbp + mov rbp, rsp + pop rbp + ret + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_e0796f2f86586929 + .p2align 2 +L_OBJC_IMAGE_INFO_e0796f2f86586929: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__objc_classrefs,regular,no_dead_strip + .globl L_OBJC_CLASSLIST_REFERENCES_$_e0796f2f86586929 + .p2align 3 +L_OBJC_CLASSLIST_REFERENCES_$_e0796f2f86586929: + .quad _OBJC_CLASS_$_NSObject + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_1121b6b8519ae283 + .p2align 2 +L_OBJC_IMAGE_INFO_1121b6b8519ae283: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__objc_classrefs,regular,no_dead_strip + .globl L_OBJC_CLASSLIST_REFERENCES_$_1121b6b8519ae283 + .p2align 3 +L_OBJC_CLASSLIST_REFERENCES_$_1121b6b8519ae283: + .quad _OBJC_CLASS_$_NSObject + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_7314246f93b118b1 + .p2align 2 +L_OBJC_IMAGE_INFO_7314246f93b118b1: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__objc_classrefs,regular,no_dead_strip + .globl L_OBJC_CLASSLIST_REFERENCES_$_7314246f93b118b1 + .p2align 3 +L_OBJC_CLASSLIST_REFERENCES_$_7314246f93b118b1: + .quad _OBJC_CLASS_$_NSString + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_f5b45e093b02d6c9 + .p2align 2 +L_OBJC_IMAGE_INFO_f5b45e093b02d6c9: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__objc_classrefs,regular,no_dead_strip + .globl L_OBJC_CLASSLIST_REFERENCES_$_f5b45e093b02d6c9 + .p2align 3 +L_OBJC_CLASSLIST_REFERENCES_$_f5b45e093b02d6c9: + .quad _OBJC_CLASS_$_NSData + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_16e72be3e810c687 + .p2align 2 +L_OBJC_IMAGE_INFO_16e72be3e810c687: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__objc_classrefs,regular,no_dead_strip + .globl L_OBJC_CLASSLIST_REFERENCES_$_16e72be3e810c687 + .p2align 3 +L_OBJC_CLASSLIST_REFERENCES_$_16e72be3e810c687: + .quad _OBJC_CLASS_$_NSException + + .section __DATA,__objc_imageinfo,regular,no_dead_strip + .globl L_OBJC_IMAGE_INFO_4465b4c2c67ae674 + .p2align 2 +L_OBJC_IMAGE_INFO_4465b4c2c67ae674: + .asciz "\000\000\000\000@\000\000" + + .section __DATA,__objc_classrefs,regular,no_dead_strip + .globl L_OBJC_CLASSLIST_REFERENCES_$_4465b4c2c67ae674 + .p2align 3 +L_OBJC_CLASSLIST_REFERENCES_$_4465b4c2c67ae674: + .quad _OBJC_CLASS_$_NSLock + +.subsections_via_symbols diff --git a/tests/assembly/test_static_class/lib.rs b/tests/assembly/test_static_class/lib.rs new file mode 100644 index 000000000..5476089c6 --- /dev/null +++ b/tests/assembly/test_static_class/lib.rs @@ -0,0 +1,51 @@ +//! Test the output of the `class!` macro. +#![cfg(all(feature = "apple", not(all(target_os = "macos", target_arch = "x86"))))] +use objc2::class; +use objc2::runtime::Class; + +#[cfg(feature = "apple")] +#[link(name = "Foundation", kind = "framework")] +extern "C" {} + +#[no_mangle] +fn get_class() -> &'static Class { + class!(NSObject) +} + +#[no_mangle] +fn get_same_class() -> &'static Class { + class!(NSObject) +} + +#[no_mangle] +fn get_different_class() -> &'static Class { + class!(NSString) +} + +#[no_mangle] +fn unused_sel() { + let _ = class!(NSData); +} + +#[no_mangle] +fn use_fns() -> [&'static Class; 4] { + let s1 = get_class(); + let s2 = get_same_class(); + let s3 = get_different_class(); + let s4 = class!(NSException); + [s1, s2, s3, s4] +} + +#[no_mangle] +fn use_same_twice() -> [&'static Class; 2] { + // Should not need to load twice + [get_class(), get_class()] +} + +#[no_mangle] +fn use_in_loop(n: usize) { + for _i in 0..n { + // Should be a noop + let _ = class!(NSLock); + } +}