]> git.saurik.com Git - apple/objc4.git/blobdiff - runtime/objc-internal.h
objc4-493.9.tar.gz
[apple/objc4.git] / runtime / objc-internal.h
index 97e0028bcc565cc489c689c4d7082640ce5e4957..c960d3eae09285b3cfd2070b20c6db83d5e6d632 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008 Apple Inc.  All Rights Reserved.
+ * Copyright (c) 2009 Apple Inc.  All Rights Reserved.
  * 
  * @APPLE_LICENSE_HEADER_START@
  * 
  * When your program breaks, you get to keep both pieces.
  */
 
+/*
+ * objc-internal.h: Private SPI for use by other system frameworks.
+ */
+
 #include <objc/objc.h>
 #include <Availability.h>
+#include <malloc/malloc.h>
+#include <dispatch/dispatch.h>
 
+__BEGIN_DECLS
+
+// In-place construction of an Objective-C instance.
 OBJC_EXPORT id objc_constructInstance(Class cls, void *bytes) 
-    __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA);
+    __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0)
+    OBJC_ARC_UNAVAILABLE;
 OBJC_EXPORT void *objc_destructInstance(id obj) 
-    __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA);
+    __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0)
+    OBJC_ARC_UNAVAILABLE;
+
+// In-place construction of an Objective-C class.
+OBJC_EXPORT Class objc_initializeClassPair(Class superclass_gen, const char *name, Class cls_gen, Class meta_gen) 
+    __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0);
+
+#if __OBJC2__  &&  __LP64__
+// Register a tagged pointer class.
+OBJC_EXPORT void _objc_insert_tagged_isa(unsigned char slotNumber, Class isa)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
+#endif
+
+// Batch object allocation using malloc_zone_batch_malloc().
+OBJC_EXPORT unsigned class_createInstances(Class cls, size_t extraBytes, 
+                                           id *results, unsigned num_requested)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3)
+    OBJC_ARC_UNAVAILABLE;
+
+// Get the isa pointer written into objects just before being freed.
+OBJC_EXPORT Class _objc_getFreedObjectClass(void)
+    __OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
+
+// Substitute receiver for messages to nil.
+// Not supported for all messages to nil.
+OBJC_EXPORT id _objc_setNilReceiver(id newNilReceiver)
+    __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_NA);
+OBJC_EXPORT id _objc_getNilReceiver(void)
+    __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_NA);
+
+// Return NO if no instance of `cls` has ever owned an associative reference.
+OBJC_EXPORT BOOL class_instancesHaveAssociatedObjects(Class cls)
+    __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0);
+
+// Return YES if GC is on and `object` is a GC allocation.
+OBJC_EXPORT BOOL objc_isAuto(id object) 
+    __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_NA);
+
+// env NSObjCMessageLoggingEnabled
+OBJC_EXPORT void instrumentObjcMessageSends(BOOL flag)
+    __OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
+
+// GC startup callback from Foundation
+OBJC_EXPORT malloc_zone_t *objc_collect_init(int (*callback)(void))
+    __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_NA);
+
+// Plainly-implemented GC barriers. Rosetta used to use these.
+OBJC_EXPORT id objc_assign_strongCast_generic(id value, id *dest)
+    UNAVAILABLE_ATTRIBUTE;
+OBJC_EXPORT id objc_assign_global_generic(id value, id *dest)
+    UNAVAILABLE_ATTRIBUTE;
+OBJC_EXPORT id objc_assign_threadlocal_generic(id value, id *dest)
+    UNAVAILABLE_ATTRIBUTE;
+OBJC_EXPORT id objc_assign_ivar_generic(id value, id dest, ptrdiff_t offset)
+    UNAVAILABLE_ATTRIBUTE;
+
+// Install missing-class callback. Used by the late unlamented ZeroLink.
+OBJC_EXPORT void _objc_setClassLoader(BOOL (*newClassLoader)(const char *))  OBJC2_UNAVAILABLE;
+
+// This can go away when AppKit stops calling it (rdar://7811851)
+#if __OBJC2__
+OBJC_EXPORT void objc_setMultithreaded (BOOL flag)
+    __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0,__MAC_10_5, __IPHONE_NA,__IPHONE_NA);
+#endif
+
+// Used by ExceptionHandling.framework
+#if !__OBJC2__
+OBJC_EXPORT void _objc_error(id rcv, const char *fmt, va_list args)
+    __attribute__((noreturn))
+    __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0,__MAC_10_5, __IPHONE_NA,__IPHONE_NA);
+
+#endif
+
+// External Reference support. Used to support compaction.
+
+enum {
+    OBJC_XREF_STRONG = 1,
+    OBJC_XREF_WEAK = 2
+};
+typedef uintptr_t objc_xref_type_t;
+typedef uintptr_t objc_xref_t;
+
+OBJC_EXPORT objc_xref_t _object_addExternalReference(id object, objc_xref_type_t type)
+     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
+OBJC_EXPORT void _object_removeExternalReference(objc_xref_t xref)
+     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
+OBJC_EXPORT id _object_readExternalReference(objc_xref_t xref)
+     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
+
+OBJC_EXPORT uintptr_t _object_getExternalHash(id object)
+     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+// Instance-specific instance variable layout.
+
+OBJC_EXPORT void _class_setIvarLayoutAccessor(Class cls_gen, const uint8_t* (*accessor) (id object))
+     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+OBJC_EXPORT const uint8_t *_object_getIvarLayout(Class cls_gen, id object)
+     __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
+
+OBJC_EXPORT BOOL _class_usesAutomaticRetainRelease(Class cls)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+// API to only be called by root classes like NSObject or NSProxy
+
+OBJC_EXPORT
+id
+_objc_rootRetain(id obj)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+OBJC_EXPORT
+void
+_objc_rootRelease(id obj)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+OBJC_EXPORT
+bool
+_objc_rootReleaseWasZero(id obj)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+OBJC_EXPORT
+bool
+_objc_rootTryRetain(id obj)
+__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+OBJC_EXPORT
+bool
+_objc_rootIsDeallocating(id obj)
+__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+OBJC_EXPORT
+id
+_objc_rootAutorelease(id obj)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+OBJC_EXPORT
+uintptr_t
+_objc_rootRetainCount(id obj)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+OBJC_EXPORT
+id
+_objc_rootInit(id obj)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+OBJC_EXPORT
+id
+_objc_rootAllocWithZone(Class cls, malloc_zone_t *zone)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+OBJC_EXPORT
+id
+_objc_rootAlloc(Class cls)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+OBJC_EXPORT
+void
+_objc_rootDealloc(id obj)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+OBJC_EXPORT
+void
+_objc_rootFinalize(id obj)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+OBJC_EXPORT
+malloc_zone_t *
+_objc_rootZone(id obj)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+OBJC_EXPORT
+uintptr_t
+_objc_rootHash(id obj)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+OBJC_EXPORT
+void *
+objc_autoreleasePoolPush(void)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+OBJC_EXPORT
+void
+objc_autoreleasePoolPop(void *context)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+
+OBJC_EXPORT id objc_retain(id obj)
+    __asm__("_objc_retain")
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+OBJC_EXPORT void objc_release(id obj)
+    __asm__("_objc_release")
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+OBJC_EXPORT id objc_autorelease(id obj)
+    __asm__("_objc_autorelease")
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+// wraps objc_autorelease(obj) in a useful way when used with return values
+OBJC_EXPORT
+id
+objc_autoreleaseReturnValue(id obj)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+// wraps objc_autorelease(objc_retain(obj)) in a useful way when used with return values
+OBJC_EXPORT
+id
+objc_retainAutoreleaseReturnValue(id obj)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+// called ONLY by ARR by callers to undo the autorelease (if possible), otherwise objc_retain
+OBJC_EXPORT
+id
+objc_retainAutoreleasedReturnValue(id obj)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+OBJC_EXPORT
+void
+objc_storeStrong(id *location, id obj)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+OBJC_EXPORT
+id
+objc_retainAutorelease(id obj)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+// obsolete.
+OBJC_EXPORT id objc_retain_autorelease(id obj)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+OBJC_EXPORT
+id
+objc_loadWeakRetained(id *location)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+OBJC_EXPORT
+id 
+objc_initWeak(id *addr, id val) 
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+OBJC_EXPORT
+void 
+objc_destroyWeak(id *addr) 
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+OBJC_EXPORT
+void 
+objc_copyWeak(id *to, id *from)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+OBJC_EXPORT
+void 
+objc_moveWeak(id *to, id *from) 
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+
+OBJC_EXPORT
+void
+_objc_autoreleasePoolPrint(void)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+OBJC_EXPORT BOOL objc_should_deallocate(id object)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+OBJC_EXPORT void objc_clear_deallocating(id object)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+// to make CF link for now
+
+OBJC_EXPORT
+void *
+_objc_autoreleasePoolPush(void)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+OBJC_EXPORT
+void
+_objc_autoreleasePoolPop(void *context)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+
+
+// API to only be called by classes that provide their own reference count storage
+
+OBJC_EXPORT
+void
+_objc_deallocOnMainThreadHelper(void *context)
+    __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
+
+#define _OBJC_SUPPORTED_INLINE_REFCNT_LOGIC(_rc_ivar, _dealloc2main)    \
+    -(id)retain {                                                       \
+        /* this will fail to compile if _rc_ivar is an unsigned type */ \
+        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 < 0) {                                                \
+            __builtin_trap(); /* BUG: retain of dealloc'ed ref */       \
+        }                                                               \
+        return self;                                                    \
+    }                                                                   \
+    -(oneway void)release {                                             \
+        __typeof__(_rc_ivar) _prev = __sync_fetch_and_sub(&_rc_ivar, 2); \
+        if (_prev == 0) {                                               \
+            if (__sync_bool_compare_and_swap(&_rc_ivar, -2, 1)) {       \
+                if (_dealloc2main) {                                    \
+                    dispatch_barrier_async_f(dispatch_get_main_queue(), \
+                                             self, _objc_deallocOnMainThreadHelper); \
+                } else {                                                \
+                    [self dealloc];                                     \
+                }                                                       \
+            } else {                                                    \
+                __builtin_trap(); /* BUG: dangling ref did a retain */  \
+            }                                                           \
+        } else if (_prev < 0) {                                         \
+            __builtin_trap(); /* BUG: over-release */                   \
+        }                                                               \
+    }                                                                   \
+    -(NSUInteger)retainCount {                                          \
+        return (_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(); /* BUG: over-release elsewhere */     \
+            }                                                           \
+        } 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(); /* BUG: over-release elsewhere */         \
+        }                                                               \
+        return _rc_ivar & 1;                                            \
+    }
+
+#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)
+
+__END_DECLS
 
 #endif