1214152Sed/* 2214152Sed * Block_private.h 3214152Sed * 4214152Sed * Copyright 2008-2010 Apple, Inc. Permission is hereby granted, free of charge, 5214152Sed * to any person obtaining a copy of this software and associated documentation 6214152Sed * files (the "Software"), to deal in the Software without restriction, 7214152Sed * including without limitation the rights to use, copy, modify, merge, publish, 8214152Sed * distribute, sublicense, and/or sell copies of the Software, and to permit 9214152Sed * persons to whom the Software is furnished to do so, subject to the following 10214152Sed * conditions: 11214152Sed * 12214152Sed * The above copyright notice and this permission notice shall be included in 13214152Sed * all copies or substantial portions of the Software. 14214152Sed * 15214152Sed * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16214152Sed * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17214152Sed * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18214152Sed * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19214152Sed * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20214152Sed * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21214152Sed * SOFTWARE. 22214152Sed * 23214152Sed */ 24214152Sed 25214152Sed#ifndef _BLOCK_PRIVATE_H_ 26214152Sed#define _BLOCK_PRIVATE_H_ 27214152Sed 28214152Sed#if !defined(BLOCK_EXPORT) 29214152Sed# if defined(__cplusplus) 30214152Sed# define BLOCK_EXPORT extern "C" 31214152Sed# else 32214152Sed# define BLOCK_EXPORT extern 33214152Sed# endif 34214152Sed#endif 35214152Sed 36214152Sed#ifndef _MSC_VER 37214152Sed#include <stdbool.h> 38214152Sed#else 39214152Sed/* MSVC doesn't have <stdbool.h>. Compensate. */ 40214152Sedtypedef char bool; 41214152Sed#define true (bool)1 42214152Sed#define false (bool)0 43214152Sed#endif 44214152Sed 45214152Sed#if defined(__cplusplus) 46214152Sedextern "C" { 47214152Sed#endif 48214152Sed 49214152Sed 50214152Sedenum { 51214152Sed BLOCK_REFCOUNT_MASK = (0xffff), 52214152Sed BLOCK_NEEDS_FREE = (1 << 24), 53214152Sed BLOCK_HAS_COPY_DISPOSE = (1 << 25), 54214152Sed BLOCK_HAS_CTOR = (1 << 26), /* Helpers have C++ code. */ 55214152Sed BLOCK_IS_GC = (1 << 27), 56214152Sed BLOCK_IS_GLOBAL = (1 << 28), 57214152Sed BLOCK_HAS_DESCRIPTOR = (1 << 29) 58214152Sed}; 59214152Sed 60214152Sed 61214152Sed/* Revised new layout. */ 62214152Sedstruct Block_descriptor { 63214152Sed unsigned long int reserved; 64214152Sed unsigned long int size; 65214152Sed void (*copy)(void *dst, void *src); 66214152Sed void (*dispose)(void *); 67214152Sed}; 68214152Sed 69214152Sed 70214152Sedstruct Block_layout { 71214152Sed void *isa; 72214152Sed int flags; 73214152Sed int reserved; 74214152Sed void (*invoke)(void *, ...); 75214152Sed struct Block_descriptor *descriptor; 76214152Sed /* Imported variables. */ 77214152Sed}; 78214152Sed 79214152Sed 80214152Sedstruct Block_byref { 81214152Sed void *isa; 82214152Sed struct Block_byref *forwarding; 83214152Sed int flags; /* refcount; */ 84214152Sed int size; 85214152Sed void (*byref_keep)(struct Block_byref *dst, struct Block_byref *src); 86214152Sed void (*byref_destroy)(struct Block_byref *); 87214152Sed /* long shared[0]; */ 88214152Sed}; 89214152Sed 90214152Sed 91214152Sedstruct Block_byref_header { 92214152Sed void *isa; 93214152Sed struct Block_byref *forwarding; 94214152Sed int flags; 95214152Sed int size; 96214152Sed}; 97214152Sed 98214152Sed 99214152Sed/* Runtime support functions used by compiler when generating copy/dispose helpers. */ 100214152Sed 101214152Sedenum { 102214152Sed /* See function implementation for a more complete description of these fields and combinations */ 103214152Sed BLOCK_FIELD_IS_OBJECT = 3, /* id, NSObject, __attribute__((NSObject)), block, ... */ 104214152Sed BLOCK_FIELD_IS_BLOCK = 7, /* a block variable */ 105214152Sed BLOCK_FIELD_IS_BYREF = 8, /* the on stack structure holding the __block variable */ 106214152Sed BLOCK_FIELD_IS_WEAK = 16, /* declared __weak, only used in byref copy helpers */ 107214152Sed BLOCK_BYREF_CALLER = 128 /* called from __block (byref) copy/dispose support routines. */ 108214152Sed}; 109214152Sed 110214152Sed/* Runtime entry point called by compiler when assigning objects inside copy helper routines */ 111214152SedBLOCK_EXPORT void _Block_object_assign(void *destAddr, const void *object, const int flags); 112214152Sed /* BLOCK_FIELD_IS_BYREF is only used from within block copy helpers */ 113214152Sed 114214152Sed 115214152Sed/* runtime entry point called by the compiler when disposing of objects inside dispose helper routine */ 116214152SedBLOCK_EXPORT void _Block_object_dispose(const void *object, const int flags); 117214152Sed 118214152Sed 119214152Sed 120214152Sed/* Other support functions */ 121214152Sed 122214152Sed/* Runtime entry to get total size of a closure */ 123214152SedBLOCK_EXPORT unsigned long int Block_size(void *block_basic); 124214152Sed 125214152Sed 126214152Sed 127214152Sed/* the raw data space for runtime classes for blocks */ 128214152Sed/* class+meta used for stack, malloc, and collectable based blocks */ 129214152SedBLOCK_EXPORT void * _NSConcreteStackBlock[32]; 130214152SedBLOCK_EXPORT void * _NSConcreteMallocBlock[32]; 131214152SedBLOCK_EXPORT void * _NSConcreteAutoBlock[32]; 132214152SedBLOCK_EXPORT void * _NSConcreteFinalizingBlock[32]; 133214152SedBLOCK_EXPORT void * _NSConcreteGlobalBlock[32]; 134214152SedBLOCK_EXPORT void * _NSConcreteWeakBlockVariable[32]; 135214152Sed 136214152Sed 137214152Sed/* the intercept routines that must be used under GC */ 138214152SedBLOCK_EXPORT void _Block_use_GC( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject), 139214152Sed void (*setHasRefcount)(const void *, const bool), 140214152Sed void (*gc_assign_strong)(void *, void **), 141214152Sed void (*gc_assign_weak)(const void *, void *), 142214152Sed void (*gc_memmove)(void *, void *, unsigned long)); 143214152Sed 144214152Sed/* earlier version, now simply transitional */ 145214152SedBLOCK_EXPORT void _Block_use_GC5( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject), 146214152Sed void (*setHasRefcount)(const void *, const bool), 147214152Sed void (*gc_assign_strong)(void *, void **), 148214152Sed void (*gc_assign_weak)(const void *, void *)); 149214152Sed 150214152SedBLOCK_EXPORT void _Block_use_RR( void (*retain)(const void *), 151214152Sed void (*release)(const void *)); 152214152Sed 153214152Sed/* make a collectable GC heap based Block. Not useful under non-GC. */ 154214152SedBLOCK_EXPORT void *_Block_copy_collectable(const void *aBlock); 155214152Sed 156214152Sed/* thread-unsafe diagnostic */ 157214152SedBLOCK_EXPORT const char *_Block_dump(const void *block); 158214152Sed 159214152Sed 160214152Sed/* Obsolete */ 161214152Sed 162214152Sed/* first layout */ 163214152Sedstruct Block_basic { 164214152Sed void *isa; 165214152Sed int Block_flags; /* int32_t */ 166214152Sed int Block_size; /* XXX should be packed into Block_flags */ 167214152Sed void (*Block_invoke)(void *); 168214152Sed void (*Block_copy)(void *dst, void *src); /* iff BLOCK_HAS_COPY_DISPOSE */ 169214152Sed void (*Block_dispose)(void *); /* iff BLOCK_HAS_COPY_DISPOSE */ 170214152Sed /* long params[0]; // where const imports, __block storage references, etc. get laid down */ 171214152Sed}; 172214152Sed 173214152Sed 174214152Sed#if defined(__cplusplus) 175214152Sed} 176214152Sed#endif 177214152Sed 178214152Sed 179214152Sed#endif /* _BLOCK_PRIVATE_H_ */ 180