]> git.saurik.com Git - apple/objc4.git/blob - runtime/objc-internal.h
objc4-493.9.tar.gz
[apple/objc4.git] / runtime / objc-internal.h
1 /*
2 * Copyright (c) 2009 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25 #ifndef _OBJC_INTERNAL_H
26 #define _OBJC_INTERNAL_H
27
28 /*
29 * WARNING DANGER HAZARD BEWARE EEK
30 *
31 * Everything in this file is for Apple Internal use only.
32 * These will change in arbitrary OS updates and in unpredictable ways.
33 * When your program breaks, you get to keep both pieces.
34 */
35
36 /*
37 * objc-internal.h: Private SPI for use by other system frameworks.
38 */
39
40 #include <objc/objc.h>
41 #include <Availability.h>
42 #include <malloc/malloc.h>
43 #include <dispatch/dispatch.h>
44
45 __BEGIN_DECLS
46
47 // In-place construction of an Objective-C instance.
48 OBJC_EXPORT id objc_constructInstance(Class cls, void *bytes)
49 __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0)
50 OBJC_ARC_UNAVAILABLE;
51 OBJC_EXPORT void *objc_destructInstance(id obj)
52 __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0)
53 OBJC_ARC_UNAVAILABLE;
54
55 // In-place construction of an Objective-C class.
56 OBJC_EXPORT Class objc_initializeClassPair(Class superclass_gen, const char *name, Class cls_gen, Class meta_gen)
57 __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0);
58
59 #if __OBJC2__ && __LP64__
60 // Register a tagged pointer class.
61 OBJC_EXPORT void _objc_insert_tagged_isa(unsigned char slotNumber, Class isa)
62 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
63 #endif
64
65 // Batch object allocation using malloc_zone_batch_malloc().
66 OBJC_EXPORT unsigned class_createInstances(Class cls, size_t extraBytes,
67 id *results, unsigned num_requested)
68 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3)
69 OBJC_ARC_UNAVAILABLE;
70
71 // Get the isa pointer written into objects just before being freed.
72 OBJC_EXPORT Class _objc_getFreedObjectClass(void)
73 __OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
74
75 // Substitute receiver for messages to nil.
76 // Not supported for all messages to nil.
77 OBJC_EXPORT id _objc_setNilReceiver(id newNilReceiver)
78 __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_NA);
79 OBJC_EXPORT id _objc_getNilReceiver(void)
80 __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_NA);
81
82 // Return NO if no instance of `cls` has ever owned an associative reference.
83 OBJC_EXPORT BOOL class_instancesHaveAssociatedObjects(Class cls)
84 __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0);
85
86 // Return YES if GC is on and `object` is a GC allocation.
87 OBJC_EXPORT BOOL objc_isAuto(id object)
88 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_NA);
89
90 // env NSObjCMessageLoggingEnabled
91 OBJC_EXPORT void instrumentObjcMessageSends(BOOL flag)
92 __OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
93
94 // GC startup callback from Foundation
95 OBJC_EXPORT malloc_zone_t *objc_collect_init(int (*callback)(void))
96 __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_NA);
97
98 // Plainly-implemented GC barriers. Rosetta used to use these.
99 OBJC_EXPORT id objc_assign_strongCast_generic(id value, id *dest)
100 UNAVAILABLE_ATTRIBUTE;
101 OBJC_EXPORT id objc_assign_global_generic(id value, id *dest)
102 UNAVAILABLE_ATTRIBUTE;
103 OBJC_EXPORT id objc_assign_threadlocal_generic(id value, id *dest)
104 UNAVAILABLE_ATTRIBUTE;
105 OBJC_EXPORT id objc_assign_ivar_generic(id value, id dest, ptrdiff_t offset)
106 UNAVAILABLE_ATTRIBUTE;
107
108 // Install missing-class callback. Used by the late unlamented ZeroLink.
109 OBJC_EXPORT void _objc_setClassLoader(BOOL (*newClassLoader)(const char *)) OBJC2_UNAVAILABLE;
110
111 // This can go away when AppKit stops calling it (rdar://7811851)
112 #if __OBJC2__
113 OBJC_EXPORT void objc_setMultithreaded (BOOL flag)
114 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0,__MAC_10_5, __IPHONE_NA,__IPHONE_NA);
115 #endif
116
117 // Used by ExceptionHandling.framework
118 #if !__OBJC2__
119 OBJC_EXPORT void _objc_error(id rcv, const char *fmt, va_list args)
120 __attribute__((noreturn))
121 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0,__MAC_10_5, __IPHONE_NA,__IPHONE_NA);
122
123 #endif
124
125 // External Reference support. Used to support compaction.
126
127 enum {
128 OBJC_XREF_STRONG = 1,
129 OBJC_XREF_WEAK = 2
130 };
131 typedef uintptr_t objc_xref_type_t;
132 typedef uintptr_t objc_xref_t;
133
134 OBJC_EXPORT objc_xref_t _object_addExternalReference(id object, objc_xref_type_t type)
135 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
136 OBJC_EXPORT void _object_removeExternalReference(objc_xref_t xref)
137 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
138 OBJC_EXPORT id _object_readExternalReference(objc_xref_t xref)
139 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
140
141 OBJC_EXPORT uintptr_t _object_getExternalHash(id object)
142 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
143
144 // Instance-specific instance variable layout.
145
146 OBJC_EXPORT void _class_setIvarLayoutAccessor(Class cls_gen, const uint8_t* (*accessor) (id object))
147 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
148 OBJC_EXPORT const uint8_t *_object_getIvarLayout(Class cls_gen, id object)
149 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
150
151 OBJC_EXPORT BOOL _class_usesAutomaticRetainRelease(Class cls)
152 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
153
154 // API to only be called by root classes like NSObject or NSProxy
155
156 OBJC_EXPORT
157 id
158 _objc_rootRetain(id obj)
159 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
160
161 OBJC_EXPORT
162 void
163 _objc_rootRelease(id obj)
164 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
165
166 OBJC_EXPORT
167 bool
168 _objc_rootReleaseWasZero(id obj)
169 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
170
171 OBJC_EXPORT
172 bool
173 _objc_rootTryRetain(id obj)
174 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
175
176 OBJC_EXPORT
177 bool
178 _objc_rootIsDeallocating(id obj)
179 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
180
181 OBJC_EXPORT
182 id
183 _objc_rootAutorelease(id obj)
184 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
185
186 OBJC_EXPORT
187 uintptr_t
188 _objc_rootRetainCount(id obj)
189 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
190
191 OBJC_EXPORT
192 id
193 _objc_rootInit(id obj)
194 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
195
196 OBJC_EXPORT
197 id
198 _objc_rootAllocWithZone(Class cls, malloc_zone_t *zone)
199 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
200
201 OBJC_EXPORT
202 id
203 _objc_rootAlloc(Class cls)
204 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
205
206 OBJC_EXPORT
207 void
208 _objc_rootDealloc(id obj)
209 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
210
211 OBJC_EXPORT
212 void
213 _objc_rootFinalize(id obj)
214 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
215
216 OBJC_EXPORT
217 malloc_zone_t *
218 _objc_rootZone(id obj)
219 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
220
221 OBJC_EXPORT
222 uintptr_t
223 _objc_rootHash(id obj)
224 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
225
226 OBJC_EXPORT
227 void *
228 objc_autoreleasePoolPush(void)
229 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
230
231 OBJC_EXPORT
232 void
233 objc_autoreleasePoolPop(void *context)
234 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
235
236
237 OBJC_EXPORT id objc_retain(id obj)
238 __asm__("_objc_retain")
239 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
240
241 OBJC_EXPORT void objc_release(id obj)
242 __asm__("_objc_release")
243 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
244
245 OBJC_EXPORT id objc_autorelease(id obj)
246 __asm__("_objc_autorelease")
247 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
248
249 // wraps objc_autorelease(obj) in a useful way when used with return values
250 OBJC_EXPORT
251 id
252 objc_autoreleaseReturnValue(id obj)
253 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
254
255 // wraps objc_autorelease(objc_retain(obj)) in a useful way when used with return values
256 OBJC_EXPORT
257 id
258 objc_retainAutoreleaseReturnValue(id obj)
259 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
260
261 // called ONLY by ARR by callers to undo the autorelease (if possible), otherwise objc_retain
262 OBJC_EXPORT
263 id
264 objc_retainAutoreleasedReturnValue(id obj)
265 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
266
267 OBJC_EXPORT
268 void
269 objc_storeStrong(id *location, id obj)
270 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
271
272 OBJC_EXPORT
273 id
274 objc_retainAutorelease(id obj)
275 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
276
277 // obsolete.
278 OBJC_EXPORT id objc_retain_autorelease(id obj)
279 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
280
281 OBJC_EXPORT
282 id
283 objc_loadWeakRetained(id *location)
284 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
285
286 OBJC_EXPORT
287 id
288 objc_initWeak(id *addr, id val)
289 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
290
291 OBJC_EXPORT
292 void
293 objc_destroyWeak(id *addr)
294 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
295
296 OBJC_EXPORT
297 void
298 objc_copyWeak(id *to, id *from)
299 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
300
301 OBJC_EXPORT
302 void
303 objc_moveWeak(id *to, id *from)
304 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
305
306
307 OBJC_EXPORT
308 void
309 _objc_autoreleasePoolPrint(void)
310 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
311
312 OBJC_EXPORT BOOL objc_should_deallocate(id object)
313 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
314
315 OBJC_EXPORT void objc_clear_deallocating(id object)
316 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
317
318
319 // to make CF link for now
320
321 OBJC_EXPORT
322 void *
323 _objc_autoreleasePoolPush(void)
324 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
325
326 OBJC_EXPORT
327 void
328 _objc_autoreleasePoolPop(void *context)
329 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
330
331
332
333 // API to only be called by classes that provide their own reference count storage
334
335 OBJC_EXPORT
336 void
337 _objc_deallocOnMainThreadHelper(void *context)
338 __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
339
340 #define _OBJC_SUPPORTED_INLINE_REFCNT_LOGIC(_rc_ivar, _dealloc2main) \
341 -(id)retain { \
342 /* this will fail to compile if _rc_ivar is an unsigned type */ \
343 int _retain_count_ivar_must_not_be_unsigned[0L - (__typeof__(_rc_ivar))-1] __attribute__((unused)); \
344 __typeof__(_rc_ivar) _prev = __sync_fetch_and_add(&_rc_ivar, 2); \
345 if (_prev < 0) { \
346 __builtin_trap(); /* BUG: retain of dealloc'ed ref */ \
347 } \
348 return self; \
349 } \
350 -(oneway void)release { \
351 __typeof__(_rc_ivar) _prev = __sync_fetch_and_sub(&_rc_ivar, 2); \
352 if (_prev == 0) { \
353 if (__sync_bool_compare_and_swap(&_rc_ivar, -2, 1)) { \
354 if (_dealloc2main) { \
355 dispatch_barrier_async_f(dispatch_get_main_queue(), \
356 self, _objc_deallocOnMainThreadHelper); \
357 } else { \
358 [self dealloc]; \
359 } \
360 } else { \
361 __builtin_trap(); /* BUG: dangling ref did a retain */ \
362 } \
363 } else if (_prev < 0) { \
364 __builtin_trap(); /* BUG: over-release */ \
365 } \
366 } \
367 -(NSUInteger)retainCount { \
368 return (_rc_ivar + 2) >> 1; \
369 } \
370 -(BOOL)_tryRetain { \
371 __typeof__(_rc_ivar) _prev; \
372 do { \
373 _prev = _rc_ivar; \
374 if (_prev & 1) { \
375 return 0; \
376 } else if (_prev == -2) { \
377 return 0; \
378 } else if (_prev < -2) { \
379 __builtin_trap(); /* BUG: over-release elsewhere */ \
380 } \
381 } while ( ! __sync_bool_compare_and_swap(&_rc_ivar, _prev, _prev + 2)); \
382 return 1; \
383 } \
384 -(BOOL)_isDeallocating { \
385 if (_rc_ivar == -2) { \
386 return 1; \
387 } else if (_rc_ivar < -2) { \
388 __builtin_trap(); /* BUG: over-release elsewhere */ \
389 } \
390 return _rc_ivar & 1; \
391 }
392
393 #define _OBJC_SUPPORTED_INLINE_REFCNT(_rc_ivar) _OBJC_SUPPORTED_INLINE_REFCNT_LOGIC(_rc_ivar, 0)
394 #define _OBJC_SUPPORTED_INLINE_REFCNT_WITH_DEALLOC2MAIN(_rc_ivar) _OBJC_SUPPORTED_INLINE_REFCNT_LOGIC(_rc_ivar, 1)
395
396 __END_DECLS
397
398 #endif