Block_private.h revision 327952
1276789Sdim/* 2276789Sdim * Block_private.h 3276789Sdim * 4276789Sdim * Copyright 2008-2010 Apple, Inc. Permission is hereby granted, free of charge, 5276789Sdim * to any person obtaining a copy of this software and associated documentation 6276789Sdim * files (the "Software"), to deal in the Software without restriction, 7276789Sdim * including without limitation the rights to use, copy, modify, merge, publish, 8276789Sdim * distribute, sublicense, and/or sell copies of the Software, and to permit 9276789Sdim * persons to whom the Software is furnished to do so, subject to the following 10276789Sdim * conditions: 11276789Sdim * 12276789Sdim * The above copyright notice and this permission notice shall be included in 13276789Sdim * all copies or substantial portions of the Software. 14276789Sdim * 15276789Sdim * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16276789Sdim * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17276789Sdim * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18276789Sdim * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19276789Sdim * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20276789Sdim * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21276789Sdim * SOFTWARE. 22276789Sdim * 23276789Sdim */ 24276789Sdim 25276789Sdim#ifndef _BLOCK_PRIVATE_H_ 26276789Sdim#define _BLOCK_PRIVATE_H_ 27276789Sdim 28276789Sdim#if !defined(BLOCK_EXPORT) 29276789Sdim# if defined(__cplusplus) 30327952Sdim# define BLOCK_EXPORT extern "C" 31276789Sdim# else 32276789Sdim# define BLOCK_EXPORT extern 33276789Sdim# endif 34276789Sdim#endif 35276789Sdim 36276789Sdim#ifndef _MSC_VER 37276789Sdim#include <stdbool.h> 38276789Sdim#else 39276789Sdim/* MSVC doesn't have <stdbool.h>. Compensate. */ 40276789Sdimtypedef char bool; 41276789Sdim#define true (bool)1 42276789Sdim#define false (bool)0 43276789Sdim#endif 44276789Sdim 45276789Sdim#if defined(__cplusplus) 46276789Sdimextern "C" { 47276789Sdim#endif 48276789Sdim 49276789Sdim 50276789Sdimenum { 51276789Sdim BLOCK_REFCOUNT_MASK = (0xffff), 52276789Sdim BLOCK_NEEDS_FREE = (1 << 24), 53276789Sdim BLOCK_HAS_COPY_DISPOSE = (1 << 25), 54276789Sdim BLOCK_HAS_CTOR = (1 << 26), /* Helpers have C++ code. */ 55276789Sdim BLOCK_IS_GC = (1 << 27), 56276789Sdim BLOCK_IS_GLOBAL = (1 << 28), 57276789Sdim BLOCK_HAS_DESCRIPTOR = (1 << 29) 58276789Sdim}; 59276789Sdim 60276789Sdim 61276789Sdim/* Revised new layout. */ 62276789Sdimstruct Block_descriptor { 63276789Sdim unsigned long int reserved; 64276789Sdim unsigned long int size; 65276789Sdim void (*copy)(void *dst, void *src); 66276789Sdim void (*dispose)(void *); 67276789Sdim}; 68276789Sdim 69276789Sdim 70276789Sdimstruct Block_layout { 71276789Sdim void *isa; 72276789Sdim int flags; 73276789Sdim int reserved; 74276789Sdim void (*invoke)(void *, ...); 75276789Sdim struct Block_descriptor *descriptor; 76276789Sdim /* Imported variables. */ 77276789Sdim}; 78276789Sdim 79276789Sdim 80276789Sdimstruct Block_byref { 81276789Sdim void *isa; 82276789Sdim struct Block_byref *forwarding; 83276789Sdim int flags; /* refcount; */ 84276789Sdim int size; 85276789Sdim void (*byref_keep)(struct Block_byref *dst, struct Block_byref *src); 86276789Sdim void (*byref_destroy)(struct Block_byref *); 87276789Sdim /* long shared[0]; */ 88276789Sdim}; 89276789Sdim 90276789Sdim 91276789Sdimstruct Block_byref_header { 92276789Sdim void *isa; 93276789Sdim struct Block_byref *forwarding; 94276789Sdim int flags; 95276789Sdim int size; 96276789Sdim}; 97276789Sdim 98276789Sdim 99276789Sdim/* Runtime support functions used by compiler when generating copy/dispose helpers. */ 100276789Sdim 101276789Sdimenum { 102276789Sdim /* See function implementation for a more complete description of these fields and combinations */ 103276789Sdim BLOCK_FIELD_IS_OBJECT = 3, /* id, NSObject, __attribute__((NSObject)), block, ... */ 104276789Sdim BLOCK_FIELD_IS_BLOCK = 7, /* a block variable */ 105276789Sdim BLOCK_FIELD_IS_BYREF = 8, /* the on stack structure holding the __block variable */ 106276789Sdim BLOCK_FIELD_IS_WEAK = 16, /* declared __weak, only used in byref copy helpers */ 107276789Sdim BLOCK_BYREF_CALLER = 128 /* called from __block (byref) copy/dispose support routines. */ 108276789Sdim}; 109276789Sdim 110276789Sdim/* Runtime entry point called by compiler when assigning objects inside copy helper routines */ 111276789SdimBLOCK_EXPORT void _Block_object_assign(void *destAddr, const void *object, const int flags); 112276789Sdim /* BLOCK_FIELD_IS_BYREF is only used from within block copy helpers */ 113276789Sdim 114276789Sdim 115276789Sdim/* runtime entry point called by the compiler when disposing of objects inside dispose helper routine */ 116276789SdimBLOCK_EXPORT void _Block_object_dispose(const void *object, const int flags); 117276789Sdim 118276789Sdim 119276789Sdim 120276789Sdim/* Other support functions */ 121276789Sdim 122276789Sdim/* Runtime entry to get total size of a closure */ 123276789SdimBLOCK_EXPORT unsigned long int Block_size(void *block_basic); 124276789Sdim 125276789Sdim 126276789Sdim 127276789Sdim/* the raw data space for runtime classes for blocks */ 128276789Sdim/* class+meta used for stack, malloc, and collectable based blocks */ 129276789SdimBLOCK_EXPORT void * _NSConcreteStackBlock[32]; 130276789SdimBLOCK_EXPORT void * _NSConcreteMallocBlock[32]; 131276789SdimBLOCK_EXPORT void * _NSConcreteAutoBlock[32]; 132276789SdimBLOCK_EXPORT void * _NSConcreteFinalizingBlock[32]; 133276789SdimBLOCK_EXPORT void * _NSConcreteGlobalBlock[32]; 134276789SdimBLOCK_EXPORT void * _NSConcreteWeakBlockVariable[32]; 135276789Sdim 136276789Sdim 137276789Sdim/* the intercept routines that must be used under GC */ 138276789SdimBLOCK_EXPORT void _Block_use_GC( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject), 139276789Sdim void (*setHasRefcount)(const void *, const bool), 140276789Sdim void (*gc_assign_strong)(void *, void **), 141276789Sdim void (*gc_assign_weak)(const void *, void *), 142276789Sdim void (*gc_memmove)(void *, void *, unsigned long)); 143276789Sdim 144276789Sdim/* earlier version, now simply transitional */ 145276789SdimBLOCK_EXPORT void _Block_use_GC5( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject), 146276789Sdim void (*setHasRefcount)(const void *, const bool), 147276789Sdim void (*gc_assign_strong)(void *, void **), 148276789Sdim void (*gc_assign_weak)(const void *, void *)); 149276789Sdim 150276789SdimBLOCK_EXPORT void _Block_use_RR( void (*retain)(const void *), 151276789Sdim void (*release)(const void *)); 152276789Sdim 153276789Sdim/* make a collectable GC heap based Block. Not useful under non-GC. */ 154276789SdimBLOCK_EXPORT void *_Block_copy_collectable(const void *aBlock); 155276789Sdim 156276789Sdim/* thread-unsafe diagnostic */ 157276789SdimBLOCK_EXPORT const char *_Block_dump(const void *block); 158276789Sdim 159276789Sdim 160276789Sdim/* Obsolete */ 161276789Sdim 162276789Sdim/* first layout */ 163276789Sdimstruct Block_basic { 164276789Sdim void *isa; 165276789Sdim int Block_flags; /* int32_t */ 166276789Sdim int Block_size; /* XXX should be packed into Block_flags */ 167276789Sdim void (*Block_invoke)(void *); 168276789Sdim void (*Block_copy)(void *dst, void *src); /* iff BLOCK_HAS_COPY_DISPOSE */ 169276789Sdim void (*Block_dispose)(void *); /* iff BLOCK_HAS_COPY_DISPOSE */ 170276789Sdim /* long params[0]; // where const imports, __block storage references, etc. get laid down */ 171276789Sdim}; 172276789Sdim 173276789Sdim 174276789Sdim#if defined(__cplusplus) 175276789Sdim} 176276789Sdim#endif 177276789Sdim 178276789Sdim 179276789Sdim#endif /* _BLOCK_PRIVATE_H_ */ 180