blob: 6201846790d236e1f32358a1a0f5ea80b60731af [file] [log] [blame]
Blaine Garstcc08af12009-06-10 18:41:48 +00001/*
2 * Block_private.h
Blaine Garstcc08af12009-06-10 18:41:48 +00003 *
Daniel Dunbarfd089992009-06-26 16:47:03 +00004 * Copyright 2008-2009 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
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 *
Blaine Garstcc08af12009-06-10 18:41:48 +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
36#include <AvailabilityMacros.h>
37#include <TargetConditionals.h>
38
39#include <stdbool.h>
40
41#if __cplusplus
42extern "C" {
43#endif
44
45
46
47enum {
48 BLOCK_REFCOUNT_MASK = (0xffff),
49 BLOCK_NEEDS_FREE = (1 << 24),
50 BLOCK_HAS_COPY_DISPOSE = (1 << 25),
Edward O'Callaghan7a6cb5f2009-08-05 19:57:20 +000051 BLOCK_HAS_CTOR = (1 << 26), /* helpers have C++ code */
Blaine Garstcc08af12009-06-10 18:41:48 +000052 BLOCK_IS_GC = (1 << 27),
53 BLOCK_IS_GLOBAL = (1 << 28),
54 BLOCK_HAS_DESCRIPTOR = (1 << 29),
55};
56
Edward O'Callaghan7a6cb5f2009-08-05 19:57:20 +000057/* revised new layout */
Blaine Garstcc08af12009-06-10 18:41:48 +000058struct Block_descriptor {
59 unsigned long int reserved;
60 unsigned long int size;
61 void (*copy)(void *dst, void *src);
62 void (*dispose)(void *);
63};
64
65struct Block_layout {
66 void *isa;
67 int flags;
68 int reserved;
69 void (*invoke)(void *, ...);
70 struct Block_descriptor *descriptor;
Edward O'Callaghan7a6cb5f2009-08-05 19:57:20 +000071 /* imported variables */
Blaine Garstcc08af12009-06-10 18:41:48 +000072};
73
74
75
76struct Block_byref {
77 void *isa;
78 struct Block_byref *forwarding;
Edward O'Callaghan7a6cb5f2009-08-05 19:57:20 +000079 int flags; /* refcount; */
Blaine Garstcc08af12009-06-10 18:41:48 +000080 int size;
81 void (*byref_keep)(struct Block_byref *dst, struct Block_byref *src);
82 void (*byref_destroy)(struct Block_byref *);
Edward O'Callaghan7a6cb5f2009-08-05 19:57:20 +000083 /* long shared[0]; */
Blaine Garstcc08af12009-06-10 18:41:48 +000084};
85
86struct Block_byref_header {
87 void *isa;
88 struct Block_byref *forwarding;
89 int flags;
90 int size;
91};
92
93
Edward O'Callaghan7a6cb5f2009-08-05 19:57:20 +000094/* Runtime support functions used by compiler when generating copy/dispose helpers */
Blaine Garstcc08af12009-06-10 18:41:48 +000095
96enum {
Edward O'Callaghan7a6cb5f2009-08-05 19:57:20 +000097 /* see function implementation for a more complete description of these fields and combinations */
98 BLOCK_FIELD_IS_OBJECT = 3, /* id, NSObject, __attribute__((NSObject)), block, ... */
99 BLOCK_FIELD_IS_BLOCK = 7, /* a block variable */
100 BLOCK_FIELD_IS_BYREF = 8, /* the on stack structure holding the __block variable */
101 BLOCK_FIELD_IS_WEAK = 16, /* declared __weak, only used in byref copy helpers */
102 BLOCK_BYREF_CALLER = 128, /* called from __block (byref) copy/dispose support routines. */
Blaine Garstcc08af12009-06-10 18:41:48 +0000103};
104
Edward O'Callaghan7a6cb5f2009-08-05 19:57:20 +0000105/* Runtime entry point called by compiler when assigning objects inside copy helper routines */
Blaine Garstcc08af12009-06-10 18:41:48 +0000106BLOCK_EXPORT void _Block_object_assign(void *destAddr, const void *object, const int flags);
Edward O'Callaghan7a6cb5f2009-08-05 19:57:20 +0000107 /* BLOCK_FIELD_IS_BYREF is only used from within block copy helpers */
Blaine Garstcc08af12009-06-10 18:41:48 +0000108
109
Edward O'Callaghan7a6cb5f2009-08-05 19:57:20 +0000110/* runtime entry point called by the compiler when disposing of objects inside dispose helper routine */
Blaine Garstcc08af12009-06-10 18:41:48 +0000111BLOCK_EXPORT void _Block_object_dispose(const void *object, const int flags);
112
113
114
Edward O'Callaghan7a6cb5f2009-08-05 19:57:20 +0000115/* Other support functions */
Blaine Garstcc08af12009-06-10 18:41:48 +0000116
Edward O'Callaghan7a6cb5f2009-08-05 19:57:20 +0000117/* runtime entry to get total size of a closure */
Blaine Garstcc08af12009-06-10 18:41:48 +0000118BLOCK_EXPORT unsigned long int Block_size(void *block_basic);
119
120
121
Edward O'Callaghan7a6cb5f2009-08-05 19:57:20 +0000122/* the raw data space for runtime classes for blocks */
123/* class+meta used for stack, malloc, and collectable based blocks */
Blaine Garstcc08af12009-06-10 18:41:48 +0000124BLOCK_EXPORT void * _NSConcreteStackBlock[32];
125BLOCK_EXPORT void * _NSConcreteMallocBlock[32];
126BLOCK_EXPORT void * _NSConcreteAutoBlock[32];
127BLOCK_EXPORT void * _NSConcreteFinalizingBlock[32];
128BLOCK_EXPORT void * _NSConcreteGlobalBlock[32];
129BLOCK_EXPORT void * _NSConcreteWeakBlockVariable[32];
130
131
Edward O'Callaghan7a6cb5f2009-08-05 19:57:20 +0000132/* the intercept routines that must be used under GC */
Blaine Garstcc08af12009-06-10 18:41:48 +0000133BLOCK_EXPORT void _Block_use_GC( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject),
134 void (*setHasRefcount)(const void *, const bool),
135 void (*gc_assign_strong)(void *, void **),
136 void (*gc_assign_weak)(const void *, void *),
137 void (*gc_memmove)(void *, void *, unsigned long));
138
Edward O'Callaghan7a6cb5f2009-08-05 19:57:20 +0000139/* earlier version, now simply transitional */
Blaine Garstcc08af12009-06-10 18:41:48 +0000140BLOCK_EXPORT void _Block_use_GC5( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject),
141 void (*setHasRefcount)(const void *, const bool),
142 void (*gc_assign_strong)(void *, void **),
143 void (*gc_assign_weak)(const void *, void *));
144
145BLOCK_EXPORT void _Block_use_RR( void (*retain)(const void *),
146 void (*release)(const void *));
147
Edward O'Callaghan7a6cb5f2009-08-05 19:57:20 +0000148/* make a collectable GC heap based Block. Not useful under non-GC. */
Blaine Garstcc08af12009-06-10 18:41:48 +0000149BLOCK_EXPORT void *_Block_copy_collectable(const void *aBlock);
150
Edward O'Callaghan7a6cb5f2009-08-05 19:57:20 +0000151/* thread-unsafe diagnostic */
Blaine Garstcc08af12009-06-10 18:41:48 +0000152BLOCK_EXPORT const char *_Block_dump(const void *block);
153
154
Edward O'Callaghan7a6cb5f2009-08-05 19:57:20 +0000155/* Obsolete */
Blaine Garstcc08af12009-06-10 18:41:48 +0000156
Edward O'Callaghan7a6cb5f2009-08-05 19:57:20 +0000157/* first layout */
Blaine Garstcc08af12009-06-10 18:41:48 +0000158struct Block_basic {
159 void *isa;
Edward O'Callaghan7a6cb5f2009-08-05 19:57:20 +0000160 int Block_flags; /* int32_t */
161 int Block_size; /* XXX should be packed into Block_flags */
Blaine Garstcc08af12009-06-10 18:41:48 +0000162 void (*Block_invoke)(void *);
Edward O'Callaghan7a6cb5f2009-08-05 19:57:20 +0000163 void (*Block_copy)(void *dst, void *src); /* iff BLOCK_HAS_COPY_DISPOSE */
164 void (*Block_dispose)(void *); /* iff BLOCK_HAS_COPY_DISPOSE */
165 /* long params[0]; // where const imports, __block storage references, etc. get laid down */
Blaine Garstcc08af12009-06-10 18:41:48 +0000166};
167
168
169#if __cplusplus
170}
171#endif
172
173
174#endif