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 ) ]
289293pub 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 ) ]
314319pub 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 {
348358pub 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 {
374384pub 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" ) ]
389398pub 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}
0 commit comments