Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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