Skip to content

Commit

Permalink
Improve no_std support in dispatch2 and objc2-foundation
Browse files Browse the repository at this point in the history
  • Loading branch information
madsmtm committed Dec 25, 2024
1 parent e6eda12 commit 321d4cb
Show file tree
Hide file tree
Showing 20 changed files with 56 additions and 33 deletions.
2 changes: 1 addition & 1 deletion crates/dispatch2/src/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#![allow(missing_docs, non_camel_case_types)]

use core::ffi::{c_long, c_uint, c_ulong, c_void};
use std::ptr::addr_of;
use core::ptr::addr_of;

#[cfg(feature = "objc2")]
use objc2::encode::{Encode, Encoding, RefEncode};
Expand Down
4 changes: 2 additions & 2 deletions crates/dispatch2/src/group.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//! Dispatch group definition.
use std::time::Duration;

use alloc::boxed::Box;
use core::ffi::c_void;
use core::time::Duration;

use super::object::DispatchObject;
use super::queue::Queue;
Expand Down
9 changes: 9 additions & 0 deletions crates/dispatch2/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,22 @@
//! queue.exec_async(|| println!("Hello"));
//! queue.exec_sync(|| println!("World"));
//! ```
#![no_std]
#![allow(unreachable_patterns)]
#![warn(missing_docs)]
#![warn(clippy::undocumented_unsafe_blocks)]
#![warn(clippy::missing_safety_doc)]
// Update in Cargo.toml as well.
#![doc(html_root_url = "https://docs.rs/dispatch2/0.1.0")]

#[cfg(not(feature = "alloc"))]
compile_error!("The `alloc` feature currently must be enabled.");

extern crate alloc;

#[cfg(feature = "std")]
extern crate std;

use self::ffi::dispatch_qos_class_t;

pub mod ffi;
Expand Down
2 changes: 1 addition & 1 deletion crates/dispatch2/src/main_thread_bound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ impl<T> MainThreadBound<T> {
/// Create a shared static that is only available from the main thread.
///
/// ```
/// use std::cell::Cell;
/// use core::cell::Cell;
/// use dispatch2::MainThreadBound;
/// use objc2::MainThreadMarker;
///
Expand Down
2 changes: 2 additions & 0 deletions crates/dispatch2/src/object.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//! Dispatch object definition.
use alloc::boxed::Box;

use super::{ffi::*, queue::Queue, utils::function_wrapper, QualityOfServiceClass};

/// Error returned by [DispatchObject::set_target_queue].
Expand Down
23 changes: 10 additions & 13 deletions crates/dispatch2/src/once.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
use core::cell::UnsafeCell;
use core::ffi::c_void;
use core::fmt;
use core::panic::{RefUnwindSafe, UnwindSafe};
use core::ptr::NonNull;
use std::cell::UnsafeCell;
use std::panic::{RefUnwindSafe, UnwindSafe};
use std::sync::atomic::AtomicIsize;
use std::sync::atomic::Ordering;
use core::sync::atomic::{AtomicIsize, Ordering};

use crate::ffi;

Expand Down Expand Up @@ -166,13 +165,13 @@ impl Once {
invoke_dispatch_once(predicate, work);
}

// NOTE: Unlike in C, we cannot use `std::hint::assert_unchecked`,
// NOTE: Unlike in C, we cannot use `core::hint::assert_unchecked`,
// since that would actually be lying from a language perspective;
// the value seems to only settle on being !0 after some time
// (something about the _COMM_PAGE_CPU_QUIESCENT_COUNTER?)
//
// TODO: Investigate this further!
// std::hint::assert_unchecked(atomic_predicate.load(Ordering::Acquire) == !0);
// core::hint::assert_unchecked(atomic_predicate.load(Ordering::Acquire) == !0);
} else {
invoke_dispatch_once(predicate, work);
}
Expand All @@ -196,9 +195,8 @@ impl fmt::Debug for Once {

#[cfg(test)]
mod tests {
use std::cell::Cell;
use std::mem::ManuallyDrop;
use std::thread;
use core::cell::Cell;
use core::mem::ManuallyDrop;

use super::*;

Expand Down Expand Up @@ -249,12 +247,13 @@ mod tests {
}

#[test]
#[cfg(feature = "std")]
fn test_threaded() {
let once = Once::new();

let num = AtomicIsize::new(0);

thread::scope(|scope| {
std::thread::scope(|scope| {
scope.spawn(|| {
once.call_once(|| {
num.fetch_add(1, Ordering::Relaxed);
Expand Down Expand Up @@ -329,9 +328,7 @@ mod tests {
let once = Once::new();

once.call_once(|| {
once.call_once(|| {
println!("foo");
});
once.call_once(|| {});
});
}
}
11 changes: 6 additions & 5 deletions crates/dispatch2/src/queue.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
//! Dispatch queue definition.
use std::borrow::{Borrow, BorrowMut};
use std::ffi::CString;
use std::ops::{Deref, DerefMut};
use std::ptr::NonNull;
use std::time::Duration;
use alloc::boxed::Box;
use alloc::ffi::CString;
use core::borrow::{Borrow, BorrowMut};
use core::ops::{Deref, DerefMut};
use core::ptr::NonNull;
use core::time::Duration;

use super::object::{DispatchObject, QualityOfServiceClassFloorError, TargetQueueError};
use super::utils::function_wrapper;
Expand Down
2 changes: 1 addition & 1 deletion crates/dispatch2/src/semaphore.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Dispatch semaphore definition.
use std::time::Duration;
use core::time::Duration;

use super::ffi::*;
use super::object::DispatchObject;
Expand Down
4 changes: 2 additions & 2 deletions crates/dispatch2/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::time::Duration;

use alloc::boxed::Box;
use core::ffi::c_void;
use core::time::Duration;

use super::ffi::{dispatch_time, dispatch_time_t, DISPATCH_TIME_NOW};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ struct.__IOSurface.skipped = true
# Needs io_service_t from the kernel
fn.CGDisplayIOServicePort.skipped = true

# Needs std::ffi::VaList, currently unstable
# Needs core::ffi::VaList, currently unstable
fn.CGColorConversionInfoCreateFromListWithArguments.skipped = true

# Unknown how to handle the calling convention here?
Expand Down
5 changes: 4 additions & 1 deletion framework-crates/objc2-foundation/src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ impl NSData {
}

#[cfg(feature = "block2")]
#[cfg(feature = "alloc")]
pub fn from_vec(bytes: Vec<u8>) -> Retained<Self> {
// GNUStep's NSData `initWithBytesNoCopy:length:deallocator:` has a
// bug; it forgets to assign the input buffer and length to the
Expand Down Expand Up @@ -201,7 +202,7 @@ pub struct Iter<'a> {
data: &'a NSData,
#[cfg(debug_assertions)]
length: usize,
bytes: std::vec::IntoIter<u8>,
bytes: alloc::vec::IntoIter<u8>,
}

impl<'a> Iter<'a> {
Expand Down Expand Up @@ -289,6 +290,7 @@ impl<'a> Extend<&'a u8> for &NSMutableData {
}
}

#[cfg(feature = "std")]
impl std::io::Write for &NSMutableData {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.extend_from_slice(buf);
Expand Down Expand Up @@ -322,6 +324,7 @@ impl RetainedFromIterator<u8> for NSMutableData {
}

#[cfg(feature = "block2")]
#[cfg(feature = "alloc")]
unsafe fn with_vec<T: objc2::Message>(obj: objc2::rc::Allocated<T>, bytes: Vec<u8>) -> Retained<T> {
use core::mem::ManuallyDrop;

Expand Down
3 changes: 3 additions & 0 deletions framework-crates/objc2-foundation/src/dictionary.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//! Utilities for the `NSDictionary` and `NSMutableDictionary` classes.
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
use core::fmt;
use core::mem;
Expand Down Expand Up @@ -215,6 +216,7 @@ impl<KeyType: Message, ObjectType: Message> NSDictionary<KeyType, ObjectType> {
/// The dictionary must not be mutated while the returned references are
/// alive.
#[doc(alias = "getObjects:andKeys:")]
#[cfg(feature = "alloc")]
pub unsafe fn to_vecs_unchecked(&self) -> (Vec<&KeyType>, Vec<&ObjectType>) {
let len = self.len();
let mut keys = Vec::with_capacity(len);
Expand Down Expand Up @@ -314,6 +316,7 @@ impl<KeyType: Message, ObjectType: Message> NSDictionary<KeyType, ObjectType> {
/// }
/// ```
#[doc(alias = "getObjects:")]
#[cfg(feature = "alloc")]
pub fn to_vecs(&self) -> (Vec<Retained<KeyType>>, Vec<Retained<ObjectType>>) {
// SAFETY: We retain the elements below, so that we know that the
// dictionary isn't mutated while they are alive.
Expand Down
4 changes: 3 additions & 1 deletion framework-crates/objc2-foundation/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,9 @@
#![allow(non_snake_case)]
#![recursion_limit = "512"]

#[cfg(feature = "alloc")]
#[cfg(not(feature = "alloc"))]
compile_error!("The `alloc` feature currently must be enabled.");

extern crate alloc;

#[cfg(feature = "std")]
Expand Down
4 changes: 3 additions & 1 deletion framework-crates/objc2-foundation/src/tests/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
use alloc::format;

use crate::NSBundle;
use objc2::runtime::NSObjectProtocol;

#[test]
#[cfg(feature = "NSString")]
Expand All @@ -10,8 +11,9 @@ use crate::NSBundle;
fn try_running_functions() {
// This is mostly empty since cargo doesn't bundle the application
// before executing.

let bundle = NSBundle::mainBundle();
std::println!("{bundle:?}");
let _ = bundle.description();
assert_eq!(format!("{:?}", bundle.infoDictionary().unwrap()), "{}");
assert_eq!(bundle.name(), None);
}
2 changes: 1 addition & 1 deletion framework-crates/objc2-foundation/src/tests/dictionary.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#![cfg(feature = "NSDictionary")]
#![cfg(feature = "NSString")]
#![cfg(feature = "NSObject")]
use alloc::ffi::CString;
use alloc::format;
use alloc::string::ToString;
use core::ptr;
use std::ffi::CString;

use objc2::{
ffi, msg_send,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ fn test_iter_mutation_detection() {
feature = "gnustep-1-7",
ignore = "thread safety issues regarding initialization"
)]
#[cfg(feature = "std")]
fn test_threaded() {
std::thread::scope(|s| {
s.spawn(|| {
Expand Down
3 changes: 2 additions & 1 deletion framework-crates/objc2-foundation/src/tests/number.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ fn float_int_equality() {
#[test]
#[cfg(feature = "NSString")]
fn display_debug() {
use std::{fmt, format};
use alloc::format;
use core::fmt;

fn assert_display_debug<T: fmt::Debug + fmt::Display>(val: T, expected: &str) {
// The two impls for these happen to be the same
Expand Down
3 changes: 2 additions & 1 deletion framework-crates/objc2-foundation/src/tests/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,11 @@ fn test_strips_first_leading_zero_width_no_break_space() {
}

#[test]
#[cfg(feature = "std")]
fn test_hash() {
use core::hash::Hash;
use core::hash::Hasher;
use std::collections::hash_map::DefaultHasher;
use std::hash::Hash;

let s1 = NSString::from_str("example string goes here");
let s2 = NSString::from_str("example string goes here");
Expand Down
1 change: 1 addition & 0 deletions framework-crates/objc2-foundation/src/tests/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ fn test_main_thread() {
}

#[test]
#[cfg(feature = "std")]
fn test_not_main_thread() {
let res = std::thread::spawn(|| NSThread::currentThread().isMainThread())
.join()
Expand Down
2 changes: 1 addition & 1 deletion framework-crates/objc2-metal/src/slice.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#![allow(unused_imports)]
#![allow(clippy::missing_safety_doc)]
use std::ptr::NonNull;
use core::ptr::NonNull;

use crate::*;

Expand Down

0 comments on commit 321d4cb

Please sign in to comment.