Skip to content

Commit 04919d1

Browse files
committed
Fix block-sys types
Use `c_void` since e.g. `Block_descriptor_header` and `Block_byref_extended` only has provenance over parts of the struct. We must do this because we don't have access to extern types yet!
1 parent dbddcb8 commit 04919d1

File tree

4 files changed

+39
-37
lines changed

4 files changed

+39
-37
lines changed

block-sys/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
1212
scripts becomes `DEP_BLOCK_0_0_CC_ARGS`).
1313
* **BREAKING**: Apple's runtime is now always the default.
1414

15+
### Fixed
16+
* **BREAKING**: Tweak the types of a lot of fields and arguments.
17+
1518

1619
## 0.0.3 - 2022-01-03
1720

block-sys/src/lib.rs

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
//!
1010
//! [ABI]: https://clang.llvm.org/docs/Block-ABI-Apple.html
1111
12+
// TODO: Replace `extern "C"` with `extern "C-unwind"` where applicable.
13+
// See https://rust-lang.github.io/rfcs/2945-c-unwind-abi.html.
14+
1215
#![no_std]
1316
// Update in Cargo.toml as well.
1417
#![doc(html_root_url = "https://docs.rs/block-sys/0.0.3")]
@@ -244,7 +247,7 @@ pub struct Block_layout {
244247
/// Class pointer. Always initialised to &_NSConcreteStackBlock for blocks
245248
/// that are created on the stack or &_NSConcreteGlobalBlock for blocks
246249
/// that are created in global storage.
247-
pub isa: *mut Class,
250+
pub isa: *const Class,
248251
/// Flags.
249252
/// See the `block_flags` enumerated type for possible values.
250253
/// Contains ref count in Apple and ObjFW.
@@ -259,7 +262,7 @@ pub struct Block_layout {
259262
/// parameters. If the BLOCK_USE_SRET & BLOCK_HAS_SIGNATURE flag is set,
260263
/// there is an additional hidden argument, which is a pointer to the
261264
/// space on the stack allocated to hold the return value.
262-
pub invoke: Option<unsafe extern "C" fn(block: *mut Block_layout, ...)>,
265+
pub invoke: Option<unsafe extern "C" fn()>,
263266
/// The block's descriptor. The actual type of this is:
264267
/// ```pseudo-code
265268
/// match (BLOCK_HAS_COPY_DISPOSE, BLOCK_HAS_SIGNATURE) {
@@ -271,7 +274,8 @@ pub struct Block_layout {
271274
/// ```
272275
///
273276
/// But it is safe to access this through just `Block_descriptor_header`.
274-
pub descriptor: *mut Block_descriptor_header,
277+
// Note: Important to use `*const c_void` until we know which type it is!
278+
pub descriptor: *const c_void,
275279
}
276280

277281
#[repr(C)]
@@ -288,12 +292,13 @@ pub struct Block_descriptor_header {
288292
#[repr(C)]
289293
pub struct Block_descriptor {
290294
pub header: Block_descriptor_header,
295+
291296
/// Copy function, generated by the compiler to help copy the block if it
292297
/// contains nontrivial copy operations.
293-
pub copy: Option<unsafe extern "C" fn(dst: *mut Block_byref, src: *mut Block_byref)>,
298+
pub copy: Option<unsafe extern "C" fn(dst: *mut c_void, src: *mut c_void)>,
294299
/// Dispose function, generated by the compiler to help copy the block if
295300
/// it contains nontrivial destructors.
296-
pub dispose: Option<unsafe extern "C" fn(src: *mut Block_byref)>,
301+
pub dispose: Option<unsafe extern "C" fn(src: *mut c_void)>,
297302
}
298303

299304
/// Extended block descriptor that does not contain copy and dispose helper
@@ -312,7 +317,12 @@ pub struct Block_descriptor_basic {
312317
/// Requires BLOCK_HAS_COPY_DISPOSE and BLOCK_HAS_SIGNATURE
313318
#[repr(C)]
314319
pub struct Block_descriptor_with_signature {
315-
pub inner: Block_descriptor,
320+
pub header: Block_descriptor_header,
321+
322+
/// Same as [`Block_descriptor::copy`].
323+
pub copy: Option<unsafe extern "C" fn(dst: *mut c_void, src: *mut c_void)>,
324+
/// Same as [`Block_descriptor::dispose`].
325+
pub dispose: Option<unsafe extern "C" fn(src: *mut c_void)>,
316326

317327
/// Objective-C type encoding of the block.
318328
#[doc(alias = "signature")]
@@ -336,7 +346,7 @@ pub struct Block_descriptor_with_signature {
336346
// pub isa: *mut c_void,
337347
// pub Block_flags: i32,
338348
// pub Block_size: i32,
339-
// pub Block_invoke: Option<unsafe extern "C" fn(block: *mut c_void)>,
349+
// pub Block_invoke: Option<unsafe extern "C" fn()>,
340350
// pub Block_copy: Option<unsafe extern "C" fn(dst: *mut c_void, src: *mut c_void)>,
341351
// pub Block_dispose: Option<unsafe extern "C" fn(block: *mut c_void)>,
342352
// }
@@ -348,7 +358,7 @@ pub struct Block_descriptor_with_signature {
348358
pub struct Block_byref_header {
349359
/// Class pointer. Currently unused on GNUStep and always NULL. Could be
350360
/// used in the future to support introspection.
351-
pub isa: *mut c_void,
361+
pub isa: *const Class,
352362
/// The pointer to the structure that contains the real version of the
353363
/// data. All accesses go via this pointer. If an on-stack byref structure
354364
/// is copied to the heap, then its forwarding pointer should point to the
@@ -374,10 +384,9 @@ pub struct Block_byref_header {
374384
pub struct Block_byref {
375385
pub header: Block_byref_header,
376386
/// Copy function.
377-
pub keep:
378-
Option<unsafe extern "C" fn(dst: *mut Block_byref_header, src: *mut Block_byref_header)>,
387+
pub keep: Option<unsafe extern "C" fn(dst: *mut c_void, src: *mut c_void)>,
379388
/// Dispose function.
380-
pub destroy: Option<unsafe extern "C" fn(src: *mut Block_byref_header)>,
389+
pub destroy: Option<unsafe extern "C" fn(src: *mut c_void)>,
381390
}
382391

383392
#[cfg(feature = "apple")]
@@ -387,7 +396,11 @@ pub struct Block_byref {
387396
#[repr(C)]
388397
#[doc(alias = "Block_byref_3")]
389398
pub struct Block_byref_extended {
390-
pub inner: Block_byref,
399+
pub header: Block_byref_header,
400+
/// Same as [`Block_byref::keep`].
401+
pub keep: Option<unsafe extern "C" fn(dst: *mut c_void, src: *mut c_void)>,
402+
/// Same as [`Block_byref::destroy`].
403+
pub destroy: Option<unsafe extern "C" fn(src: *mut c_void)>,
391404
pub layout: *const c_char,
392405
}
393406

@@ -399,41 +412,27 @@ mod tests {
399412

400413
#[test]
401414
fn smoke() {
402-
assert_eq!(unsafe { _Block_copy(ptr::null()) }, ptr::null_mut());
415+
assert_eq!(unsafe { _Block_copy(ptr::null_mut()) }, ptr::null_mut());
403416
}
404417

405418
#[test]
406419
fn test_linkable() {
407420
println!("{:p}", unsafe { &_NSConcreteGlobalBlock });
408421
println!("{:p}", unsafe { &_NSConcreteStackBlock });
409422
println!("{:p}", unsafe { &_NSConcreteMallocBlock });
423+
println!("{:p}", _Block_copy as unsafe extern "C" fn(_) -> _);
410424
println!(
411425
"{:p}",
412-
_Block_copy as unsafe extern "C" fn(*const c_void) -> *mut c_void
413-
);
414-
println!(
415-
"{:p}",
416-
_Block_object_assign
417-
as unsafe extern "C" fn(*mut c_void, *const c_void, block_assign_dispose_flags)
418-
);
419-
println!(
420-
"{:p}",
421-
_Block_object_dispose
422-
as unsafe extern "C" fn(*const c_void, block_assign_dispose_flags)
423-
);
424-
println!(
425-
"{:p}",
426-
_Block_release as unsafe extern "C" fn(*const c_void)
426+
_Block_object_assign as unsafe extern "C" fn(_, _, _)
427427
);
428+
println!("{:p}", _Block_object_dispose as unsafe extern "C" fn(_, _));
429+
println!("{:p}", _Block_release as unsafe extern "C" fn(_));
428430
#[cfg(any(feature = "apple", feature = "compiler-rt"))]
429431
{
430432
println!("{:p}", unsafe { &_NSConcreteAutoBlock });
431433
println!("{:p}", unsafe { &_NSConcreteFinalizingBlock });
432434
println!("{:p}", unsafe { &_NSConcreteWeakBlockVariable });
433-
println!(
434-
"{:p}",
435-
Block_size as unsafe extern "C" fn(*mut c_void) -> c_ulong
436-
);
435+
println!("{:p}", Block_size as unsafe extern "C" fn(_) -> _);
437436
}
438437
}
439438
}

block2/src/global.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use core::ffi::c_void;
12
use core::marker::PhantomData;
23
use core::mem;
34
use core::ops::Deref;
@@ -61,7 +62,7 @@ impl<A, R> GlobalBlock<A, R> {
6162
reserved: 0,
6263
// Populated in `global_block!`
6364
invoke: None,
64-
descriptor: &GLOBAL_DESCRIPTOR as *const _ as *mut _,
65+
descriptor: &GLOBAL_DESCRIPTOR as *const ffi::Block_descriptor_header as *mut c_void,
6566
};
6667

6768
/// Use the [`global_block`] macro instead.
@@ -168,7 +169,7 @@ macro_rules! global_block {
168169
#[allow(unused_unsafe)]
169170
$vis static $name: $crate::GlobalBlock<($($t,)*) $(, $r)?> = unsafe {
170171
let mut layout = $crate::GlobalBlock::<($($t,)*) $(, $r)?>::__DEFAULT_LAYOUT;
171-
layout.isa = &$crate::ffi::_NSConcreteGlobalBlock as *const _ as *mut _;
172+
layout.isa = &$crate::ffi::_NSConcreteGlobalBlock;
172173
layout.invoke = ::core::option::Option::Some({
173174
unsafe extern "C" fn inner(_: *mut $crate::ffi::Block_layout, $($a: $t),*) $(-> $r)? {
174175
$body

block2/src/lib.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@ extern crate std;
8989
#[doc = include_str!("../README.md")]
9090
extern "C" {}
9191

92-
use core::ffi::c_void;
9392
use core::marker::PhantomData;
9493
use core::mem::{self, ManuallyDrop};
9594
use core::ops::{Deref, DerefMut};
@@ -229,7 +228,7 @@ impl<A, R> RcBlock<A, R> {
229228
/// The given pointer must point to a valid `Block`.
230229
pub unsafe fn copy(ptr: *mut Block<A, R>) -> Self {
231230
// SAFETY: The caller ensures the pointer is valid.
232-
let ptr: *mut Block<A, R> = unsafe { ffi::_Block_copy(ptr as *const c_void) }.cast();
231+
let ptr: *mut Block<A, R> = unsafe { ffi::_Block_copy(ptr.cast()) }.cast();
233232
// SAFETY: We just copied the block, so the reference count is +1
234233
//
235234
// TODO: Does _Block_copy always returns a valid pointer?
@@ -256,7 +255,7 @@ impl<A, R> Deref for RcBlock<A, R> {
256255

257256
impl<A, R> Drop for RcBlock<A, R> {
258257
fn drop(&mut self) {
259-
unsafe { ffi::_Block_release(self.ptr as *const c_void) };
258+
unsafe { ffi::_Block_release(self.ptr.cast()) };
260259
}
261260
}
262261

0 commit comments

Comments
 (0)