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 <objc/runtime.h> 
  42 #include <Availability.h> 
  43 #include <malloc/malloc.h> 
  44 #include <dispatch/dispatch.h> 
  48 // Termination reasons in the OS_REASON_OBJC namespace. 
  49 #define OBJC_EXIT_REASON_UNSPECIFIED 1 
  50 #define OBJC_EXIT_REASON_GC_NOT_SUPPORTED 2 
  52 // This is the allocation size required for each of the class and the metaclass  
  53 // with objc_initializeClassPair() and objc_readClassPair(). 
  54 // The runtime's class structure will never grow beyond this. 
  55 #define OBJC_MAX_CLASS_SIZE (32*sizeof(void*)) 
  57 // In-place construction of an Objective-C class. 
  58 // cls and metacls must each be OBJC_MAX_CLASS_SIZE bytes. 
  59 // Returns nil if a class with the same name already exists. 
  60 // Returns nil if the superclass is under construction. 
  61 // Call objc_registerClassPair() when you are done. 
  62 OBJC_EXPORT Class 
objc_initializeClassPair(Class superclass
, const char *name
, Class cls
, Class metacls
)  
  63     OBJC_AVAILABLE(10.6, 3.0, 9.0, 1.0); 
  65 // Class and metaclass construction from a compiler-generated memory image. 
  66 // cls and cls->isa must each be OBJC_MAX_CLASS_SIZE bytes.  
  67 // Extra bytes not used the the metadata must be zero. 
  68 // info is the same objc_image_info that would be emitted by a static compiler. 
  69 // Returns nil if a class with the same name already exists. 
  70 // Returns nil if the superclass is nil and the class is not marked as a root. 
  71 // Returns nil if the superclass is under construction. 
  72 // Do not call objc_registerClassPair(). 
  74 struct objc_image_info
; 
  75 OBJC_EXPORT Class 
objc_readClassPair(Class cls
,  
  76                                      const struct objc_image_info 
*info
) 
  77     OBJC_AVAILABLE(10.10, 8.0, 9.0, 1.0); 
  80 // Batch object allocation using malloc_zone_batch_malloc(). 
  81 OBJC_EXPORT 
unsigned class_createInstances(Class cls
, size_t extraBytes
,  
  82                                            id 
*results
, unsigned num_requested
) 
  83     OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0) 
  86 // Get the isa pointer written into objects just before being freed. 
  87 OBJC_EXPORT Class 
_objc_getFreedObjectClass(void) 
  88     OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); 
  90 // env NSObjCMessageLoggingEnabled 
  91 OBJC_EXPORT 
void instrumentObjcMessageSends(BOOL flag
) 
  92     OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); 
  94 // Initializer called by libSystem 
  95 OBJC_EXPORT 
void _objc_init(void) 
  97     OBJC_AVAILABLE(10.8, 6.0, 9.0, 1.0); 
  99     OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0); 
 102 // Return YES if GC is on and `object` is a GC allocation. 
 103 OBJC_EXPORT BOOL 
objc_isAuto(id object
)  
 104     __OSX_DEPRECATED(10.4, 10.8, "it always returns NO")  
 105     __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE
; 
 107 // GC startup callback from Foundation 
 108 OBJC_EXPORT malloc_zone_t 
*objc_collect_init(int (*callback
)(void)) 
 109     __OSX_DEPRECATED(10.4, 10.8, "it does nothing")  
 110     __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE
; 
 112 // Plainly-implemented GC barriers. Rosetta used to use these. 
 113 OBJC_EXPORT id 
objc_assign_strongCast_generic(id value
, id 
*dest
) 
 114     UNAVAILABLE_ATTRIBUTE
; 
 115 OBJC_EXPORT id 
objc_assign_global_generic(id value
, id 
*dest
) 
 116     UNAVAILABLE_ATTRIBUTE
; 
 117 OBJC_EXPORT id 
objc_assign_threadlocal_generic(id value
, id 
*dest
) 
 118     UNAVAILABLE_ATTRIBUTE
; 
 119 OBJC_EXPORT id 
objc_assign_ivar_generic(id value
, id dest
, ptrdiff_t offset
) 
 120     UNAVAILABLE_ATTRIBUTE
; 
 122 // GC preflight for an app executable. 
 123 // 1: some slice requires GC 
 124 // 0: no slice requires GC 
 125 // -1: I/O or file format error 
 126 OBJC_EXPORT 
int objc_appRequiresGC(int fd
) 
 127     __OSX_AVAILABLE(10.11)  
 128     __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE
; 
 130 // Install missing-class callback. Used by the late unlamented ZeroLink. 
 131 OBJC_EXPORT 
void _objc_setClassLoader(BOOL (*newClassLoader
)(const char *))  OBJC2_UNAVAILABLE
; 
 133 // Install handler for allocation failures.  
 134 // Handler may abort, or throw, or provide an object to return. 
 135 OBJC_EXPORT 
void _objc_setBadAllocHandler(id (*newHandler
)(Class isa
)) 
 136     OBJC_AVAILABLE(10.8, 6.0, 9.0, 1.0); 
 138 // This can go away when AppKit stops calling it (rdar://7811851) 
 140 OBJC_EXPORT 
void objc_setMultithreaded (BOOL flag
) 
 141     __OSX_DEPRECATED(10.0, 10.5, "multithreading is always available")  
 142     __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE
; 
 145 // Used by ExceptionHandling.framework 
 147 OBJC_EXPORT 
void _objc_error(id rcv
, const char *fmt
, va_list args
) 
 148     __attribute__((noreturn
)) 
 149     __OSX_DEPRECATED(10.0, 10.5, "use other logging facilities instead")  
 150     __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE
; 
 155 // Tagged pointer objects. 
 158 #define OBJC_HAVE_TAGGED_POINTERS 1 
 161 #if OBJC_HAVE_TAGGED_POINTERS 
 163 // Tagged pointer layout and usage is subject to change on different OS versions. 
 165 // Tag indexes 0..<7 have a 60-bit payload. 
 166 // Tag index 7 is reserved. 
 167 // Tag indexes 8..<264 have a 52-bit payload. 
 168 // Tag index 264 is reserved. 
 170 #if __has_feature(objc_fixed_enum)  ||  __cplusplus >= 201103L 
 171 enum objc_tag_index_t 
: uint16_t 
 173 typedef uint16_t objc_tag_index_t
; 
 179     OBJC_TAG_NSString          
= 2,  
 180     OBJC_TAG_NSNumber          
= 3,  
 181     OBJC_TAG_NSIndexPath       
= 4,  
 182     OBJC_TAG_NSManagedObjectID 
= 5,  
 184     OBJC_TAG_RESERVED_7        
= 7,  
 186     OBJC_TAG_First60BitPayload 
= 0,  
 187     OBJC_TAG_Last60BitPayload  
= 6,  
 188     OBJC_TAG_First52BitPayload 
= 8,  
 189     OBJC_TAG_Last52BitPayload  
= 263,  
 191     OBJC_TAG_RESERVED_264      
= 264 
 193 #if __has_feature(objc_fixed_enum)  &&  !defined(__cplusplus) 
 194 typedef enum objc_tag_index_t objc_tag_index_t
; 
 198 // Returns true if tagged pointers are enabled. 
 199 // The other functions below must not be called if tagged pointers are disabled. 
 201 _objc_taggedPointersEnabled(void); 
 203 // Register a class for a tagged pointer tag. 
 204 // Aborts if the tag is invalid or already in use. 
 205 OBJC_EXPORT 
void _objc_registerTaggedPointerClass(objc_tag_index_t tag
, Class cls
) 
 206     OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0); 
 208 // Returns the registered class for the given tag. 
 209 // Returns nil if the tag is valid but has no registered class. 
 210 // Aborts if the tag is invalid. 
 211 OBJC_EXPORT Class 
_objc_getClassForTag(objc_tag_index_t tag
) 
 212     OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0); 
 214 // Create a tagged pointer object with the given tag and payload. 
 215 // Assumes the tag is valid. 
 216 // Assumes tagged pointers are enabled. 
 217 // The payload will be silently truncated to fit. 
 219 _objc_makeTaggedPointer(objc_tag_index_t tag
, uintptr_t payload
); 
 221 // Return true if ptr is a tagged pointer object. 
 222 // Does not check the validity of ptr's class. 
 224 _objc_isTaggedPointer(const void *ptr
); 
 226 // Extract the tag value from the given tagged pointer object. 
 227 // Assumes ptr is a valid tagged pointer object. 
 228 // Does not check the validity of ptr's tag. 
 229 static inline objc_tag_index_t 
 
 230 _objc_getTaggedPointerTag(const void *ptr
); 
 232 // Extract the payload from the given tagged pointer object. 
 233 // Assumes ptr is a valid tagged pointer object. 
 234 // The payload value is zero-extended. 
 235 static inline uintptr_t 
 236 _objc_getTaggedPointerValue(const void *ptr
); 
 238 // Extract the payload from the given tagged pointer object. 
 239 // Assumes ptr is a valid tagged pointer object. 
 240 // The payload value is sign-extended. 
 241 static inline intptr_t 
 242 _objc_getTaggedPointerSignedValue(const void *ptr
); 
 244 // Don't use the values below. Use the declarations above. 
 246 #if TARGET_OS_OSX && __x86_64__ 
 247     // 64-bit Mac - tag bit is LSB 
 248 #   define OBJC_MSB_TAGGED_POINTERS 0 
 250     // Everything else - tag bit is MSB 
 251 #   define OBJC_MSB_TAGGED_POINTERS 1 
 254 #define _OBJC_TAG_INDEX_MASK 0x7 
 255 // array slot includes the tag bit itself 
 256 #define _OBJC_TAG_SLOT_COUNT 16 
 257 #define _OBJC_TAG_SLOT_MASK 0xf 
 259 #define _OBJC_TAG_EXT_INDEX_MASK 0xff 
 260 // array slot has no extra bits 
 261 #define _OBJC_TAG_EXT_SLOT_COUNT 256 
 262 #define _OBJC_TAG_EXT_SLOT_MASK 0xff 
 264 #if OBJC_MSB_TAGGED_POINTERS 
 265 #   define _OBJC_TAG_MASK (1ULL<<63) 
 266 #   define _OBJC_TAG_INDEX_SHIFT 60 
 267 #   define _OBJC_TAG_SLOT_SHIFT 60 
 268 #   define _OBJC_TAG_PAYLOAD_LSHIFT 4 
 269 #   define _OBJC_TAG_PAYLOAD_RSHIFT 4 
 270 #   define _OBJC_TAG_EXT_MASK (0xfULL<<60) 
 271 #   define _OBJC_TAG_EXT_INDEX_SHIFT 52 
 272 #   define _OBJC_TAG_EXT_SLOT_SHIFT 52 
 273 #   define _OBJC_TAG_EXT_PAYLOAD_LSHIFT 12 
 274 #   define _OBJC_TAG_EXT_PAYLOAD_RSHIFT 12 
 276 #   define _OBJC_TAG_MASK 1 
 277 #   define _OBJC_TAG_INDEX_SHIFT 1 
 278 #   define _OBJC_TAG_SLOT_SHIFT 0 
 279 #   define _OBJC_TAG_PAYLOAD_LSHIFT 0 
 280 #   define _OBJC_TAG_PAYLOAD_RSHIFT 4 
 281 #   define _OBJC_TAG_EXT_MASK 0xfULL 
 282 #   define _OBJC_TAG_EXT_INDEX_SHIFT 4 
 283 #   define _OBJC_TAG_EXT_SLOT_SHIFT 4 
 284 #   define _OBJC_TAG_EXT_PAYLOAD_LSHIFT 0 
 285 #   define _OBJC_TAG_EXT_PAYLOAD_RSHIFT 12 
 289 _objc_taggedPointersEnabled(void) 
 291     extern uintptr_t objc_debug_taggedpointer_mask
; 
 292     return (objc_debug_taggedpointer_mask 
!= 0); 
 296 _objc_makeTaggedPointer(objc_tag_index_t tag
, uintptr_t value
) 
 298     // PAYLOAD_LSHIFT and PAYLOAD_RSHIFT are the payload extraction shifts. 
 299     // They are reversed here for payload insertion. 
 301     // assert(_objc_taggedPointersEnabled()); 
 302     if (tag 
<= OBJC_TAG_Last60BitPayload
) { 
 303         // assert(((value << _OBJC_TAG_PAYLOAD_RSHIFT) >> _OBJC_TAG_PAYLOAD_LSHIFT) == value); 
 306              ((uintptr_t)tag 
<< _OBJC_TAG_INDEX_SHIFT
) |  
 307              ((value 
<< _OBJC_TAG_PAYLOAD_RSHIFT
) >> _OBJC_TAG_PAYLOAD_LSHIFT
)); 
 309         // assert(tag >= OBJC_TAG_First52BitPayload); 
 310         // assert(tag <= OBJC_TAG_Last52BitPayload); 
 311         // assert(((value << _OBJC_TAG_EXT_PAYLOAD_RSHIFT) >> _OBJC_TAG_EXT_PAYLOAD_LSHIFT) == value); 
 313             (_OBJC_TAG_EXT_MASK 
| 
 314              ((uintptr_t)(tag 
- OBJC_TAG_First52BitPayload
) << _OBJC_TAG_EXT_INDEX_SHIFT
) | 
 315              ((value 
<< _OBJC_TAG_EXT_PAYLOAD_RSHIFT
) >> _OBJC_TAG_EXT_PAYLOAD_LSHIFT
)); 
 320 _objc_isTaggedPointer(const void *ptr
)  
 322     return ((intptr_t)ptr 
& _OBJC_TAG_MASK
) == _OBJC_TAG_MASK
; 
 325 static inline objc_tag_index_t 
 
 326 _objc_getTaggedPointerTag(const void *ptr
)  
 328     // assert(_objc_isTaggedPointer(ptr)); 
 329     uintptr_t basicTag 
= ((uintptr_t)ptr 
>> _OBJC_TAG_INDEX_SHIFT
) & _OBJC_TAG_INDEX_MASK
; 
 330     uintptr_t extTag 
=   ((uintptr_t)ptr 
>> _OBJC_TAG_EXT_INDEX_SHIFT
) & _OBJC_TAG_EXT_INDEX_MASK
; 
 331     if (basicTag 
== _OBJC_TAG_INDEX_MASK
) { 
 332         return (objc_tag_index_t
)(extTag 
+ OBJC_TAG_First52BitPayload
); 
 334         return (objc_tag_index_t
)basicTag
; 
 338 static inline uintptr_t 
 339 _objc_getTaggedPointerValue(const void *ptr
)  
 341     // assert(_objc_isTaggedPointer(ptr)); 
 342     uintptr_t basicTag 
= ((uintptr_t)ptr 
>> _OBJC_TAG_INDEX_SHIFT
) & _OBJC_TAG_INDEX_MASK
; 
 343     if (basicTag 
== _OBJC_TAG_INDEX_MASK
) { 
 344         return ((uintptr_t)ptr 
<< _OBJC_TAG_EXT_PAYLOAD_LSHIFT
) >> _OBJC_TAG_EXT_PAYLOAD_RSHIFT
; 
 346         return ((uintptr_t)ptr 
<< _OBJC_TAG_PAYLOAD_LSHIFT
) >> _OBJC_TAG_PAYLOAD_RSHIFT
; 
 350 static inline intptr_t 
 351 _objc_getTaggedPointerSignedValue(const void *ptr
)  
 353     // assert(_objc_isTaggedPointer(ptr)); 
 354     uintptr_t basicTag 
= ((uintptr_t)ptr 
>> _OBJC_TAG_INDEX_SHIFT
) & _OBJC_TAG_INDEX_MASK
; 
 355     if (basicTag 
== _OBJC_TAG_INDEX_MASK
) { 
 356         return ((intptr_t)ptr 
<< _OBJC_TAG_EXT_PAYLOAD_LSHIFT
) >> _OBJC_TAG_EXT_PAYLOAD_RSHIFT
; 
 358         return ((intptr_t)ptr 
<< _OBJC_TAG_PAYLOAD_LSHIFT
) >> _OBJC_TAG_PAYLOAD_RSHIFT
; 
 362 // OBJC_HAVE_TAGGED_POINTERS 
 367  * Returns the method implementation of an object. 
 369  * @param obj An Objective-C object. 
 370  * @param name An Objective-C selector. 
 372  * @return The IMP corresponding to the instance method implemented by 
 373  * the class of \e obj. 
 375  * @note Equivalent to: 
 377  * class_getMethodImplementation(object_getClass(obj), name); 
 379 OBJC_EXPORT IMP 
object_getMethodImplementation(id obj
, SEL name
) 
 380     OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0); 
 382 OBJC_EXPORT IMP 
object_getMethodImplementation_stret(id obj
, SEL name
) 
 383     OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0) 
 384     OBJC_ARM64_UNAVAILABLE
; 
 387 // Instance-specific instance variable layout. 
 389 OBJC_EXPORT 
void _class_setIvarLayoutAccessor(Class cls_gen
, const uint8_t* (*accessor
) (id object
)) 
 390     __OSX_AVAILABLE(10.7)  
 391     __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE
; 
 392 OBJC_EXPORT 
const uint8_t *_object_getIvarLayout(Class cls_gen
, id object
) 
 393     __OSX_AVAILABLE(10.7)  
 394     __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE
; 
 397   "Unknown" includes non-object ivars and non-ARC non-__weak ivars 
 398   "Strong" includes ARC __strong ivars 
 399   "Weak" includes ARC and new MRC __weak ivars 
 400   "Unretained" includes ARC __unsafe_unretained and old GC+MRC __weak ivars 
 403     objc_ivar_memoryUnknown
,     // unknown / unknown 
 404     objc_ivar_memoryStrong
,      // direct access / objc_storeStrong 
 405     objc_ivar_memoryWeak
,        // objc_loadWeak[Retained] / objc_storeWeak 
 406     objc_ivar_memoryUnretained   
// direct access / direct access 
 407 } objc_ivar_memory_management_t
; 
 409 OBJC_EXPORT objc_ivar_memory_management_t 
_class_getIvarMemoryManagement(Class cls
, Ivar ivar
) 
 410     OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0); 
 412 OBJC_EXPORT BOOL 
_class_isFutureClass(Class cls
) 
 413     OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0); 
 416 // API to only be called by root classes like NSObject or NSProxy 
 420 _objc_rootRetain(id obj
) 
 421     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 425 _objc_rootRelease(id obj
) 
 426     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 430 _objc_rootReleaseWasZero(id obj
) 
 431     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 435 _objc_rootTryRetain(id obj
) 
 436     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 440 _objc_rootIsDeallocating(id obj
) 
 441     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 445 _objc_rootAutorelease(id obj
) 
 446     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 450 _objc_rootRetainCount(id obj
) 
 451     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 455 _objc_rootInit(id obj
) 
 456     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 460 _objc_rootAllocWithZone(Class cls
, malloc_zone_t 
*zone
) 
 461     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 465 _objc_rootAlloc(Class cls
) 
 466     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 470 _objc_rootDealloc(id obj
) 
 471     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 475 _objc_rootFinalize(id obj
) 
 476     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 480 _objc_rootZone(id obj
) 
 481     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 485 _objc_rootHash(id obj
) 
 486     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 490 objc_autoreleasePoolPush(void) 
 491     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 495 objc_autoreleasePoolPop(void *context
) 
 496     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 499 OBJC_EXPORT id 
objc_alloc(Class cls
) 
 500     OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0); 
 502 OBJC_EXPORT id 
objc_allocWithZone(Class cls
) 
 503     OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0); 
 505 OBJC_EXPORT id 
objc_retain(id obj
) 
 506     __asm__("_objc_retain") 
 507     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 509 OBJC_EXPORT 
void objc_release(id obj
) 
 510     __asm__("_objc_release") 
 511     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 513 OBJC_EXPORT id 
objc_autorelease(id obj
) 
 514     __asm__("_objc_autorelease") 
 515     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 517 // Prepare a value at +1 for return through a +0 autoreleasing convention. 
 520 objc_autoreleaseReturnValue(id obj
) 
 521     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 523 // Prepare a value at +0 for return through a +0 autoreleasing convention. 
 526 objc_retainAutoreleaseReturnValue(id obj
) 
 527     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 529 // Accept a value returned through a +0 autoreleasing convention for use at +1. 
 532 objc_retainAutoreleasedReturnValue(id obj
) 
 533     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 535 // Accept a value returned through a +0 autoreleasing convention for use at +0. 
 538 objc_unsafeClaimAutoreleasedReturnValue(id obj
) 
 539     OBJC_AVAILABLE(10.11, 9.0, 9.0, 1.0); 
 543 objc_storeStrong(id 
*location
, id obj
) 
 544     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 548 objc_retainAutorelease(id obj
) 
 549     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 552 OBJC_EXPORT id 
objc_retain_autorelease(id obj
) 
 553     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 557 objc_loadWeakRetained(id 
*location
) 
 558     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 562 objc_initWeak(id 
*location
, id val
)  
 563     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 565 // Like objc_storeWeak, but stores nil if the new object is deallocating  
 566 // or the new object's class does not support weak references. 
 567 // Returns the value stored (either the new object or nil). 
 570 objc_storeWeakOrNil(id 
*location
, id obj
) 
 571     OBJC_AVAILABLE(10.11, 9.0, 9.0, 1.0); 
 573 // Like objc_initWeak, but stores nil if the new object is deallocating  
 574 // or the new object's class does not support weak references. 
 575 // Returns the value stored (either the new object or nil). 
 578 objc_initWeakOrNil(id 
*location
, id val
)  
 579     OBJC_AVAILABLE(10.11, 9.0, 9.0, 1.0); 
 583 objc_destroyWeak(id 
*location
)  
 584     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 588 objc_copyWeak(id 
*to
, id 
*from
) 
 589     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 593 objc_moveWeak(id 
*to
, id 
*from
)  
 594     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 599 _objc_autoreleasePoolPrint(void) 
 600     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 602 OBJC_EXPORT BOOL 
objc_should_deallocate(id object
) 
 603     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 605 OBJC_EXPORT 
void objc_clear_deallocating(id object
) 
 606     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 609 // to make CF link for now 
 613 _objc_autoreleasePoolPush(void) 
 614     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 618 _objc_autoreleasePoolPop(void *context
) 
 619     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 622 // Extra @encode data for XPC, or NULL 
 623 OBJC_EXPORT 
const char *_protocol_getMethodTypeEncoding(Protocol 
*p
, SEL sel
, BOOL isRequiredMethod
, BOOL isInstanceMethod
) 
 624     OBJC_AVAILABLE(10.8, 6.0, 9.0, 1.0); 
 627 // API to only be called by classes that provide their own reference count storage 
 631 _objc_deallocOnMainThreadHelper(void *context
) 
 632     OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0); 
 634 // On async versus sync deallocation and the _dealloc2main flag 
 638 // If order matters, then code must always: [self dealloc]. 
 639 // If order doesn't matter, then always async should be safe. 
 643 // The _dealloc2main bit is set for GUI objects that may be retained by other 
 644 // threads. Once deallocation begins on the main thread, doing more async 
 645 // deallocation will at best cause extra UI latency and at worst cause 
 646 // use-after-free bugs in unretained delegate style patterns. Yes, this is 
 647 // extremely fragile. Yes, in the long run, developers should switch to weak 
 650 // Note is NOT safe to do any equality check against the result of 
 651 // dispatch_get_current_queue(). The main thread can and does drain more than 
 652 // one dispatch queue. That is why we call pthread_main_np(). 
 656     _OBJC_RESURRECT_OBJECT 
= -1,        /* _logicBlock has called -retain, and scheduled a -release for later. */ 
 657     _OBJC_DEALLOC_OBJECT_NOW 
= 1,       /* call [self dealloc] immediately. */ 
 658     _OBJC_DEALLOC_OBJECT_LATER 
= 2      /* call [self dealloc] on the main queue. */ 
 659 } _objc_object_disposition_t
; 
 661 #define _OBJC_SUPPORTED_INLINE_REFCNT_LOGIC_BLOCK(_rc_ivar, _logicBlock)        \ 
 663         /* this will fail to compile if _rc_ivar is an unsigned type */         \ 
 664         int _retain_count_ivar_must_not_be_unsigned[0L - (__typeof__(_rc_ivar))-1] __attribute__((unused)); \ 
 665         __typeof__(_rc_ivar) _prev = __sync_fetch_and_add(&_rc_ivar, 2);        \ 
 666         if (_prev < -2) { /* specifically allow resurrection from logical 0. */ \ 
 667             __builtin_trap(); /* BUG: retain of over-released ref */            \ 
 671     -(oneway void)release {                                                     \ 
 672         __typeof__(_rc_ivar) _prev = __sync_fetch_and_sub(&_rc_ivar, 2);        \ 
 675         } else if (_prev < 0) {                                                 \ 
 676             __builtin_trap(); /* BUG: over-release */                           \ 
 678         _objc_object_disposition_t fate = _logicBlock(self);                    \ 
 679         if (fate == _OBJC_RESURRECT_OBJECT) {                                   \ 
 682         /* mark the object as deallocating. */                                  \ 
 683         if (!__sync_bool_compare_and_swap(&_rc_ivar, -2, 1)) {                  \ 
 684             __builtin_trap(); /* BUG: dangling ref did a retain */              \ 
 686         if (fate == _OBJC_DEALLOC_OBJECT_NOW) {                                 \ 
 688         } else if (fate == _OBJC_DEALLOC_OBJECT_LATER) {                        \ 
 689             dispatch_barrier_async_f(dispatch_get_main_queue(), self,           \ 
 690                 _objc_deallocOnMainThreadHelper);                               \ 
 692             __builtin_trap(); /* BUG: bogus fate value */                       \ 
 695     -(NSUInteger)retainCount {                                                  \ 
 696         return (_rc_ivar + 2) >> 1;                                             \ 
 698     -(BOOL)_tryRetain {                                                         \ 
 699         __typeof__(_rc_ivar) _prev;                                             \ 
 704             } else if (_prev == -2) {                                           \ 
 706             } else if (_prev < -2) {                                            \ 
 707                 __builtin_trap(); /* BUG: over-release elsewhere */             \ 
 709         } while ( ! __sync_bool_compare_and_swap(&_rc_ivar, _prev, _prev + 2)); \ 
 712     -(BOOL)_isDeallocating {                                                    \ 
 713         if (_rc_ivar == -2) {                                                   \ 
 715         } else if (_rc_ivar < -2) {                                             \ 
 716             __builtin_trap(); /* BUG: over-release elsewhere */                 \ 
 718         return _rc_ivar & 1;                                                    \ 
 721 #define _OBJC_SUPPORTED_INLINE_REFCNT_LOGIC(_rc_ivar, _dealloc2main)            \ 
 722     _OBJC_SUPPORTED_INLINE_REFCNT_LOGIC_BLOCK(_rc_ivar, (^(id _self_ __attribute__((unused))) { \ 
 723         if (_dealloc2main && !pthread_main_np()) {                              \ 
 724             return _OBJC_DEALLOC_OBJECT_LATER;                                  \ 
 726             return _OBJC_DEALLOC_OBJECT_NOW;                                    \ 
 730 #define _OBJC_SUPPORTED_INLINE_REFCNT(_rc_ivar) _OBJC_SUPPORTED_INLINE_REFCNT_LOGIC(_rc_ivar, 0) 
 731 #define _OBJC_SUPPORTED_INLINE_REFCNT_WITH_DEALLOC2MAIN(_rc_ivar) _OBJC_SUPPORTED_INLINE_REFCNT_LOGIC(_rc_ivar, 1)