Skip to content

Commit

Permalink
Merge pull request #19 from madsmtm/sys-crates
Browse files Browse the repository at this point in the history
Add `objc_sys` crate
  • Loading branch information
madsmtm authored Sep 8, 2021
2 parents d48dc10 + a97a2ea commit 8d49116
Show file tree
Hide file tree
Showing 36 changed files with 1,495 additions and 271 deletions.
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

0 comments on commit 8d49116

Please sign in to comment.