Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add objc_sys crate #19

Merged
merged 36 commits into from
Sep 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
a626c49
Move objc::runtime into new objc_sys crate
madsmtm Sep 2, 2021
62cf446
sys: Rename types to match original header files and docs
madsmtm Sep 3, 2021
b80be65
sys: Move types to their own file
madsmtm Sep 3, 2021
9e64aeb
sys: Add more types
madsmtm Sep 4, 2021
915d582
sys: Mark opaque types as !Send, !Sync, !Unpin and so on
madsmtm Sep 4, 2021
7d5ad7d
sys: Add various constants (nil, Nil and OBJC_X defines)
madsmtm Sep 4, 2021
316cf28
sys: Add the `objc_msgSend` familiy of functions.
madsmtm Sep 4, 2021
254a6ed
sys: Add helper scripts to generate function bindings to libobjc
madsmtm Sep 4, 2021
96a80f0
sys: Add autogenerated bindings
madsmtm Sep 4, 2021
052bcd6
sys: Move ARC functions to their own file, and add missing declarations
madsmtm Sep 4, 2021
cbad530
sys: Remove extra extern "C" from bindings
madsmtm Sep 4, 2021
cbba512
sys: Sort bindings alphabetically
madsmtm Sep 4, 2021
fc4f4f7
sys: Simplify bindings by including std types
madsmtm Sep 4, 2021
5446efa
sys: Use preferred types in bindings
madsmtm Sep 4, 2021
75d42b4
sys: Split bindings.rs into separate files
madsmtm Sep 4, 2021
b736cb5
sys: Move classes into their respective files
madsmtm Sep 4, 2021
6cf189a
sys: Update variable names and const-ness
madsmtm Sep 4, 2021
ea55781
sys: Add a few cfg-bound functions
madsmtm Sep 4, 2021
7309ada
sys: Add functions marked with OBJC_ARC_UNAVAILABLE
madsmtm Sep 4, 2021
9028470
sys: Fix IMP being a valid NULL in class_replaceMethod
madsmtm Sep 4, 2021
b8a54e5
Specify the "links" key in objc_sys
madsmtm Sep 4, 2021
a0f01d7
sys: Add generated GNUStep libobjc2 bindings from v1.7
madsmtm Sep 5, 2021
3c01d3a
sys: Generate GNUStep libobjc2 bindings from v2.1
madsmtm Sep 5, 2021
1327d24
Add cfg(apple) and cfg(gnustep) helpers
madsmtm Sep 5, 2021
2d19c5f
sys: Verify that GNUStep supports all ARC functions
madsmtm Sep 5, 2021
6b9f624
sys: Verify that GNUStep supports objc types
madsmtm Sep 5, 2021
87504cd
sys: Mark Apple-only functions and types
madsmtm Sep 5, 2021
39faf9e
sys: Remove GNUStep functions that we've already defined
madsmtm Sep 5, 2021
513ed03
sys: Remove some deprecated and non-available GNUStep functions
madsmtm Sep 5, 2021
4d72245
sys: Configure GNUStep exception functions
madsmtm Sep 5, 2021
98ae6d3
sys: Add some GNUStep objc_msg_X functions
madsmtm Sep 5, 2021
a275174
Make objc_sys::IMP nullable
madsmtm Sep 5, 2021
216b1b4
sys: Fix GNUStep imports
madsmtm Sep 5, 2021
991b50f
sys: Fix a few mistakes
madsmtm Sep 6, 2021
e63fc13
sys: Add a few comments mentioning private functions in objc-abi.h
madsmtm Sep 7, 2021
a97a2ea
sys: Add README
madsmtm Sep 7, 2021
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
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ members = [
"objc_foundation",
"objc_foundation_derive",
"objc_id",
"objc_sys",
"objc_test_utils",
]
exclude = ["objc/tests-ios"]
1 change: 1 addition & 0 deletions objc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,6 @@ unstable_autoreleasesafe = []

[dependencies]
malloc_buf = "1.0"
objc_sys = { path = "../objc_sys" }
objc-encode = { path = "../objc_encode", version = "1.0" }
objc_exception = { path = "../objc_exception", version = "0.1", optional = true }
8 changes: 4 additions & 4 deletions objc/src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ impl CachedSel {
// It should be fine to use `Relaxed` ordering here because `sel_registerName` is
// thread-safe.
if ptr.is_null() {
let sel = runtime::sel_registerName(name.as_ptr() as *const _);
self.ptr.store(sel.as_ptr() as *mut _, Ordering::Relaxed);
sel
let ptr = runtime::sel_registerName(name.as_ptr() as *const _);
self.ptr.store(ptr as *mut _, Ordering::Relaxed);
Sel::from_ptr(ptr as *const _)
} else {
Sel::from_ptr(ptr)
}
Expand Down Expand Up @@ -56,7 +56,7 @@ impl CachedClass {
// `Relaxed` should be fine since `objc_getClass` is thread-safe.
let ptr = self.ptr.load(Ordering::Relaxed);
if ptr.is_null() {
let cls = runtime::objc_getClass(name.as_ptr() as *const _);
let cls = runtime::objc_getClass(name.as_ptr() as *const _) as *const Class;
self.ptr.store(cls as *mut _, Ordering::Relaxed);
cls.as_ref()
} else {
Expand Down
42 changes: 29 additions & 13 deletions objc/src/declare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,12 @@ pub struct ClassDecl {
impl ClassDecl {
fn with_superclass(name: &str, superclass: Option<&Class>) -> Option<ClassDecl> {
let name = CString::new(name).unwrap();
let super_ptr = superclass.map_or(ptr::null(), |c| c);
let super_ptr = superclass.map_or(ptr::null(), |c| c) as _;
let cls = unsafe { runtime::objc_allocateClassPair(super_ptr, name.as_ptr(), 0) };
if cls.is_null() {
None
} else {
Some(ClassDecl { cls })
Some(ClassDecl { cls: cls as _ })
}
}

Expand Down Expand Up @@ -182,7 +182,12 @@ impl ClassDecl {
);

let types = method_type_encoding(&F::Ret::ENCODING, encs);
let success = runtime::class_addMethod(self.cls, sel, func.imp(), types.as_ptr());
let success = runtime::class_addMethod(
self.cls as _,
sel.as_ptr() as _,
Some(func.imp()),
types.as_ptr(),
);
assert!(success != NO, "Failed to add method {:?}", sel);
}

Expand Down Expand Up @@ -212,7 +217,12 @@ impl ClassDecl {

let types = method_type_encoding(&F::Ret::ENCODING, encs);
let metaclass = (*self.cls).metaclass() as *const _ as *mut _;
let success = runtime::class_addMethod(metaclass, sel, func.imp(), types.as_ptr());
let success = runtime::class_addMethod(
metaclass,
sel.as_ptr() as _,
Some(func.imp()),
types.as_ptr(),
);
assert!(success != NO, "Failed to add class method {:?}", sel);
}

Expand All @@ -227,7 +237,13 @@ impl ClassDecl {
let size = mem::size_of::<T>();
let align = log2_align_of::<T>();
let success = unsafe {
runtime::class_addIvar(self.cls, c_name.as_ptr(), size, align, encoding.as_ptr())
runtime::class_addIvar(
self.cls as _,
c_name.as_ptr(),
size,
align,
encoding.as_ptr(),
)
};
assert!(success != NO, "Failed to add ivar {}", name);
}
Expand All @@ -238,7 +254,7 @@ impl ClassDecl {
///
/// If the protocol wasn't successfully added.
pub fn add_protocol(&mut self, proto: &Protocol) {
let success = unsafe { runtime::class_addProtocol(self.cls, proto) };
let success = unsafe { runtime::class_addProtocol(self.cls as _, proto.as_ptr()) };
assert!(success != NO, "Failed to add protocol {:?}", proto);
}

Expand All @@ -247,7 +263,7 @@ impl ClassDecl {
pub fn register(self) -> &'static Class {
unsafe {
let cls = self.cls;
runtime::objc_registerClassPair(cls);
runtime::objc_registerClassPair(cls as _);
// Forget self otherwise the class will be disposed in drop
mem::forget(self);
&*cls
Expand All @@ -258,7 +274,7 @@ impl ClassDecl {
impl Drop for ClassDecl {
fn drop(&mut self) {
unsafe {
runtime::objc_disposeClassPair(self.cls);
runtime::objc_disposeClassPair(self.cls as _);
}
}
}
Expand All @@ -275,7 +291,7 @@ impl ProtocolDecl {
/// Returns [`None`] if the protocol couldn't be allocated.
pub fn new(name: &str) -> Option<ProtocolDecl> {
let c_name = CString::new(name).unwrap();
let proto = unsafe { runtime::objc_allocateProtocol(c_name.as_ptr()) };
let proto = unsafe { runtime::objc_allocateProtocol(c_name.as_ptr()) } as *mut Protocol;
if proto.is_null() {
None
} else {
Expand Down Expand Up @@ -303,8 +319,8 @@ impl ProtocolDecl {
let types = method_type_encoding(&Ret::ENCODING, encs);
unsafe {
runtime::protocol_addMethodDescription(
self.proto,
sel,
self.proto as _,
sel.as_ptr() as _,
types.as_ptr(),
is_required as BOOL,
is_instance_method as BOOL,
Expand Down Expand Up @@ -333,15 +349,15 @@ impl ProtocolDecl {
/// Adds a requirement on another protocol.
pub fn add_protocol(&mut self, proto: &Protocol) {
unsafe {
runtime::protocol_addProtocol(self.proto, proto);
runtime::protocol_addProtocol(self.proto as _, proto.as_ptr());
}
}

/// Registers the [`ProtocolDecl`], consuming it and returning a reference
/// to the newly registered [`Protocol`].
pub fn register(self) -> &'static Protocol {
unsafe {
runtime::objc_registerProtocol(self.proto);
runtime::objc_registerProtocol(self.proto as _);
&*self.proto
}
}
Expand Down
10 changes: 1 addition & 9 deletions objc/src/message/apple/arm.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,10 @@
use core::mem;
use objc_sys::{objc_msgSend, objc_msgSendSuper, objc_msgSendSuper_stret, objc_msgSend_stret};

use super::MsgSendFn;
use crate::runtime::Imp;
use crate::{Encode, Encoding};

// TODO: C-unwind
extern "C" {
fn objc_msgSend();
fn objc_msgSend_stret();

fn objc_msgSendSuper();
fn objc_msgSendSuper_stret();
}

/// Double-word sized fundamental data types don't use stret, but any
/// composite type larger than 4 bytes does.
///
Expand Down
9 changes: 2 additions & 7 deletions objc/src/message/apple/arm64.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
use objc_sys::{objc_msgSend, objc_msgSendSuper};

use super::MsgSendFn;
use crate::runtime::Imp;
use crate::Encode;

// TODO: C-unwind
extern "C" {
fn objc_msgSend();

fn objc_msgSendSuper();
}

/// `objc_msgSend_stret` is not even available in arm64.
///
/// <https://twitter.com/gparker/status/378079715824660480>
Expand Down
12 changes: 7 additions & 5 deletions objc/src/message/apple/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use super::{Encode, Message, MessageArguments, MessageError, Super};
use objc_sys::objc_super;

use super::{Encode, Message, MessageArguments, MessageError};
use crate::runtime::{Class, Imp, Object, Sel};

#[cfg(target_arch = "x86")]
Expand Down Expand Up @@ -43,11 +45,11 @@ where
A: MessageArguments,
R: Encode,
{
let sup = Super {
receiver: obj as *mut T as *mut Object,
superclass,
let sup = objc_super {
receiver: obj as *mut T as *mut Object as *mut _,
super_class: superclass as *const Class as *const _,
};
let receiver = &sup as *const Super as *mut Object;
let receiver = &sup as *const objc_super as *mut Object;
let msg_send_fn = R::MSG_SEND_SUPER;
objc_try!({ A::invoke(msg_send_fn, receiver, sel, args) })
}
14 changes: 4 additions & 10 deletions objc/src/message/apple/x86.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
use core::mem;
use objc_sys::{
objc_msgSend, objc_msgSendSuper, objc_msgSendSuper_stret, objc_msgSend_fpret,
objc_msgSend_stret,
};

use super::MsgSendFn;
use crate::runtime::Imp;
use crate::{Encode, Encoding};

// TODO: C-unwind
extern "C" {
fn objc_msgSend();
fn objc_msgSend_fpret();
fn objc_msgSend_stret();

fn objc_msgSendSuper();
fn objc_msgSendSuper_stret();
}

/// Structures 1 or 2 bytes in size are placed in EAX.
/// Structures 4 or 8 bytes in size are placed in: EAX and EDX.
/// Structures of other sizes are placed at the address supplied by the caller.
Expand Down
11 changes: 2 additions & 9 deletions objc/src/message/apple/x86_64.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,17 @@
use core::mem;
use objc_sys::{objc_msgSend, objc_msgSendSuper, objc_msgSendSuper_stret, objc_msgSend_stret};

use super::MsgSendFn;
use crate::runtime::Imp;
use crate::Encode;

// TODO: C-unwind
extern "C" {
fn objc_msgSend();
fn objc_msgSend_stret();

fn objc_msgSendSuper();
fn objc_msgSendSuper_stret();
}

/// 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
/// the return value and passes the address of this storage.
///
/// <http://people.freebsd.org/~obrien/amd64-elf-abi.pdf>
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 {
objc_msgSend
Expand Down
24 changes: 10 additions & 14 deletions objc/src/message/gnustep.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
use core::mem;
use objc_sys::{objc_msg_lookup, objc_msg_lookup_super, objc_super};

use super::{Encode, Message, MessageArguments, MessageError, Super};
use crate::runtime::{Class, Imp, Object, Sel};

extern "C" {
fn objc_msg_lookup(receiver: *mut Object, op: Sel) -> Imp;
fn objc_msg_lookup_super(sup: *const Super, sel: Sel) -> Imp;
}
use super::{Encode, Message, MessageArguments, MessageError};
use crate::runtime::{Class, Object, Sel};

pub unsafe fn send_unverified<T, A, R>(obj: *const T, sel: Sel, args: A) -> Result<R, MessageError>
where
Expand All @@ -19,8 +15,8 @@ where
}

let receiver = obj as *mut T as *mut Object;
let msg_send_fn = objc_msg_lookup(receiver, sel);
objc_try!({ A::invoke(msg_send_fn, receiver, sel, args) })
let msg_send_fn = objc_msg_lookup(receiver as *mut _, sel.as_ptr() as *const _);
objc_try!({ A::invoke(msg_send_fn.expect("Null IMP"), receiver, sel, args) })
}

pub unsafe fn send_super_unverified<T, A, R>(
Expand All @@ -35,10 +31,10 @@ where
R: Encode,
{
let receiver = obj as *mut T as *mut Object;
let sup = Super {
receiver: receiver,
superclass: superclass,
let sup = objc_super {
receiver: receiver as *mut _,
super_class: superclass as *const Class as *const _,
};
let msg_send_fn = objc_msg_lookup_super(&sup, sel);
objc_try!({ A::invoke(msg_send_fn, receiver, sel, args) })
let msg_send_fn = objc_msg_lookup_super(&sup, sel.as_ptr() as *const _);
objc_try!({ A::invoke(msg_send_fn.expect("Null IMP"), receiver, sel, args) })
}
9 changes: 0 additions & 9 deletions objc/src/message/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,6 @@ mod platform;
use self::platform::{send_super_unverified, send_unverified};
use self::verify::{verify_message_signature, VerificationError};

/// Specifies the superclass of an instance.
#[repr(C)]
struct Super {
/// Specifies an instance of a class.
pub receiver: *mut Object,
/// Specifies the particular superclass of the instance to message.
pub superclass: *const Class,
}

/// This trait marks types that can be sent Objective-C messages.
///
/// Examples include objects, classes, and blocks.
Expand Down
6 changes: 3 additions & 3 deletions objc/src/rc/strong.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ impl StrongPtr {
///
/// The caller must ensure the given object pointer is valid.
pub unsafe fn retain(ptr: *mut Object) -> Self {
StrongPtr(runtime::objc_retain(ptr))
Self(runtime::objc_retain(ptr as _) as _)
}

/// Autoreleases self, meaning that the object is not immediately released,
Expand All @@ -37,7 +37,7 @@ impl StrongPtr {
let ptr = self.0;
mem::forget(self);
unsafe {
runtime::objc_autorelease(ptr);
runtime::objc_autorelease(ptr as _);
}
ptr
}
Expand All @@ -51,7 +51,7 @@ impl StrongPtr {
impl Drop for StrongPtr {
fn drop(&mut self) {
unsafe {
runtime::objc_release(self.0);
runtime::objc_release(self.0 as _);
}
}
}
Expand Down
10 changes: 5 additions & 5 deletions objc/src/rc/weak.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,24 @@ impl WeakPtr {
/// The caller must ensure the given object pointer is valid.
pub unsafe fn new(obj: *mut Object) -> Self {
let ptr = Box::new(UnsafeCell::new(ptr::null_mut()));
runtime::objc_initWeak(ptr.get(), obj);
runtime::objc_initWeak(ptr.get() as _, obj as _);
WeakPtr(ptr)
}

/// Loads the object self points to, returning a [`StrongPtr`].
/// If the object has been deallocated, the returned pointer will be null.
pub fn load(&self) -> StrongPtr {
unsafe {
let ptr = runtime::objc_loadWeakRetained(self.0.get());
StrongPtr::new(ptr)
let ptr = runtime::objc_loadWeakRetained(self.0.get() as _);
StrongPtr::new(ptr as _)
}
}
}

impl Drop for WeakPtr {
fn drop(&mut self) {
unsafe {
runtime::objc_destroyWeak(self.0.get());
runtime::objc_destroyWeak(self.0.get() as _);
}
}
}
Expand All @@ -47,7 +47,7 @@ impl Clone for WeakPtr {
fn clone(&self) -> Self {
let ptr = Box::new(UnsafeCell::new(ptr::null_mut()));
unsafe {
runtime::objc_copyWeak(ptr.get(), self.0.get());
runtime::objc_copyWeak(ptr.get() as _, self.0.get() as _);
}
WeakPtr(ptr)
}
Expand Down
Loading