blob: 8ae821815ebe7a4ccb3559f2b353338259e13cf7 [file] [log] [blame]
Daniel Dunbar8cbe1632009-06-26 16:21:04 +00001/*
2 * Block_private.h
Daniel Dunbar8cbe1632009-06-26 16:21:04 +00003 *
Blaine Garstb1c07152010-04-21 04:34:46 +00004 * Copyright 2008-2010 Apple, Inc. Permission is hereby granted, free of charge,
Daniel Dunbarb3a69012009-06-26 16:47:03 +00005 * 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
10 * conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
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
21 * SOFTWARE.
22 *
Daniel Dunbar8cbe1632009-06-26 16:21:04 +000023 */
24
25#ifndef _BLOCK_PRIVATE_H_
26#define _BLOCK_PRIVATE_H_
27
28#if !defined(BLOCK_EXPORT)
29# if defined(__cplusplus)
30# define BLOCK_EXPORT extern "C"
31# else
32# define BLOCK_EXPORT extern
33# endif
34#endif
35
Charles Davisffd69e72010-04-29 23:44:00 +000036#ifndef _MSC_VER
Daniel Dunbar8cbe1632009-06-26 16:21:04 +000037#include <stdbool.h>
Charles Davisffd69e72010-04-29 23:44:00 +000038#else
39/* MSVC doesn't have <stdbool.h>. Compensate. */
40typedef char bool;
41#define true (bool)1
42#define false (bool)0
43#endif
Daniel Dunbar8cbe1632009-06-26 16:21:04 +000044
Shantonu Senb4c3b6f2009-09-22 00:49:12 +000045#if defined(__cplusplus)
Daniel Dunbar8cbe1632009-06-26 16:21:04 +000046extern "C" {
47#endif
48
49
Daniel Dunbar8cbe1632009-06-26 16:21:04 +000050enum {
51 BLOCK_REFCOUNT_MASK = (0xffff),
52 BLOCK_NEEDS_FREE = (1 << 24),
53 BLOCK_HAS_COPY_DISPOSE = (1 << 25),
Edward O'Callaghan09870642009-09-12 15:47:39 +000054 BLOCK_HAS_CTOR = (1 << 26), /* Helpers have C++ code. */
Daniel Dunbar8cbe1632009-06-26 16:21:04 +000055 BLOCK_IS_GC = (1 << 27),
56 BLOCK_IS_GLOBAL = (1 << 28),
Edward O'Callaghan09870642009-09-12 15:47:39 +000057 BLOCK_HAS_DESCRIPTOR = (1 << 29)
Daniel Dunbar8cbe1632009-06-26 16:21:04 +000058};
59
Edward O'Callaghan09870642009-09-12 15:47:39 +000060
61/* Revised new layout. */
Daniel Dunbar8cbe1632009-06-26 16:21:04 +000062struct Block_descriptor {
63 unsigned long int reserved;
64 unsigned long int size;
65 void (*copy)(void *dst, void *src);
66 void (*dispose)(void *);
67};
68
Edward O'Callaghan09870642009-09-12 15:47:39 +000069
Daniel Dunbar8cbe1632009-06-26 16:21:04 +000070struct Block_layout {
71 void *isa;
72 int flags;
73 int reserved;
74 void (*invoke)(void *, ...);
75 struct Block_descriptor *descriptor;
Edward O'Callaghan09870642009-09-12 15:47:39 +000076 /* Imported variables. */
Daniel Dunbar8cbe1632009-06-26 16:21:04 +000077};
78
79
Daniel Dunbar8cbe1632009-06-26 16:21:04 +000080struct Block_byref {
81 void *isa;
82 struct Block_byref *forwarding;
Edward O'Callaghan0898ee92009-08-05 19:57:20 +000083 int flags; /* refcount; */
Daniel Dunbar8cbe1632009-06-26 16:21:04 +000084 int size;
85 void (*byref_keep)(struct Block_byref *dst, struct Block_byref *src);
86 void (*byref_destroy)(struct Block_byref *);
Edward O'Callaghan0898ee92009-08-05 19:57:20 +000087 /* long shared[0]; */
Daniel Dunbar8cbe1632009-06-26 16:21:04 +000088};
89
Edward O'Callaghan09870642009-09-12 15:47:39 +000090
Daniel Dunbar8cbe1632009-06-26 16:21:04 +000091struct Block_byref_header {
92 void *isa;
93 struct Block_byref *forwarding;
94 int flags;
95 int size;
96};
97
98
Edward O'Callaghan09870642009-09-12 15:47:39 +000099/* Runtime support functions used by compiler when generating copy/dispose helpers. */
Daniel Dunbar8cbe1632009-06-26 16:21:04 +0000100
101enum {
Edward O'Callaghan09870642009-09-12 15:47:39 +0000102 /* See function implementation for a more complete description of these fields and combinations */
Edward O'Callaghan0898ee92009-08-05 19:57:20 +0000103 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 */
Edward O'Callaghan09870642009-09-12 15:47:39 +0000107 BLOCK_BYREF_CALLER = 128 /* called from __block (byref) copy/dispose support routines. */
Daniel Dunbar8cbe1632009-06-26 16:21:04 +0000108};
109
Edward O'Callaghan0898ee92009-08-05 19:57:20 +0000110/* Runtime entry point called by compiler when assigning objects inside copy helper routines */
Daniel Dunbar8cbe1632009-06-26 16:21:04 +0000111BLOCK_EXPORT void _Block_object_assign(void *destAddr, const void *object, const int flags);
Edward O'Callaghan0898ee92009-08-05 19:57:20 +0000112 /* BLOCK_FIELD_IS_BYREF is only used from within block copy helpers */
Daniel Dunbar8cbe1632009-06-26 16:21:04 +0000113
114
Edward O'Callaghan0898ee92009-08-05 19:57:20 +0000115/* runtime entry point called by the compiler when disposing of objects inside dispose helper routine */
Daniel Dunbar8cbe1632009-06-26 16:21:04 +0000116BLOCK_EXPORT void _Block_object_dispose(const void *object, const int flags);
117
118
119
Edward O'Callaghan0898ee92009-08-05 19:57:20 +0000120/* Other support functions */
Daniel Dunbar8cbe1632009-06-26 16:21:04 +0000121
Edward O'Callaghan09870642009-09-12 15:47:39 +0000122/* Runtime entry to get total size of a closure */
Daniel Dunbar8cbe1632009-06-26 16:21:04 +0000123BLOCK_EXPORT unsigned long int Block_size(void *block_basic);
124
125
126
Edward O'Callaghan0898ee92009-08-05 19:57:20 +0000127/* the raw data space for runtime classes for blocks */
128/* class+meta used for stack, malloc, and collectable based blocks */
Daniel Dunbar8cbe1632009-06-26 16:21:04 +0000129BLOCK_EXPORT void * _NSConcreteStackBlock[32];
130BLOCK_EXPORT void * _NSConcreteMallocBlock[32];
131BLOCK_EXPORT void * _NSConcreteAutoBlock[32];
132BLOCK_EXPORT void * _NSConcreteFinalizingBlock[32];
133BLOCK_EXPORT void * _NSConcreteGlobalBlock[32];
134BLOCK_EXPORT void * _NSConcreteWeakBlockVariable[32];
135
136
Edward O'Callaghan0898ee92009-08-05 19:57:20 +0000137/* the intercept routines that must be used under GC */
Daniel Dunbar8cbe1632009-06-26 16:21:04 +0000138BLOCK_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));
143
Edward O'Callaghan0898ee92009-08-05 19:57:20 +0000144/* earlier version, now simply transitional */
Daniel Dunbar8cbe1632009-06-26 16:21:04 +0000145BLOCK_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 *));
149
150BLOCK_EXPORT void _Block_use_RR( void (*retain)(const void *),
151 void (*release)(const void *));
152
Edward O'Callaghan0898ee92009-08-05 19:57:20 +0000153/* make a collectable GC heap based Block. Not useful under non-GC. */
Daniel Dunbar8cbe1632009-06-26 16:21:04 +0000154BLOCK_EXPORT void *_Block_copy_collectable(const void *aBlock);
155
Edward O'Callaghan0898ee92009-08-05 19:57:20 +0000156/* thread-unsafe diagnostic */
Daniel Dunbar8cbe1632009-06-26 16:21:04 +0000157BLOCK_EXPORT const char *_Block_dump(const void *block);
158
159
Edward O'Callaghan0898ee92009-08-05 19:57:20 +0000160/* Obsolete */
Daniel Dunbar8cbe1632009-06-26 16:21:04 +0000161
Edward O'Callaghan0898ee92009-08-05 19:57:20 +0000162/* first layout */
Daniel Dunbar8cbe1632009-06-26 16:21:04 +0000163struct Block_basic {
164 void *isa;
Edward O'Callaghan0898ee92009-08-05 19:57:20 +0000165 int Block_flags; /* int32_t */
Edward O'Callaghan09870642009-09-12 15:47:39 +0000166 int Block_size; /* XXX should be packed into Block_flags */
Daniel Dunbar8cbe1632009-06-26 16:21:04 +0000167 void (*Block_invoke)(void *);
Edward O'Callaghan0898ee92009-08-05 19:57:20 +0000168 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 */
Daniel Dunbar8cbe1632009-06-26 16:21:04 +0000171};
172
173
Shantonu Senb4c3b6f2009-09-22 00:49:12 +0000174#if defined(__cplusplus)
Daniel Dunbar8cbe1632009-06-26 16:21:04 +0000175}
176#endif
177
178
Shantonu Senb4c3b6f2009-09-22 00:49:12 +0000179#endif /* _BLOCK_PRIVATE_H_ */