1 /* 2 * Block_private.h 3 * 4 * Copyright 2008-2010 Apple, Inc. Permission is hereby granted, free of charge, 5 * to any person obtaining a copy of this software and associated documentation 6 * files (the "Software"), to deal in the Software without restriction, 7 * including without limitation the rights to use, copy, modify, merge, publish, 8 * distribute, sublicense, and/or sell copies of the Software, and to permit 9 * persons to whom the Software is furnished to do so, subject to the following 10 * conditions: 11 * 12 * The above copyright notice and this permission notice shall be included in 13 * all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 * SOFTWARE. 22 * 23 */ 24 25 #ifndef _BLOCK_PRIVATE_H_ 26 #define _BLOCK_PRIVATE_H_ 27 28 #if !defined(BLOCK_EXPORT) 29 # if defined(__cplusplus) 30 # define BLOCK_EXPORT extern "C" 31 # else 32 # define BLOCK_EXPORT extern 33 # endif 34 #endif 35 36 #ifndef _MSC_VER 37 #include <stdbool.h> 38 #else 39 /* MSVC doesn't have <stdbool.h>. Compensate. */ 40 typedef char bool; 41 #define true (bool)1 42 #define false (bool)0 43 #endif 44 45 #if defined(__cplusplus) 46 extern "C" { 47 #endif 48 49 50 enum { 51 BLOCK_REFCOUNT_MASK = (0xffff), 52 BLOCK_NEEDS_FREE = (1 << 24), 53 BLOCK_HAS_COPY_DISPOSE = (1 << 25), 54 BLOCK_HAS_CTOR = (1 << 26), /* Helpers have C++ code. */ 55 BLOCK_IS_GC = (1 << 27), 56 BLOCK_IS_GLOBAL = (1 << 28), 57 BLOCK_HAS_DESCRIPTOR = (1 << 29) 58 }; 59 60 61 /* Revised new layout. */ 62 struct Block_descriptor { 63 unsigned long int reserved; 64 unsigned long int size; 65 void (*copy)(void *dst, void *src); 66 void (*dispose)(void *); 67 }; 68 69 70 struct Block_layout { 71 void *isa; 72 int flags; 73 int reserved; 74 void (*invoke)(void *, ...); 75 struct Block_descriptor *descriptor; 76 /* Imported variables. */ 77 }; 78 79 80 struct Block_byref { 81 void *isa; 82 struct Block_byref *forwarding; 83 int flags; /* refcount; */ 84 int size; 85 void (*byref_keep)(struct Block_byref *dst, struct Block_byref *src); 86 void (*byref_destroy)(struct Block_byref *); 87 /* long shared[0]; */ 88 }; 89 90 91 struct Block_byref_header { 92 void *isa; 93 struct Block_byref *forwarding; 94 int flags; 95 int size; 96 }; 97 98 99 /* Runtime support functions used by compiler when generating copy/dispose helpers. */ 100 101 enum { 102 /* See function implementation for a more complete description of these fields and combinations */ 103 BLOCK_FIELD_IS_OBJECT = 3, /* id, NSObject, __attribute__((NSObject)), block, ... */ 104 BLOCK_FIELD_IS_BLOCK = 7, /* a block variable */ 105 BLOCK_FIELD_IS_BYREF = 8, /* the on stack structure holding the __block variable */ 106 BLOCK_FIELD_IS_WEAK = 16, /* declared __weak, only used in byref copy helpers */ 107 BLOCK_BYREF_CALLER = 128 /* called from __block (byref) copy/dispose support routines. */ 108 }; 109 110 /* Runtime entry point called by compiler when assigning objects inside copy helper routines */ 111 BLOCK_EXPORT void _Block_object_assign(void *destAddr, const void *object, const int flags); 112 /* BLOCK_FIELD_IS_BYREF is only used from within block copy helpers */ 113 114 115 /* runtime entry point called by the compiler when disposing of objects inside dispose helper routine */ 116 BLOCK_EXPORT void _Block_object_dispose(const void *object, const int flags); 117 118 119 120 /* Other support functions */ 121 122 /* Runtime entry to get total size of a closure */ 123 BLOCK_EXPORT unsigned long int Block_size(void *block_basic); 124 125 126 127 /* the raw data space for runtime classes for blocks */ 128 /* class+meta used for stack, malloc, and collectable based blocks */ 129 BLOCK_EXPORT void * _NSConcreteStackBlock[32]; 130 BLOCK_EXPORT void * _NSConcreteMallocBlock[32]; 131 BLOCK_EXPORT void * _NSConcreteAutoBlock[32]; 132 BLOCK_EXPORT void * _NSConcreteFinalizingBlock[32]; 133 BLOCK_EXPORT void * _NSConcreteGlobalBlock[32]; 134 BLOCK_EXPORT void * _NSConcreteWeakBlockVariable[32]; 135 136 137 /* the intercept routines that must be used under GC */ 138 BLOCK_EXPORT void _Block_use_GC( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject), 139 void (*setHasRefcount)(const void *, const bool), 140 void (*gc_assign_strong)(void *, void **), 141 void (*gc_assign_weak)(const void *, void *), 142 void (*gc_memmove)(void *, void *, unsigned long)); 143 144 /* earlier version, now simply transitional */ 145 BLOCK_EXPORT void _Block_use_GC5( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject), 146 void (*setHasRefcount)(const void *, const bool), 147 void (*gc_assign_strong)(void *, void **), 148 void (*gc_assign_weak)(const void *, void *)); 149 150 BLOCK_EXPORT void _Block_use_RR( void (*retain)(const void *), 151 void (*release)(const void *)); 152 153 /* make a collectable GC heap based Block. Not useful under non-GC. */ 154 BLOCK_EXPORT void *_Block_copy_collectable(const void *aBlock); 155 156 /* thread-unsafe diagnostic */ 157 BLOCK_EXPORT const char *_Block_dump(const void *block); 158 159 160 /* Obsolete */ 161 162 /* first layout */ 163 struct Block_basic { 164 void *isa; 165 int Block_flags; /* int32_t */ 166 int Block_size; /* XXX should be packed into Block_flags */ 167 void (*Block_invoke)(void *); 168 void (*Block_copy)(void *dst, void *src); /* iff BLOCK_HAS_COPY_DISPOSE */ 169 void (*Block_dispose)(void *); /* iff BLOCK_HAS_COPY_DISPOSE */ 170 /* long params[0]; // where const imports, __block storage references, etc. get laid down */ 171 }; 172 173 174 #if defined(__cplusplus) 175 } 176 #endif 177 178 179 #endif /* _BLOCK_PRIVATE_H_ */ 180