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