1276789Sdim/*
2276789Sdim * Block_private.h
3276789Sdim *
4276789Sdim * Copyright 2008-2010 Apple, Inc. Permission is hereby granted, free of charge,
5276789Sdim * to any person obtaining a copy of this software and associated documentation
6276789Sdim * files (the "Software"), to deal in the Software without restriction,
7276789Sdim * including without limitation the rights to use, copy, modify, merge, publish,
8276789Sdim * distribute, sublicense, and/or sell copies of the Software, and to permit
9276789Sdim * persons to whom the Software is furnished to do so, subject to the following
10276789Sdim * conditions:
11276789Sdim *
12276789Sdim * The above copyright notice and this permission notice shall be included in
13276789Sdim * all copies or substantial portions of the Software.
14276789Sdim *
15276789Sdim * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16276789Sdim * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17276789Sdim * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18276789Sdim * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19276789Sdim * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20276789Sdim * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21276789Sdim * SOFTWARE.
22276789Sdim *
23276789Sdim */
24276789Sdim
25276789Sdim#ifndef _BLOCK_PRIVATE_H_
26276789Sdim#define _BLOCK_PRIVATE_H_
27276789Sdim
28276789Sdim#if !defined(BLOCK_EXPORT)
29276789Sdim#   if defined(__cplusplus)
30327952Sdim#       define BLOCK_EXPORT extern "C"
31276789Sdim#   else
32276789Sdim#       define BLOCK_EXPORT extern
33276789Sdim#   endif
34276789Sdim#endif
35276789Sdim
36276789Sdim#ifndef _MSC_VER
37276789Sdim#include <stdbool.h>
38276789Sdim#else
39276789Sdim/* MSVC doesn't have <stdbool.h>. Compensate. */
40276789Sdimtypedef char bool;
41276789Sdim#define true (bool)1
42276789Sdim#define false (bool)0
43276789Sdim#endif
44276789Sdim
45276789Sdim#if defined(__cplusplus)
46276789Sdimextern "C" {
47276789Sdim#endif
48276789Sdim
49276789Sdim
50276789Sdimenum {
51276789Sdim    BLOCK_REFCOUNT_MASK =     (0xffff),
52276789Sdim    BLOCK_NEEDS_FREE =        (1 << 24),
53276789Sdim    BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
54276789Sdim    BLOCK_HAS_CTOR =          (1 << 26), /* Helpers have C++ code. */
55276789Sdim    BLOCK_IS_GC =             (1 << 27),
56276789Sdim    BLOCK_IS_GLOBAL =         (1 << 28),
57276789Sdim    BLOCK_HAS_DESCRIPTOR =    (1 << 29)
58276789Sdim};
59276789Sdim
60276789Sdim
61276789Sdim/* Revised new layout. */
62276789Sdimstruct Block_descriptor {
63276789Sdim    unsigned long int reserved;
64276789Sdim    unsigned long int size;
65276789Sdim    void (*copy)(void *dst, void *src);
66276789Sdim    void (*dispose)(void *);
67276789Sdim};
68276789Sdim
69276789Sdim
70276789Sdimstruct Block_layout {
71276789Sdim    void *isa;
72276789Sdim    int flags;
73276789Sdim    int reserved;
74276789Sdim    void (*invoke)(void *, ...);
75276789Sdim    struct Block_descriptor *descriptor;
76276789Sdim    /* Imported variables. */
77276789Sdim};
78276789Sdim
79276789Sdim
80276789Sdimstruct Block_byref {
81276789Sdim    void *isa;
82276789Sdim    struct Block_byref *forwarding;
83276789Sdim    int flags; /* refcount; */
84276789Sdim    int size;
85276789Sdim    void (*byref_keep)(struct Block_byref *dst, struct Block_byref *src);
86276789Sdim    void (*byref_destroy)(struct Block_byref *);
87276789Sdim    /* long shared[0]; */
88276789Sdim};
89276789Sdim
90276789Sdim
91276789Sdimstruct Block_byref_header {
92276789Sdim    void *isa;
93276789Sdim    struct Block_byref *forwarding;
94276789Sdim    int flags;
95276789Sdim    int size;
96276789Sdim};
97276789Sdim
98276789Sdim
99276789Sdim/* Runtime support functions used by compiler when generating copy/dispose helpers. */
100276789Sdim
101276789Sdimenum {
102276789Sdim    /* See function implementation for a more complete description of these fields and combinations */
103276789Sdim    BLOCK_FIELD_IS_OBJECT   =  3,  /* id, NSObject, __attribute__((NSObject)), block, ... */
104276789Sdim    BLOCK_FIELD_IS_BLOCK    =  7,  /* a block variable */
105276789Sdim    BLOCK_FIELD_IS_BYREF    =  8,  /* the on stack structure holding the __block variable */
106276789Sdim    BLOCK_FIELD_IS_WEAK     = 16,  /* declared __weak, only used in byref copy helpers */
107276789Sdim    BLOCK_BYREF_CALLER      = 128  /* called from __block (byref) copy/dispose support routines. */
108276789Sdim};
109276789Sdim
110276789Sdim/* Runtime entry point called by compiler when assigning objects inside copy helper routines */
111276789SdimBLOCK_EXPORT void _Block_object_assign(void *destAddr, const void *object, const int flags);
112276789Sdim    /* BLOCK_FIELD_IS_BYREF is only used from within block copy helpers */
113276789Sdim
114276789Sdim
115276789Sdim/* runtime entry point called by the compiler when disposing of objects inside dispose helper routine */
116276789SdimBLOCK_EXPORT void _Block_object_dispose(const void *object, const int flags);
117276789Sdim
118276789Sdim
119276789Sdim
120276789Sdim/* Other support functions */
121276789Sdim
122276789Sdim/* Runtime entry to get total size of a closure */
123276789SdimBLOCK_EXPORT unsigned long int Block_size(void *block_basic);
124276789Sdim
125276789Sdim
126276789Sdim
127276789Sdim/* the raw data space for runtime classes for blocks */
128276789Sdim/* class+meta used for stack, malloc, and collectable based blocks */
129276789SdimBLOCK_EXPORT void * _NSConcreteStackBlock[32];
130276789SdimBLOCK_EXPORT void * _NSConcreteMallocBlock[32];
131276789SdimBLOCK_EXPORT void * _NSConcreteAutoBlock[32];
132276789SdimBLOCK_EXPORT void * _NSConcreteFinalizingBlock[32];
133276789SdimBLOCK_EXPORT void * _NSConcreteGlobalBlock[32];
134276789SdimBLOCK_EXPORT void * _NSConcreteWeakBlockVariable[32];
135276789Sdim
136276789Sdim
137276789Sdim/* the intercept routines that must be used under GC */
138276789SdimBLOCK_EXPORT void _Block_use_GC( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject),
139276789Sdim                                  void (*setHasRefcount)(const void *, const bool),
140276789Sdim                                  void (*gc_assign_strong)(void *, void **),
141276789Sdim                                  void (*gc_assign_weak)(const void *, void *),
142276789Sdim                                  void (*gc_memmove)(void *, void *, unsigned long));
143276789Sdim
144276789Sdim/* earlier version, now simply transitional */
145276789SdimBLOCK_EXPORT void _Block_use_GC5( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject),
146276789Sdim                                  void (*setHasRefcount)(const void *, const bool),
147276789Sdim                                  void (*gc_assign_strong)(void *, void **),
148276789Sdim                                  void (*gc_assign_weak)(const void *, void *));
149276789Sdim
150276789SdimBLOCK_EXPORT void _Block_use_RR( void (*retain)(const void *),
151276789Sdim                                 void (*release)(const void *));
152276789Sdim
153276789Sdim/* make a collectable GC heap based Block.  Not useful under non-GC. */
154276789SdimBLOCK_EXPORT void *_Block_copy_collectable(const void *aBlock);
155276789Sdim
156276789Sdim/* thread-unsafe diagnostic */
157276789SdimBLOCK_EXPORT const char *_Block_dump(const void *block);
158276789Sdim
159276789Sdim
160276789Sdim/* Obsolete */
161276789Sdim
162276789Sdim/* first layout */
163276789Sdimstruct Block_basic {
164276789Sdim    void *isa;
165276789Sdim    int Block_flags;  /* int32_t */
166276789Sdim    int Block_size;  /* XXX should be packed into Block_flags */
167276789Sdim    void (*Block_invoke)(void *);
168276789Sdim    void (*Block_copy)(void *dst, void *src);  /* iff BLOCK_HAS_COPY_DISPOSE */
169276789Sdim    void (*Block_dispose)(void *);             /* iff BLOCK_HAS_COPY_DISPOSE */
170276789Sdim    /* long params[0];  // where const imports, __block storage references, etc. get laid down */
171276789Sdim};
172276789Sdim
173276789Sdim
174276789Sdim#if defined(__cplusplus)
175276789Sdim}
176276789Sdim#endif
177276789Sdim
178276789Sdim
179276789Sdim#endif /* _BLOCK_PRIVATE_H_ */
180