Skip to content

Commit

Permalink
Merge pull request #20 from madsmtm/encode-complex
Browse files Browse the repository at this point in the history
Add `LongDouble`, `FloatComplex`, `DoubleComplex` and `LongDoubleComplex` encodings
  • Loading branch information
madsmtm authored Nov 3, 2021
2 parents 5061958 + f896a60 commit 076d711
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 6 deletions.
31 changes: 29 additions & 2 deletions objc2-encode/src/encoding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ 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> {
/// A C `char`. Corresponds to the `c` code.
Char,
Expand All @@ -39,6 +42,15 @@ 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,
// TODO: Complex(&Encoding) ???
/// A C++ `bool` / C99 `_Bool`. Corresponds to the `B` code.
Bool,
/// A C `void`. Corresponds to the `v` code.
Expand All @@ -54,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.
///
Expand Down Expand Up @@ -81,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<'_> {
Expand All @@ -99,6 +122,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 => "*",
Expand Down
5 changes: 5 additions & 0 deletions objc2-encode/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
//! # Objective-C type-encoding
//!
//! This is re-exported into the top level of `objc2`.
//!
//! Further resources:
//! - <https://dmaclach.medium.com/objective-c-encoding-and-you-866624cc02de>
//! - <https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html>
//! - <https://dmaclach.medium.com/objective-c-encoding-and-you-866624cc02de>
#![no_std]
#![warn(elided_lifetimes_in_paths)]
Expand Down
4 changes: 4 additions & 0 deletions objc2-encode/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 => "*",
Expand Down
4 changes: 3 additions & 1 deletion objc2/src/message/apple/x86.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ use crate::{Encode, Encoding};
/// <https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/LowLevelABI/130-IA-32_Function_Calling_Conventions/IA32.html>
unsafe impl<T: Encode> 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::<T>() {
objc_msgSend
Expand Down
15 changes: 12 additions & 3 deletions objc2/src/message/apple/x86_64.rs
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -13,7 +16,13 @@ use crate::Encode;
unsafe impl<T: Encode> MsgSendFn for T {
// TODO: Should we use objc_msgSend_fpret and objc_msgSend_fp2ret ?
const MSG_SEND: Imp = {
if mem::size_of::<T>() <= 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::<T>() <= 16 {
objc_msgSend
} else {
objc_msgSend_stret
Expand Down

0 comments on commit 076d711

Please sign in to comment.