]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
1 | /* |
2 | * Block_private.h | |
3 | * | |
4 | * Copyright 2008-2010 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) | |
2c00a5a8 | 30 | # define BLOCK_EXPORT extern "C" |
1a4d82fc JJ |
31 | # else |
32 | # define BLOCK_EXPORT extern | |
33 | # endif | |
34 | #endif | |
35 | ||
36 | #ifndef _MSC_VER | |
37 | #include <stdbool.h> | |
38 | #else | |
39 | /* MSVC doesn't have <stdbool.h>. Compensate. */ | |
40 | typedef char bool; | |
41 | #define true (bool)1 | |
42 | #define false (bool)0 | |
43 | #endif | |
44 | ||
45 | #if defined(__cplusplus) | |
46 | extern "C" { | |
47 | #endif | |
48 | ||
49 | ||
50 | enum { | |
51 | BLOCK_REFCOUNT_MASK = (0xffff), | |
52 | BLOCK_NEEDS_FREE = (1 << 24), | |
53 | BLOCK_HAS_COPY_DISPOSE = (1 << 25), | |
54 | BLOCK_HAS_CTOR = (1 << 26), /* Helpers have C++ code. */ | |
55 | BLOCK_IS_GC = (1 << 27), | |
56 | BLOCK_IS_GLOBAL = (1 << 28), | |
57 | BLOCK_HAS_DESCRIPTOR = (1 << 29) | |
58 | }; | |
59 | ||
60 | ||
61 | /* Revised new layout. */ | |
62 | struct Block_descriptor { | |
63 | unsigned long int reserved; | |
64 | unsigned long int size; | |
65 | void (*copy)(void *dst, void *src); | |
66 | void (*dispose)(void *); | |
67 | }; | |
68 | ||
69 | ||
70 | struct Block_layout { | |
71 | void *isa; | |
72 | int flags; | |
73 | int reserved; | |
74 | void (*invoke)(void *, ...); | |
75 | struct Block_descriptor *descriptor; | |
76 | /* Imported variables. */ | |
77 | }; | |
78 | ||
79 | ||
80 | struct Block_byref { | |
81 | void *isa; | |
82 | struct Block_byref *forwarding; | |
83 | int flags; /* refcount; */ | |
84 | int size; | |
85 | void (*byref_keep)(struct Block_byref *dst, struct Block_byref *src); | |
86 | void (*byref_destroy)(struct Block_byref *); | |
87 | /* long shared[0]; */ | |
88 | }; | |
89 | ||
90 | ||
91 | struct Block_byref_header { | |
92 | void *isa; | |
93 | struct Block_byref *forwarding; | |
94 | int flags; | |
95 | int size; | |
96 | }; | |
97 | ||
98 | ||
99 | /* Runtime support functions used by compiler when generating copy/dispose helpers. */ | |
100 | ||
101 | enum { | |
102 | /* See function implementation for a more complete description of these fields and combinations */ | |
103 | BLOCK_FIELD_IS_OBJECT = 3, /* id, NSObject, __attribute__((NSObject)), block, ... */ | |
104 | BLOCK_FIELD_IS_BLOCK = 7, /* a block variable */ | |
105 | BLOCK_FIELD_IS_BYREF = 8, /* the on stack structure holding the __block variable */ | |
106 | BLOCK_FIELD_IS_WEAK = 16, /* declared __weak, only used in byref copy helpers */ | |
107 | BLOCK_BYREF_CALLER = 128 /* called from __block (byref) copy/dispose support routines. */ | |
108 | }; | |
109 | ||
110 | /* Runtime entry point called by compiler when assigning objects inside copy helper routines */ | |
111 | BLOCK_EXPORT void _Block_object_assign(void *destAddr, const void *object, const int flags); | |
112 | /* BLOCK_FIELD_IS_BYREF is only used from within block copy helpers */ | |
113 | ||
114 | ||
115 | /* runtime entry point called by the compiler when disposing of objects inside dispose helper routine */ | |
116 | BLOCK_EXPORT void _Block_object_dispose(const void *object, const int flags); | |
117 | ||
118 | ||
119 | ||
120 | /* Other support functions */ | |
121 | ||
122 | /* Runtime entry to get total size of a closure */ | |
123 | BLOCK_EXPORT unsigned long int Block_size(void *block_basic); | |
124 | ||
125 | ||
126 | ||
127 | /* the raw data space for runtime classes for blocks */ | |
128 | /* class+meta used for stack, malloc, and collectable based blocks */ | |
129 | BLOCK_EXPORT void * _NSConcreteStackBlock[32]; | |
130 | BLOCK_EXPORT void * _NSConcreteMallocBlock[32]; | |
131 | BLOCK_EXPORT void * _NSConcreteAutoBlock[32]; | |
132 | BLOCK_EXPORT void * _NSConcreteFinalizingBlock[32]; | |
133 | BLOCK_EXPORT void * _NSConcreteGlobalBlock[32]; | |
134 | BLOCK_EXPORT void * _NSConcreteWeakBlockVariable[32]; | |
135 | ||
136 | ||
137 | /* the intercept routines that must be used under GC */ | |
138 | BLOCK_EXPORT void _Block_use_GC( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject), | |
139 | void (*setHasRefcount)(const void *, const bool), | |
140 | void (*gc_assign_strong)(void *, void **), | |
141 | void (*gc_assign_weak)(const void *, void *), | |
142 | void (*gc_memmove)(void *, void *, unsigned long)); | |
143 | ||
144 | /* earlier version, now simply transitional */ | |
145 | BLOCK_EXPORT void _Block_use_GC5( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject), | |
146 | void (*setHasRefcount)(const void *, const bool), | |
147 | void (*gc_assign_strong)(void *, void **), | |
148 | void (*gc_assign_weak)(const void *, void *)); | |
149 | ||
150 | BLOCK_EXPORT void _Block_use_RR( void (*retain)(const void *), | |
151 | void (*release)(const void *)); | |
152 | ||
153 | /* make a collectable GC heap based Block. Not useful under non-GC. */ | |
154 | BLOCK_EXPORT void *_Block_copy_collectable(const void *aBlock); | |
155 | ||
156 | /* thread-unsafe diagnostic */ | |
157 | BLOCK_EXPORT const char *_Block_dump(const void *block); | |
158 | ||
159 | ||
160 | /* Obsolete */ | |
161 | ||
162 | /* first layout */ | |
163 | struct Block_basic { | |
164 | void *isa; | |
165 | int Block_flags; /* int32_t */ | |
166 | int Block_size; /* XXX should be packed into Block_flags */ | |
167 | void (*Block_invoke)(void *); | |
168 | void (*Block_copy)(void *dst, void *src); /* iff BLOCK_HAS_COPY_DISPOSE */ | |
169 | void (*Block_dispose)(void *); /* iff BLOCK_HAS_COPY_DISPOSE */ | |
170 | /* long params[0]; // where const imports, __block storage references, etc. get laid down */ | |
171 | }; | |
172 | ||
173 | ||
174 | #if defined(__cplusplus) | |
175 | } | |
176 | #endif | |
177 | ||
178 | ||
179 | #endif /* _BLOCK_PRIVATE_H_ */ |