Block_private.h revision b3a6901e66f55b35aa9e01bcb24134e6a65ea004
1/*
2 * Block_private.h
3 *
4 * Copyright 2008-2009 Apple, Inc. Permission is hereby granted, free of charge,
5 * to any person obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to permit
9 * persons to whom the Software is furnished to do so, subject to the following
10 * conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 *
23 */
24
25#ifndef _BLOCK_PRIVATE_H_
26#define _BLOCK_PRIVATE_H_
27
28#if !defined(BLOCK_EXPORT)
29#   if defined(__cplusplus)
30#       define BLOCK_EXPORT extern "C"
31#   else
32#       define BLOCK_EXPORT extern
33#   endif
34#endif
35
36#include <AvailabilityMacros.h>
37#include <TargetConditionals.h>
38
39#include <stdbool.h>
40
41#if __cplusplus
42extern "C" {
43#endif
44
45
46
47enum {
48    BLOCK_REFCOUNT_MASK =     (0xffff),
49    BLOCK_NEEDS_FREE =        (1 << 24),
50    BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
51    BLOCK_HAS_CTOR =          (1 << 26), // helpers have C++ code
52    BLOCK_IS_GC =             (1 << 27),
53    BLOCK_IS_GLOBAL =         (1 << 28),
54    BLOCK_HAS_DESCRIPTOR =    (1 << 29),
55};
56
57// revised new layout
58struct Block_descriptor {
59    unsigned long int reserved;
60    unsigned long int size;
61    void (*copy)(void *dst, void *src);
62    void (*dispose)(void *);
63};
64
65struct Block_layout {
66    void *isa;
67    int flags;
68    int reserved;
69    void (*invoke)(void *, ...);
70    struct Block_descriptor *descriptor;
71    // imported variables
72};
73
74
75
76struct Block_byref {
77    void *isa;
78    struct Block_byref *forwarding;
79    int flags;//refcount;
80    int size;
81    void (*byref_keep)(struct Block_byref *dst, struct Block_byref *src);
82    void (*byref_destroy)(struct Block_byref *);
83    // long shared[0];
84};
85
86struct Block_byref_header {
87    void *isa;
88    struct Block_byref *forwarding;
89    int flags;
90    int size;
91};
92
93
94// Runtime support functions used by compiler when generating copy/dispose helpers
95
96enum {
97    // see function implementation for a more complete description of these fields and combinations
98    BLOCK_FIELD_IS_OBJECT   =  3,  // id, NSObject, __attribute__((NSObject)), block, ...
99    BLOCK_FIELD_IS_BLOCK    =  7,  // a block variable
100    BLOCK_FIELD_IS_BYREF    =  8,  // the on stack structure holding the __block variable
101    BLOCK_FIELD_IS_WEAK     = 16,  // declared __weak, only used in byref copy helpers
102    BLOCK_BYREF_CALLER      = 128, // called from __block (byref) copy/dispose support routines.
103};
104
105// Runtime entry point called by compiler when assigning objects inside copy helper routines
106BLOCK_EXPORT void _Block_object_assign(void *destAddr, const void *object, const int flags);
107    // BLOCK_FIELD_IS_BYREF is only used from within block copy helpers
108
109
110// runtime entry point called by the compiler when disposing of objects inside dispose helper routine
111BLOCK_EXPORT void _Block_object_dispose(const void *object, const int flags);
112
113
114
115// Other support functions
116
117// runtime entry to get total size of a closure
118BLOCK_EXPORT unsigned long int Block_size(void *block_basic);
119
120
121
122// the raw data space for runtime classes for blocks
123// class+meta used for stack, malloc, and collectable based blocks
124BLOCK_EXPORT void * _NSConcreteStackBlock[32];
125BLOCK_EXPORT void * _NSConcreteMallocBlock[32];
126BLOCK_EXPORT void * _NSConcreteAutoBlock[32];
127BLOCK_EXPORT void * _NSConcreteFinalizingBlock[32];
128BLOCK_EXPORT void * _NSConcreteGlobalBlock[32];
129BLOCK_EXPORT void * _NSConcreteWeakBlockVariable[32];
130
131
132// the intercept routines that must be used under GC
133BLOCK_EXPORT void _Block_use_GC( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject),
134                                  void (*setHasRefcount)(const void *, const bool),
135                                  void (*gc_assign_strong)(void *, void **),
136                                  void (*gc_assign_weak)(const void *, void *),
137                                  void (*gc_memmove)(void *, void *, unsigned long));
138
139// earlier version, now simply transitional
140BLOCK_EXPORT void _Block_use_GC5( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject),
141                                  void (*setHasRefcount)(const void *, const bool),
142                                  void (*gc_assign_strong)(void *, void **),
143                                  void (*gc_assign_weak)(const void *, void *));
144
145BLOCK_EXPORT void _Block_use_RR( void (*retain)(const void *),
146                                 void (*release)(const void *));
147
148// make a collectable GC heap based Block.  Not useful under non-GC.
149BLOCK_EXPORT void *_Block_copy_collectable(const void *aBlock);
150
151// thread-unsafe diagnostic
152BLOCK_EXPORT const char *_Block_dump(const void *block);
153
154
155// Obsolete
156
157// first layout
158struct Block_basic {
159    void *isa;
160    int Block_flags;  // int32_t
161    int Block_size; // XXX should be packed into Block_flags
162    void (*Block_invoke)(void *);
163    void (*Block_copy)(void *dst, void *src);  // iff BLOCK_HAS_COPY_DISPOSE
164    void (*Block_dispose)(void *);             // iff BLOCK_HAS_COPY_DISPOSE
165    //long params[0];  // where const imports, __block storage references, etc. get laid down
166};
167
168
169#if __cplusplus
170}
171#endif
172
173
174#endif
175