#ifndef _OBJC_INTERNAL_H
#define _OBJC_INTERNAL_H
#include <objc/objc.h>
#include <objc/runtime.h>
#include <Availability.h>
#include <malloc/malloc.h>
#include <mach-o/loader.h>
#include <dispatch/dispatch.h>
#if __OBJC__
#include <objc/NSObject.h>
#endif
#define OBJC_EXIT_REASON_UNSPECIFIED 1
#define OBJC_EXIT_REASON_GC_NOT_SUPPORTED 2
#define OBJC_MAX_CLASS_SIZE (32*sizeof(void*))
#define _OBJC_ASSOCIATION_SYSTEM_OBJECT (1 << 16)
__BEGIN_DECLS
#if defined(OBJC_IS_DEBUG_BUILD)
OBJC_EXPORT void _objc_isDebugBuild(void);
#endif
OBJC_EXPORT Class _Nullable
objc_initializeClassPair(Class _Nullable superclass, const char * _Nonnull name,
Class _Nonnull cls, Class _Nonnull metacls)
OBJC_AVAILABLE(10.6, 3.0, 9.0, 1.0, 2.0);
#if __OBJC2__
struct objc_image_info;
OBJC_EXPORT Class _Nullable
objc_readClassPair(Class _Nonnull cls,
const struct objc_image_info * _Nonnull info)
OBJC_AVAILABLE(10.10, 8.0, 9.0, 1.0, 2.0);
#endif
OBJC_EXPORT unsigned
class_createInstances(Class _Nullable cls, size_t extraBytes,
id _Nonnull * _Nonnull results, unsigned num_requested)
OBJC_AVAILABLE(10.7, 4.3, 9.0, 1.0, 2.0)
OBJC_ARC_UNAVAILABLE;
OBJC_EXPORT Class _Nonnull
_objc_getFreedObjectClass(void)
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);
OBJC_EXPORT void
instrumentObjcMessageSends(BOOL flag)
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);
OBJC_EXPORT void
_objc_init(void)
#if __OBJC2__
OBJC_AVAILABLE(10.8, 6.0, 9.0, 1.0, 2.0);
#else
OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0);
#endif
OBJC_EXPORT void
_objc_atfork_prepare(void)
OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0);
OBJC_EXPORT void
_objc_atfork_parent(void)
OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0);
OBJC_EXPORT void
_objc_atfork_child(void)
OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0);
OBJC_EXPORT BOOL
objc_isAuto(id _Nullable object)
OBJC_OSX_DEPRECATED_OTHERS_UNAVAILABLE(10.4, 10.8, "it always returns NO");
OBJC_EXPORT BOOL
objc_dumpHeap(char * _Nonnull filename, unsigned long length)
OBJC_OSX_DEPRECATED_OTHERS_UNAVAILABLE(10.4, 10.8, "it always returns NO");
OBJC_EXPORT malloc_zone_t * _Nullable
objc_collect_init(int (* _Nonnull callback)(void))
OBJC_OSX_DEPRECATED_OTHERS_UNAVAILABLE(10.4, 10.8, "it does nothing");
#if __OBJC2__
OBJC_EXPORT
Class _Nonnull * _Nullable
objc_copyRealizedClassList(unsigned int *_Nullable outCount)
OBJC_AVAILABLE(10.15, 13.0, 13.0, 6.0, 5.0);
typedef struct objc_imp_cache_entry {
SEL _Nonnull sel;
IMP _Nonnull imp;
} objc_imp_cache_entry;
OBJC_EXPORT
objc_imp_cache_entry *_Nullable
class_copyImpCache(Class _Nonnull cls, int * _Nullable outCount)
OBJC_AVAILABLE(10.15, 13.0, 13.0, 6.0, 5.0);
OBJC_EXPORT
unsigned long
sel_hash(SEL _Nullable sel)
OBJC_AVAILABLE(10.16, 14.0, 14.0, 7.0, 6.0);
#endif
OBJC_EXPORT id _Nullable
objc_assign_strongCast_generic(id _Nullable value, id _Nullable * _Nonnull dest)
UNAVAILABLE_ATTRIBUTE;
OBJC_EXPORT id _Nullable
objc_assign_global_generic(id _Nullable value, id _Nullable * _Nonnull dest)
UNAVAILABLE_ATTRIBUTE;
OBJC_EXPORT id _Nullable
objc_assign_threadlocal_generic(id _Nullable value,
id _Nullable * _Nonnull dest)
UNAVAILABLE_ATTRIBUTE;
OBJC_EXPORT id _Nullable
objc_assign_ivar_generic(id _Nullable value, id _Nonnull dest, ptrdiff_t offset)
UNAVAILABLE_ATTRIBUTE;
OBJC_EXPORT int
objc_appRequiresGC(int fd)
__OSX_AVAILABLE(10.11)
__IOS_UNAVAILABLE __TVOS_UNAVAILABLE
__WATCHOS_UNAVAILABLE
#ifndef __APPLE_BLEACH_SDK__
__BRIDGEOS_UNAVAILABLE
#endif
;
OBJC_EXPORT void
_objc_setClassLoader(BOOL (* _Nonnull newClassLoader)(const char * _Nonnull))
OBJC2_UNAVAILABLE;
#if !(TARGET_OS_OSX && !TARGET_OS_MACCATALYST && __i386__)
OBJC_EXPORT void
_objc_setClassCopyFixupHandler(void (* _Nonnull newFixupHandler)
(Class _Nonnull oldClass, Class _Nonnull newClass))
OBJC_AVAILABLE(10.14, 12.0, 12.0, 5.0, 3.0);
#endif
OBJC_EXPORT void
_objc_setBadAllocHandler(id _Nullable (* _Nonnull newHandler)
(Class _Nullable isa))
OBJC_AVAILABLE(10.8, 6.0, 9.0, 1.0, 2.0);
#if !__OBJC2__
OBJC_EXPORT void
_objc_error(id _Nullable rcv, const char * _Nonnull fmt, va_list args)
__attribute__((noreturn, cold))
OBJC_OSX_DEPRECATED_OTHERS_UNAVAILABLE(10.0, 10.5, "use other logging facilities instead");
#endif
OBJC_EXPORT const char * _Nonnull * _Nullable
objc_copyClassNamesForImageHeader(const struct mach_header * _Nonnull mh,
unsigned int * _Nullable outCount)
OBJC_AVAILABLE(10.14, 12.0, 12.0, 5.0, 3.0);
OBJC_EXPORT Class _Nonnull * _Nullable
objc_copyClassesForImage(const char * _Nonnull image,
unsigned int * _Nullable outCount)
OBJC_AVAILABLE(10.16, 14.0, 14.0, 7.0, 4.0);
#if __LP64__
#define OBJC_HAVE_TAGGED_POINTERS 1
#endif
#if OBJC_HAVE_TAGGED_POINTERS
#if __has_feature(objc_fixed_enum) || __cplusplus >= 201103L
enum objc_tag_index_t : uint16_t
#else
typedef uint16_t objc_tag_index_t;
enum
#endif
{
OBJC_TAG_NSAtom = 0,
OBJC_TAG_1 = 1,
OBJC_TAG_NSString = 2,
OBJC_TAG_NSNumber = 3,
OBJC_TAG_NSIndexPath = 4,
OBJC_TAG_NSManagedObjectID = 5,
OBJC_TAG_NSDate = 6,
OBJC_TAG_RESERVED_7 = 7,
OBJC_TAG_Photos_1 = 8,
OBJC_TAG_Photos_2 = 9,
OBJC_TAG_Photos_3 = 10,
OBJC_TAG_Photos_4 = 11,
OBJC_TAG_XPC_1 = 12,
OBJC_TAG_XPC_2 = 13,
OBJC_TAG_XPC_3 = 14,
OBJC_TAG_XPC_4 = 15,
OBJC_TAG_NSColor = 16,
OBJC_TAG_UIColor = 17,
OBJC_TAG_CGColor = 18,
OBJC_TAG_NSIndexSet = 19,
OBJC_TAG_NSMethodSignature = 20,
OBJC_TAG_UTTypeRecord = 21,
OBJC_TAG_FirstUnobfuscatedSplitTag = 136,
OBJC_TAG_Constant_CFString = 136,
OBJC_TAG_First60BitPayload = 0,
OBJC_TAG_Last60BitPayload = 6,
OBJC_TAG_First52BitPayload = 8,
OBJC_TAG_Last52BitPayload = 263,
OBJC_TAG_RESERVED_264 = 264
};
#if __has_feature(objc_fixed_enum) && !defined(__cplusplus)
typedef enum objc_tag_index_t objc_tag_index_t;
#endif
static inline bool
_objc_taggedPointersEnabled(void);
OBJC_EXPORT void
_objc_registerTaggedPointerClass(objc_tag_index_t tag, Class _Nonnull cls)
OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0);
OBJC_EXPORT Class _Nullable
_objc_getClassForTag(objc_tag_index_t tag)
OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0);
static inline void * _Nonnull
_objc_makeTaggedPointer(objc_tag_index_t tag, uintptr_t payload);
static inline bool
_objc_isTaggedPointer(const void * _Nullable ptr);
static inline objc_tag_index_t
_objc_getTaggedPointerTag(const void * _Nullable ptr);
static inline uintptr_t
_objc_getTaggedPointerValue(const void * _Nullable ptr);
static inline intptr_t
_objc_getTaggedPointerSignedValue(const void * _Nullable ptr);
#if __arm64__
# define OBJC_SPLIT_TAGGED_POINTERS 1
#else
# define OBJC_SPLIT_TAGGED_POINTERS 0
#endif
#if (TARGET_OS_OSX || TARGET_OS_MACCATALYST) && __x86_64__
# define OBJC_MSB_TAGGED_POINTERS 0
#else
# define OBJC_MSB_TAGGED_POINTERS 1
#endif
#define _OBJC_TAG_INDEX_MASK 0x7UL
#if OBJC_SPLIT_TAGGED_POINTERS
#define _OBJC_TAG_SLOT_COUNT 8
#define _OBJC_TAG_SLOT_MASK 0x7UL
#else
#define _OBJC_TAG_SLOT_COUNT 16
#define _OBJC_TAG_SLOT_MASK 0xfUL
#endif
#define _OBJC_TAG_EXT_INDEX_MASK 0xff
#define _OBJC_TAG_EXT_SLOT_COUNT 256
#define _OBJC_TAG_EXT_SLOT_MASK 0xff
#if OBJC_SPLIT_TAGGED_POINTERS
# define _OBJC_TAG_MASK (1UL<<63)
# define _OBJC_TAG_INDEX_SHIFT 0
# define _OBJC_TAG_SLOT_SHIFT 0
# define _OBJC_TAG_PAYLOAD_LSHIFT 1
# define _OBJC_TAG_PAYLOAD_RSHIFT 4
# define _OBJC_TAG_EXT_MASK (_OBJC_TAG_MASK | 0x7UL)
# define _OBJC_TAG_NO_OBFUSCATION_MASK ((1UL<<62) | _OBJC_TAG_EXT_MASK)
# define _OBJC_TAG_CONSTANT_POINTER_MASK \
~(_OBJC_TAG_EXT_MASK | ((uintptr_t)_OBJC_TAG_EXT_SLOT_MASK << _OBJC_TAG_EXT_SLOT_SHIFT))
# define _OBJC_TAG_EXT_INDEX_SHIFT 55
# define _OBJC_TAG_EXT_SLOT_SHIFT 55
# define _OBJC_TAG_EXT_PAYLOAD_LSHIFT 9
# define _OBJC_TAG_EXT_PAYLOAD_RSHIFT 12
#elif OBJC_MSB_TAGGED_POINTERS
# define _OBJC_TAG_MASK (1UL<<63)
# define _OBJC_TAG_INDEX_SHIFT 60
# define _OBJC_TAG_SLOT_SHIFT 60
# define _OBJC_TAG_PAYLOAD_LSHIFT 4
# define _OBJC_TAG_PAYLOAD_RSHIFT 4
# define _OBJC_TAG_EXT_MASK (0xfUL<<60)
# define _OBJC_TAG_EXT_INDEX_SHIFT 52
# define _OBJC_TAG_EXT_SLOT_SHIFT 52
# define _OBJC_TAG_EXT_PAYLOAD_LSHIFT 12
# define _OBJC_TAG_EXT_PAYLOAD_RSHIFT 12
#else
# define _OBJC_TAG_MASK 1UL
# define _OBJC_TAG_INDEX_SHIFT 1
# define _OBJC_TAG_SLOT_SHIFT 0
# define _OBJC_TAG_PAYLOAD_LSHIFT 0
# define _OBJC_TAG_PAYLOAD_RSHIFT 4
# define _OBJC_TAG_EXT_MASK 0xfUL
# define _OBJC_TAG_EXT_INDEX_SHIFT 4
# define _OBJC_TAG_EXT_SLOT_SHIFT 4
# define _OBJC_TAG_EXT_PAYLOAD_LSHIFT 0
# define _OBJC_TAG_EXT_PAYLOAD_RSHIFT 12
#endif
extern uintptr_t objc_debug_taggedpointer_obfuscator;
#if OBJC_SPLIT_TAGGED_POINTERS
extern uint8_t objc_debug_tag60_permutations[8];
static inline uintptr_t _objc_basicTagToObfuscatedTag(uintptr_t tag) {
return objc_debug_tag60_permutations[tag];
}
static inline uintptr_t _objc_obfuscatedTagToBasicTag(uintptr_t tag) {
for (unsigned i = 0; i < 7; i++)
if (objc_debug_tag60_permutations[i] == tag)
return i;
return 7;
}
#endif
static inline void * _Nonnull
_objc_encodeTaggedPointer(uintptr_t ptr)
{
uintptr_t value = (objc_debug_taggedpointer_obfuscator ^ ptr);
#if OBJC_SPLIT_TAGGED_POINTERS
if ((value & _OBJC_TAG_NO_OBFUSCATION_MASK) == _OBJC_TAG_NO_OBFUSCATION_MASK)
return (void *)ptr;
uintptr_t basicTag = (value >> _OBJC_TAG_INDEX_SHIFT) & _OBJC_TAG_INDEX_MASK;
uintptr_t permutedTag = _objc_basicTagToObfuscatedTag(basicTag);
value &= ~(_OBJC_TAG_INDEX_MASK << _OBJC_TAG_INDEX_SHIFT);
value |= permutedTag << _OBJC_TAG_INDEX_SHIFT;
#endif
return (void *)value;
}
static inline uintptr_t
_objc_decodeTaggedPointer_noPermute(const void * _Nullable ptr)
{
uintptr_t value = (uintptr_t)ptr;
#if OBJC_SPLIT_TAGGED_POINTERS
if ((value & _OBJC_TAG_NO_OBFUSCATION_MASK) == _OBJC_TAG_NO_OBFUSCATION_MASK)
return value;
#endif
return value ^ objc_debug_taggedpointer_obfuscator;
}
static inline uintptr_t
_objc_decodeTaggedPointer(const void * _Nullable ptr)
{
uintptr_t value = _objc_decodeTaggedPointer_noPermute(ptr);
#if OBJC_SPLIT_TAGGED_POINTERS
uintptr_t basicTag = (value >> _OBJC_TAG_INDEX_SHIFT) & _OBJC_TAG_INDEX_MASK;
value &= ~(_OBJC_TAG_INDEX_MASK << _OBJC_TAG_INDEX_SHIFT);
value |= _objc_obfuscatedTagToBasicTag(basicTag) << _OBJC_TAG_INDEX_SHIFT;
#endif
return value;
}
static inline bool
_objc_taggedPointersEnabled(void)
{
extern uintptr_t objc_debug_taggedpointer_mask;
return (objc_debug_taggedpointer_mask != 0);
}
static inline void * _Nonnull
_objc_makeTaggedPointer(objc_tag_index_t tag, uintptr_t value)
{
if (tag <= OBJC_TAG_Last60BitPayload) {
uintptr_t result =
(_OBJC_TAG_MASK |
((uintptr_t)tag << _OBJC_TAG_INDEX_SHIFT) |
((value << _OBJC_TAG_PAYLOAD_RSHIFT) >> _OBJC_TAG_PAYLOAD_LSHIFT));
return _objc_encodeTaggedPointer(result);
} else {
uintptr_t result =
(_OBJC_TAG_EXT_MASK |
((uintptr_t)(tag - OBJC_TAG_First52BitPayload) << _OBJC_TAG_EXT_INDEX_SHIFT) |
((value << _OBJC_TAG_EXT_PAYLOAD_RSHIFT) >> _OBJC_TAG_EXT_PAYLOAD_LSHIFT));
return _objc_encodeTaggedPointer(result);
}
}
static inline bool
_objc_isTaggedPointer(const void * _Nullable ptr)
{
return ((uintptr_t)ptr & _OBJC_TAG_MASK) == _OBJC_TAG_MASK;
}
static inline bool
_objc_isTaggedPointerOrNil(const void * _Nullable ptr)
{
return !ptr || ((uintptr_t)ptr & _OBJC_TAG_MASK) == _OBJC_TAG_MASK;
}
static inline objc_tag_index_t
_objc_getTaggedPointerTag(const void * _Nullable ptr)
{
uintptr_t value = _objc_decodeTaggedPointer(ptr);
uintptr_t basicTag = (value >> _OBJC_TAG_INDEX_SHIFT) & _OBJC_TAG_INDEX_MASK;
uintptr_t extTag = (value >> _OBJC_TAG_EXT_INDEX_SHIFT) & _OBJC_TAG_EXT_INDEX_MASK;
if (basicTag == _OBJC_TAG_INDEX_MASK) {
return (objc_tag_index_t)(extTag + OBJC_TAG_First52BitPayload);
} else {
return (objc_tag_index_t)basicTag;
}
}
static inline uintptr_t
_objc_getTaggedPointerValue(const void * _Nullable ptr)
{
uintptr_t value = _objc_decodeTaggedPointer_noPermute(ptr);
uintptr_t basicTag = (value >> _OBJC_TAG_INDEX_SHIFT) & _OBJC_TAG_INDEX_MASK;
if (basicTag == _OBJC_TAG_INDEX_MASK) {
return (value << _OBJC_TAG_EXT_PAYLOAD_LSHIFT) >> _OBJC_TAG_EXT_PAYLOAD_RSHIFT;
} else {
return (value << _OBJC_TAG_PAYLOAD_LSHIFT) >> _OBJC_TAG_PAYLOAD_RSHIFT;
}
}
static inline intptr_t
_objc_getTaggedPointerSignedValue(const void * _Nullable ptr)
{
uintptr_t value = _objc_decodeTaggedPointer_noPermute(ptr);
uintptr_t basicTag = (value >> _OBJC_TAG_INDEX_SHIFT) & _OBJC_TAG_INDEX_MASK;
if (basicTag == _OBJC_TAG_INDEX_MASK) {
return ((intptr_t)value << _OBJC_TAG_EXT_PAYLOAD_LSHIFT) >> _OBJC_TAG_EXT_PAYLOAD_RSHIFT;
} else {
return ((intptr_t)value << _OBJC_TAG_PAYLOAD_LSHIFT) >> _OBJC_TAG_PAYLOAD_RSHIFT;
}
}
# if OBJC_SPLIT_TAGGED_POINTERS
static inline void * _Nullable
_objc_getTaggedPointerRawPointerValue(const void * _Nullable ptr) {
return (void *)((uintptr_t)ptr & _OBJC_TAG_CONSTANT_POINTER_MASK);
}
# endif
#endif
OBJC_EXPORT IMP _Nonnull
object_getMethodImplementation(id _Nullable obj, SEL _Nonnull name)
OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0);
OBJC_EXPORT IMP _Nonnull
object_getMethodImplementation_stret(id _Nullable obj, SEL _Nonnull name)
OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0)
OBJC_ARM64_UNAVAILABLE;
#if __OBJC2__
OBJC_EXPORT _Nullable SEL * _Nullable
class_addMethodsBulk(_Nullable Class cls, _Nonnull const SEL * _Nonnull names,
_Nonnull const IMP * _Nonnull imps,
const char * _Nonnull * _Nonnull types, uint32_t count,
uint32_t * _Nullable outFailedCount)
OBJC_AVAILABLE(10.14, 12.0, 12.0, 5.0, 3.0);
#endif
#if __OBJC2__
OBJC_EXPORT void
class_replaceMethodsBulk(_Nullable Class cls,
_Nonnull const SEL * _Nonnull names,
_Nonnull const IMP * _Nonnull imps,
const char * _Nonnull * _Nonnull types,
uint32_t count)
OBJC_AVAILABLE(10.14, 12.0, 12.0, 5.0, 3.0);
#endif
OBJC_EXPORT void
_class_setIvarLayoutAccessor(Class _Nullable cls,
const uint8_t* _Nullable (* _Nonnull accessor)
(id _Nullable object))
UNAVAILABLE_ATTRIBUTE;
OBJC_EXPORT const uint8_t * _Nullable
_object_getIvarLayout(Class _Nullable cls, id _Nullable object)
UNAVAILABLE_ATTRIBUTE;
typedef enum {
objc_ivar_memoryUnknown, objc_ivar_memoryStrong, objc_ivar_memoryWeak, objc_ivar_memoryUnretained } objc_ivar_memory_management_t;
OBJC_EXPORT objc_ivar_memory_management_t
_class_getIvarMemoryManagement(Class _Nullable cls, Ivar _Nonnull ivar)
OBJC_AVAILABLE(10.12, 10.0, 10.0, 3.0, 2.0);
OBJC_EXPORT BOOL _class_isFutureClass(Class _Nullable cls)
OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0);
OBJC_EXPORT BOOL _class_isSwift(Class _Nullable cls)
OBJC_AVAILABLE(10.16, 14.0, 14.0, 7.0, 5.0);
OBJC_EXPORT
id _Nonnull
_objc_rootRetain(id _Nonnull obj)
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
OBJC_EXPORT
void
_objc_rootRelease(id _Nonnull obj)
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
OBJC_EXPORT
bool
_objc_rootReleaseWasZero(id _Nonnull obj)
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
OBJC_EXPORT
bool
_objc_rootTryRetain(id _Nonnull obj)
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
OBJC_EXPORT
bool
_objc_rootIsDeallocating(id _Nonnull obj)
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
OBJC_EXPORT
id _Nonnull
_objc_rootAutorelease(id _Nonnull obj)
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
OBJC_EXPORT
uintptr_t
_objc_rootRetainCount(id _Nonnull obj)
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
OBJC_EXPORT
id _Nonnull
_objc_rootInit(id _Nonnull obj)
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
OBJC_EXPORT
id _Nullable
_objc_rootAllocWithZone(Class _Nonnull cls, malloc_zone_t * _Nullable zone)
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
OBJC_EXPORT
id _Nullable
_objc_rootAlloc(Class _Nonnull cls)
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
OBJC_EXPORT
void
_objc_rootDealloc(id _Nonnull obj)
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
OBJC_EXPORT
void
_objc_rootFinalize(id _Nonnull obj)
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
OBJC_EXPORT
malloc_zone_t * _Nonnull
_objc_rootZone(id _Nonnull obj)
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
OBJC_EXPORT
uintptr_t
_objc_rootHash(id _Nonnull obj)
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
OBJC_EXPORT
void * _Nonnull
objc_autoreleasePoolPush(void)
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
OBJC_EXPORT
void
objc_autoreleasePoolPop(void * _Nonnull context)
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
OBJC_EXPORT id _Nullable
objc_alloc(Class _Nullable cls)
OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0);
OBJC_EXPORT id _Nullable
objc_allocWithZone(Class _Nullable cls)
OBJC_AVAILABLE(10.9, 7.0, 9.0, 1.0, 2.0);
OBJC_EXPORT id _Nullable
objc_alloc_init(Class _Nullable cls)
OBJC_AVAILABLE(10.14.4, 12.2, 12.2, 5.2, 3.2);
OBJC_EXPORT id _Nullable
objc_opt_new(Class _Nullable cls)
OBJC_AVAILABLE(10.15, 13.0, 13.0, 6.0, 5.0);
OBJC_EXPORT id _Nullable
objc_opt_self(id _Nullable obj)
OBJC_AVAILABLE(10.15, 13.0, 13.0, 6.0, 5.0);
OBJC_EXPORT Class _Nullable
objc_opt_class(id _Nullable obj)
OBJC_AVAILABLE(10.15, 13.0, 13.0, 6.0, 5.0);
OBJC_EXPORT BOOL
objc_opt_respondsToSelector(id _Nullable obj, SEL _Nullable sel)
OBJC_AVAILABLE(10.15, 13.0, 13.0, 6.0, 5.0);
OBJC_EXPORT BOOL
objc_opt_isKindOfClass(id _Nullable obj, Class _Nullable cls)
OBJC_AVAILABLE(10.15, 13.0, 13.0, 6.0, 5.0);
OBJC_EXPORT BOOL
objc_sync_try_enter(id _Nonnull obj)
OBJC_AVAILABLE(10.15, 13.0, 13.0, 6.0, 5.0);
OBJC_EXPORT id _Nullable
objc_retain(id _Nullable obj)
__asm__("_objc_retain")
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
OBJC_EXPORT void
objc_release(id _Nullable obj)
__asm__("_objc_release")
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
OBJC_EXPORT id _Nullable
objc_autorelease(id _Nullable obj)
__asm__("_objc_autorelease")
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
OBJC_EXPORT id _Nullable
objc_autoreleaseReturnValue(id _Nullable obj)
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
OBJC_EXPORT id _Nullable
objc_retainAutoreleaseReturnValue(id _Nullable obj)
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
OBJC_EXPORT id _Nullable
objc_retainAutoreleasedReturnValue(id _Nullable obj)
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
OBJC_EXPORT id _Nullable
objc_unsafeClaimAutoreleasedReturnValue(id _Nullable obj)
OBJC_AVAILABLE(10.11, 9.0, 9.0, 1.0, 2.0);
OBJC_EXPORT void
objc_storeStrong(id _Nullable * _Nonnull location, id _Nullable obj)
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
OBJC_EXPORT id _Nullable
objc_retainAutorelease(id _Nullable obj)
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
OBJC_EXPORT id _Nullable
objc_retain_autorelease(id _Nullable obj)
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
OBJC_EXPORT id _Nullable
objc_loadWeakRetained(id _Nullable * _Nonnull location)
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
OBJC_EXPORT id _Nullable
objc_initWeak(id _Nullable * _Nonnull location, id _Nullable val)
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
OBJC_EXPORT id _Nullable
objc_storeWeakOrNil(id _Nullable * _Nonnull location, id _Nullable obj)
OBJC_AVAILABLE(10.11, 9.0, 9.0, 1.0, 2.0);
OBJC_EXPORT id _Nullable
objc_initWeakOrNil(id _Nullable * _Nonnull location, id _Nullable val)
OBJC_AVAILABLE(10.11, 9.0, 9.0, 1.0, 2.0);
OBJC_EXPORT void
objc_destroyWeak(id _Nullable * _Nonnull location)
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
OBJC_EXPORT void
objc_copyWeak(id _Nullable * _Nonnull to, id _Nullable * _Nonnull from)
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
OBJC_EXPORT void
objc_moveWeak(id _Nullable * _Nonnull to, id _Nullable * _Nonnull from)
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
OBJC_EXPORT void
_objc_autoreleasePoolPrint(void)
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
OBJC_EXPORT BOOL
objc_should_deallocate(id _Nonnull object)
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
OBJC_EXPORT void
objc_clear_deallocating(id _Nonnull object)
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
OBJC_EXPORT void * _Nonnull
_objc_autoreleasePoolPush(void)
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
OBJC_EXPORT void
_objc_autoreleasePoolPop(void * _Nonnull context)
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
#if __OBJC2__
OBJC_EXPORT _Nullable Class
objc_loadClassref(_Nullable Class * _Nonnull clsref)
OBJC_AVAILABLE(10.15, 13.0, 13.0, 6.0, 5.0);
#endif
OBJC_EXPORT const char * _Nullable
_protocol_getMethodTypeEncoding(Protocol * _Nonnull proto, SEL _Nonnull sel,
BOOL isRequiredMethod, BOOL isInstanceMethod)
OBJC_AVAILABLE(10.8, 6.0, 9.0, 1.0, 2.0);
struct mach_header;
typedef void (*_objc_func_willInitializeClass)(void * _Nullable context, Class _Nonnull cls);
#define OBJC_WILLINITIALIZECLASSFUNC_DEFINED 1
OBJC_EXPORT void _objc_addWillInitializeClassFunc(_objc_func_willInitializeClass _Nonnull func, void * _Nullable context)
OBJC_AVAILABLE(10.15, 13.0, 13.0, 6.0, 4.0);
#if __ARM_ARCH_7K__ >= 2 || (__arm64__ && !__LP64__) || \
!(!__LP64__ || TARGET_OS_WIN32 || \
(TARGET_OS_SIMULATOR && !TARGET_OS_MACCATALYST && !__arm64__))
OBJC_EXPORT const uintptr_t _objc_has_weak_formation_callout;
#define OBJC_WEAK_FORMATION_CALLOUT_DEFINED 1
#else
#define OBJC_WEAK_FORMATION_CALLOUT_DEFINED 0
#endif
#if defined(__arm64__) && TARGET_OS_IOS && !TARGET_OS_SIMULATOR && !TARGET_OS_MACCATALYST
#define CONFIG_USE_PREOPT_CACHES 1
#else
#define CONFIG_USE_PREOPT_CACHES 0
#endif
#if __OBJC2__
OBJC_EXPORT void _method_setImplementationRawUnsafe(Method _Nonnull m, IMP _Nonnull imp)
OBJC_AVAILABLE(10.16, 14.0, 14.0, 7.0, 5.0);
#endif
OBJC_EXPORT void
_objc_deallocOnMainThreadHelper(void * _Nullable context)
OBJC_AVAILABLE(10.7, 5.0, 9.0, 1.0, 2.0);
#if __OBJC__
@interface NSObject ()
- (BOOL)_tryRetain;
- (BOOL)_isDeallocating;
@end
#endif
typedef enum {
_OBJC_RESURRECT_OBJECT = -1,
_OBJC_DEALLOC_OBJECT_NOW = 1,
_OBJC_DEALLOC_OBJECT_LATER = 2
} _objc_object_disposition_t;
#define _OBJC_SUPPORTED_INLINE_REFCNT_LOGIC_BLOCK(_rc_ivar, _logicBlock) \
-(id)retain { \
\
int _retain_count_ivar_must_not_be_unsigned[0L - (__typeof__(_rc_ivar))-1] __attribute__((unused)); \
__typeof__(_rc_ivar) _prev = __sync_fetch_and_add(&_rc_ivar, 2); \
if (_prev < -2) { \
__builtin_trap(); \
} \
return self; \
} \
-(oneway void)release { \
__typeof__(_rc_ivar) _prev = __sync_fetch_and_sub(&_rc_ivar, 2); \
if (_prev > 0) { \
return; \
} else if (_prev < 0) { \
__builtin_trap(); \
} \
_objc_object_disposition_t fate = _logicBlock(self); \
if (fate == _OBJC_RESURRECT_OBJECT) { \
return; \
} \
\
if (!__sync_bool_compare_and_swap(&_rc_ivar, -2, 1)) { \
__builtin_trap(); \
} \
if (fate == _OBJC_DEALLOC_OBJECT_NOW) { \
[self dealloc]; \
} else if (fate == _OBJC_DEALLOC_OBJECT_LATER) { \
dispatch_barrier_async_f(dispatch_get_main_queue(), self, \
_objc_deallocOnMainThreadHelper); \
} else { \
__builtin_trap(); \
} \
} \
-(NSUInteger)retainCount { \
return (NSUInteger)(_rc_ivar + 2) >> 1; \
} \
-(BOOL)_tryRetain { \
__typeof__(_rc_ivar) _prev; \
do { \
_prev = _rc_ivar; \
if (_prev & 1) { \
return 0; \
} else if (_prev == -2) { \
return 0; \
} else if (_prev < -2) { \
__builtin_trap(); \
} \
} while ( ! __sync_bool_compare_and_swap(&_rc_ivar, _prev, _prev + 2)); \
return 1; \
} \
-(BOOL)_isDeallocating { \
if (_rc_ivar == -2) { \
return 1; \
} else if (_rc_ivar < -2) { \
__builtin_trap(); \
} \
return (_rc_ivar & 1) != 0; \
}
#define _OBJC_SUPPORTED_INLINE_REFCNT_LOGIC(_rc_ivar, _dealloc2main) \
_OBJC_SUPPORTED_INLINE_REFCNT_LOGIC_BLOCK(_rc_ivar, (^(id _self_ __attribute__((unused))) { \
if ((_dealloc2main) && !pthread_main_np()) { \
return _OBJC_DEALLOC_OBJECT_LATER; \
} else { \
return _OBJC_DEALLOC_OBJECT_NOW; \
} \
}))
#define _OBJC_SUPPORTED_INLINE_REFCNT(_rc_ivar) _OBJC_SUPPORTED_INLINE_REFCNT_LOGIC(_rc_ivar, 0)
#define _OBJC_SUPPORTED_INLINE_REFCNT_WITH_DEALLOC2MAIN(_rc_ivar) _OBJC_SUPPORTED_INLINE_REFCNT_LOGIC(_rc_ivar, 1)
struct cache_t;
struct bucket_t;
struct preopt_cache_t;
OBJC_EXPORT struct bucket_t * _Nonnull objc_cache_buckets(const struct cache_t * _Nonnull cache);
OBJC_EXPORT size_t objc_cache_bytesForCapacity(uint32_t cap);
OBJC_EXPORT uint32_t objc_cache_occupied(const struct cache_t * _Nonnull cache);
OBJC_EXPORT unsigned objc_cache_capacity(const struct cache_t * _Nonnull cache);
#if CONFIG_USE_PREOPT_CACHES
OBJC_EXPORT bool objc_cache_isConstantOptimizedCache(const struct cache_t * _Nonnull cache, bool strict, uintptr_t empty_addr);
OBJC_EXPORT unsigned objc_cache_preoptCapacity(const struct cache_t * _Nonnull cache);
OBJC_EXPORT Class _Nonnull objc_cache_preoptFallbackClass(const struct cache_t * _Nonnull cache);
OBJC_EXPORT const struct preopt_cache_t * _Nonnull objc_cache_preoptCache(const struct cache_t * _Nonnull cache);
#endif
__END_DECLS
#endif