From 0cfeefc68021696dc2b967afbff5db9c6a0984e5 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Sat, 4 Sep 2021 02:59:57 +0200 Subject: [PATCH 1/3] encode: Add LongDouble, FloatComplex, DoubleComplex + LongDoubleComplex Found while working on objc_sys, there might be others we're missing so I've marked `Encoding` with `#[non_exhaustive]` --- objc2-encode/src/encoding.rs | 13 +++++++++++++ objc2-encode/src/parse.rs | 4 ++++ 2 files changed, 17 insertions(+) diff --git a/objc2-encode/src/encoding.rs b/objc2-encode/src/encoding.rs index e1079422b..dcb35a757 100644 --- a/objc2-encode/src/encoding.rs +++ b/objc2-encode/src/encoding.rs @@ -14,6 +14,7 @@ use crate::parse; /// /// [ocrtTypeEncodings]: https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html #[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[non_exhaustive] // Maybe we're missing some encodings? pub enum Encoding<'a> { /// A C `char`. Corresponds to the `c` code. Char, @@ -39,6 +40,14 @@ pub enum Encoding<'a> { Float, /// A C `double`. Corresponds to the `d` code. Double, + /// A C `long double`. Corresponds to the `D` code. + LongDouble, + /// A C `float _Complex`. Corresponds to the `jf` code. + FloatComplex, + /// A C `_Complex` or `double _Complex`. Corresponds to the `jd` code. + DoubleComplex, + /// A C `long double _Complex`. Corresponds to the `jD` code. + LongDoubleComplex, /// A C++ `bool` / C99 `_Bool`. Corresponds to the `B` code. Bool, /// A C `void`. Corresponds to the `v` code. @@ -99,6 +108,10 @@ impl fmt::Display for Encoding<'_> { ULongLong => "Q", Float => "f", Double => "d", + LongDouble => "D", + FloatComplex => "jf", + DoubleComplex => "jd", + LongDoubleComplex => "jD", Bool => "B", Void => "v", String => "*", diff --git a/objc2-encode/src/parse.rs b/objc2-encode/src/parse.rs index 9fa00817b..69cd60009 100644 --- a/objc2-encode/src/parse.rs +++ b/objc2-encode/src/parse.rs @@ -28,6 +28,10 @@ fn rm_enc_prefix<'a>(s: &'a str, enc: &Encoding<'_>) -> Option<&'a str> { ULongLong => "Q", Float => "f", Double => "d", + LongDouble => "D", + FloatComplex => "jf", + DoubleComplex => "jd", + LongDoubleComplex => "jD", Bool => "B", Void => "v", String => "*", From ae824f3d3d46396a05955524b6e627929b8d596e Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Wed, 3 Nov 2021 12:40:52 +0100 Subject: [PATCH 2/3] Add a bit more documentation to objc2-encode --- objc2-encode/src/encoding.rs | 18 ++++++++++++++++-- objc2-encode/src/lib.rs | 5 +++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/objc2-encode/src/encoding.rs b/objc2-encode/src/encoding.rs index dcb35a757..0d8b5bd27 100644 --- a/objc2-encode/src/encoding.rs +++ b/objc2-encode/src/encoding.rs @@ -10,9 +10,11 @@ use crate::parse; /// NSLog(@"Encoding of NSException: %s", @encode(NSException)); /// ``` /// -/// For more information, see [Apple's documentation][ocrtTypeEncodings]. +/// For more information, see [Apple's documentation][ocrtTypeEncodings] and +/// [`clang`'s source code for generating `@encode`][clang-src]. /// -/// [ocrtTypeEncodings]: https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html +/// [ocrtTypeEncodings]: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html +/// [clang-src]: https://github.com/llvm/llvm-project/blob/fae0dfa6421ea6c02f86ba7292fa782e1e2b69d1/clang/lib/AST/ASTContext.cpp#L7500-L7850 #[derive(Clone, Copy, Debug, PartialEq, Eq)] #[non_exhaustive] // Maybe we're missing some encodings? pub enum Encoding<'a> { @@ -48,6 +50,7 @@ pub enum Encoding<'a> { DoubleComplex, /// A C `long double _Complex`. Corresponds to the `jD` code. LongDoubleComplex, + // TODO: Complex(&Encoding) ??? /// A C++ `bool` / C99 `_Bool`. Corresponds to the `B` code. Bool, /// A C `void`. Corresponds to the `v` code. @@ -63,6 +66,8 @@ pub enum Encoding<'a> { /// An Objective-C selector (`SEL`). Corresponds to the `:` code. Sel, /// An unknown type. Corresponds to the `?` code. + /// + /// This is usually used to encode functions. Unknown, /// A bitfield with the given number of bits. /// @@ -90,6 +95,15 @@ pub enum Encoding<'a> { /// /// Corresponds to the `(name=fields...)` code. Union(&'a str, &'a [Encoding<'a>]), + // "Vector" types have the '!' encoding, but are not implemented in clang + + // TODO: Atomic, const and other such specifiers + // typedef struct x { + // int a; + // void* b; + // } x_t; + // NSLog(@"Encoding: %s", @encode(_Atomic x_t)); // -> A{x} + // NSLog(@"Encoding: %s", @encode(const int*)); // -> r^i } impl fmt::Display for Encoding<'_> { diff --git a/objc2-encode/src/lib.rs b/objc2-encode/src/lib.rs index d38590088..bc94f984a 100644 --- a/objc2-encode/src/lib.rs +++ b/objc2-encode/src/lib.rs @@ -1,6 +1,11 @@ //! # Objective-C type-encoding //! //! This is re-exported into the top level of `objc2`. +//! +//! Further resources: +//! - +//! - +//! - #![no_std] #![warn(elided_lifetimes_in_paths)] From f896a6027b25f8fb7e3f070efbcd6a17dffc2d43 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Wed, 3 Nov 2021 12:52:30 +0100 Subject: [PATCH 3/3] Fix sending messages to methods returning LongDouble/LongDoubleComplex --- objc2/src/message/apple/x86.rs | 4 +++- objc2/src/message/apple/x86_64.rs | 15 ++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/objc2/src/message/apple/x86.rs b/objc2/src/message/apple/x86.rs index a782ab942..ab2088faf 100644 --- a/objc2/src/message/apple/x86.rs +++ b/objc2/src/message/apple/x86.rs @@ -15,7 +15,9 @@ use crate::{Encode, Encoding}; /// unsafe impl MsgSendFn for T { const MSG_SEND: Imp = { - if let Encoding::Float | Encoding::Double = T::ENCODING { + // See lines 156 to 172 in: + // https://opensource.apple.com/source/objc4/objc4-818.2/runtime/message.h.auto.html + if let Encoding::Float | Encoding::Double | Encoding::LongDouble = T::ENCODING { objc_msgSend_fpret } else if let 0 | 1 | 2 | 4 | 8 = mem::size_of::() { objc_msgSend diff --git a/objc2/src/message/apple/x86_64.rs b/objc2/src/message/apple/x86_64.rs index 78fbbc3b5..1f1ee4147 100644 --- a/objc2/src/message/apple/x86_64.rs +++ b/objc2/src/message/apple/x86_64.rs @@ -1,9 +1,12 @@ use core::mem; -use objc_sys::{objc_msgSend, objc_msgSendSuper, objc_msgSendSuper_stret, objc_msgSend_stret}; +use objc_sys::{ + objc_msgSend, objc_msgSendSuper, objc_msgSendSuper_stret, objc_msgSend_fp2ret, + objc_msgSend_fpret, objc_msgSend_stret, +}; use super::MsgSendFn; use crate::runtime::Imp; -use crate::Encode; +use crate::{Encode, Encoding}; /// If the size of an object is larger than two eightbytes, it has class /// MEMORY. If the type has class MEMORY, then the caller provides space for @@ -13,7 +16,13 @@ use crate::Encode; unsafe impl MsgSendFn for T { // TODO: Should we use objc_msgSend_fpret and objc_msgSend_fp2ret ? const MSG_SEND: Imp = { - if mem::size_of::() <= 16 { + // See lines 156 to 172 in: + // https://opensource.apple.com/source/objc4/objc4-818.2/runtime/message.h.auto.html + if let Encoding::LongDouble = T::ENCODING { + objc_msgSend_fpret + } else if let Encoding::LongDoubleComplex = T::ENCODING { + objc_msgSend_fp2ret + } else if mem::size_of::() <= 16 { objc_msgSend } else { objc_msgSend_stret