Block_private.h revision b3a6901e66f55b35aa9e01bcb24134e6a65ea004
1/* 2 * Block_private.h 3 * 4 * Copyright 2008-2009 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#include <AvailabilityMacros.h> 37#include <TargetConditionals.h> 38 39#include <stdbool.h> 40 41#if __cplusplus 42extern "C" { 43#endif 44 45 46 47enum { 48 BLOCK_REFCOUNT_MASK = (0xffff), 49 BLOCK_NEEDS_FREE = (1 << 24), 50 BLOCK_HAS_COPY_DISPOSE = (1 << 25), 51 BLOCK_HAS_CTOR = (1 << 26), // helpers have C++ code 52 BLOCK_IS_GC = (1 << 27), 53 BLOCK_IS_GLOBAL = (1 << 28), 54 BLOCK_HAS_DESCRIPTOR = (1 << 29), 55}; 56 57// revised new layout 58struct Block_descriptor { 59 unsigned long int reserved; 60 unsigned long int size; 61 void (*copy)(void *dst, void *src); 62 void (*dispose)(void *); 63}; 64 65struct Block_layout { 66 void *isa; 67 int flags; 68 int reserved; 69 void (*invoke)(void *, ...); 70 struct Block_descriptor *descriptor; 71 // imported variables 72}; 73 74 75 76struct Block_byref { 77 void *isa; 78 struct Block_byref *forwarding; 79 int flags;//refcount; 80 int size; 81 void (*byref_keep)(struct Block_byref *dst, struct Block_byref *src); 82 void (*byref_destroy)(struct Block_byref *); 83 // long shared[0]; 84}; 85 86struct Block_byref_header { 87 void *isa; 88 struct Block_byref *forwarding; 89 int flags; 90 int size; 91}; 92 93 94// Runtime support functions used by compiler when generating copy/dispose helpers 95 96enum { 97 // see function implementation for a more complete description of these fields and combinations 98 BLOCK_FIELD_IS_OBJECT = 3, // id, NSObject, __attribute__((NSObject)), block, ... 99 BLOCK_FIELD_IS_BLOCK = 7, // a block variable 100 BLOCK_FIELD_IS_BYREF = 8, // the on stack structure holding the __block variable 101 BLOCK_FIELD_IS_WEAK = 16, // declared __weak, only used in byref copy helpers 102 BLOCK_BYREF_CALLER = 128, // called from __block (byref) copy/dispose support routines. 103}; 104 105// Runtime entry point called by compiler when assigning objects inside copy helper routines 106BLOCK_EXPORT void _Block_object_assign(void *destAddr, const void *object, const int flags); 107 // BLOCK_FIELD_IS_BYREF is only used from within block copy helpers 108 109 110// runtime entry point called by the compiler when disposing of objects inside dispose helper routine 111BLOCK_EXPORT void _Block_object_dispose(const void *object, const int flags); 112 113 114 115// Other support functions 116 117// runtime entry to get total size of a closure 118BLOCK_EXPORT unsigned long int Block_size(void *block_basic); 119 120 121 122// the raw data space for runtime classes for blocks 123// class+meta used for stack, malloc, and collectable based blocks 124BLOCK_EXPORT void * _NSConcreteStackBlock[32]; 125BLOCK_EXPORT void * _NSConcreteMallocBlock[32]; 126BLOCK_EXPORT void * _NSConcreteAutoBlock[32]; 127BLOCK_EXPORT void * _NSConcreteFinalizingBlock[32]; 128BLOCK_EXPORT void * _NSConcreteGlobalBlock[32]; 129BLOCK_EXPORT void * _NSConcreteWeakBlockVariable[32]; 130 131 132// the intercept routines that must be used under GC 133BLOCK_EXPORT void _Block_use_GC( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject), 134 void (*setHasRefcount)(const void *, const bool), 135 void (*gc_assign_strong)(void *, void **), 136 void (*gc_assign_weak)(const void *, void *), 137 void (*gc_memmove)(void *, void *, unsigned long)); 138 139// earlier version, now simply transitional 140BLOCK_EXPORT void _Block_use_GC5( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject), 141 void (*setHasRefcount)(const void *, const bool), 142 void (*gc_assign_strong)(void *, void **), 143 void (*gc_assign_weak)(const void *, void *)); 144 145BLOCK_EXPORT void _Block_use_RR( void (*retain)(const void *), 146 void (*release)(const void *)); 147 148// make a collectable GC heap based Block. Not useful under non-GC. 149BLOCK_EXPORT void *_Block_copy_collectable(const void *aBlock); 150 151// thread-unsafe diagnostic 152BLOCK_EXPORT const char *_Block_dump(const void *block); 153 154 155// Obsolete 156 157// first layout 158struct Block_basic { 159 void *isa; 160 int Block_flags; // int32_t 161 int Block_size; // XXX should be packed into Block_flags 162 void (*Block_invoke)(void *); 163 void (*Block_copy)(void *dst, void *src); // iff BLOCK_HAS_COPY_DISPOSE 164 void (*Block_dispose)(void *); // iff BLOCK_HAS_COPY_DISPOSE 165 //long params[0]; // where const imports, __block storage references, etc. get laid down 166}; 167 168 169#if __cplusplus 170} 171#endif 172 173 174#endif 175