Block_private.h revision ffd69e7b181a486cbba10deb386558cf3ff5e24a
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