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