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