2 * Copyright (c) 2009 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
25 #ifndef _OBJC_INTERNAL_H
26 #define _OBJC_INTERNAL_H
29 * WARNING DANGER HAZARD BEWARE EEK
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.
37 * objc-internal.h: Private SPI for use by other system frameworks.
40 #include <objc/objc.h>
41 #include <Availability.h>
42 #include <malloc/malloc.h>
43 #include <dispatch/dispatch.h>
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
)
51 OBJC_EXPORT
void *objc_destructInstance(id obj
)
52 __OSX_AVAILABLE_STARTING(__MAC_10_6
, __IPHONE_3_0
)
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
);
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
);
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
)
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
);
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
);
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
);
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
);
90 // env NSObjCMessageLoggingEnabled
91 OBJC_EXPORT
void instrumentObjcMessageSends(BOOL flag
)
92 __OSX_AVAILABLE_STARTING(__MAC_10_0
, __IPHONE_2_0
);
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
);
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
;
108 // Install missing-class callback. Used by the late unlamented ZeroLink.
109 OBJC_EXPORT
void _objc_setClassLoader(BOOL (*newClassLoader
)(const char *)) OBJC2_UNAVAILABLE
;
111 // This can go away when AppKit stops calling it (rdar://7811851)
113 OBJC_EXPORT
void objc_setMultithreaded (BOOL flag
)
114 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0
,__MAC_10_5
, __IPHONE_NA
,__IPHONE_NA
);
117 // Used by ExceptionHandling.framework
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
);
125 // External Reference support. Used to support compaction.
128 OBJC_XREF_STRONG
= 1,
131 typedef uintptr_t objc_xref_type_t
;
132 typedef uintptr_t objc_xref_t
;
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
);
141 OBJC_EXPORT
uintptr_t _object_getExternalHash(id object
)
142 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
144 // Instance-specific instance variable layout.
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
);
151 OBJC_EXPORT BOOL
_class_usesAutomaticRetainRelease(Class cls
)
152 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
154 // API to only be called by root classes like NSObject or NSProxy
158 _objc_rootRetain(id obj
)
159 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
163 _objc_rootRelease(id obj
)
164 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
168 _objc_rootReleaseWasZero(id obj
)
169 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
173 _objc_rootTryRetain(id obj
)
174 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
178 _objc_rootIsDeallocating(id obj
)
179 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
183 _objc_rootAutorelease(id obj
)
184 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
188 _objc_rootRetainCount(id obj
)
189 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
193 _objc_rootInit(id obj
)
194 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
198 _objc_rootAllocWithZone(Class cls
, malloc_zone_t
*zone
)
199 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
203 _objc_rootAlloc(Class cls
)
204 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
208 _objc_rootDealloc(id obj
)
209 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
213 _objc_rootFinalize(id obj
)
214 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
218 _objc_rootZone(id obj
)
219 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
223 _objc_rootHash(id obj
)
224 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
228 objc_autoreleasePoolPush(void)
229 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
233 objc_autoreleasePoolPop(void *context
)
234 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
237 OBJC_EXPORT id
objc_retain(id obj
)
238 __asm__("_objc_retain")
239 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
241 OBJC_EXPORT
void objc_release(id obj
)
242 __asm__("_objc_release")
243 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
245 OBJC_EXPORT id
objc_autorelease(id obj
)
246 __asm__("_objc_autorelease")
247 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
249 // wraps objc_autorelease(obj) in a useful way when used with return values
252 objc_autoreleaseReturnValue(id obj
)
253 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
255 // wraps objc_autorelease(objc_retain(obj)) in a useful way when used with return values
258 objc_retainAutoreleaseReturnValue(id obj
)
259 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
261 // called ONLY by ARR by callers to undo the autorelease (if possible), otherwise objc_retain
264 objc_retainAutoreleasedReturnValue(id obj
)
265 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
269 objc_storeStrong(id
*location
, id obj
)
270 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
274 objc_retainAutorelease(id obj
)
275 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
278 OBJC_EXPORT id
objc_retain_autorelease(id obj
)
279 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
283 objc_loadWeakRetained(id
*location
)
284 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
288 objc_initWeak(id
*addr
, id val
)
289 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
293 objc_destroyWeak(id
*addr
)
294 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
298 objc_copyWeak(id
*to
, id
*from
)
299 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
303 objc_moveWeak(id
*to
, id
*from
)
304 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
309 _objc_autoreleasePoolPrint(void)
310 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
312 OBJC_EXPORT BOOL
objc_should_deallocate(id object
)
313 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
315 OBJC_EXPORT
void objc_clear_deallocating(id object
)
316 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
319 // to make CF link for now
323 _objc_autoreleasePoolPush(void)
324 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
328 _objc_autoreleasePoolPop(void *context
)
329 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
333 // API to only be called by classes that provide their own reference count storage
337 _objc_deallocOnMainThreadHelper(void *context
)
338 __OSX_AVAILABLE_STARTING(__MAC_10_7
, __IPHONE_5_0
);
340 #define _OBJC_SUPPORTED_INLINE_REFCNT_LOGIC(_rc_ivar, _dealloc2main) \
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); \
346 __builtin_trap(); /* BUG: retain of dealloc'ed ref */ \
350 -(oneway void)release { \
351 __typeof__(_rc_ivar) _prev = __sync_fetch_and_sub(&_rc_ivar, 2); \
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); \
361 __builtin_trap(); /* BUG: dangling ref did a retain */ \
363 } else if (_prev < 0) { \
364 __builtin_trap(); /* BUG: over-release */ \
367 -(NSUInteger)retainCount { \
368 return (_rc_ivar + 2) >> 1; \
370 -(BOOL)_tryRetain { \
371 __typeof__(_rc_ivar) _prev; \
376 } else if (_prev == -2) { \
378 } else if (_prev < -2) { \
379 __builtin_trap(); /* BUG: over-release elsewhere */ \
381 } while ( ! __sync_bool_compare_and_swap(&_rc_ivar, _prev, _prev + 2)); \
384 -(BOOL)_isDeallocating { \
385 if (_rc_ivar == -2) { \
387 } else if (_rc_ivar < -2) { \
388 __builtin_trap(); /* BUG: over-release elsewhere */ \
390 return _rc_ivar & 1; \
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)