177ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao/* 277ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao * Block_private.h 377ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao * 477ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao * Copyright 2008-2009 Apple, Inc. Permission is hereby granted, free of charge, 577ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao * to any person obtaining a copy of this software and associated documentation 677ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao * files (the "Software"), to deal in the Software without restriction, 777ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao * including without limitation the rights to use, copy, modify, merge, publish, 877ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao * distribute, sublicense, and/or sell copies of the Software, and to permit 977ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao * persons to whom the Software is furnished to do so, subject to the following 1077ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao * conditions: 1177ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao * 1277ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao * The above copyright notice and this permission notice shall be included in 1377ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao * all copies or substantial portions of the Software. 1477ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao * 1577ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1677ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1777ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1877ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1977ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 2077ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 2177ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao * SOFTWARE. 2277ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao * 2377ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao */ 2477ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 2577ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao#ifndef _BLOCK_PRIVATE_H_ 2677ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao#define _BLOCK_PRIVATE_H_ 2777ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 2877ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao#if !defined(BLOCK_EXPORT) 2977ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao# if defined(__cplusplus) 3077ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao# define BLOCK_EXPORT extern "C" 3177ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao# else 3277ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao# define BLOCK_EXPORT extern 3377ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao# endif 3477ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao#endif 3577ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 3677ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao#include <stdbool.h> 3777ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 3877ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao#if defined(__cplusplus) 3977ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liaoextern "C" { 4077ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao#endif 4177ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 4277ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 4377ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liaoenum { 4477ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao BLOCK_REFCOUNT_MASK = (0xffff), 4577ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao BLOCK_NEEDS_FREE = (1 << 24), 4677ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao BLOCK_HAS_COPY_DISPOSE = (1 << 25), 4777ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao BLOCK_HAS_CTOR = (1 << 26), /* Helpers have C++ code. */ 4877ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao BLOCK_IS_GC = (1 << 27), 4977ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao BLOCK_IS_GLOBAL = (1 << 28), 5077ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao BLOCK_HAS_DESCRIPTOR = (1 << 29) 5177ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao}; 5277ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 5377ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 5477ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao/* Revised new layout. */ 5577ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liaostruct Block_descriptor { 5677ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao unsigned long int reserved; 5777ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao unsigned long int size; 5877ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao void (*copy)(void *dst, void *src); 5977ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao void (*dispose)(void *); 6077ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao}; 6177ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 6277ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 6377ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liaostruct Block_layout { 6477ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao void *isa; 6577ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao int flags; 6677ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao int reserved; 6777ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao void (*invoke)(void *, ...); 6877ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao struct Block_descriptor *descriptor; 6977ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao /* Imported variables. */ 7077ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao}; 7177ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 7277ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 7377ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liaostruct Block_byref { 7477ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao void *isa; 7577ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao struct Block_byref *forwarding; 7677ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao int flags; /* refcount; */ 7777ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao int size; 7877ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao void (*byref_keep)(struct Block_byref *dst, struct Block_byref *src); 7977ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao void (*byref_destroy)(struct Block_byref *); 8077ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao /* long shared[0]; */ 8177ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao}; 8277ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 8377ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 8477ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liaostruct Block_byref_header { 8577ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao void *isa; 8677ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao struct Block_byref *forwarding; 8777ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao int flags; 8877ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao int size; 8977ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao}; 9077ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 9177ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 9277ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao/* Runtime support functions used by compiler when generating copy/dispose helpers. */ 9377ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 9477ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liaoenum { 9577ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao /* See function implementation for a more complete description of these fields and combinations */ 9677ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao BLOCK_FIELD_IS_OBJECT = 3, /* id, NSObject, __attribute__((NSObject)), block, ... */ 9777ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao BLOCK_FIELD_IS_BLOCK = 7, /* a block variable */ 9877ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao BLOCK_FIELD_IS_BYREF = 8, /* the on stack structure holding the __block variable */ 9977ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao BLOCK_FIELD_IS_WEAK = 16, /* declared __weak, only used in byref copy helpers */ 10077ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao BLOCK_BYREF_CALLER = 128 /* called from __block (byref) copy/dispose support routines. */ 10177ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao}; 10277ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 10377ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao/* Runtime entry point called by compiler when assigning objects inside copy helper routines */ 10477ed6142daed1e068fbda64405d0de9845e40e1Shih-wei LiaoBLOCK_EXPORT void _Block_object_assign(void *destAddr, const void *object, const int flags); 10577ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao /* BLOCK_FIELD_IS_BYREF is only used from within block copy helpers */ 10677ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 10777ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 10877ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao/* runtime entry point called by the compiler when disposing of objects inside dispose helper routine */ 10977ed6142daed1e068fbda64405d0de9845e40e1Shih-wei LiaoBLOCK_EXPORT void _Block_object_dispose(const void *object, const int flags); 11077ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 11177ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 11277ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 11377ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao/* Other support functions */ 11477ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 11577ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao/* Runtime entry to get total size of a closure */ 11677ed6142daed1e068fbda64405d0de9845e40e1Shih-wei LiaoBLOCK_EXPORT unsigned long int Block_size(void *block_basic); 11777ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 11877ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 11977ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 12077ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao/* the raw data space for runtime classes for blocks */ 12177ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao/* class+meta used for stack, malloc, and collectable based blocks */ 12277ed6142daed1e068fbda64405d0de9845e40e1Shih-wei LiaoBLOCK_EXPORT void * _NSConcreteStackBlock[32]; 12377ed6142daed1e068fbda64405d0de9845e40e1Shih-wei LiaoBLOCK_EXPORT void * _NSConcreteMallocBlock[32]; 12477ed6142daed1e068fbda64405d0de9845e40e1Shih-wei LiaoBLOCK_EXPORT void * _NSConcreteAutoBlock[32]; 12577ed6142daed1e068fbda64405d0de9845e40e1Shih-wei LiaoBLOCK_EXPORT void * _NSConcreteFinalizingBlock[32]; 12677ed6142daed1e068fbda64405d0de9845e40e1Shih-wei LiaoBLOCK_EXPORT void * _NSConcreteGlobalBlock[32]; 12777ed6142daed1e068fbda64405d0de9845e40e1Shih-wei LiaoBLOCK_EXPORT void * _NSConcreteWeakBlockVariable[32]; 12877ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 12977ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 13077ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao/* the intercept routines that must be used under GC */ 13177ed6142daed1e068fbda64405d0de9845e40e1Shih-wei LiaoBLOCK_EXPORT void _Block_use_GC( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject), 13277ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao void (*setHasRefcount)(const void *, const bool), 13377ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao void (*gc_assign_strong)(void *, void **), 13477ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao void (*gc_assign_weak)(const void *, void *), 13577ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao void (*gc_memmove)(void *, void *, unsigned long)); 13677ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 13777ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao/* earlier version, now simply transitional */ 13877ed6142daed1e068fbda64405d0de9845e40e1Shih-wei LiaoBLOCK_EXPORT void _Block_use_GC5( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject), 13977ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao void (*setHasRefcount)(const void *, const bool), 14077ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao void (*gc_assign_strong)(void *, void **), 14177ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao void (*gc_assign_weak)(const void *, void *)); 14277ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 14377ed6142daed1e068fbda64405d0de9845e40e1Shih-wei LiaoBLOCK_EXPORT void _Block_use_RR( void (*retain)(const void *), 14477ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao void (*release)(const void *)); 14577ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 14677ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao/* make a collectable GC heap based Block. Not useful under non-GC. */ 14777ed6142daed1e068fbda64405d0de9845e40e1Shih-wei LiaoBLOCK_EXPORT void *_Block_copy_collectable(const void *aBlock); 14877ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 14977ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao/* thread-unsafe diagnostic */ 15077ed6142daed1e068fbda64405d0de9845e40e1Shih-wei LiaoBLOCK_EXPORT const char *_Block_dump(const void *block); 15177ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 15277ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 15377ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao/* Obsolete */ 15477ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 15577ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao/* first layout */ 15677ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liaostruct Block_basic { 15777ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao void *isa; 15877ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao int Block_flags; /* int32_t */ 15977ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao int Block_size; /* XXX should be packed into Block_flags */ 16077ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao void (*Block_invoke)(void *); 16177ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao void (*Block_copy)(void *dst, void *src); /* iff BLOCK_HAS_COPY_DISPOSE */ 16277ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao void (*Block_dispose)(void *); /* iff BLOCK_HAS_COPY_DISPOSE */ 16377ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao /* long params[0]; // where const imports, __block storage references, etc. get laid down */ 16477ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao}; 16577ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 16677ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 16777ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao#if defined(__cplusplus) 16877ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao} 16977ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao#endif 17077ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 17177ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao 17277ed6142daed1e068fbda64405d0de9845e40e1Shih-wei Liao#endif /* _BLOCK_PRIVATE_H_ */ 173