diff --git a/objc-sys/Cargo.toml b/objc-sys/Cargo.toml index 4e4def307..710b2af0b 100644 --- a/objc-sys/Cargo.toml +++ b/objc-sys/Cargo.toml @@ -59,6 +59,9 @@ unstable-docsrs = [] [build-dependencies] cc = { version = "1", optional = true } +[dependencies] +objc2-proc-macros = { path = "../objc2-proc-macros" } + [package.metadata.docs.rs] default-target = "x86_64-apple-darwin" no-default-features = true diff --git a/objc-sys/build.rs b/objc-sys/build.rs index ecc07a847..8391792fe 100644 --- a/objc-sys/build.rs +++ b/objc-sys/build.rs @@ -99,6 +99,8 @@ fn main() { } } + println!("cargo:rustc-env=MACOSX_DEPLOYMENT_TARGET=10.11"); + let runtime = match (apple, gnustep, objfw) { (true, false, false) => { Apple(match &*target_os { diff --git a/objc-sys/src/internal.rs b/objc-sys/src/internal.rs new file mode 100644 index 000000000..cddb51c7f --- /dev/null +++ b/objc-sys/src/internal.rs @@ -0,0 +1,18 @@ +//! Defined in `objc-internal.h` +#[allow(unused)] +use crate::{objc_class, objc_object}; +use objc2_proc_macros::cfg_available; + +extern_c_unwind! { + #[cfg(apple)] + #[cfg_available(macOS(10.9), iOS(7.0), tvOS(9.0), watchOS(1.0))] + pub fn objc_alloc(cls: *const objc_class) -> *mut objc_object; + + #[cfg(apple)] + #[cfg_available(macOS(10.14.4), iOS(12.2), tvOS(12.2), watchOS(5.2))] + pub fn objc_alloc_init(cls: *const objc_class) -> *mut objc_object; + + #[cfg(apple)] + #[cfg_available(macOS(10.15), iOS(13.0), tvOS(13.0), watchOS(6.0))] + pub fn objc_opt_new(cls: *const objc_class) -> *mut objc_object; +} diff --git a/objc-sys/src/lib.rs b/objc-sys/src/lib.rs index dea08cbf4..23465d7f2 100644 --- a/objc-sys/src/lib.rs +++ b/objc-sys/src/lib.rs @@ -140,6 +140,7 @@ mod constants; mod exception; mod image_info; +mod internal; mod message; mod method; mod object; @@ -154,6 +155,7 @@ pub use class::*; pub use constants::*; pub use exception::*; pub use image_info::*; +pub use internal::*; pub use message::*; pub use method::*; pub use object::*; diff --git a/objc2-proc-macros/src/available.rs b/objc2-proc-macros/src/available.rs new file mode 100644 index 000000000..00245da29 --- /dev/null +++ b/objc2-proc-macros/src/available.rs @@ -0,0 +1,248 @@ +//! https://developer.apple.com/library/archive/documentation/DeveloperTools/Conceptual/cross_development/Introduction/Introduction.html +//! https://developer.apple.com/library/archive/technotes/tn2064/_index.html +//! See also AvailabilityMacros.h and Availability.h +//! https://clang.llvm.org/docs/LanguageExtensions.html#objective-c-available + +use std::str::FromStr; + +use crate::deployment_target::{self, Version}; +use proc_macro::{Delimiter, TokenStream, TokenTree}; + +fn macos(min: Version) -> Option<&'static str> { + // Note: Implicitly assumes that `macos_aarch64` will return an equal or + // higher value than `macos` + + if deployment_target::macos() >= min { + // Available on all macOS + Some(r#"target_os = "macos""#) + } else if deployment_target::macos_aarch64() >= min { + // Available on Aarch64, not available on others + Some(r#"not(all(target_os = "macos", not(target_arch = "aarch64")))"#) + } else { + // Not available on macOS + None + } +} + +fn ios(min: Version) -> Option<&'static str> { + if deployment_target::ios() >= min { + Some(r#"target_os = "ios""#) + } else { + None + } +} + +fn tvos(min: Version) -> Option<&'static str> { + match deployment_target::tvos() { + Some(v) if v >= min => Some(r#"target_os = "tvos""#), + // Disable everything on tvOS if deployment target is not specified + // TODO: Change this once rustc sets a default deployment target + _ => None, + } +} + +fn watchos(min: Version) -> Option<&'static str> { + if deployment_target::watchos() >= min { + Some(r#"target_os = "watchos""#) + } else { + None + } +} + +#[derive(Debug, Default)] +pub(crate) struct AvailableSince { + macos: Option, + ios: Option, + tvos: Option, + watchos: Option, +} + +impl AvailableSince { + pub(crate) fn from_tokenstream(attr: TokenStream) -> Self { + let mut this = Self::default(); + let mut iter = attr.into_iter(); + loop { + let ident = match iter.next() { + Some(TokenTree::Ident(ident)) => ident, + None => return this, + _ => panic!("expected ident"), + }; + let version = match iter.next() { + Some(TokenTree::Group(group)) => { + assert_eq!( + group.delimiter(), + Delimiter::Parenthesis, + "Invalid delimiters" + ); + Version::from_str(&group.stream().to_string()).expect("Invalid version") + } + _ => panic!("expected version string"), + }; + let os = ident.to_string(); + match &*os { + "macOS" => this.macos = Some(version), + "iOS" => this.ios = Some(version), + "tvOS" => this.tvos = Some(version), + "watchOS" => this.watchos = Some(version), + _ => panic!("Unknown OS {}", os), + } + let _comma = match iter.next() { + Some(TokenTree::Punct(ident)) => ident, + None => return this, + _ => panic!("expected ident"), + }; + } + } + + fn into_cfg_string(&self) -> String { + let mut result = "any(".to_string(); + if let Some(s) = self.macos.and_then(macos) { + result += s; + result += ", "; + } + if let Some(s) = self.ios.and_then(ios) { + result += s; + result += ", "; + } + if let Some(s) = self.tvos.and_then(tvos) { + result += s; + result += ", "; + } + if let Some(s) = self.watchos.and_then(watchos) { + result += s; + result += ", "; + } + if result == "any(" { + // If didn't change + result.push_str("__not_available_anywhere"); + } else { + // Remove extra ", " + result.pop(); + result.pop(); + } + result += ")"; + result + } + + pub(crate) fn into_cfg(self) -> TokenStream { + format!("#[cfg({})]", self.into_cfg_string()) + .parse() + .expect("invalid cfg string") + } + + pub(crate) fn into_not_cfg(self) -> TokenStream { + format!("#[cfg(not({}))]", self.into_cfg_string()) + .parse() + .expect("invalid cfg string") + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_availability_cfg_string() { + #[track_caller] + fn assert_cfg(available_since: &AvailableSince, expected: &str) { + assert_eq!(available_since.into_cfg_string(), expected); + } + + let mut available_since = AvailableSince::default(); + assert_cfg(&available_since, r#"any(__not_available_anywhere)"#); + + available_since.macos = Some(Version::new(12, 0)); + assert_cfg(&available_since, r#"any(__not_available_anywhere)"#); + available_since.macos = Some(Version::new(10, 0)); + assert_cfg(&available_since, r#"any(target_os = "macos")"#); + + available_since.ios = Some(Version::new(9, 0)); + assert_cfg(&available_since, r#"any(target_os = "macos")"#); + available_since.ios = Some(Version::new(5, 0)); + assert_cfg( + &available_since, + r#"any(target_os = "macos", target_os = "ios")"#, + ); + + available_since.tvos = Some(Version::new(0, 0)); + assert_cfg( + &available_since, + r#"any(target_os = "macos", target_os = "ios")"#, + ); + + available_since.watchos = Some(Version::new(0, 0)); + assert_cfg( + &available_since, + r#"any(target_os = "macos", target_os = "ios", target_os = "watchos")"#, + ); + } +} + +#[cfg(ideas)] +mod ideas { + //! Ideas for usage + + // Procedural macros + + // Mimic Objective-C: + // __API_AVAILABLE(macos(10.4), ios(8.0), watchos(2.0), tvos(10.0)) + #[available_since(macos(10.9), ios(8.0))] + // #[not_available(macos(10.9), ios(8.0))] + fn my_fn() {} + + // Mimic Swift's @available + #[available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)] + #[available(macOS, introduced: 10.15)] + #[available(iOS, introduced: 13)] + #[available(iOS, deprecated: 14)] + #[available(iOS, obsoleted: 15)] + #[available(iOS, unavailable)] + fn my_fn() {} + + #[available::macos(10.9)] + #[available::ios(8.0)] + // #[available::macos(not(10.9))] + // #[available::ios(not(8.0))] + // #[available::not_macos(10.9)] + // #[available::not_ios(8.0)] + fn my_fn() {} + + // https://crates.io/crates/assert2 + #[available(macos >= 10.9, ios >= 8.0)] + fn my_fn() {} + + // Helper functions / macros for doing runtime version checks (and omit + // them when the DEPLOYMENT_TARGET is high enough). + + fn some_fn() { + if available_macos(10.9) && available_ios(6.0) { + } else { + } + + if available!(macos(10.9), ios(6.0)) { + } else { + } + + #[cfg(target_os = "macos")] + if available_macos(10.9) { + } else { + } + #[cfg(target_os = "ios")] + if available_ios(6.0) { + } else { + } + + #[is_available(macos(10.9), ios(6.0))] + {} + #[not(is_available(macos(10.9), ios(6.0)))] + {} + + if available(Availability { + macos: 10.9, + ios: 6.0, + ..Default::default() + }) { + } else { + } + } +} diff --git a/objc2-proc-macros/src/deployment_target.rs b/objc2-proc-macros/src/deployment_target.rs new file mode 100644 index 000000000..820ee5631 --- /dev/null +++ b/objc2-proc-macros/src/deployment_target.rs @@ -0,0 +1,218 @@ +//! Utilities for getting the deployment target of the application. +//! +//! There are many different ways of getting the deployment target environment +//! variable. Some possibilities include: +//! 1. Use `option_env!` in the `proc-macro` +//! 2. Use `std::env::var` in the `proc-macro` +//! 3. Add `build.rs` to proc-macro, and use `option_env!` there. +//! 4. Add `build.rs` to proc-macro, and use `std::env::var` there. +//! 5. Output an `option_env!` within the crate itself. +//! 6. Output an `std::env::var` within the crate itself. +//! +//! Option 1, 3 and 4 would require a recompilation of the `proc-macro` crate, +//! while option 2, 5 and 6 wouldn't. +//! +//! Option 6 is out of the question, since that would be a dynamic check at +//! binary runtime! +//! +//! Option 5 is interesting, but ultimately won't work since we need to emit +//! `cfg` guards, and `option_env!` can't be used in those. +//! +//! Option 4 is not really different from option 1, except adding extra +//! compile time (since environment variables are, as far as I can tell) +//! +//! Option 3 is basically just an inefficient version of option 4. +//! +//! Option 2 is interesting in that it can be influenced by the user setting +//! the environemnt variable in their build script using `cargo:rustc-env=`. +//! However, this is probably an anti-feature, since that will only work for +//! the specific crate with the build script, while any other crates will +//! assume a different deployment target! +//! But more importantly, we can't ensure that the target crate is recompiled +//! when the environment variable changes (could be hacked by _also_ +//! outputting `option_env!` into the target crate, but that seems brittle, +//! and the solution , `proc_macro::tracked_env::var` is nightly-only). +//! +//! Basically, option 1 seemed the most stable. + +use std::{fmt, num::ParseIntError, str::FromStr}; + +#[derive(Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Clone, Copy)] +pub(crate) struct Version { + major: u32, + minor: u32, + /// Some things (e.g. `objc_setHook_getClass`) are cfg-gated on `10.14.4`, + /// so allow parsing that. + subminor: u32, +} + +impl fmt::Display for Version { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if self.subminor == 0 { + write!(f, "{}.{}", self.major, self.minor) + } else { + write!(f, "{}.{}.{}", self.major, self.minor, self.subminor) + } + } +} + +impl Version { + pub(crate) fn new(major: u32, minor: u32) -> Self { + Self { + major, + minor, + subminor: 0, + } + } + + fn new_subminor(major: u32, minor: u32, subminor: u32) -> Self { + Self { + major, + minor, + subminor, + } + } + + fn from_env(env: &str) -> Self { + match Version::from_str(env) { + Ok(v) => v, + // TODO: Don't ignore error + Err(_) => panic!(concat!( + "invalid deployment target version! ", + "Must have the format `major.minor[.subminor]`. ", + "Example: `10.7`, `7.0`, `10.14.4`." + )), + } + } +} + +impl FromStr for Version { + type Err = VersionParseError; + + fn from_str(s: &str) -> Result { + let mut iter = s.split('.'); + let major = iter.next().ok_or(VersionParseError::Empty)?.parse()?; + let minor = iter.next().ok_or(VersionParseError::TooShort)?.parse()?; + let res = match iter.next() { + Some(subminor) => Self::new_subminor(major, minor, subminor.parse()?), + None => Self::new(major, minor), + }; + if iter.next().is_some() { + return Err(VersionParseError::TooLong); + } + Ok(res) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub(crate) enum VersionParseError { + Empty, + TooShort, + TooLong, + ParseIntError(ParseIntError), +} + +impl From for VersionParseError { + fn from(e: ParseIntError) -> Self { + Self::ParseIntError(e) + } +} + +// Default values are the same as rustc: +// https://github.com/rust-lang/rust/blob/e55c53c57e953a4f5716461dbaf4af5d623d80da/compiler/rustc_target/src/spec/apple_base.rs +pub(crate) fn macos_aarch64() -> Version { + option_env!("MACOSX_DEPLOYMENT_TARGET") + .map(Version::from_env) + .unwrap_or_else(|| Version::new(11, 0)) +} +pub(crate) fn macos() -> Version { + option_env!("MACOSX_DEPLOYMENT_TARGET") + .map(Version::from_env) + .unwrap_or_else(|| Version::new(10, 7)) +} +pub(crate) fn ios() -> Version { + option_env!("IPHONEOS_DEPLOYMENT_TARGET") + .map(Version::from_env) + .unwrap_or_else(|| Version::new(7, 0)) +} +pub(crate) fn tvos() -> Option { + // TODO: Set a default value here when rustc does + option_env!("TVOS_DEPLOYMENT_TARGET").map(Version::from_env) +} +pub(crate) fn watchos() -> Version { + option_env!("WATCHOS_DEPLOYMENT_TARGET") + .map(Version::from_env) + .unwrap_or_else(|| Version::new(5, 0)) +} +// No Rust target for `BRIDGEOS_DEPLOYMENT_TARGET`, and it probably won't come + +// Clang flags for these environment variables: +// -mmacos-version-min +// -mios-version-min +// -mtvos-version-min +// -mwatchos-version-min +// -mbridgeos-version-min +// -mmaccatalyst-version-min +// -mios-simulator-version-min +// -mtvos-simulator-version-min +// -mwatchos-simulator-version-min +// -mdriverkit-version-min + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_version_cmp() { + assert_eq!(Version::new(10, 0), Version::new(10, 0)); + assert!(Version::new(10, 0) < Version::new(10, 1)); + assert!(Version::new(10, 7) < Version::new(11, 0)); + assert!(Version::new(7, 0) < Version::new(9, 1)); + + // Subminor + assert!(Version::new_subminor(7, 0, 1) < Version::new_subminor(7, 0, 2)); + assert!(Version::new(7, 0) < Version::new_subminor(7, 0, 1)); + assert_eq!(Version::new(7, 0), Version::new_subminor(7, 0, 0)); + } + + #[test] + fn version_env_parse() { + assert_eq!(Version::from_str("7.0").unwrap(), Version::new(7, 0)); + assert_eq!(Version::from_str("7.0.0").unwrap(), Version::new(7, 0)); + assert_eq!( + Version::from_str("7.0.1").unwrap(), + Version::new_subminor(7, 0, 1) + ); + assert_eq!(Version::from_str("5.0").unwrap(), Version::new(5, 0)); + assert_eq!(Version::from_str("10.7").unwrap(), Version::new(10, 7)); + assert_eq!(Version::from_str("12.1").unwrap(), Version::new(12, 1)); + assert_eq!( + Version::from_str("10.14.4").unwrap(), + Version::new_subminor(10, 14, 4) + ); + } + + #[test] + #[should_panic] + fn version_env_not_number() { + let _ = Version::from_str("abc").unwrap(); + } + + #[test] + #[should_panic] + fn version_env_large_number() { + let _ = Version::from_str("1234567890123467890.0").unwrap(); + } + + #[test] + #[should_panic] + fn version_env_too_few() { + let _ = Version::from_str("10").unwrap(); + } + + #[test] + #[should_panic] + fn version_env_too_many() { + let _ = Version::from_str("10.0.0.0").unwrap(); + } +} diff --git a/objc2-proc-macros/src/lib.rs b/objc2-proc-macros/src/lib.rs index 3aba96a6c..aa6285146 100644 --- a/objc2-proc-macros/src/lib.rs +++ b/objc2-proc-macros/src/lib.rs @@ -13,6 +13,9 @@ // Update in Cargo.toml as well. #![doc(html_root_url = "https://docs.rs/objc2-proc-macros/0.1.0")] +mod available; +mod deployment_target; + #[cfg(doctest)] #[doc = include_str!("../README.md")] extern "C" {} @@ -24,6 +27,8 @@ use proc_macro::Literal; use proc_macro::TokenStream; use proc_macro::TokenTree; +use crate::available::AvailableSince; + /// Quick n' dirty way to extract the idents given by the `sel!` macro. fn get_idents(input: TokenStream) -> impl Iterator { input.into_iter().flat_map(|token| { @@ -80,3 +85,53 @@ pub fn __hash_idents(input: TokenStream) -> TokenStream { let s = format!("{:016x}", hasher.finish()); TokenTree::Literal(Literal::string(&s)).into() } + +/// TODO. +/// +/// The syntax mimic's Objective-C's `@available`. +/// +/// ```no_run +/// use objc2_proc_macros::{cfg_available, cfg_not_available}; +/// +/// // In `-sys` crate +/// extern "C" { +/// #[cfg_available(macOS(10.15), iOS(7.0), tvOS(13.0), watchOS(6.0))] +/// fn my_fn(); +/// } +/// +/// // Later usage +/// #[cfg_available(macOS(10.15), iOS(7.0), tvOS(13.0), watchOS(6.0))] +/// fn my_safe_fn() { +/// unsafe { my_fn() }; +/// } +/// #[cfg_not_available(macOS(10.15), iOS(7.0), tvOS(13.0), watchOS(6.0))] +/// fn my_safe_fn() { +/// // Fallback +/// } +/// ``` +#[proc_macro_attribute] +pub fn cfg_available(attr: TokenStream, item: TokenStream) -> TokenStream { + println!("attr: \"{}\"", attr.to_string()); + println!("item: \"{}\"", item.to_string()); + let available_since = AvailableSince::from_tokenstream(attr); + println!("available_since: \"{:?}\"", available_since); + + let mut res = available_since.into_cfg(); + println!("res: \"{}\"", res.to_string()); + res.extend(item); + res +} + +/// The inverse of [`cfg_available`]. +#[proc_macro_attribute] +pub fn cfg_not_available(attr: TokenStream, item: TokenStream) -> TokenStream { + println!("attr: \"{}\"", attr.to_string()); + println!("item: \"{}\"", item.to_string()); + let available_since = AvailableSince::from_tokenstream(attr); + println!("available_since: \"{:?}\"", available_since); + + let mut res = available_since.into_not_cfg(); + println!("res: \"{}\"", res.to_string()); + res.extend(item); + res +} diff --git a/objc2-proc-macros/src/versions.rs b/objc2-proc-macros/src/versions.rs new file mode 100644 index 000000000..ac3543e48 --- /dev/null +++ b/objc2-proc-macros/src/versions.rs @@ -0,0 +1,198 @@ +/* automatically generated by rust-bindgen 0.59.2 */ + +pub const __MAC_10_0: u32 = 1000; +pub const __MAC_10_1: u32 = 1010; +pub const __MAC_10_2: u32 = 1020; +pub const __MAC_10_3: u32 = 1030; +pub const __MAC_10_4: u32 = 1040; +pub const __MAC_10_5: u32 = 1050; +pub const __MAC_10_6: u32 = 1060; +pub const __MAC_10_7: u32 = 1070; +pub const __MAC_10_8: u32 = 1080; +pub const __MAC_10_9: u32 = 1090; +pub const __MAC_10_10: u32 = 101000; +pub const __MAC_10_10_2: u32 = 101002; +pub const __MAC_10_10_3: u32 = 101003; +pub const __MAC_10_11: u32 = 101100; +pub const __MAC_10_11_2: u32 = 101102; +pub const __MAC_10_11_3: u32 = 101103; +pub const __MAC_10_11_4: u32 = 101104; +pub const __MAC_10_12: u32 = 101200; +pub const __MAC_10_12_1: u32 = 101201; +pub const __MAC_10_12_2: u32 = 101202; +pub const __MAC_10_12_4: u32 = 101204; +pub const __MAC_10_13: u32 = 101300; +pub const __MAC_10_13_1: u32 = 101301; +pub const __MAC_10_13_2: u32 = 101302; +pub const __MAC_10_13_4: u32 = 101304; +pub const __MAC_10_14: u32 = 101400; +pub const __MAC_10_14_1: u32 = 101401; +pub const __MAC_10_14_4: u32 = 101404; +pub const __MAC_10_14_6: u32 = 101406; +pub const __MAC_10_15: u32 = 101500; +pub const __MAC_10_15_1: u32 = 101501; +pub const __MAC_10_15_4: u32 = 101504; +pub const __MAC_10_16: u32 = 101600; +pub const __MAC_11_0: u32 = 110000; +pub const __MAC_11_1: u32 = 110100; +pub const __MAC_11_3: u32 = 110300; +pub const __MAC_11_4: u32 = 110400; +pub const __MAC_11_5: u32 = 110500; +pub const __MAC_12_0: u32 = 120000; + +pub const __IPHONE_2_0: u32 = 20000; +pub const __IPHONE_2_1: u32 = 20100; +pub const __IPHONE_2_2: u32 = 20200; +pub const __IPHONE_3_0: u32 = 30000; +pub const __IPHONE_3_1: u32 = 30100; +pub const __IPHONE_3_2: u32 = 30200; +pub const __IPHONE_4_0: u32 = 40000; +pub const __IPHONE_4_1: u32 = 40100; +pub const __IPHONE_4_2: u32 = 40200; +pub const __IPHONE_4_3: u32 = 40300; +pub const __IPHONE_5_0: u32 = 50000; +pub const __IPHONE_5_1: u32 = 50100; +pub const __IPHONE_6_0: u32 = 60000; +pub const __IPHONE_6_1: u32 = 60100; +pub const __IPHONE_7_0: u32 = 70000; +pub const __IPHONE_7_1: u32 = 70100; +pub const __IPHONE_8_0: u32 = 80000; +pub const __IPHONE_8_1: u32 = 80100; +pub const __IPHONE_8_2: u32 = 80200; +pub const __IPHONE_8_3: u32 = 80300; +pub const __IPHONE_8_4: u32 = 80400; +pub const __IPHONE_9_0: u32 = 90000; +pub const __IPHONE_9_1: u32 = 90100; +pub const __IPHONE_9_2: u32 = 90200; +pub const __IPHONE_9_3: u32 = 90300; +pub const __IPHONE_10_0: u32 = 100000; +pub const __IPHONE_10_1: u32 = 100100; +pub const __IPHONE_10_2: u32 = 100200; +pub const __IPHONE_10_3: u32 = 100300; +pub const __IPHONE_11_0: u32 = 110000; +pub const __IPHONE_11_1: u32 = 110100; +pub const __IPHONE_11_2: u32 = 110200; +pub const __IPHONE_11_3: u32 = 110300; +pub const __IPHONE_11_4: u32 = 110400; +pub const __IPHONE_12_0: u32 = 120000; +pub const __IPHONE_12_1: u32 = 120100; +pub const __IPHONE_12_2: u32 = 120200; +pub const __IPHONE_12_3: u32 = 120300; +pub const __IPHONE_12_4: u32 = 120400; +pub const __IPHONE_13_0: u32 = 130000; +pub const __IPHONE_13_1: u32 = 130100; +pub const __IPHONE_13_2: u32 = 130200; +pub const __IPHONE_13_3: u32 = 130300; +pub const __IPHONE_13_4: u32 = 130400; +pub const __IPHONE_13_5: u32 = 130500; +pub const __IPHONE_13_6: u32 = 130600; +pub const __IPHONE_13_7: u32 = 130700; +pub const __IPHONE_14_0: u32 = 140000; +pub const __IPHONE_14_1: u32 = 140100; +pub const __IPHONE_14_2: u32 = 140200; +pub const __IPHONE_14_3: u32 = 140300; +pub const __IPHONE_14_5: u32 = 140500; +pub const __IPHONE_14_6: u32 = 140600; +pub const __IPHONE_14_7: u32 = 140700; +pub const __IPHONE_14_8: u32 = 140800; +pub const __IPHONE_15_0: u32 = 150000; + +pub const __TVOS_9_0: u32 = 90000; +pub const __TVOS_9_1: u32 = 90100; +pub const __TVOS_9_2: u32 = 90200; +pub const __TVOS_10_0: u32 = 100000; +pub const __TVOS_10_0_1: u32 = 100001; +pub const __TVOS_10_1: u32 = 100100; +pub const __TVOS_10_2: u32 = 100200; +pub const __TVOS_11_0: u32 = 110000; +pub const __TVOS_11_1: u32 = 110100; +pub const __TVOS_11_2: u32 = 110200; +pub const __TVOS_11_3: u32 = 110300; +pub const __TVOS_11_4: u32 = 110400; +pub const __TVOS_12_0: u32 = 120000; +pub const __TVOS_12_1: u32 = 120100; +pub const __TVOS_12_2: u32 = 120200; +pub const __TVOS_12_3: u32 = 120300; +pub const __TVOS_12_4: u32 = 120400; +pub const __TVOS_13_0: u32 = 130000; +pub const __TVOS_13_2: u32 = 130200; +pub const __TVOS_13_3: u32 = 130300; +pub const __TVOS_13_4: u32 = 130400; +pub const __TVOS_14_0: u32 = 140000; +pub const __TVOS_14_1: u32 = 140100; +pub const __TVOS_14_2: u32 = 140200; +pub const __TVOS_14_3: u32 = 140300; +pub const __TVOS_14_5: u32 = 140500; +pub const __TVOS_14_6: u32 = 140600; +pub const __TVOS_14_7: u32 = 140700; +pub const __TVOS_15_0: u32 = 150000; + +pub const __WATCHOS_1_0: u32 = 10000; +pub const __WATCHOS_2_0: u32 = 20000; +pub const __WATCHOS_2_1: u32 = 20100; +pub const __WATCHOS_2_2: u32 = 20200; +pub const __WATCHOS_3_0: u32 = 30000; +pub const __WATCHOS_3_1: u32 = 30100; +pub const __WATCHOS_3_1_1: u32 = 30101; +pub const __WATCHOS_3_2: u32 = 30200; +pub const __WATCHOS_4_0: u32 = 40000; +pub const __WATCHOS_4_1: u32 = 40100; +pub const __WATCHOS_4_2: u32 = 40200; +pub const __WATCHOS_4_3: u32 = 40300; +pub const __WATCHOS_5_0: u32 = 50000; +pub const __WATCHOS_5_1: u32 = 50100; +pub const __WATCHOS_5_2: u32 = 50200; +pub const __WATCHOS_5_3: u32 = 50300; +pub const __WATCHOS_6_0: u32 = 60000; +pub const __WATCHOS_6_1: u32 = 60100; +pub const __WATCHOS_6_2: u32 = 60200; +pub const __WATCHOS_7_0: u32 = 70000; +pub const __WATCHOS_7_1: u32 = 70100; +pub const __WATCHOS_7_2: u32 = 70200; +pub const __WATCHOS_7_3: u32 = 70300; +pub const __WATCHOS_7_4: u32 = 70400; +pub const __WATCHOS_7_5: u32 = 70500; +pub const __WATCHOS_7_6: u32 = 70600; +pub const __WATCHOS_8_0: u32 = 80000; + +pub const MAC_OS_X_VERSION_10_0: u32 = 1000; +pub const MAC_OS_X_VERSION_10_1: u32 = 1010; +pub const MAC_OS_X_VERSION_10_2: u32 = 1020; +pub const MAC_OS_X_VERSION_10_3: u32 = 1030; +pub const MAC_OS_X_VERSION_10_4: u32 = 1040; +pub const MAC_OS_X_VERSION_10_5: u32 = 1050; +pub const MAC_OS_X_VERSION_10_6: u32 = 1060; +pub const MAC_OS_X_VERSION_10_7: u32 = 1070; +pub const MAC_OS_X_VERSION_10_8: u32 = 1080; +pub const MAC_OS_X_VERSION_10_9: u32 = 1090; +pub const MAC_OS_X_VERSION_10_10: u32 = 101000; +pub const MAC_OS_X_VERSION_10_10_2: u32 = 101002; +pub const MAC_OS_X_VERSION_10_10_3: u32 = 101003; +pub const MAC_OS_X_VERSION_10_11: u32 = 101100; +pub const MAC_OS_X_VERSION_10_11_2: u32 = 101102; +pub const MAC_OS_X_VERSION_10_11_3: u32 = 101103; +pub const MAC_OS_X_VERSION_10_11_4: u32 = 101104; +pub const MAC_OS_X_VERSION_10_12: u32 = 101200; +pub const MAC_OS_X_VERSION_10_12_1: u32 = 101201; +pub const MAC_OS_X_VERSION_10_12_2: u32 = 101202; +pub const MAC_OS_X_VERSION_10_12_4: u32 = 101204; +pub const MAC_OS_X_VERSION_10_13: u32 = 101300; +pub const MAC_OS_X_VERSION_10_13_1: u32 = 101301; +pub const MAC_OS_X_VERSION_10_13_2: u32 = 101302; +pub const MAC_OS_X_VERSION_10_13_4: u32 = 101304; +pub const MAC_OS_X_VERSION_10_14: u32 = 101400; +pub const MAC_OS_X_VERSION_10_14_1: u32 = 101401; +pub const MAC_OS_X_VERSION_10_14_4: u32 = 101404; +pub const MAC_OS_X_VERSION_10_14_6: u32 = 101406; +pub const MAC_OS_X_VERSION_10_15: u32 = 101500; +pub const MAC_OS_X_VERSION_10_15_1: u32 = 101501; +pub const MAC_OS_X_VERSION_10_16: u32 = 101600; +pub const MAC_OS_VERSION_11_0: u32 = 110000; +pub const MAC_OS_VERSION_12_0: u32 = 120000; + +pub const __DRIVERKIT_19_0: u32 = 190000; +pub const __DRIVERKIT_20_0: u32 = 200000; +pub const __DRIVERKIT_21_0: u32 = 210000; + +pub const __MAC_OS_X_VERSION_MAX_ALLOWED: u32 = 120000; +pub const __ENABLE_LEGACY_MAC_AVAILABILITY: u32 = 1; diff --git a/objc2/Cargo.toml b/objc2/Cargo.toml index 675b15e8c..b6f59aa29 100644 --- a/objc2/Cargo.toml +++ b/objc2/Cargo.toml @@ -49,7 +49,7 @@ malloc = ["malloc_buf"] # # Please test it, and report any issues you may find: # https://github.com/madsmtm/objc2/issues/new -unstable-static-sel = ["objc2-proc-macros"] +unstable-static-sel = [] unstable-static-sel-inlined = ["unstable-static-sel"] # Uses nightly features to make AutoreleasePool zero-cost even in debug mode @@ -73,7 +73,7 @@ gnustep-2-1 = ["gnustep-2-0", "objc-sys/gnustep-2-1"] malloc_buf = { version = "1.0", optional = true } objc-sys = { path = "../objc-sys", version = "=0.2.0-beta.1", default-features = false } objc2-encode = { path = "../objc2-encode", version = "=2.0.0-pre.1", default-features = false } -objc2-proc-macros = { path = "../objc2-proc-macros", version = "0.1.0", optional = true } +objc2-proc-macros = { path = "../objc2-proc-macros", version = "0.1.0" } [dev-dependencies] iai = { version = "0.1", git = "https://github.com/madsmtm/iai", branch = "callgrind" } diff --git a/objc2/src/__macro_helpers.rs b/objc2/src/__macro_helpers.rs index c2b8de12f..03cf36131 100644 --- a/objc2/src/__macro_helpers.rs +++ b/objc2/src/__macro_helpers.rs @@ -9,8 +9,7 @@ pub use core::cell::UnsafeCell; pub use core::option::Option::{self, None, Some}; pub use core::primitive::{bool, str, u8}; pub use core::{compile_error, concat, panic, stringify}; -#[cfg(feature = "objc2-proc-macros")] -pub use objc2_proc_macros::__hash_idents; +pub use objc2_proc_macros::{__hash_idents, cfg_available, cfg_not_available}; /// Helper for specifying the retain semantics for a given selector family. /// @@ -143,6 +142,55 @@ impl MsgSendId> } } +#[inline] +#[track_caller] +#[cfg_available(macOS(10.9), iOS(7.0), tvOS(9.0), watchOS(1.0))] +pub unsafe fn send_message_id_alloc( + cls: &Class, +) -> Option, O>> { + // SAFETY: Checked by caller that [cls alloc] is valid + let obj = unsafe { crate::ffi::objc_alloc(cls.as_ptr()) as *mut T }; + unsafe { Id::new_allocated(obj) } +} + +#[inline] +#[track_caller] +#[cfg_not_available(macOS(10.9), iOS(7.0), tvOS(9.0), watchOS(1.0))] +pub unsafe fn send_message_id_alloc( + cls: &Class, +) -> Option, O>> { + // SAFETY: Checked by caller + unsafe { + >::send_message_id(cls, crate::sel!(alloc), ()) + } +} + +#[inline] +#[track_caller] +#[cfg(feature = "apple")] +#[cfg_attr( + feature = "apple", + cfg_available(macOS(10.15), iOS(13.0), tvOS(13.0), watchOS(6.0)) +)] +pub unsafe fn send_message_id_new(cls: &Class) -> Option> { + // SAFETY: Checked by caller that [cls new] is valid + let obj = unsafe { crate::ffi::objc_opt_new(cls.as_ptr()) as *mut T }; + unsafe { Id::new(obj) } +} + +#[inline] +#[track_caller] +#[cfg_attr( + feature = "apple", + cfg_not_available(macOS(10.15), iOS(13.0), tvOS(13.0), watchOS(6.0)) +)] +pub unsafe fn send_message_id_new(cls: &Class) -> Option> { + // SAFETY: Checked by caller + unsafe { + >::send_message_id(cls, crate::sel!(new), ()) + } +} + /// Checks whether a given selector is said to be in a given selector family. /// /// diff --git a/objc2/src/macros.rs b/objc2/src/macros.rs index baa72c536..503f2ba67 100644 --- a/objc2/src/macros.rs +++ b/objc2/src/macros.rs @@ -651,6 +651,17 @@ macro_rules! msg_send_bool { /// ``` #[macro_export] macro_rules! msg_send_id { + // Special case `new` and `alloc` for performance + [$obj:expr, alloc $(,)?] => ({ + let result; + result = $crate::__macro_helpers::send_message_id_alloc($obj); + result + }); + [$obj:expr, new $(,)?] => ({ + let result; + result = $crate::__macro_helpers::send_message_id_new($obj); + result + }); [$obj:expr, $selector:ident $(,)?] => ({ $crate::__msg_send_id_helper!(@verify $selector); let sel = $crate::sel!($selector); diff --git a/objc2/src/runtime.rs b/objc2/src/runtime.rs index 55d07b65f..2d548a81d 100644 --- a/objc2/src/runtime.rs +++ b/objc2/src/runtime.rs @@ -300,6 +300,7 @@ impl UnwindSafe for Method {} impl RefUnwindSafe for Method {} impl Class { + #[inline] pub(crate) fn as_ptr(&self) -> *const ffi::objc_class { let ptr: *const Self = self; ptr.cast() diff --git a/test-assembly/crates/test_msg_send_static_sel/expected/apple-aarch64.s b/test-assembly/crates/test_msg_send_static_sel/expected/apple-aarch64.s index 5ac1a3c05..847796ed3 100644 --- a/test-assembly/crates/test_msg_send_static_sel/expected/apple-aarch64.s +++ b/test-assembly/crates/test_msg_send_static_sel/expected/apple-aarch64.s @@ -19,17 +19,11 @@ Lloh2: adrp x8, L_OBJC_SELECTOR_REFERENCES_cb49b9ab1b00e328@PAGE Lloh3: ldr x19, [x8, L_OBJC_SELECTOR_REFERENCES_cb49b9ab1b00e328@PAGEOFF] -Lloh4: - adrp x8, L_OBJC_SELECTOR_REFERENCES_dcb825748735621d@PAGE -Lloh5: - ldr x1, [x8, L_OBJC_SELECTOR_REFERENCES_dcb825748735621d@PAGEOFF] - bl _objc_msgSend + bl _objc_alloc mov x1, x19 ldp x29, x30, [sp, #16] ldp x20, x19, [sp], #32 b _objc_msgSend - .loh AdrpLdr Lloh4, Lloh5 - .loh AdrpAdrp Lloh2, Lloh4 .loh AdrpLdr Lloh2, Lloh3 .globl _use_generic @@ -39,32 +33,32 @@ _use_generic: stp x29, x30, [sp, #16] add x29, sp, #16 mov x19, x0 -Lloh6: +Lloh4: adrp x8, L_OBJC_SELECTOR_REFERENCES_f16064a6f68ca673@PAGE -Lloh7: +Lloh5: ldr x1, [x8, L_OBJC_SELECTOR_REFERENCES_f16064a6f68ca673@PAGEOFF] adrp x20, L_OBJC_SELECTOR_REFERENCES_457d234345d46cbe@PAGE ldr x2, [x20, L_OBJC_SELECTOR_REFERENCES_457d234345d46cbe@PAGEOFF] bl _objc_msgSend -Lloh8: +Lloh6: adrp x8, L_OBJC_SELECTOR_REFERENCES_9f134b97cb598446@PAGE -Lloh9: +Lloh7: ldr x1, [x8, L_OBJC_SELECTOR_REFERENCES_9f134b97cb598446@PAGEOFF] ldr x2, [x20, L_OBJC_SELECTOR_REFERENCES_457d234345d46cbe@PAGEOFF] mov x0, x19 bl _objc_msgSend -Lloh10: +Lloh8: adrp x8, L_OBJC_SELECTOR_REFERENCES_e76e01e8b2327e5d@PAGE -Lloh11: +Lloh9: ldr x1, [x8, L_OBJC_SELECTOR_REFERENCES_e76e01e8b2327e5d@PAGEOFF] ldr x2, [x20, L_OBJC_SELECTOR_REFERENCES_457d234345d46cbe@PAGEOFF] mov x0, x19 ldp x29, x30, [sp, #16] ldp x20, x19, [sp], #32 b _objc_msgSend - .loh AdrpLdr Lloh10, Lloh11 .loh AdrpLdr Lloh8, Lloh9 .loh AdrpLdr Lloh6, Lloh7 + .loh AdrpLdr Lloh4, Lloh5 .section __DATA,__objc_imageinfo,regular,no_dead_strip .globl L_OBJC_IMAGE_INFO_044375a4329d08dc @@ -100,23 +94,6 @@ L_OBJC_METH_VAR_NAME_cb49b9ab1b00e328: L_OBJC_SELECTOR_REFERENCES_cb49b9ab1b00e328: .quad L_OBJC_METH_VAR_NAME_cb49b9ab1b00e328 - .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_dcb825748735621d - .p2align 2 -L_OBJC_IMAGE_INFO_dcb825748735621d: - .asciz "\000\000\000\000@\000\000" - - .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_dcb825748735621d -L_OBJC_METH_VAR_NAME_dcb825748735621d: - .asciz "alloc" - - .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_dcb825748735621d - .p2align 3 -L_OBJC_SELECTOR_REFERENCES_dcb825748735621d: - .quad L_OBJC_METH_VAR_NAME_dcb825748735621d - .section __DATA,__objc_imageinfo,regular,no_dead_strip .globl L_OBJC_IMAGE_INFO_457d234345d46cbe .p2align 2 diff --git a/test-assembly/crates/test_msg_send_static_sel/expected/apple-armv7.s b/test-assembly/crates/test_msg_send_static_sel/expected/apple-armv7.s index 8a2d6e837..900f2cf44 100644 --- a/test-assembly/crates/test_msg_send_static_sel/expected/apple-armv7.s +++ b/test-assembly/crates/test_msg_send_static_sel/expected/apple-armv7.s @@ -16,15 +16,11 @@ LPC0_0: _handle_alloc_init: push {r4, r7, lr} add r7, sp, #4 - movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_dcb825748735621d-(LPC1_0+8)) - movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_dcb825748735621d-(LPC1_0+8)) + movw r4, :lower16:(L_OBJC_SELECTOR_REFERENCES_cb49b9ab1b00e328-(LPC1_0+8)) + movt r4, :upper16:(L_OBJC_SELECTOR_REFERENCES_cb49b9ab1b00e328-(LPC1_0+8)) LPC1_0: - ldr r1, [pc, r1] - movw r4, :lower16:(L_OBJC_SELECTOR_REFERENCES_cb49b9ab1b00e328-(LPC1_1+8)) - movt r4, :upper16:(L_OBJC_SELECTOR_REFERENCES_cb49b9ab1b00e328-(LPC1_1+8)) -LPC1_1: ldr r4, [pc, r4] - bl _objc_msgSend + bl _objc_alloc mov r1, r4 pop {r4, r7, lr} b _objc_msgSend @@ -101,23 +97,6 @@ L_OBJC_METH_VAR_NAME_cb49b9ab1b00e328: L_OBJC_SELECTOR_REFERENCES_cb49b9ab1b00e328: .long L_OBJC_METH_VAR_NAME_cb49b9ab1b00e328 - .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_dcb825748735621d - .p2align 2 -L_OBJC_IMAGE_INFO_dcb825748735621d: - .asciz "\000\000\000\000@\000\000" - - .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_dcb825748735621d -L_OBJC_METH_VAR_NAME_dcb825748735621d: - .asciz "alloc" - - .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_dcb825748735621d - .p2align 2 -L_OBJC_SELECTOR_REFERENCES_dcb825748735621d: - .long L_OBJC_METH_VAR_NAME_dcb825748735621d - .section __DATA,__objc_imageinfo,regular,no_dead_strip .globl L_OBJC_IMAGE_INFO_457d234345d46cbe .p2align 2 diff --git a/test-assembly/crates/test_msg_send_static_sel/expected/apple-armv7s.s b/test-assembly/crates/test_msg_send_static_sel/expected/apple-armv7s.s index b258c95dd..4495baccc 100644 --- a/test-assembly/crates/test_msg_send_static_sel/expected/apple-armv7s.s +++ b/test-assembly/crates/test_msg_send_static_sel/expected/apple-armv7s.s @@ -19,15 +19,11 @@ LPC0_0: _handle_alloc_init: push {r4, r7, lr} add r7, sp, #4 - movw r1, :lower16:(L_OBJC_SELECTOR_REFERENCES_dcb825748735621d-(LPC1_0+8)) - movt r1, :upper16:(L_OBJC_SELECTOR_REFERENCES_dcb825748735621d-(LPC1_0+8)) + movw r4, :lower16:(L_OBJC_SELECTOR_REFERENCES_cb49b9ab1b00e328-(LPC1_0+8)) + movt r4, :upper16:(L_OBJC_SELECTOR_REFERENCES_cb49b9ab1b00e328-(LPC1_0+8)) LPC1_0: - ldr r1, [pc, r1] - movw r4, :lower16:(L_OBJC_SELECTOR_REFERENCES_cb49b9ab1b00e328-(LPC1_1+8)) - movt r4, :upper16:(L_OBJC_SELECTOR_REFERENCES_cb49b9ab1b00e328-(LPC1_1+8)) -LPC1_1: ldr r4, [pc, r4] - bl _objc_msgSend + bl _objc_alloc mov r1, r4 bl _objc_msgSend pop {r4, r7, pc} @@ -104,23 +100,6 @@ L_OBJC_METH_VAR_NAME_cb49b9ab1b00e328: L_OBJC_SELECTOR_REFERENCES_cb49b9ab1b00e328: .long L_OBJC_METH_VAR_NAME_cb49b9ab1b00e328 - .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_dcb825748735621d - .p2align 2 -L_OBJC_IMAGE_INFO_dcb825748735621d: - .asciz "\000\000\000\000@\000\000" - - .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_dcb825748735621d -L_OBJC_METH_VAR_NAME_dcb825748735621d: - .asciz "alloc" - - .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_dcb825748735621d - .p2align 2 -L_OBJC_SELECTOR_REFERENCES_dcb825748735621d: - .long L_OBJC_METH_VAR_NAME_dcb825748735621d - .section __DATA,__objc_imageinfo,regular,no_dead_strip .globl L_OBJC_IMAGE_INFO_457d234345d46cbe .p2align 2 diff --git a/test-assembly/crates/test_msg_send_static_sel/expected/apple-old-x86.s b/test-assembly/crates/test_msg_send_static_sel/expected/apple-old-x86.s index 576f30749..5e977080c 100644 --- a/test-assembly/crates/test_msg_send_static_sel/expected/apple-old-x86.s +++ b/test-assembly/crates/test_msg_send_static_sel/expected/apple-old-x86.s @@ -23,18 +23,16 @@ _handle_alloc_init: push ebp mov ebp, esp push esi - push eax + sub esp, 20 call L1$pb L1$pb: pop eax + mov ecx, dword ptr [ebp + 8] mov esi, dword ptr [eax + L_OBJC_SELECTOR_REFERENCES_cb49b9ab1b00e328-L1$pb] - sub esp, 8 - push dword ptr [eax + L_OBJC_SELECTOR_REFERENCES_dcb825748735621d-L1$pb] - push dword ptr [ebp + 8] - call _objc_msgSend - add esp, 8 - push esi - push eax + mov dword ptr [esp], ecx + call _objc_alloc + mov dword ptr [esp + 4], esi + mov dword ptr [esp], eax call _objc_msgSend add esp, 20 pop esi @@ -107,23 +105,6 @@ L_OBJC_METH_VAR_NAME_cb49b9ab1b00e328: L_OBJC_SELECTOR_REFERENCES_cb49b9ab1b00e328: .long L_OBJC_METH_VAR_NAME_cb49b9ab1b00e328 - .section __OBJC,__image_info - .globl L_OBJC_IMAGE_INFO_dcb825748735621d - .p2align 2 -L_OBJC_IMAGE_INFO_dcb825748735621d: - .asciz "\000\000\000\000@\000\000" - - .section __TEXT,__cstring,cstring_literals - .globl L_OBJC_METH_VAR_NAME_dcb825748735621d -L_OBJC_METH_VAR_NAME_dcb825748735621d: - .asciz "alloc" - - .section __OBJC,__message_refs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_dcb825748735621d - .p2align 2 -L_OBJC_SELECTOR_REFERENCES_dcb825748735621d: - .long L_OBJC_METH_VAR_NAME_dcb825748735621d - .section __OBJC,__image_info .globl L_OBJC_IMAGE_INFO_457d234345d46cbe .p2align 2 diff --git a/test-assembly/crates/test_msg_send_static_sel/expected/apple-x86.s b/test-assembly/crates/test_msg_send_static_sel/expected/apple-x86.s index 0420a25c4..2745531e1 100644 --- a/test-assembly/crates/test_msg_send_static_sel/expected/apple-x86.s +++ b/test-assembly/crates/test_msg_send_static_sel/expected/apple-x86.s @@ -23,18 +23,16 @@ _handle_alloc_init: push ebp mov ebp, esp push esi - push eax + sub esp, 20 call L1$pb L1$pb: pop eax + mov ecx, dword ptr [ebp + 8] mov esi, dword ptr [eax + L_OBJC_SELECTOR_REFERENCES_cb49b9ab1b00e328-L1$pb] - sub esp, 8 - push dword ptr [eax + L_OBJC_SELECTOR_REFERENCES_dcb825748735621d-L1$pb] - push dword ptr [ebp + 8] - call _objc_msgSend - add esp, 8 - push esi - push eax + mov dword ptr [esp], ecx + call _objc_alloc + mov dword ptr [esp + 4], esi + mov dword ptr [esp], eax call _objc_msgSend add esp, 20 pop esi @@ -107,23 +105,6 @@ L_OBJC_METH_VAR_NAME_cb49b9ab1b00e328: L_OBJC_SELECTOR_REFERENCES_cb49b9ab1b00e328: .long L_OBJC_METH_VAR_NAME_cb49b9ab1b00e328 - .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_dcb825748735621d - .p2align 2 -L_OBJC_IMAGE_INFO_dcb825748735621d: - .asciz "\000\000\000\000@\000\000" - - .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_dcb825748735621d -L_OBJC_METH_VAR_NAME_dcb825748735621d: - .asciz "alloc" - - .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_dcb825748735621d - .p2align 2 -L_OBJC_SELECTOR_REFERENCES_dcb825748735621d: - .long L_OBJC_METH_VAR_NAME_dcb825748735621d - .section __DATA,__objc_imageinfo,regular,no_dead_strip .globl L_OBJC_IMAGE_INFO_457d234345d46cbe .p2align 2 diff --git a/test-assembly/crates/test_msg_send_static_sel/expected/apple-x86_64.s b/test-assembly/crates/test_msg_send_static_sel/expected/apple-x86_64.s index 787f51ed8..21890e88e 100644 --- a/test-assembly/crates/test_msg_send_static_sel/expected/apple-x86_64.s +++ b/test-assembly/crates/test_msg_send_static_sel/expected/apple-x86_64.s @@ -17,8 +17,7 @@ _handle_alloc_init: push rbx push rax mov rbx, qword ptr [rip + L_OBJC_SELECTOR_REFERENCES_cb49b9ab1b00e328] - mov rsi, qword ptr [rip + L_OBJC_SELECTOR_REFERENCES_dcb825748735621d] - call _objc_msgSend + call _objc_alloc mov rdi, rax mov rsi, rbx add rsp, 8 @@ -83,23 +82,6 @@ L_OBJC_METH_VAR_NAME_cb49b9ab1b00e328: L_OBJC_SELECTOR_REFERENCES_cb49b9ab1b00e328: .quad L_OBJC_METH_VAR_NAME_cb49b9ab1b00e328 - .section __DATA,__objc_imageinfo,regular,no_dead_strip - .globl L_OBJC_IMAGE_INFO_dcb825748735621d - .p2align 2 -L_OBJC_IMAGE_INFO_dcb825748735621d: - .asciz "\000\000\000\000@\000\000" - - .section __TEXT,__objc_methname,cstring_literals - .globl L_OBJC_METH_VAR_NAME_dcb825748735621d -L_OBJC_METH_VAR_NAME_dcb825748735621d: - .asciz "alloc" - - .section __DATA,__objc_selrefs,literal_pointers,no_dead_strip - .globl L_OBJC_SELECTOR_REFERENCES_dcb825748735621d - .p2align 3 -L_OBJC_SELECTOR_REFERENCES_dcb825748735621d: - .quad L_OBJC_METH_VAR_NAME_dcb825748735621d - .section __DATA,__objc_imageinfo,regular,no_dead_strip .globl L_OBJC_IMAGE_INFO_457d234345d46cbe .p2align 2