18cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar/* 28cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar * Block_private.h 38cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar * 4b1c07156bab839c0502789f09654ec5da8d33c39Blaine Garst * Copyright 2008-2010 Apple, Inc. Permission is hereby granted, free of charge, 5b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar * to any person obtaining a copy of this software and associated documentation 6b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar * files (the "Software"), to deal in the Software without restriction, 7b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar * including without limitation the rights to use, copy, modify, merge, publish, 8b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar * distribute, sublicense, and/or sell copies of the Software, and to permit 9b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar * persons to whom the Software is furnished to do so, subject to the following 10b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar * conditions: 11b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar * 12b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar * The above copyright notice and this permission notice shall be included in 13b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar * all copies or substantial portions of the Software. 14b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar * 15b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar * SOFTWARE. 22b3a6901e66f55b35aa9e01bcb24134e6a65ea004Daniel Dunbar * 238cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar */ 248cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 258cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar#ifndef _BLOCK_PRIVATE_H_ 268cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar#define _BLOCK_PRIVATE_H_ 278cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 288cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar#if !defined(BLOCK_EXPORT) 298cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar# if defined(__cplusplus) 308cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar# define BLOCK_EXPORT extern "C" 318cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar# else 328cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar# define BLOCK_EXPORT extern 338cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar# endif 348cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar#endif 358cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 36ffd69e7b181a486cbba10deb386558cf3ff5e24aCharles Davis#ifndef _MSC_VER 378cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar#include <stdbool.h> 38ffd69e7b181a486cbba10deb386558cf3ff5e24aCharles Davis#else 39ffd69e7b181a486cbba10deb386558cf3ff5e24aCharles Davis/* MSVC doesn't have <stdbool.h>. Compensate. */ 40ffd69e7b181a486cbba10deb386558cf3ff5e24aCharles Davistypedef char bool; 41ffd69e7b181a486cbba10deb386558cf3ff5e24aCharles Davis#define true (bool)1 42ffd69e7b181a486cbba10deb386558cf3ff5e24aCharles Davis#define false (bool)0 43ffd69e7b181a486cbba10deb386558cf3ff5e24aCharles Davis#endif 448cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 45b4c3b6f8a2d3481bac6b0e9b4240fa0c99412d10Shantonu Sen#if defined(__cplusplus) 468cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbarextern "C" { 478cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar#endif 488cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 498cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 508cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbarenum { 518cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar BLOCK_REFCOUNT_MASK = (0xffff), 528cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar BLOCK_NEEDS_FREE = (1 << 24), 538cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar BLOCK_HAS_COPY_DISPOSE = (1 << 25), 5409870645031d5a05c7c3b9a66a53348a0d82ae52Edward O'Callaghan BLOCK_HAS_CTOR = (1 << 26), /* Helpers have C++ code. */ 558cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar BLOCK_IS_GC = (1 << 27), 568cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar BLOCK_IS_GLOBAL = (1 << 28), 5709870645031d5a05c7c3b9a66a53348a0d82ae52Edward O'Callaghan BLOCK_HAS_DESCRIPTOR = (1 << 29) 588cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar}; 598cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 6009870645031d5a05c7c3b9a66a53348a0d82ae52Edward O'Callaghan 6109870645031d5a05c7c3b9a66a53348a0d82ae52Edward O'Callaghan/* Revised new layout. */ 628cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbarstruct Block_descriptor { 638cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar unsigned long int reserved; 648cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar unsigned long int size; 658cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar void (*copy)(void *dst, void *src); 668cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar void (*dispose)(void *); 678cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar}; 688cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 6909870645031d5a05c7c3b9a66a53348a0d82ae52Edward O'Callaghan 708cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbarstruct Block_layout { 718cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar void *isa; 728cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar int flags; 738cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar int reserved; 748cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar void (*invoke)(void *, ...); 758cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar struct Block_descriptor *descriptor; 7609870645031d5a05c7c3b9a66a53348a0d82ae52Edward O'Callaghan /* Imported variables. */ 778cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar}; 788cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 798cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 808cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbarstruct Block_byref { 818cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar void *isa; 828cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar struct Block_byref *forwarding; 830898ee9197a0049e479a12f4c5b3c65e3deaf03bEdward O'Callaghan int flags; /* refcount; */ 848cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar int size; 858cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar void (*byref_keep)(struct Block_byref *dst, struct Block_byref *src); 868cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar void (*byref_destroy)(struct Block_byref *); 870898ee9197a0049e479a12f4c5b3c65e3deaf03bEdward O'Callaghan /* long shared[0]; */ 888cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar}; 898cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 9009870645031d5a05c7c3b9a66a53348a0d82ae52Edward O'Callaghan 918cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbarstruct Block_byref_header { 928cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar void *isa; 938cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar struct Block_byref *forwarding; 948cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar int flags; 958cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar int size; 968cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar}; 978cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 988cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 9909870645031d5a05c7c3b9a66a53348a0d82ae52Edward O'Callaghan/* Runtime support functions used by compiler when generating copy/dispose helpers. */ 1008cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 1018cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbarenum { 10209870645031d5a05c7c3b9a66a53348a0d82ae52Edward O'Callaghan /* See function implementation for a more complete description of these fields and combinations */ 1030898ee9197a0049e479a12f4c5b3c65e3deaf03bEdward O'Callaghan BLOCK_FIELD_IS_OBJECT = 3, /* id, NSObject, __attribute__((NSObject)), block, ... */ 1040898ee9197a0049e479a12f4c5b3c65e3deaf03bEdward O'Callaghan BLOCK_FIELD_IS_BLOCK = 7, /* a block variable */ 1050898ee9197a0049e479a12f4c5b3c65e3deaf03bEdward O'Callaghan BLOCK_FIELD_IS_BYREF = 8, /* the on stack structure holding the __block variable */ 1060898ee9197a0049e479a12f4c5b3c65e3deaf03bEdward O'Callaghan BLOCK_FIELD_IS_WEAK = 16, /* declared __weak, only used in byref copy helpers */ 10709870645031d5a05c7c3b9a66a53348a0d82ae52Edward O'Callaghan BLOCK_BYREF_CALLER = 128 /* called from __block (byref) copy/dispose support routines. */ 1088cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar}; 1098cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 1100898ee9197a0049e479a12f4c5b3c65e3deaf03bEdward O'Callaghan/* Runtime entry point called by compiler when assigning objects inside copy helper routines */ 1118cbe163cba77c772621f89ddb33793ac170b1faDaniel DunbarBLOCK_EXPORT void _Block_object_assign(void *destAddr, const void *object, const int flags); 1120898ee9197a0049e479a12f4c5b3c65e3deaf03bEdward O'Callaghan /* BLOCK_FIELD_IS_BYREF is only used from within block copy helpers */ 1138cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 1148cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 1150898ee9197a0049e479a12f4c5b3c65e3deaf03bEdward O'Callaghan/* runtime entry point called by the compiler when disposing of objects inside dispose helper routine */ 1168cbe163cba77c772621f89ddb33793ac170b1faDaniel DunbarBLOCK_EXPORT void _Block_object_dispose(const void *object, const int flags); 1178cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 1188cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 1198cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 1200898ee9197a0049e479a12f4c5b3c65e3deaf03bEdward O'Callaghan/* Other support functions */ 1218cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 12209870645031d5a05c7c3b9a66a53348a0d82ae52Edward O'Callaghan/* Runtime entry to get total size of a closure */ 1238cbe163cba77c772621f89ddb33793ac170b1faDaniel DunbarBLOCK_EXPORT unsigned long int Block_size(void *block_basic); 1248cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 1258cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 1268cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 1270898ee9197a0049e479a12f4c5b3c65e3deaf03bEdward O'Callaghan/* the raw data space for runtime classes for blocks */ 1280898ee9197a0049e479a12f4c5b3c65e3deaf03bEdward O'Callaghan/* class+meta used for stack, malloc, and collectable based blocks */ 1298cbe163cba77c772621f89ddb33793ac170b1faDaniel DunbarBLOCK_EXPORT void * _NSConcreteStackBlock[32]; 1308cbe163cba77c772621f89ddb33793ac170b1faDaniel DunbarBLOCK_EXPORT void * _NSConcreteMallocBlock[32]; 1318cbe163cba77c772621f89ddb33793ac170b1faDaniel DunbarBLOCK_EXPORT void * _NSConcreteAutoBlock[32]; 1328cbe163cba77c772621f89ddb33793ac170b1faDaniel DunbarBLOCK_EXPORT void * _NSConcreteFinalizingBlock[32]; 1338cbe163cba77c772621f89ddb33793ac170b1faDaniel DunbarBLOCK_EXPORT void * _NSConcreteGlobalBlock[32]; 1348cbe163cba77c772621f89ddb33793ac170b1faDaniel DunbarBLOCK_EXPORT void * _NSConcreteWeakBlockVariable[32]; 1358cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 1368cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 1370898ee9197a0049e479a12f4c5b3c65e3deaf03bEdward O'Callaghan/* the intercept routines that must be used under GC */ 1388cbe163cba77c772621f89ddb33793ac170b1faDaniel DunbarBLOCK_EXPORT void _Block_use_GC( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject), 1398cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar void (*setHasRefcount)(const void *, const bool), 1408cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar void (*gc_assign_strong)(void *, void **), 1418cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar void (*gc_assign_weak)(const void *, void *), 1428cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar void (*gc_memmove)(void *, void *, unsigned long)); 1438cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 1440898ee9197a0049e479a12f4c5b3c65e3deaf03bEdward O'Callaghan/* earlier version, now simply transitional */ 1458cbe163cba77c772621f89ddb33793ac170b1faDaniel DunbarBLOCK_EXPORT void _Block_use_GC5( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject), 1468cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar void (*setHasRefcount)(const void *, const bool), 1478cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar void (*gc_assign_strong)(void *, void **), 1488cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar void (*gc_assign_weak)(const void *, void *)); 1498cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 1508cbe163cba77c772621f89ddb33793ac170b1faDaniel DunbarBLOCK_EXPORT void _Block_use_RR( void (*retain)(const void *), 1518cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar void (*release)(const void *)); 1528cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 1530898ee9197a0049e479a12f4c5b3c65e3deaf03bEdward O'Callaghan/* make a collectable GC heap based Block. Not useful under non-GC. */ 1548cbe163cba77c772621f89ddb33793ac170b1faDaniel DunbarBLOCK_EXPORT void *_Block_copy_collectable(const void *aBlock); 1558cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 1560898ee9197a0049e479a12f4c5b3c65e3deaf03bEdward O'Callaghan/* thread-unsafe diagnostic */ 1578cbe163cba77c772621f89ddb33793ac170b1faDaniel DunbarBLOCK_EXPORT const char *_Block_dump(const void *block); 1588cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 1598cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 1600898ee9197a0049e479a12f4c5b3c65e3deaf03bEdward O'Callaghan/* Obsolete */ 1618cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 1620898ee9197a0049e479a12f4c5b3c65e3deaf03bEdward O'Callaghan/* first layout */ 1638cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbarstruct Block_basic { 1648cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar void *isa; 1650898ee9197a0049e479a12f4c5b3c65e3deaf03bEdward O'Callaghan int Block_flags; /* int32_t */ 16609870645031d5a05c7c3b9a66a53348a0d82ae52Edward O'Callaghan int Block_size; /* XXX should be packed into Block_flags */ 1678cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar void (*Block_invoke)(void *); 1680898ee9197a0049e479a12f4c5b3c65e3deaf03bEdward O'Callaghan void (*Block_copy)(void *dst, void *src); /* iff BLOCK_HAS_COPY_DISPOSE */ 1690898ee9197a0049e479a12f4c5b3c65e3deaf03bEdward O'Callaghan void (*Block_dispose)(void *); /* iff BLOCK_HAS_COPY_DISPOSE */ 1700898ee9197a0049e479a12f4c5b3c65e3deaf03bEdward O'Callaghan /* long params[0]; // where const imports, __block storage references, etc. get laid down */ 1718cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar}; 1728cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 1738cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 174b4c3b6f8a2d3481bac6b0e9b4240fa0c99412d10Shantonu Sen#if defined(__cplusplus) 1758cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar} 1768cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar#endif 1778cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 1788cbe163cba77c772621f89ddb33793ac170b1faDaniel Dunbar 179b4c3b6f8a2d3481bac6b0e9b4240fa0c99412d10Shantonu Sen#endif /* _BLOCK_PRIVATE_H_ */ 180