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
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
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
25 #ifndef _BLOCK_PRIVATE_H_
26 #define _BLOCK_PRIVATE_H_
28 #if !defined(BLOCK_EXPORT)
29 # if defined(__cplusplus)
30 # define BLOCK_EXPORT extern "C"
32 # define BLOCK_EXPORT extern
39 /* MSVC doesn't have <stdbool.h>. Compensate. */
45 #if defined(__cplusplus)
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)
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 *);
74 void (*invoke
)(void *, ...);
75 struct Block_descriptor
*descriptor
;
76 /* Imported variables. */
82 struct Block_byref
*forwarding
;
83 int flags
; /* refcount; */
85 void (*byref_keep
)(struct Block_byref
*dst
, struct Block_byref
*src
);
86 void (*byref_destroy
)(struct Block_byref
*);
91 struct Block_byref_header
{
93 struct Block_byref
*forwarding
;
99 /* Runtime support functions used by compiler when generating copy/dispose helpers. */
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. */
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 */
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
);
120 /* Other support functions */
122 /* Runtime entry to get total size of a closure */
123 BLOCK_EXPORT
unsigned long int Block_size(void *block_basic
);
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];
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));
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 *));
150 BLOCK_EXPORT
void _Block_use_RR( void (*retain
)(const void *),
151 void (*release
)(const void *));
153 /* make a collectable GC heap based Block. Not useful under non-GC. */
154 BLOCK_EXPORT
void *_Block_copy_collectable(const void *aBlock
);
156 /* thread-unsafe diagnostic */
157 BLOCK_EXPORT
const char *_Block_dump(const void *block
);
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 */
174 #if defined(__cplusplus)
179 #endif /* _BLOCK_PRIVATE_H_ */