1/* 2 * Block_private.h 3 * 4 * SPI for Blocks 5 * 6 * Copyright (c) 2008-2010 Apple Inc. All rights reserved. 7 * 8 * @APPLE_LLVM_LICENSE_HEADER@ 9 * 10 */ 11 12#ifndef _BLOCK_PRIVATE_H_ 13#define _BLOCK_PRIVATE_H_ 14 15#include <Availability.h> 16#include <AvailabilityMacros.h> 17#include <TargetConditionals.h> 18 19#include <stdbool.h> 20#include <stdint.h> 21#include <stdio.h> 22 23#include <Block.h> 24 25#if __cplusplus 26extern "C" { 27#endif 28 29 30// Values for Block_layout->flags to describe block objects 31enum { 32 BLOCK_DEALLOCATING = (0x0001), // runtime 33 BLOCK_REFCOUNT_MASK = (0xfffe), // runtime 34 BLOCK_NEEDS_FREE = (1 << 24), // runtime 35 BLOCK_HAS_COPY_DISPOSE = (1 << 25), // compiler 36 BLOCK_HAS_CTOR = (1 << 26), // compiler: helpers have C++ code 37 BLOCK_IS_GC = (1 << 27), // runtime 38 BLOCK_IS_GLOBAL = (1 << 28), // compiler 39 BLOCK_USE_STRET = (1 << 29), // compiler: undefined if !BLOCK_HAS_SIGNATURE 40 BLOCK_HAS_SIGNATURE = (1 << 30), // compiler 41 BLOCK_HAS_EXTENDED_LAYOUT=(1 << 31) // compiler 42}; 43 44#define BLOCK_DESCRIPTOR_1 1 45struct Block_descriptor_1 { 46 uintptr_t reserved; 47 uintptr_t size; 48}; 49 50#define BLOCK_DESCRIPTOR_2 1 51struct Block_descriptor_2 { 52 // requires BLOCK_HAS_COPY_DISPOSE 53 void (*copy)(void *dst, const void *src); 54 void (*dispose)(const void *); 55}; 56 57#define BLOCK_DESCRIPTOR_3 1 58struct Block_descriptor_3 { 59 // requires BLOCK_HAS_SIGNATURE 60 const char *signature; 61 const char *layout; // contents depend on BLOCK_HAS_EXTENDED_LAYOUT 62}; 63 64struct Block_layout { 65 void *isa; 66 volatile int32_t flags; // contains ref count 67 int32_t reserved; 68 void (*invoke)(void *, ...); 69 struct Block_descriptor_1 *descriptor; 70 // imported variables 71}; 72 73 74// Values for Block_byref->flags to describe __block variables 75enum { 76 // Byref refcount must use the same bits as Block_layout's refcount. 77 // BLOCK_DEALLOCATING = (0x0001), // runtime 78 // BLOCK_REFCOUNT_MASK = (0xfffe), // runtime 79 80 BLOCK_BYREF_LAYOUT_MASK = (0xf << 28), // compiler 81 BLOCK_BYREF_LAYOUT_EXTENDED = ( 1 << 28), // compiler 82 BLOCK_BYREF_LAYOUT_NON_OBJECT = ( 2 << 28), // compiler 83 BLOCK_BYREF_LAYOUT_STRONG = ( 3 << 28), // compiler 84 BLOCK_BYREF_LAYOUT_WEAK = ( 4 << 28), // compiler 85 BLOCK_BYREF_LAYOUT_UNRETAINED = ( 5 << 28), // compiler 86 87 BLOCK_BYREF_IS_GC = ( 1 << 27), // runtime 88 89 BLOCK_BYREF_HAS_COPY_DISPOSE = ( 1 << 25), // compiler 90 BLOCK_BYREF_NEEDS_FREE = ( 1 << 24), // runtime 91}; 92 93struct Block_byref { 94 void *isa; 95 struct Block_byref *forwarding; 96 volatile int32_t flags; // contains ref count 97 uint32_t size; 98}; 99 100struct Block_byref_2 { 101 // requires BLOCK_BYREF_HAS_COPY_DISPOSE 102 void (*byref_keep)(struct Block_byref *dst, struct Block_byref *src); 103 void (*byref_destroy)(struct Block_byref *); 104}; 105 106struct Block_byref_3 { 107 // requires BLOCK_BYREF_LAYOUT_EXTENDED 108 const char *layout; 109}; 110 111 112// Extended layout encoding. 113 114// Values for Block_descriptor_3->layout with BLOCK_HAS_EXTENDED_LAYOUT 115// and for Block_byref_3->layout with BLOCK_BYREF_LAYOUT_EXTENDED 116 117// If the layout field is less than 0x1000, then it is a compact encoding 118// of the form 0xXYZ: X strong pointers, then Y byref pointers, 119// then Z weak pointers. 120 121// If the layout field is 0x1000 or greater, it points to a 122// string of layout bytes. Each byte is of the form 0xPN. 123// Operator P is from the list below. Value N is a parameter for the operator. 124// Byte 0x00 terminates the layout; remaining block data is non-pointer bytes. 125 126enum { 127 BLOCK_LAYOUT_ESCAPE = 0, // N=0 halt, rest is non-pointer. N!=0 reserved. 128 BLOCK_LAYOUT_NON_OBJECT_BYTES = 1, // N bytes non-objects 129 BLOCK_LAYOUT_NON_OBJECT_WORDS = 2, // N words non-objects 130 BLOCK_LAYOUT_STRONG = 3, // N words strong pointers 131 BLOCK_LAYOUT_BYREF = 4, // N words byref pointers 132 BLOCK_LAYOUT_WEAK = 5, // N words weak pointers 133 BLOCK_LAYOUT_UNRETAINED = 6, // N words unretained pointers 134 BLOCK_LAYOUT_UNKNOWN_WORDS_7 = 7, // N words, reserved 135 BLOCK_LAYOUT_UNKNOWN_WORDS_8 = 8, // N words, reserved 136 BLOCK_LAYOUT_UNKNOWN_WORDS_9 = 9, // N words, reserved 137 BLOCK_LAYOUT_UNKNOWN_WORDS_A = 0xA, // N words, reserved 138 BLOCK_LAYOUT_UNUSED_B = 0xB, // unspecified, reserved 139 BLOCK_LAYOUT_UNUSED_C = 0xC, // unspecified, reserved 140 BLOCK_LAYOUT_UNUSED_D = 0xD, // unspecified, reserved 141 BLOCK_LAYOUT_UNUSED_E = 0xE, // unspecified, reserved 142 BLOCK_LAYOUT_UNUSED_F = 0xF, // unspecified, reserved 143}; 144 145 146// Runtime support functions used by compiler when generating copy/dispose helpers 147 148// Values for _Block_object_assign() and _Block_object_dispose() parameters 149enum { 150 // see function implementation for a more complete description of these fields and combinations 151 BLOCK_FIELD_IS_OBJECT = 3, // id, NSObject, __attribute__((NSObject)), block, ... 152 BLOCK_FIELD_IS_BLOCK = 7, // a block variable 153 BLOCK_FIELD_IS_BYREF = 8, // the on stack structure holding the __block variable 154 BLOCK_FIELD_IS_WEAK = 16, // declared __weak, only used in byref copy helpers 155 BLOCK_BYREF_CALLER = 128, // called from __block (byref) copy/dispose support routines. 156}; 157 158enum { 159 BLOCK_ALL_COPY_DISPOSE_FLAGS = 160 BLOCK_FIELD_IS_OBJECT | BLOCK_FIELD_IS_BLOCK | BLOCK_FIELD_IS_BYREF | 161 BLOCK_FIELD_IS_WEAK | BLOCK_BYREF_CALLER 162}; 163 164// Runtime entry point called by compiler when assigning objects inside copy helper routines 165BLOCK_EXPORT void _Block_object_assign(void *destAddr, const void *object, const int flags); 166 // BLOCK_FIELD_IS_BYREF is only used from within block copy helpers 167 168 169// runtime entry point called by the compiler when disposing of objects inside dispose helper routine 170BLOCK_EXPORT void _Block_object_dispose(const void *object, const int flags); 171 172 173// Other support functions 174 175// runtime entry to get total size of a closure 176BLOCK_EXPORT size_t Block_size(void *aBlock); 177 178// indicates whether block was compiled with compiler that sets the ABI related metadata bits 179BLOCK_EXPORT bool _Block_has_signature(void *aBlock) 180 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); 181 182// returns TRUE if return value of block is on the stack, FALSE otherwise 183BLOCK_EXPORT bool _Block_use_stret(void *aBlock) 184 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); 185 186// Returns a string describing the block's parameter and return types. 187// The encoding scheme is the same as Objective-C @encode. 188// Returns NULL for blocks compiled with some compilers. 189BLOCK_EXPORT const char * _Block_signature(void *aBlock) 190 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); 191 192// Returns a string describing the block's GC layout. 193// This uses the GC skip/scan encoding. 194// May return NULL. 195BLOCK_EXPORT const char * _Block_layout(void *aBlock) 196 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); 197 198// Returns a string describing the block's layout. 199// This uses the "extended layout" form described above. 200// May return NULL. 201BLOCK_EXPORT const char * _Block_extended_layout(void *aBlock) 202 __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_7_0); 203 204// Callable only from the ARR weak subsystem while in exclusion zone 205BLOCK_EXPORT bool _Block_tryRetain(const void *aBlock) 206 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); 207 208// Callable only from the ARR weak subsystem while in exclusion zone 209BLOCK_EXPORT bool _Block_isDeallocating(const void *aBlock) 210 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3); 211 212 213// the raw data space for runtime classes for blocks 214// class+meta used for stack, malloc, and collectable based blocks 215BLOCK_EXPORT void * _NSConcreteMallocBlock[32] 216 __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); 217BLOCK_EXPORT void * _NSConcreteAutoBlock[32] 218 __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); 219BLOCK_EXPORT void * _NSConcreteFinalizingBlock[32] 220 __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); 221BLOCK_EXPORT void * _NSConcreteWeakBlockVariable[32] 222 __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2); 223// declared in Block.h 224// BLOCK_EXPORT void * _NSConcreteGlobalBlock[32]; 225// BLOCK_EXPORT void * _NSConcreteStackBlock[32]; 226 227 228// the intercept routines that must be used under GC 229BLOCK_EXPORT void _Block_use_GC( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject), 230 void (*setHasRefcount)(const void *, const bool), 231 void (*gc_assign_strong)(void *, void **), 232 void (*gc_assign_weak)(const void *, void *), 233 void (*gc_memmove)(void *, void *, unsigned long)); 234 235// earlier version, now simply transitional 236BLOCK_EXPORT void _Block_use_GC5( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject), 237 void (*setHasRefcount)(const void *, const bool), 238 void (*gc_assign_strong)(void *, void **), 239 void (*gc_assign_weak)(const void *, void *)); 240 241BLOCK_EXPORT void _Block_use_RR( void (*retain)(const void *), 242 void (*release)(const void *)); 243 244struct Block_callbacks_RR { 245 size_t size; // size == sizeof(struct Block_callbacks_RR) 246 void (*retain)(const void *); 247 void (*release)(const void *); 248 void (*destructInstance)(const void *); 249}; 250typedef struct Block_callbacks_RR Block_callbacks_RR; 251 252BLOCK_EXPORT void _Block_use_RR2(const Block_callbacks_RR *callbacks); 253 254// make a collectable GC heap based Block. Not useful under non-GC. 255BLOCK_EXPORT void *_Block_copy_collectable(const void *aBlock); 256 257// thread-unsafe diagnostic 258BLOCK_EXPORT const char *_Block_dump(const void *block); 259 260 261// Obsolete 262 263// first layout 264struct Block_basic { 265 void *isa; 266 int Block_flags; // int32_t 267 int Block_size; // XXX should be packed into Block_flags 268 void (*Block_invoke)(void *); 269 void (*Block_copy)(void *dst, void *src); // iff BLOCK_HAS_COPY_DISPOSE 270 void (*Block_dispose)(void *); // iff BLOCK_HAS_COPY_DISPOSE 271 //long params[0]; // where const imports, __block storage references, etc. get laid down 272} __attribute__((deprecated)); 273 274 275#if __cplusplus 276} 277#endif 278 279 280#endif 281