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