]> git.saurik.com Git - apple/libdispatch.git/blob - src/BlocksRuntime/Block_private.h
libdispatch-913.1.6.tar.gz
[apple/libdispatch.git] / src / BlocksRuntime / Block_private.h
1 // This source file is part of the Swift.org open source project
2 //
3 // Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
4 // Licensed under Apache License v2.0 with Runtime Library Exception
5 //
6 // See http://swift.org/LICENSE.txt for license information
7 // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
8 //
9
10
11 #ifndef _BLOCK_PRIVATE_H_
12 #define _BLOCK_PRIVATE_H_
13
14 #include <stdbool.h>
15 #include <stdint.h>
16 #include <stdio.h>
17
18 #include "Block.h"
19
20 #if __cplusplus
21 extern "C" {
22 #endif
23
24
25 // Values for Block_layout->flags to describe block objects
26 enum {
27 BLOCK_DEALLOCATING = (0x0001), // runtime
28 BLOCK_REFCOUNT_MASK = (0xfffe), // runtime
29 BLOCK_NEEDS_FREE = (1 << 24), // runtime
30 BLOCK_HAS_COPY_DISPOSE = (1 << 25), // compiler
31 BLOCK_HAS_CTOR = (1 << 26), // compiler: helpers have C++ code
32 BLOCK_IS_GC = (1 << 27), // runtime
33 BLOCK_IS_GLOBAL = (1 << 28), // compiler
34 BLOCK_USE_STRET = (1 << 29), // compiler: undefined if !BLOCK_HAS_SIGNATURE
35 BLOCK_HAS_SIGNATURE = (1 << 30), // compiler
36 BLOCK_HAS_EXTENDED_LAYOUT=(1 << 31) // compiler
37 };
38
39 #define BLOCK_DESCRIPTOR_1 1
40 struct Block_descriptor_1 {
41 uintptr_t reserved;
42 uintptr_t size;
43 };
44
45 #define BLOCK_DESCRIPTOR_2 1
46 struct Block_descriptor_2 {
47 // requires BLOCK_HAS_COPY_DISPOSE
48 void (*copy)(void *dst, const void *src);
49 void (*dispose)(const void *);
50 };
51
52 #define BLOCK_DESCRIPTOR_3 1
53 struct Block_descriptor_3 {
54 // requires BLOCK_HAS_SIGNATURE
55 const char *signature;
56 const char *layout; // contents depend on BLOCK_HAS_EXTENDED_LAYOUT
57 };
58
59 struct Block_layout {
60 void *isa;
61 volatile int32_t flags; // contains ref count
62 int32_t reserved;
63 void (*invoke)(void *, ...);
64 struct Block_descriptor_1 *descriptor;
65 // imported variables
66 };
67
68
69 // Values for Block_byref->flags to describe __block variables
70 enum {
71 // Byref refcount must use the same bits as Block_layout's refcount.
72 // BLOCK_DEALLOCATING = (0x0001), // runtime
73 // BLOCK_REFCOUNT_MASK = (0xfffe), // runtime
74
75 BLOCK_BYREF_LAYOUT_MASK = (0xf << 28), // compiler
76 BLOCK_BYREF_LAYOUT_EXTENDED = ( 1 << 28), // compiler
77 BLOCK_BYREF_LAYOUT_NON_OBJECT = ( 2 << 28), // compiler
78 BLOCK_BYREF_LAYOUT_STRONG = ( 3 << 28), // compiler
79 BLOCK_BYREF_LAYOUT_WEAK = ( 4 << 28), // compiler
80 BLOCK_BYREF_LAYOUT_UNRETAINED = ( 5 << 28), // compiler
81
82 BLOCK_BYREF_IS_GC = ( 1 << 27), // runtime
83
84 BLOCK_BYREF_HAS_COPY_DISPOSE = ( 1 << 25), // compiler
85 BLOCK_BYREF_NEEDS_FREE = ( 1 << 24), // runtime
86 };
87
88 struct Block_byref {
89 void *isa;
90 struct Block_byref *forwarding;
91 volatile int32_t flags; // contains ref count
92 uint32_t size;
93 };
94
95 struct Block_byref_2 {
96 // requires BLOCK_BYREF_HAS_COPY_DISPOSE
97 void (*byref_keep)(struct Block_byref *dst, struct Block_byref *src);
98 void (*byref_destroy)(struct Block_byref *);
99 };
100
101 struct Block_byref_3 {
102 // requires BLOCK_BYREF_LAYOUT_EXTENDED
103 const char *layout;
104 };
105
106
107 // Extended layout encoding.
108
109 // Values for Block_descriptor_3->layout with BLOCK_HAS_EXTENDED_LAYOUT
110 // and for Block_byref_3->layout with BLOCK_BYREF_LAYOUT_EXTENDED
111
112 // If the layout field is less than 0x1000, then it is a compact encoding
113 // of the form 0xXYZ: X strong pointers, then Y byref pointers,
114 // then Z weak pointers.
115
116 // If the layout field is 0x1000 or greater, it points to a
117 // string of layout bytes. Each byte is of the form 0xPN.
118 // Operator P is from the list below. Value N is a parameter for the operator.
119 // Byte 0x00 terminates the layout; remaining block data is non-pointer bytes.
120
121 enum {
122 BLOCK_LAYOUT_ESCAPE = 0, // N=0 halt, rest is non-pointer. N!=0 reserved.
123 BLOCK_LAYOUT_NON_OBJECT_BYTES = 1, // N bytes non-objects
124 BLOCK_LAYOUT_NON_OBJECT_WORDS = 2, // N words non-objects
125 BLOCK_LAYOUT_STRONG = 3, // N words strong pointers
126 BLOCK_LAYOUT_BYREF = 4, // N words byref pointers
127 BLOCK_LAYOUT_WEAK = 5, // N words weak pointers
128 BLOCK_LAYOUT_UNRETAINED = 6, // N words unretained pointers
129 BLOCK_LAYOUT_UNKNOWN_WORDS_7 = 7, // N words, reserved
130 BLOCK_LAYOUT_UNKNOWN_WORDS_8 = 8, // N words, reserved
131 BLOCK_LAYOUT_UNKNOWN_WORDS_9 = 9, // N words, reserved
132 BLOCK_LAYOUT_UNKNOWN_WORDS_A = 0xA, // N words, reserved
133 BLOCK_LAYOUT_UNUSED_B = 0xB, // unspecified, reserved
134 BLOCK_LAYOUT_UNUSED_C = 0xC, // unspecified, reserved
135 BLOCK_LAYOUT_UNUSED_D = 0xD, // unspecified, reserved
136 BLOCK_LAYOUT_UNUSED_E = 0xE, // unspecified, reserved
137 BLOCK_LAYOUT_UNUSED_F = 0xF, // unspecified, reserved
138 };
139
140
141 // Runtime support functions used by compiler when generating copy/dispose helpers
142
143 // Values for _Block_object_assign() and _Block_object_dispose() parameters
144 enum {
145 // see function implementation for a more complete description of these fields and combinations
146 BLOCK_FIELD_IS_OBJECT = 3, // id, NSObject, __attribute__((NSObject)), block, ...
147 BLOCK_FIELD_IS_BLOCK = 7, // a block variable
148 BLOCK_FIELD_IS_BYREF = 8, // the on stack structure holding the __block variable
149 BLOCK_FIELD_IS_WEAK = 16, // declared __weak, only used in byref copy helpers
150 BLOCK_BYREF_CALLER = 128, // called from __block (byref) copy/dispose support routines.
151 };
152
153 enum {
154 BLOCK_ALL_COPY_DISPOSE_FLAGS =
155 BLOCK_FIELD_IS_OBJECT | BLOCK_FIELD_IS_BLOCK | BLOCK_FIELD_IS_BYREF |
156 BLOCK_FIELD_IS_WEAK | BLOCK_BYREF_CALLER
157 };
158
159 // Runtime entry point called by compiler when assigning objects inside copy helper routines
160 BLOCK_EXPORT void _Block_object_assign(void *destAddr, const void *object, const int flags);
161 // BLOCK_FIELD_IS_BYREF is only used from within block copy helpers
162
163
164 // runtime entry point called by the compiler when disposing of objects inside dispose helper routine
165 BLOCK_EXPORT void _Block_object_dispose(const void *object, const int flags);
166
167
168 // Other support functions
169
170 // runtime entry to get total size of a closure
171 BLOCK_EXPORT size_t Block_size(void *aBlock);
172
173 // indicates whether block was compiled with compiler that sets the ABI related metadata bits
174 BLOCK_EXPORT bool _Block_has_signature(void *aBlock);
175
176 // returns TRUE if return value of block is on the stack, FALSE otherwise
177 BLOCK_EXPORT bool _Block_use_stret(void *aBlock);
178
179 // Returns a string describing the block's parameter and return types.
180 // The encoding scheme is the same as Objective-C @encode.
181 // Returns NULL for blocks compiled with some compilers.
182 BLOCK_EXPORT const char * _Block_signature(void *aBlock);
183
184 // Returns a string describing the block's GC layout.
185 // This uses the GC skip/scan encoding.
186 // May return NULL.
187 BLOCK_EXPORT const char * _Block_layout(void *aBlock);
188
189 // Returns a string describing the block's layout.
190 // This uses the "extended layout" form described above.
191 // May return NULL.
192 BLOCK_EXPORT const char * _Block_extended_layout(void *aBlock);
193
194 // Callable only from the ARR weak subsystem while in exclusion zone
195 BLOCK_EXPORT bool _Block_tryRetain(const void *aBlock);
196
197 // Callable only from the ARR weak subsystem while in exclusion zone
198 BLOCK_EXPORT bool _Block_isDeallocating(const void *aBlock);
199
200
201 // the raw data space for runtime classes for blocks
202 // class+meta used for stack, malloc, and collectable based blocks
203 BLOCK_EXPORT void * _NSConcreteMallocBlock[32];
204 BLOCK_EXPORT void * _NSConcreteAutoBlock[32];
205 BLOCK_EXPORT void * _NSConcreteFinalizingBlock[32];
206 BLOCK_EXPORT void * _NSConcreteWeakBlockVariable[32];
207 // declared in Block.h
208 // BLOCK_EXPORT void * _NSConcreteGlobalBlock[32];
209 // BLOCK_EXPORT void * _NSConcreteStackBlock[32];
210
211
212 // the intercept routines that must be used under GC
213 BLOCK_EXPORT void _Block_use_GC( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject),
214 void (*setHasRefcount)(const void *, const bool),
215 void (*gc_assign_strong)(void *, void **),
216 void (*gc_assign_weak)(const void *, void *),
217 void (*gc_memmove)(void *, void *, unsigned long));
218
219 // earlier version, now simply transitional
220 BLOCK_EXPORT void _Block_use_GC5( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject),
221 void (*setHasRefcount)(const void *, const bool),
222 void (*gc_assign_strong)(void *, void **),
223 void (*gc_assign_weak)(const void *, void *));
224
225 BLOCK_EXPORT void _Block_use_RR( void (*retain)(const void *),
226 void (*release)(const void *));
227
228 struct Block_callbacks_RR {
229 size_t size; // size == sizeof(struct Block_callbacks_RR)
230 void (*retain)(const void *);
231 void (*release)(const void *);
232 void (*destructInstance)(const void *);
233 };
234 typedef struct Block_callbacks_RR Block_callbacks_RR;
235
236 BLOCK_EXPORT void _Block_use_RR2(const Block_callbacks_RR *callbacks);
237
238 // make a collectable GC heap based Block. Not useful under non-GC.
239 BLOCK_EXPORT void *_Block_copy_collectable(const void *aBlock);
240
241 // thread-unsafe diagnostic
242 BLOCK_EXPORT const char *_Block_dump(const void *block);
243
244
245 // Obsolete
246
247 // first layout
248 struct Block_basic {
249 void *isa;
250 int Block_flags; // int32_t
251 int Block_size; // XXX should be packed into Block_flags
252 void (*Block_invoke)(void *);
253 void (*Block_copy)(void *dst, void *src); // iff BLOCK_HAS_COPY_DISPOSE
254 void (*Block_dispose)(void *); // iff BLOCK_HAS_COPY_DISPOSE
255 //long params[0]; // where const imports, __block storage references, etc. get laid down
256 } __attribute__((deprecated));
257
258
259 #if __cplusplus
260 }
261 #endif
262
263
264 #endif