]> git.saurik.com Git - apple/libdispatch.git/blobdiff - src/BlocksRuntime/Block_private.h
libdispatch-703.50.37.tar.gz
[apple/libdispatch.git] / src / BlocksRuntime / Block_private.h
diff --git a/src/BlocksRuntime/Block_private.h b/src/BlocksRuntime/Block_private.h
new file mode 100644 (file)
index 0000000..deeb19a
--- /dev/null
@@ -0,0 +1,264 @@
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See http://swift.org/LICENSE.txt for license information
+// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+
+
+#ifndef _BLOCK_PRIVATE_H_
+#define _BLOCK_PRIVATE_H_
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#include "Block.h"
+
+#if __cplusplus
+extern "C" {
+#endif
+
+
+// Values for Block_layout->flags to describe block objects
+enum {
+    BLOCK_DEALLOCATING =      (0x0001),  // runtime
+    BLOCK_REFCOUNT_MASK =     (0xfffe),  // runtime
+    BLOCK_NEEDS_FREE =        (1 << 24), // runtime
+    BLOCK_HAS_COPY_DISPOSE =  (1 << 25), // compiler
+    BLOCK_HAS_CTOR =          (1 << 26), // compiler: helpers have C++ code
+    BLOCK_IS_GC =             (1 << 27), // runtime
+    BLOCK_IS_GLOBAL =         (1 << 28), // compiler
+    BLOCK_USE_STRET =         (1 << 29), // compiler: undefined if !BLOCK_HAS_SIGNATURE
+    BLOCK_HAS_SIGNATURE  =    (1 << 30), // compiler
+    BLOCK_HAS_EXTENDED_LAYOUT=(1 << 31)  // compiler
+};
+
+#define BLOCK_DESCRIPTOR_1 1
+struct Block_descriptor_1 {
+    uintptr_t reserved;
+    uintptr_t size;
+};
+
+#define BLOCK_DESCRIPTOR_2 1
+struct Block_descriptor_2 {
+    // requires BLOCK_HAS_COPY_DISPOSE
+    void (*copy)(void *dst, const void *src);
+    void (*dispose)(const void *);
+};
+
+#define BLOCK_DESCRIPTOR_3 1
+struct Block_descriptor_3 {
+    // requires BLOCK_HAS_SIGNATURE
+    const char *signature;
+    const char *layout;     // contents depend on BLOCK_HAS_EXTENDED_LAYOUT
+};
+
+struct Block_layout {
+    void *isa;
+    volatile int32_t flags; // contains ref count
+    int32_t reserved; 
+    void (*invoke)(void *, ...);
+    struct Block_descriptor_1 *descriptor;
+    // imported variables
+};
+
+
+// Values for Block_byref->flags to describe __block variables
+enum {
+    // Byref refcount must use the same bits as Block_layout's refcount.
+    // BLOCK_DEALLOCATING =      (0x0001),  // runtime
+    // BLOCK_REFCOUNT_MASK =     (0xfffe),  // runtime
+
+    BLOCK_BYREF_LAYOUT_MASK =       (0xf << 28), // compiler
+    BLOCK_BYREF_LAYOUT_EXTENDED =   (  1 << 28), // compiler
+    BLOCK_BYREF_LAYOUT_NON_OBJECT = (  2 << 28), // compiler
+    BLOCK_BYREF_LAYOUT_STRONG =     (  3 << 28), // compiler
+    BLOCK_BYREF_LAYOUT_WEAK =       (  4 << 28), // compiler
+    BLOCK_BYREF_LAYOUT_UNRETAINED = (  5 << 28), // compiler
+
+    BLOCK_BYREF_IS_GC =             (  1 << 27), // runtime
+
+    BLOCK_BYREF_HAS_COPY_DISPOSE =  (  1 << 25), // compiler
+    BLOCK_BYREF_NEEDS_FREE =        (  1 << 24), // runtime
+};
+
+struct Block_byref {
+    void *isa;
+    struct Block_byref *forwarding;
+    volatile int32_t flags; // contains ref count
+    uint32_t size;
+};
+
+struct Block_byref_2 {
+    // requires BLOCK_BYREF_HAS_COPY_DISPOSE
+    void (*byref_keep)(struct Block_byref *dst, struct Block_byref *src);
+    void (*byref_destroy)(struct Block_byref *);
+};
+
+struct Block_byref_3 {
+    // requires BLOCK_BYREF_LAYOUT_EXTENDED
+    const char *layout;
+};
+
+
+// Extended layout encoding.
+
+// Values for Block_descriptor_3->layout with BLOCK_HAS_EXTENDED_LAYOUT
+// and for Block_byref_3->layout with BLOCK_BYREF_LAYOUT_EXTENDED
+
+// If the layout field is less than 0x1000, then it is a compact encoding 
+// of the form 0xXYZ: X strong pointers, then Y byref pointers, 
+// then Z weak pointers.
+
+// If the layout field is 0x1000 or greater, it points to a 
+// string of layout bytes. Each byte is of the form 0xPN.
+// Operator P is from the list below. Value N is a parameter for the operator.
+// Byte 0x00 terminates the layout; remaining block data is non-pointer bytes.
+
+enum {
+    BLOCK_LAYOUT_ESCAPE = 0, // N=0 halt, rest is non-pointer. N!=0 reserved.
+    BLOCK_LAYOUT_NON_OBJECT_BYTES = 1,    // N bytes non-objects
+    BLOCK_LAYOUT_NON_OBJECT_WORDS = 2,    // N words non-objects
+    BLOCK_LAYOUT_STRONG           = 3,    // N words strong pointers
+    BLOCK_LAYOUT_BYREF            = 4,    // N words byref pointers
+    BLOCK_LAYOUT_WEAK             = 5,    // N words weak pointers
+    BLOCK_LAYOUT_UNRETAINED       = 6,    // N words unretained pointers
+    BLOCK_LAYOUT_UNKNOWN_WORDS_7  = 7,    // N words, reserved
+    BLOCK_LAYOUT_UNKNOWN_WORDS_8  = 8,    // N words, reserved
+    BLOCK_LAYOUT_UNKNOWN_WORDS_9  = 9,    // N words, reserved
+    BLOCK_LAYOUT_UNKNOWN_WORDS_A  = 0xA,  // N words, reserved
+    BLOCK_LAYOUT_UNUSED_B         = 0xB,  // unspecified, reserved
+    BLOCK_LAYOUT_UNUSED_C         = 0xC,  // unspecified, reserved
+    BLOCK_LAYOUT_UNUSED_D         = 0xD,  // unspecified, reserved
+    BLOCK_LAYOUT_UNUSED_E         = 0xE,  // unspecified, reserved
+    BLOCK_LAYOUT_UNUSED_F         = 0xF,  // unspecified, reserved
+};
+
+
+// Runtime support functions used by compiler when generating copy/dispose helpers
+
+// Values for _Block_object_assign() and _Block_object_dispose() parameters
+enum {
+    // see function implementation for a more complete description of these fields and combinations
+    BLOCK_FIELD_IS_OBJECT   =  3,  // id, NSObject, __attribute__((NSObject)), block, ...
+    BLOCK_FIELD_IS_BLOCK    =  7,  // a block variable
+    BLOCK_FIELD_IS_BYREF    =  8,  // the on stack structure holding the __block variable
+    BLOCK_FIELD_IS_WEAK     = 16,  // declared __weak, only used in byref copy helpers
+    BLOCK_BYREF_CALLER      = 128, // called from __block (byref) copy/dispose support routines.
+};
+
+enum {
+    BLOCK_ALL_COPY_DISPOSE_FLAGS = 
+        BLOCK_FIELD_IS_OBJECT | BLOCK_FIELD_IS_BLOCK | BLOCK_FIELD_IS_BYREF |
+        BLOCK_FIELD_IS_WEAK | BLOCK_BYREF_CALLER
+};
+
+// Runtime entry point called by compiler when assigning objects inside copy helper routines
+BLOCK_EXPORT void _Block_object_assign(void *destAddr, const void *object, const int flags);
+    // BLOCK_FIELD_IS_BYREF is only used from within block copy helpers
+
+
+// runtime entry point called by the compiler when disposing of objects inside dispose helper routine
+BLOCK_EXPORT void _Block_object_dispose(const void *object, const int flags);
+
+
+// Other support functions
+
+// runtime entry to get total size of a closure
+BLOCK_EXPORT size_t Block_size(void *aBlock);
+
+// indicates whether block was compiled with compiler that sets the ABI related metadata bits
+BLOCK_EXPORT bool _Block_has_signature(void *aBlock);
+
+// returns TRUE if return value of block is on the stack, FALSE otherwise
+BLOCK_EXPORT bool _Block_use_stret(void *aBlock);
+
+// Returns a string describing the block's parameter and return types.
+// The encoding scheme is the same as Objective-C @encode.
+// Returns NULL for blocks compiled with some compilers.
+BLOCK_EXPORT const char * _Block_signature(void *aBlock);
+
+// Returns a string describing the block's GC layout.
+// This uses the GC skip/scan encoding.
+// May return NULL.
+BLOCK_EXPORT const char * _Block_layout(void *aBlock);
+
+// Returns a string describing the block's layout.
+// This uses the "extended layout" form described above.
+// May return NULL.
+BLOCK_EXPORT const char * _Block_extended_layout(void *aBlock);
+
+// Callable only from the ARR weak subsystem while in exclusion zone
+BLOCK_EXPORT bool _Block_tryRetain(const void *aBlock);
+
+// Callable only from the ARR weak subsystem while in exclusion zone
+BLOCK_EXPORT bool _Block_isDeallocating(const void *aBlock);
+
+
+// the raw data space for runtime classes for blocks
+// class+meta used for stack, malloc, and collectable based blocks
+BLOCK_EXPORT void * _NSConcreteMallocBlock[32];
+BLOCK_EXPORT void * _NSConcreteAutoBlock[32];
+BLOCK_EXPORT void * _NSConcreteFinalizingBlock[32];
+BLOCK_EXPORT void * _NSConcreteWeakBlockVariable[32];
+// declared in Block.h
+// BLOCK_EXPORT void * _NSConcreteGlobalBlock[32];
+// BLOCK_EXPORT void * _NSConcreteStackBlock[32];
+
+
+// the intercept routines that must be used under GC
+BLOCK_EXPORT void _Block_use_GC( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject),
+                                  void (*setHasRefcount)(const void *, const bool),
+                                  void (*gc_assign_strong)(void *, void **),
+                                  void (*gc_assign_weak)(const void *, void *),
+                                  void (*gc_memmove)(void *, void *, unsigned long));
+
+// earlier version, now simply transitional
+BLOCK_EXPORT void _Block_use_GC5( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject),
+                                  void (*setHasRefcount)(const void *, const bool),
+                                  void (*gc_assign_strong)(void *, void **),
+                                  void (*gc_assign_weak)(const void *, void *));
+
+BLOCK_EXPORT void _Block_use_RR( void (*retain)(const void *),
+                                 void (*release)(const void *));
+
+struct Block_callbacks_RR {
+    size_t  size;                   // size == sizeof(struct Block_callbacks_RR)
+    void  (*retain)(const void *);
+    void  (*release)(const void *);
+    void  (*destructInstance)(const void *);
+};
+typedef struct Block_callbacks_RR Block_callbacks_RR;
+
+BLOCK_EXPORT void _Block_use_RR2(const Block_callbacks_RR *callbacks);
+
+// make a collectable GC heap based Block.  Not useful under non-GC.
+BLOCK_EXPORT void *_Block_copy_collectable(const void *aBlock);
+
+// thread-unsafe diagnostic
+BLOCK_EXPORT const char *_Block_dump(const void *block);
+
+
+// Obsolete
+
+// first layout
+struct Block_basic {
+    void *isa;
+    int Block_flags;  // int32_t
+    int Block_size; // XXX should be packed into Block_flags
+    void (*Block_invoke)(void *);
+    void (*Block_copy)(void *dst, void *src);  // iff BLOCK_HAS_COPY_DISPOSE
+    void (*Block_dispose)(void *);             // iff BLOCK_HAS_COPY_DISPOSE
+    //long params[0];  // where const imports, __block storage references, etc. get laid down
+} __attribute__((deprecated));
+
+
+#if __cplusplus
+}
+#endif
+
+
+#endif