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