+++ /dev/null
-/*
- * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/* CFRuntime.c
- Copyright 1999-2002, Apple, Inc. All rights reserved.
- Responsibility: Christopher Kane
-*/
-
-#define ENABLE_ZOMBIES 1
-
-#include "CFRuntime.h"
-#include "CFInternal.h"
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#if defined(__MACH__)
-#include <dlfcn.h>
-#include <monitor.h>
-#include <crt_externs.h>
-#include <objc/objc-auto.h>
-#include <objc/objc-runtime.h>
-#else
-#endif
-
-#if defined(__MACH__)
-extern void __CFRecordAllocationEvent(int eventnum, void *ptr, int size, int data, const char *classname);
-#else
-#define __CFRecordAllocationEvent(a, b, c, d, e)
-#endif
-
-#if defined(__MACH__)
-extern BOOL objc_isAuto(id object);
-extern void* objc_assign_ivar_address_CF(void *value, void *base, void **slot);
-extern void* objc_assign_strongCast_CF(void* value, void **slot);
-#endif
-
-enum {
-// retain/release recording constants -- must match values
-// used by OA for now; probably will change in the future
-__kCFRetainEvent = 28,
-__kCFReleaseEvent = 29
-};
-
-/* On Win32 we should use _msize instead of malloc_size
- * (Aleksey Dukhnyakov)
- */
-#if defined(__WIN32__)
-#include <malloc.h>
-CF_INLINE size_t malloc_size(void *memblock) {
- return _msize(memblock);
-}
-#else
-#include <malloc/malloc.h>
-#endif
-
-#if defined(__MACH__)
-
-bool __CFOASafe = false;
-
-void __CFOAInitialize(void) {
- static void (*dyfunc)(void) = (void *)0xFFFFFFFF;
- if (NULL == getenv("OAKeepAllocationStatistics")) return;
- if ((void *)0xFFFFFFFF == dyfunc) {
- dyfunc = dlsym(RTLD_DEFAULT, "_OAInitialize");
- }
- if (NULL != dyfunc) {
- dyfunc();
- __CFOASafe = true;
- }
-}
-
-void __CFRecordAllocationEvent(int eventnum, void *ptr, int size, int data, const char *classname) {
- static void (*dyfunc)(int, void *, int, int, const char *) = (void *)0xFFFFFFFF;
- if (!__CFOASafe) return;
- if ((void *)0xFFFFFFFF == dyfunc) {
- dyfunc = dlsym(RTLD_DEFAULT, "_OARecordAllocationEvent");
- }
- if (NULL != dyfunc) {
- dyfunc(eventnum, ptr, size, data, classname);
- }
-}
-
-void __CFSetLastAllocationEventName(void *ptr, const char *classname) {
- static void (*dyfunc)(void *, const char *) = (void *)0xFFFFFFFF;
- if (!__CFOASafe) return;
- if ((void *)0xFFFFFFFF == dyfunc) {
- dyfunc = dlsym(RTLD_DEFAULT, "_OASetLastAllocationEventName");
- }
- if (NULL != dyfunc) {
- dyfunc(ptr, classname);
- }
-}
-#endif
-
-extern void __HALT(void);
-
-static CFTypeID __kCFNotATypeTypeID = _kCFRuntimeNotATypeID;
-
-static const CFRuntimeClass __CFNotATypeClass = {
- 0,
- "Not A Type",
- (void *)__HALT,
- (void *)__HALT,
- (void *)__HALT,
- (void *)__HALT,
- (void *)__HALT,
- (void *)__HALT,
- (void *)__HALT
-};
-
-static CFTypeID __kCFTypeTypeID = _kCFRuntimeNotATypeID;
-
-static const CFRuntimeClass __CFTypeClass = {
- 0,
- "CFType",
- (void *)__HALT,
- (void *)__HALT,
- (void *)__HALT,
- (void *)__HALT,
- (void *)__HALT,
- (void *)__HALT,
- (void *)__HALT
-};
-
-/* bits 15-8 in the CFRuntimeBase _info are type */
-/* bits 7-0 in the CFRuntimeBase are reserved for CF's use */
-
-static CFRuntimeClass * __CFRuntimeClassTable[__CFMaxRuntimeTypes] = {NULL};
-static int32_t __CFRuntimeClassTableCount = 0;
-
-#if defined(__MACH__)
-
-#if !defined(__ppc__)
-__private_extern__ void * (*__CFSendObjCMsg)(const void *, SEL, ...) = NULL;
-#endif
-
-__private_extern__ malloc_zone_t *__CFCollectableZone = NULL;
-
-static bool objc_isCollectable_nope(void* obj) { return false; }
-bool (*__CFObjCIsCollectable)(void *) = NULL;
-
-static const void* objc_AssignIvar_none(const void *value, void *base, const void **slot) { return (*slot = value); }
-const void* (*__CFObjCAssignIvar)(const void *value, const void *base, const void **slot) = objc_AssignIvar_none;
-
-static const void* objc_StrongAssign_none(const void *value, const void **slot) { return (*slot = value); }
-const void* (*__CFObjCStrongAssign)(const void *value, const void **slot) = objc_StrongAssign_none;
-
-void* (*__CFObjCMemmoveCollectable)(void *dst, const void *, unsigned) = memmove;
-
-// GC: to be moved to objc if necessary.
-static void objc_WriteBarrierRange_none(void *ptr, unsigned size) {}
-static void objc_WriteBarrierRange_auto(void *ptr, unsigned size) { auto_zone_write_barrier_range(__CFCollectableZone, ptr, size); }
-void (*__CFObjCWriteBarrierRange)(void *, unsigned) = objc_WriteBarrierRange_none;
-
-// Temporarily disabled __private_extern__
-#warning Ali, be sure to reexamine this
-struct objc_class *__CFRuntimeObjCClassTable[__CFMaxRuntimeTypes] = {NULL};
-
-#endif
-
-// Compiler uses this symbol name
-int __CFConstantStringClassReference[10] = {0};
-
-#if defined(__MACH__)
-static struct objc_class __CFNSTypeClass = {{0, 0}, NULL, {0, 0, 0, 0, 0, 0, 0}};
-#endif
-
-//static CFSpinLock_t __CFRuntimeLock = 0;
-
-CFTypeID _CFRuntimeRegisterClass(const CFRuntimeClass * const cls) {
-// version field must be 0
-// className must be pure ASCII string, non-null
- if (__CFMaxRuntimeTypes <= __CFRuntimeClassTableCount) {
- CFLog(0, CFSTR("*** CoreFoundation class table full; registration failing for class '%s'. Program will crash soon."), cls->className);
- return _kCFRuntimeNotATypeID;
- }
- __CFRuntimeClassTable[__CFRuntimeClassTableCount++] = (CFRuntimeClass *)cls;
- return __CFRuntimeClassTableCount - 1;
-}
-
-void _CFRuntimeInitializeClassForBridging(CFTypeID typeID) {
- __CFRuntimeObjCClassTable[typeID] = (struct objc_class *)calloc(sizeof(struct objc_class), 1);
-}
-
-Boolean _CFRuntimeSetupBridging(CFTypeID typeID, struct objc_class *mainClass, struct objc_class *subClass) {
- void *isa = __CFISAForTypeID(typeID);
- memmove(isa, subClass, sizeof(struct objc_class));
- class_poseAs(isa, mainClass);
- return true;
-}
-
-const CFRuntimeClass * _CFRuntimeGetClassWithTypeID(CFTypeID typeID) {
- return __CFRuntimeClassTable[typeID];
-}
-
-void _CFRuntimeUnregisterClassWithTypeID(CFTypeID typeID) {
- __CFRuntimeClassTable[typeID] = NULL;
-}
-
-
-#if defined(DEBUG) || defined(ENABLE_ZOMBIES)
-
-/* CFZombieLevel levels:
- * bit 0: scribble deallocated CF object memory
- * bit 1: do not scribble on CFRuntimeBase header (when bit 0)
- * bit 4: do not free CF objects
- * bit 7: use 3rd-order byte as scribble byte for dealloc (otherwise 0xFC)
- * bit 16: scribble allocated CF object memory
- * bit 23: use 1st-order byte as scribble byte for alloc (otherwise 0xCF)
- */
-
-static uint32_t __CFZombieLevel = 0x0;
-
-static void __CFZombifyAllocatedMemory(void *cf) {
- if (__CFZombieLevel & (1 << 16)) {
- void *ptr = cf;
- size_t size = malloc_size(cf);
- uint8_t byte = 0xCF;
- if (__CFZombieLevel & (1 << 23)) {
- byte = (__CFZombieLevel >> 24) & 0xFF;
- }
- memset(ptr, byte, size);
- }
-}
-
-static void __CFZombifyDeallocatedMemory(void *cf) {
- if (__CFZombieLevel & (1 << 0)) {
- void *ptr = cf;
- size_t size = malloc_size(cf);
- uint8_t byte = 0xFC;
- if (__CFZombieLevel & (1 << 1)) {
- ptr += sizeof(CFRuntimeBase);
- size -= sizeof(CFRuntimeBase);
- }
- if (__CFZombieLevel & (1 << 7)) {
- byte = (__CFZombieLevel >> 8) & 0xFF;
- }
- memset(ptr, byte, size);
- }
-}
-
-#endif /* DEBUG */
-
-// XXX_PCB: use the class version field as a bitmask, to allow classes to opt-in for GC scanning.
-
-CF_INLINE CFOptionFlags CF_GET_COLLECTABLE_MEMORY_TYPE(const CFRuntimeClass *cls)
-{
- return (cls->version & _kCFRuntimeScannedObject) ? AUTO_OBJECT_SCANNED : AUTO_OBJECT_UNSCANNED;
-}
-
-CFTypeRef _CFRuntimeCreateInstance(CFAllocatorRef allocator, CFTypeID typeID, uint32_t extraBytes, unsigned char *category) {
- CFRuntimeBase *memory;
- Boolean usesSystemDefaultAllocator;
- int32_t size;
-
- CFAssert1(typeID != _kCFRuntimeNotATypeID, __kCFLogAssertion, "%s(): Uninitialized type id", __PRETTY_FUNCTION__);
-
- if (NULL == __CFRuntimeClassTable[typeID]) {
- return NULL;
- }
- allocator = (NULL == allocator) ? __CFGetDefaultAllocator() : allocator;
- usesSystemDefaultAllocator = (allocator == kCFAllocatorSystemDefault);
- extraBytes = (extraBytes + (sizeof(void *) - 1)) & ~(sizeof(void *) - 1);
- size = sizeof(CFRuntimeBase) + extraBytes + (usesSystemDefaultAllocator ? 0 : sizeof(CFAllocatorRef));
- // CFType version 0 objects are unscanned by default since they don't have write-barriers and hard retain their innards
- // CFType version 1 objects are scanned and use hand coded write-barriers to store collectable storage within
- memory = CFAllocatorAllocate(allocator, size, CF_GET_COLLECTABLE_MEMORY_TYPE(__CFRuntimeClassTable[typeID]));
- if (NULL == memory) {
- return NULL;
- }
-#if defined(DEBUG) || defined(ENABLE_ZOMBIES)
- __CFZombifyAllocatedMemory((void *)memory);
-#endif
- if (__CFOASafe && category) {
- __CFSetLastAllocationEventName(memory, category);
- } else if (__CFOASafe) {
- __CFSetLastAllocationEventName(memory, __CFRuntimeClassTable[typeID]->className);
- }
- if (!usesSystemDefaultAllocator) {
- // add space to hold allocator ref for non-standard allocators.
- // (this screws up 8 byte alignment but seems to work)
- *(CFAllocatorRef *)((char *)memory) = CFRetain(allocator);
- memory = (CFRuntimeBase *)((char *)memory + sizeof(CFAllocatorRef));
- }
- memory->_isa = __CFISAForTypeID(typeID);
- memory->_rc = 1;
- memory->_info = 0;
- __CFBitfieldSetValue(memory->_info, 15, 8, typeID);
- if (usesSystemDefaultAllocator) {
- __CFBitfieldSetValue(memory->_info, 7, 7, 1);
- }
- if (NULL != __CFRuntimeClassTable[typeID]->init) {
- (__CFRuntimeClassTable[typeID]->init)(memory);
- }
- return memory;
-}
-
-void _CFRuntimeSetInstanceTypeID(CFTypeRef cf, CFTypeID typeID) {
- __CFBitfieldSetValue(((CFRuntimeBase *)cf)->_info, 15, 8, typeID);
-}
-
-CFTypeID __CFGenericTypeID(const void *cf) {
- return __CFBitfieldGetValue(((const CFRuntimeBase *)cf)->_info, 15, 8);
-}
-
-CF_INLINE CFTypeID __CFGenericTypeID_inline(const void *cf) {
- return __CFBitfieldGetValue(((const CFRuntimeBase *)cf)->_info, 15, 8);
-}
-
-CFTypeID CFTypeGetTypeID(void) {
- return __kCFTypeTypeID;
-}
-
-__private_extern__ void __CFGenericValidateType_(CFTypeRef cf, CFTypeID type, const char *func) {
- if (cf && CF_IS_OBJC(type, cf)) return;
- CFAssert2((cf != NULL) && (NULL != __CFRuntimeClassTable[__CFGenericTypeID_inline(cf)]) && (__kCFNotATypeTypeID != __CFGenericTypeID_inline(cf)) && (__kCFTypeTypeID != __CFGenericTypeID_inline(cf)), __kCFLogAssertion, "%s(): pointer 0x%x is not a CF object", func, cf); \
- CFAssert3(__CFGenericTypeID_inline(cf) == type, __kCFLogAssertion, "%s(): pointer 0x%x is not a %s", func, cf, __CFRuntimeClassTable[type]->className); \
-}
-
-#define __CFGenericAssertIsCF(cf) \
- CFAssert2(cf != NULL && (NULL != __CFRuntimeClassTable[__CFGenericTypeID_inline(cf)]) && (__kCFNotATypeTypeID != __CFGenericTypeID_inline(cf)) && (__kCFTypeTypeID != __CFGenericTypeID_inline(cf)), __kCFLogAssertion, "%s(): pointer 0x%x is not a CF object", __PRETTY_FUNCTION__, cf);
-
-#if !defined(__MACH__)
-
-#define CFTYPE_IS_OBJC(obj) (false)
-#define CFTYPE_OBJC_FUNCDISPATCH0(rettype, obj, sel) do {} while (0)
-#define CFTYPE_OBJC_FUNCDISPATCH1(rettype, obj, sel, a1) do {} while (0)
-
-#endif
-
-#if defined(__MACH__)
-
-CF_INLINE int CFTYPE_IS_OBJC(const void *obj) {
- CFTypeID typeID = __CFGenericTypeID_inline(obj);
- return CF_IS_OBJC(typeID, obj);
-}
-
-#define CFTYPE_OBJC_FUNCDISPATCH0(rettype, obj, sel) \
- if (CFTYPE_IS_OBJC(obj)) \
- {rettype (*func)(void *, SEL) = (void *)__CFSendObjCMsg; \
- static SEL s = NULL; if (!s) s = sel_registerName(sel); \
- return func((void *)obj, s);}
-#define CFTYPE_OBJC_FUNCDISPATCH1(rettype, obj, sel, a1) \
- if (CFTYPE_IS_OBJC(obj)) \
- {rettype (*func)(void *, SEL, ...) = (void *)__CFSendObjCMsg; \
- static SEL s = NULL; if (!s) s = sel_registerName(sel); \
- return func((void *)obj, s, (a1));}
-
-#endif
-
-CFTypeID CFGetTypeID(CFTypeRef cf) {
-#if defined(DEBUG)
- if (NULL == cf) HALT;
-#endif
- CFTYPE_OBJC_FUNCDISPATCH0(CFTypeID, cf, "_cfTypeID");
- __CFGenericAssertIsCF(cf);
- return __CFGenericTypeID_inline(cf);
-}
-
-CFStringRef CFCopyTypeIDDescription(CFTypeID type) {
- CFAssert2((NULL != __CFRuntimeClassTable[type]) && __kCFNotATypeTypeID != type && __kCFTypeTypeID != type, __kCFLogAssertion, "%s(): type %d is not a CF type ID", __PRETTY_FUNCTION__, type);
- return CFStringCreateWithCString(kCFAllocatorDefault, __CFRuntimeClassTable[type]->className, kCFStringEncodingASCII);
-}
-
-static CFSpinLock_t __CFGlobalRetainLock = 0;
-static CFMutableDictionaryRef __CFRuntimeExternRefCountTable = NULL;
-
-#define DISGUISE(object) ((void *)(((unsigned)object) + 1))
-#define UNDISGUISE(disguised) ((id)(((unsigned)disguised) - 1))
-
-extern void _CFDictionaryIncrementValue(CFMutableDictionaryRef dict, const void *key);
-extern int _CFDictionaryDecrementValue(CFMutableDictionaryRef dict, const void *key);
-
-// Bit 31 (highest bit) in second word of cf instance indicates external ref count
-
-extern void _CFRelease(CFTypeRef cf);
-extern CFTypeRef _CFRetain(CFTypeRef cf);
-extern CFHashCode _CFHash(CFTypeRef cf);
-
-CFTypeRef CFRetain(CFTypeRef cf) {
- // always honor CFRetain's with a hard reference
- if (CF_IS_COLLECTABLE(cf)) {
- auto_zone_retain(__CFCollectableZone, (void*)cf);
- return cf;
- }
- // XXX_PCB some Objc objects aren't really reference counted, perhaps they should be able to make that distinction?
- CFTYPE_OBJC_FUNCDISPATCH0(CFTypeRef, cf, "retain");
- __CFGenericAssertIsCF(cf);
- return _CFRetain(cf);
-}
-
-__private_extern__ void __CFAllocatorDeallocate(CFTypeRef cf);
-
-void CFRelease(CFTypeRef cf) {
- // make sure we get rid of the hard reference if called
- if (CF_IS_COLLECTABLE(cf)) {
- auto_zone_release(__CFCollectableZone, (void*)cf);
- return;
- }
- // XXX_PCB some objects aren't really reference counted.
- CFTYPE_OBJC_FUNCDISPATCH0(void, cf, "release");
- __CFGenericAssertIsCF(cf);
- _CFRelease(cf);
-}
-
-static uint64_t __CFGetFullRetainCount(CFTypeRef cf) {
- uint32_t lowBits = 0;
- uint64_t highBits = 0, compositeRC;
- lowBits = ((CFRuntimeBase *)cf)->_rc;
- if (0 == lowBits) {
- return (uint64_t)0x00ffffffffffffffULL;
- }
- if ((lowBits & 0x08000) != 0) {
- highBits = (uint64_t)(uintptr_t)CFDictionaryGetValue(__CFRuntimeExternRefCountTable, DISGUISE(cf));
- }
- compositeRC = (lowBits & 0x7fff) + (highBits << 15);
- return compositeRC;
-}
-
-CFTypeRef _CFRetainGC(CFTypeRef cf)
-{
-#if defined(DEBUG)
- if (CF_USING_COLLECTABLE_MEMORY && !CF_IS_COLLECTABLE(cf)) {
- fprintf(stderr, "non-auto object %p passed to _CFRetainGC.\n", cf);
- HALT;
- }
-#endif
- return CF_USING_COLLECTABLE_MEMORY ? cf : CFRetain(cf);
-}
-
-void _CFReleaseGC(CFTypeRef cf)
-{
-#if defined(DEBUG)
- if (CF_USING_COLLECTABLE_MEMORY && !CF_IS_COLLECTABLE(cf)) {
- fprintf(stderr, "non-auto object %p passed to _CFReleaseGC.\n", cf);
- HALT;
- }
-#endif
- if (!CF_USING_COLLECTABLE_MEMORY) CFRelease(cf);
-}
-
-CFIndex CFGetRetainCount(CFTypeRef cf) {
- uint64_t rc;
- CFIndex result;
-#if defined(DEBUG)
- if (NULL == cf) HALT;
-#endif
- if (CF_IS_COLLECTABLE(cf)) {
- return auto_zone_retain_count(__CFCollectableZone, cf);
- }
- CFTYPE_OBJC_FUNCDISPATCH0(CFIndex, cf, "retainCount");
- __CFGenericAssertIsCF(cf);
- rc = __CFGetFullRetainCount(cf);
- result = (rc < (uint64_t)0x7FFFFFFF) ? (CFIndex)rc : (CFIndex)0x7FFFFFFF;
- return result;
-}
-
-CFTypeRef CFMakeCollectable(CFTypeRef cf)
-{
- if (!cf) return NULL;
- if (CF_USING_COLLECTABLE_MEMORY) {
-#if defined(DEBUG)
- CFAllocatorRef allocator = CFGetAllocator(cf);
- if (!CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
- CFLog(0, CFSTR("object %p with non-GC allocator %p passed to CFMakeCollected."), cf, allocator);
- HALT;
- }
-#endif
- if (CFGetRetainCount(cf) == 0) {
- CFLog(0, CFSTR("object %p with 0 retain-count passed to CFMakeCollected."), cf);
- return cf;
- }
- CFRelease(cf);
- }
- return cf;
-}
-
-Boolean CFEqual(CFTypeRef cf1, CFTypeRef cf2) {
-#if defined(DEBUG)
- if (NULL == cf1) HALT;
- if (NULL == cf2) HALT;
-#endif
- if (cf1 == cf2) return true;
- CFTYPE_OBJC_FUNCDISPATCH1(Boolean, cf1, "isEqual:", cf2);
- CFTYPE_OBJC_FUNCDISPATCH1(Boolean, cf2, "isEqual:", cf1);
- __CFGenericAssertIsCF(cf1);
- __CFGenericAssertIsCF(cf2);
- if (__CFGenericTypeID_inline(cf1) != __CFGenericTypeID_inline(cf2)) return false;
- if (NULL != __CFRuntimeClassTable[__CFGenericTypeID_inline(cf1)]->equal) {
- return __CFRuntimeClassTable[__CFGenericTypeID_inline(cf1)]->equal(cf1, cf2);
- }
- return false;
-}
-
-CFHashCode CFHash(CFTypeRef cf) {
- CFTYPE_OBJC_FUNCDISPATCH0(CFHashCode, cf, "hash");
- __CFGenericAssertIsCF(cf);
- return _CFHash(cf);
-}
-
-// definition: produces a normally non-NULL debugging description of the object
-CFStringRef CFCopyDescription(CFTypeRef cf) {
-#if defined(DEBUG)
- if (NULL == cf) HALT;
-#endif
- if (CFTYPE_IS_OBJC(cf)) {
- static SEL s = NULL;
- CFStringRef (*func)(void *, SEL, ...) = (void *)__CFSendObjCMsg;
- if (!s) s = sel_registerName("_copyDescription");
- CFStringRef result = func((void *)cf, s);
- if (result && CF_USING_COLLECTABLE_MEMORY) CFRetain(result); // needs hard retain
- return result;
- }
- // CFTYPE_OBJC_FUNCDISPATCH0(CFStringRef, cf, "_copyDescription"); // XXX returns 0 refcounted item under GC
- __CFGenericAssertIsCF(cf);
- if (NULL != __CFRuntimeClassTable[__CFGenericTypeID_inline(cf)]->copyDebugDesc) {
- CFStringRef result;
- result = __CFRuntimeClassTable[__CFGenericTypeID_inline(cf)]->copyDebugDesc(cf);
- if (NULL != result) return result;
- }
- return CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("<%s %p [%p]>"), __CFRuntimeClassTable[__CFGenericTypeID_inline(cf)]->className, cf, CFGetAllocator(cf));
-}
-
-// Definition: if type produces a formatting description, return that string, otherwise NULL
-__private_extern__ CFStringRef __CFCopyFormattingDescription(CFTypeRef cf, CFDictionaryRef formatOptions) {
-#if defined(DEBUG)
- if (NULL == cf) HALT;
-#endif
-#if defined(__MACH__)
- if (CFTYPE_IS_OBJC(cf)) {
- static SEL s = NULL, r = NULL;
- CFStringRef (*func)(void *, SEL, ...) = (void *)__CFSendObjCMsg;
- if (!s) s = sel_registerName("_copyFormattingDescription:");
- if (!r) r = sel_registerName("respondsToSelector:");
- if (s && func((void *)cf, r, s)) return func((void *)cf, s, formatOptions);
- return NULL;
- }
-#endif
- __CFGenericAssertIsCF(cf);
- if (NULL != __CFRuntimeClassTable[__CFGenericTypeID_inline(cf)]->copyFormattingDesc) {
- return __CFRuntimeClassTable[__CFGenericTypeID_inline(cf)]->copyFormattingDesc(cf, formatOptions);
- }
- return NULL;
-}
-
-extern CFAllocatorRef __CFAllocatorGetAllocator(CFTypeRef);
-
-CFAllocatorRef CFGetAllocator(CFTypeRef cf) {
-#if defined(DEBUG)
- if (NULL == cf) HALT;
-#endif
-// CF: need to get allocator from objc objects in better way...how?
-// -> bridging of CFAllocators and malloc_zone_t will help this
- if (CFTYPE_IS_OBJC(cf)) return __CFGetDefaultAllocator();
- if (__kCFAllocatorTypeID_CONST == __CFGenericTypeID_inline(cf)) {
- return __CFAllocatorGetAllocator(cf);
- }
- return __CFGetAllocator(cf);
-}
-
-extern void __CFBaseInitialize(void);
-extern void __CFNullInitialize(void);
-extern void __CFAllocatorInitialize(void);
-extern void __CFStringInitialize(void);
-extern void __CFArrayInitialize(void);
-extern void __CFBagInitialize(void);
-extern void __CFBooleanInitialize(void);
-extern void __CFCharacterSetInitialize(void);
-extern void __CFDataInitialize(void);
-extern void __CFDateInitialize(void);
-extern void __CFDictionaryInitialize(void);
-extern void __CFNumberInitialize(void);
-extern void __CFSetInitialize(void);
-extern void __CFStorageInitialize(void);
-extern void __CFTimeZoneInitialize(void);
-extern void __CFTreeInitialize(void);
-extern void __CFURLInitialize(void);
-extern void __CFXMLNodeInitialize(void);
-extern void __CFXMLParserInitialize(void);
-extern void __CFLocaleInitialize(void);
-extern void __CFCalendarInitialize(void);
-extern void __CFNumberFormatterInitialize(void);
-extern void __CFDateFormatterInitialize(void);
-#if defined(__MACH__)
-extern void __CFMessagePortInitialize(void);
-extern void __CFMachPortInitialize(void);
-#endif
-#if defined(__MACH__) || defined(__WIN32__)
-extern void __CFRunLoopInitialize(void);
-extern void __CFRunLoopObserverInitialize(void);
-extern void __CFRunLoopSourceInitialize(void);
-extern void __CFRunLoopTimerInitialize(void);
-extern void __CFSocketInitialize(void);
-#endif
-extern void __CFBundleInitialize(void);
-extern void __CFPlugInInitialize(void);
-extern void __CFPlugInInstanceInitialize(void);
-extern void __CFUUIDInitialize(void);
-extern void __CFBinaryHeapInitialize(void);
-extern void __CFBitVectorInitialize(void);
-#if defined(__WIN32__)
-extern void __CFWindowsMessageQueueInitialize(void);
-extern void __CFBaseCleanup(void);
-#endif
-extern void __CFStreamInitialize(void);
-#if defined(__MACH__)
-extern void __CFPreferencesDomainInitialize(void);
-extern void __CFUserNotificationInitialize(void);
-#endif
-
-#if defined(DEBUG)
-#define DO_SYSCALL_TRACE_HELPERS 1
-#endif
-#if defined(DO_SYSCALL_TRACE_HELPERS) && defined(__MACH__)
-extern void ptrace(int, int, int, int);
-#define SYSCALL_TRACE(N) do ptrace(N, 0, 0, 0); while (0)
-#else
-#define SYSCALL_TRACE(N) do {} while (0)
-#endif
-
-#if defined(__MACH__) && defined(PROFILE)
-static void _CF_mcleanup(void) {
- monitor(0,0,0,0,0);
-}
-#endif
-
-const void *__CFArgStuff = NULL;
-__private_extern__ void *__CFAppleLanguages = NULL;
-__private_extern__ void *__CFSessionID = NULL;
-
-#if defined(__LINUX__) || defined(__FREEBSD__)
-static void __CFInitialize(void) __attribute__ ((constructor));
-static
-#endif
-#if defined(__WIN32__)
-CF_EXPORT
-#endif
-void __CFInitialize(void) {
- static int __done = 0;
- if (sizeof(int) != sizeof(long) || 4 != sizeof(long)) __HALT();
-
- if (!__done) {
- __done = 1;
- SYSCALL_TRACE(0xC000);
- {
- kCFUseCollectableAllocator = objc_collecting_enabled();
- if (kCFUseCollectableAllocator) {
- __CFCollectableZone = auto_zone();
- __CFObjCIsCollectable = objc_isAuto;
- __CFObjCAssignIvar = objc_assign_ivar_address_CF;
- __CFObjCStrongAssign = objc_assign_strongCast_CF;
- __CFObjCMemmoveCollectable = objc_memmove_collectable;
- __CFObjCWriteBarrierRange = objc_WriteBarrierRange_auto;
- }
- }
-#if defined(DEBUG) || defined(ENABLE_ZOMBIES)
- {
- const char *value = getenv("CFZombieLevel");
- if (NULL != value) {
- __CFZombieLevel = strtoul(value, NULL, 0);
- }
- if (0x0 == __CFZombieLevel) __CFZombieLevel = 0xCF00FC00; // default
- }
-#endif
-#if defined(__MACH__) && defined(PROFILE)
- {
- const char *v = getenv("DYLD_IMAGE_SUFFIX");
- const char *p = getenv("CFPROF_ENABLE");
- // ckane: People were upset that I added this feature to allow for the profiling of
- // libraries using unprofiled apps/executables, so ensure they cannot get this accidentally.
- if (v && p && 0 == strcmp("_profile", v) && 0 == strcmp(crypt(p + 2, p) + 2, "eQJhkVvMm.w")) {
- // Unfortunately, no way to know if this has already been done,
- // or I would not do it. Not much information will be lost.
- atexit(_CF_mcleanup);
- moninit();
- }
- }
-#endif
-
- __CFBaseInitialize();
-
-#if defined(__MACH__)
- {
- CFIndex idx;
- for (idx = 0; idx < __CFMaxRuntimeTypes; idx++) {
- __CFRuntimeObjCClassTable[idx] = &__CFNSTypeClass;
- }
- }
-#endif
-
- /* Here so that two runtime classes get indices 0, 1. */
- __kCFNotATypeTypeID = _CFRuntimeRegisterClass(&__CFNotATypeClass);
- __kCFTypeTypeID = _CFRuntimeRegisterClass(&__CFTypeClass);
-
- /* Here so that __kCFAllocatorTypeID gets index 2. */
- __CFAllocatorInitialize();
-
- /* Basic collections need to be up before CFString. */
- __CFDictionaryInitialize();
- __CFArrayInitialize();
- __CFDataInitialize();
- __CFSetInitialize();
-
-#if defined(__MACH__)
- {
- CFIndex idx, cnt;
- char **args = *_NSGetArgv();
- cnt = *_NSGetArgc();
- for (idx = 1; idx < cnt - 1; idx++) {
- if (0 == strcmp(args[idx], "-AppleLanguages")) {
- CFIndex length = strlen(args[idx + 1]);
- __CFAppleLanguages = malloc(length + 1);
- memmove(__CFAppleLanguages, args[idx + 1], length + 1);
- break;
- }
- }
- }
-#endif
-
-
- // Creating this lazily in CFRetain causes recursive call to CFRetain
- __CFRuntimeExternRefCountTable = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, NULL, NULL);
-
- /*** _CFRuntimeCreateInstance() can finally be called generally after this line. ***/
-
- __CFStringInitialize(); // CFString's TypeID must be 0x7, now and forever
- __CFNullInitialize(); // See above for hard-coding of this position
- __CFBooleanInitialize(); // See above for hard-coding of this position
- __CFNumberInitialize(); // See above for hard-coding of this position
- __CFDateInitialize(); // See above for hard-coding of this position
- __CFTimeZoneInitialize(); // See above for hard-coding of this position
-
- __CFBinaryHeapInitialize();
- __CFBitVectorInitialize();
- __CFBagInitialize();
- __CFCharacterSetInitialize();
- __CFStorageInitialize();
- __CFTreeInitialize();
- __CFURLInitialize();
- __CFXMLNodeInitialize();
- __CFXMLParserInitialize();
- __CFBundleInitialize();
- __CFPlugInInitialize();
- __CFPlugInInstanceInitialize();
- __CFUUIDInitialize();
-#if defined(__MACH__)
- __CFMessagePortInitialize();
- __CFMachPortInitialize();
-#endif
-#if defined(__MACH__) || defined(__WIN32__)
- __CFRunLoopInitialize();
- __CFRunLoopObserverInitialize();
- __CFRunLoopSourceInitialize();
- __CFRunLoopTimerInitialize();
- __CFSocketInitialize();
-#endif
- __CFStreamInitialize();
-#if defined(__MACH__)
- __CFPreferencesDomainInitialize();
-#endif // __MACH__
-
-
- SYSCALL_TRACE(0xC001);
-
-#if defined(__MACH__)
- {
- CFIndex idx, cnt;
- char **args = *_NSGetArgv();
- CFIndex count;
- cnt = *_NSGetArgc();
- CFStringRef *list, buffer[256];
- list = (cnt <= 256) ? buffer : malloc(cnt * sizeof(CFStringRef));
- for (idx = 0, count = 0; idx < cnt && args[idx]; idx++) {
- list[count] = CFStringCreateWithCString(kCFAllocatorSystemDefault, args[idx], kCFStringEncodingUTF8);
- if (NULL == list[count]) {
- list[count] = CFStringCreateWithCString(kCFAllocatorSystemDefault, args[idx], kCFStringEncodingISOLatin1);
- // We CANNOT use the string SystemEncoding here;
- // Do not argue: it is not initialized yet, but these
- // arguments MUST be initialized before it is.
- // We should just ignore the argument if the UTF-8
- // conversion fails, but out of charity we try once
- // more with ISO Latin1, a standard unix encoding.
- }
- if (NULL != list[count]) count++;
- }
- __CFArgStuff = CFArrayCreate(kCFAllocatorSystemDefault, (const void **)list, count, &kCFTypeArrayCallBacks);
- }
-
- __CFSessionID = getenv("SECURITYSESSIONID");
-#endif
- _CFProcessPath(); // cache this early
-
-#if defined(__MACH__)
- __CFOAInitialize();
- SYSCALL_TRACE(0xC003);
-#endif
-
- if (__CFRuntimeClassTableCount < 100) __CFRuntimeClassTableCount = 100;
-
-#if defined(DEBUG) && !defined(__WIN32__)
- // Don't log on MacOS 8 as this will create a log file unnecessarily
- CFLog (0, CFSTR("Assertions enabled"));
-#endif
- SYSCALL_TRACE(0xC0FF);
- }
-}
-
-#if defined(__WIN32__)
-
-/* We have to call __CFInitialize when library is attached to the process.
- * (Sergey Zubarev)
- */
-WINBOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID pReserved ) {
- if (dwReason == DLL_PROCESS_ATTACH) {
- __CFInitialize();
- } else if (dwReason == DLL_PROCESS_DETACH) {
- __CFStringCleanup();
- __CFSocketCleanup();
- __CFUniCharCleanup();
- __CFStreamCleanup();
- __CFBaseCleanup();
- } else if (dwReason == DLL_THREAD_DETACH) {
- __CFFinalizeThreadData(NULL);
- }
- return TRUE;
-}
-
-#endif
-
-
-// Functions that avoid ObC dispatch and CF type validation, for use by NSNotifyingCFArray, etc.
-// Hopefully all of this will just go away. 3321464. M.P. To Do - 7/9/03
-
-Boolean _CFEqual(CFTypeRef cf1, CFTypeRef cf2) {
-#if defined(DEBUG)
- if (NULL == cf1) HALT;
- if (NULL == cf2) HALT;
-#endif
- if (cf1 == cf2) return true;
- __CFGenericAssertIsCF(cf1);
- __CFGenericAssertIsCF(cf2);
- if (__CFGenericTypeID_inline(cf1) != __CFGenericTypeID_inline(cf2)) return false;
- if (NULL != __CFRuntimeClassTable[__CFGenericTypeID_inline(cf1)]->equal) {
- return __CFRuntimeClassTable[__CFGenericTypeID_inline(cf1)]->equal(cf1, cf2);
- }
- return false;
-}
-
-CFIndex _CFGetRetainCount(CFTypeRef cf) {
- uint64_t rc;
- CFIndex result;
- rc = __CFGetFullRetainCount(cf);
- result = (rc < (uint64_t)0x7FFFFFFF) ? (CFIndex)rc : (CFIndex)0x7FFFFFFF;
- return result;
-}
-
-CFHashCode _CFHash(CFTypeRef cf) {
-#if defined(DEBUG)
- if (NULL == cf) HALT;
-#endif
- if (NULL != __CFRuntimeClassTable[__CFGenericTypeID_inline(cf)]->hash) {
- return __CFRuntimeClassTable[__CFGenericTypeID_inline(cf)]->hash(cf);
- }
- return (CFHashCode)cf;
-}
-
-CF_EXPORT CFTypeRef _CFRetain(CFTypeRef cf) {
- CFIndex lowBits = 0;
-#if defined(DEBUG)
- if (NULL == cf) HALT;
-#endif
- __CFSpinLock(&__CFGlobalRetainLock);
- lowBits = ((CFRuntimeBase *)cf)->_rc;
- if (__builtin_expect(0 == lowBits, 0)) { // Constant CFTypeRef
- __CFSpinUnlock(&__CFGlobalRetainLock);
- return cf;
- }
- lowBits++;
- if (__builtin_expect((lowBits & 0x07fff) == 0, 0)) {
- // Roll over another bit to the external ref count
- _CFDictionaryIncrementValue(__CFRuntimeExternRefCountTable, DISGUISE(cf));
- lowBits = 0x8000; // Bit 16 indicates external ref count
- }
- ((CFRuntimeBase *)cf)->_rc = lowBits;
- __CFSpinUnlock(&__CFGlobalRetainLock);
- if (__builtin_expect(__CFOASafe, 0)) {
- uint64_t compositeRC;
- compositeRC = (lowBits & 0x7fff) + ((uint64_t)(uintptr_t)CFDictionaryGetValue(__CFRuntimeExternRefCountTable, DISGUISE(cf)) << 15);
- if (compositeRC > (uint64_t)0x7fffffff) compositeRC = (uint64_t)0x7fffffff;
- __CFRecordAllocationEvent(__kCFRetainEvent, (void *)cf, 0, compositeRC, NULL);
- }
- return cf;
-}
-
-CF_EXPORT void _CFRelease(CFTypeRef cf) {
- CFIndex lowBits = 0;
-#if defined(DEBUG)
- if (NULL == cf) HALT;
-#endif
- __CFSpinLock(&__CFGlobalRetainLock);
- lowBits = ((CFRuntimeBase *)cf)->_rc;
- if (__builtin_expect(0 == lowBits, 0)) { // Constant CFTypeRef
- __CFSpinUnlock(&__CFGlobalRetainLock);
- return;
- }
- if (__builtin_expect(1 == lowBits, 0)) {
- __CFSpinUnlock(&__CFGlobalRetainLock);
- if (__builtin_expect(__CFOASafe, 0)) __CFRecordAllocationEvent(__kCFReleaseEvent, (void *)cf, 0, 0, NULL);
- if (__builtin_expect(__kCFAllocatorTypeID_CONST == __CFGenericTypeID_inline(cf), 0)) {
-#if defined(DEBUG) || defined(ENABLE_ZOMBIES)
- __CFZombifyDeallocatedMemory((void *)cf);
- if (!(__CFZombieLevel & (1 << 4))) {
- __CFAllocatorDeallocate((void *)cf);
- }
-#else
- __CFAllocatorDeallocate((void *)cf);
-#endif
- } else {
- CFAllocatorRef allocator;
-// ((CFRuntimeBase *)cf)->_rc = 0;
- if (NULL != __CFRuntimeClassTable[__CFGenericTypeID_inline(cf)]->finalize) {
- __CFRuntimeClassTable[__CFGenericTypeID_inline(cf)]->finalize(cf);
- }
- if (__builtin_expect(__CFBitfieldGetValue(((const CFRuntimeBase *)cf)->_info, 7, 7), 1)) {
- allocator = kCFAllocatorSystemDefault;
- } else {
- allocator = CFGetAllocator(cf);
- (intptr_t)cf -= sizeof(CFAllocatorRef);
- }
-#if defined(DEBUG) || defined(ENABLE_ZOMBIES)
- __CFZombifyDeallocatedMemory((void *)cf);
- if (!(__CFZombieLevel & (1 << 4))) {
- CFAllocatorDeallocate(allocator, (void *)cf);
- }
-#else
- CFAllocatorDeallocate(allocator, (void *)cf);
-#endif
- if (kCFAllocatorSystemDefault != allocator) {
- CFRelease(allocator);
- }
- }
- } else {
- if (__builtin_expect(0x8000 == lowBits, 0)) {
- // Time to remove a bit from the external ref count
- if (0 == _CFDictionaryDecrementValue(__CFRuntimeExternRefCountTable, DISGUISE(cf))) {
- lowBits = 0x07fff;
- } else {
- lowBits = 0x0ffff;
- }
- } else {
- lowBits--;
- }
- ((CFRuntimeBase *)cf)->_rc = lowBits;
- __CFSpinUnlock(&__CFGlobalRetainLock);
- if (__builtin_expect(__CFOASafe, 0)) {
- uint64_t compositeRC;
- compositeRC = (lowBits & 0x7fff) + ((uint64_t)(uintptr_t)CFDictionaryGetValue(__CFRuntimeExternRefCountTable, DISGUISE(cf)) << 15);
- if (compositeRC > (uint64_t)0x7fffffff) compositeRC = (uint64_t)0x7fffffff;
- __CFRecordAllocationEvent(__kCFReleaseEvent, (void *)cf, 0, compositeRC, NULL);
- }
- }
-}
-
-#undef DO_SYSCALL_TRACE_HELPERS
-#undef SYSCALL_TRACE
-#undef __kCFAllocatorTypeID_CONST
-#undef __CFGenericAssertIsCF