2 // Implementation of class TestRoot
3 // Include this file into your main test file to use it.
7 #include <objc/objc-internal.h>
10 int TestRootInitialize = 0;
11 int TestRootAlloc = 0;
12 int TestRootAllocWithZone = 0;
14 int TestRootCopyWithZone = 0;
15 int TestRootMutableCopy = 0;
16 int TestRootMutableCopyWithZone = 0;
18 int TestRootDealloc = 0;
19 int TestRootFinalize = 0;
20 int TestRootRetain = 0;
21 int TestRootRelease = 0;
22 int TestRootAutorelease = 0;
23 int TestRootRetainCount = 0;
24 int TestRootTryRetain = 0;
25 int TestRootIsDeallocating = 0;
26 int TestRootPlusRetain = 0;
27 int TestRootPlusRelease = 0;
28 int TestRootPlusAutorelease = 0;
29 int TestRootPlusRetainCount = 0;
32 @implementation TestRoot
34 // These all use void* pending rdar://9310005.
37 retain_fn(void *self, SEL _cmd __unused) {
38 OSAtomicIncrement32(&TestRootRetain);
39 void * (*fn)(void *) = (typeof(fn))_objc_rootRetain;
44 release_fn(void *self, SEL _cmd __unused) {
45 OSAtomicIncrement32(&TestRootRelease);
46 void (*fn)(void *) = (typeof(fn))_objc_rootRelease;
51 autorelease_fn(void *self, SEL _cmd __unused) {
52 OSAtomicIncrement32(&TestRootAutorelease);
53 void * (*fn)(void *) = (typeof(fn))_objc_rootAutorelease;
58 retaincount_fn(void *self, SEL _cmd __unused) {
59 OSAtomicIncrement32(&TestRootRetainCount);
60 unsigned long (*fn)(void *) = (typeof(fn))_objc_rootRetainCount;
65 copywithzone_fn(void *self, SEL _cmd __unused, void *zone) {
66 OSAtomicIncrement32(&TestRootCopyWithZone);
67 void * (*fn)(void *, void *) = (typeof(fn))dlsym(RTLD_DEFAULT, "object_copy");
68 return fn(self, zone);
72 plusretain_fn(void *self __unused, SEL _cmd __unused) {
73 OSAtomicIncrement32(&TestRootPlusRetain);
78 plusrelease_fn(void *self __unused, SEL _cmd __unused) {
79 OSAtomicIncrement32(&TestRootPlusRelease);
83 plusautorelease_fn(void *self, SEL _cmd __unused) {
84 OSAtomicIncrement32(&TestRootPlusAutorelease);
89 plusretaincount_fn(void *self __unused, SEL _cmd __unused) {
90 OSAtomicIncrement32(&TestRootPlusRetainCount);
95 OSAtomicIncrement32(&TestRootLoad);
97 // install methods that ARR refuses to compile
98 class_addMethod(self, sel_registerName("retain"), (IMP)retain_fn, "");
99 class_addMethod(self, sel_registerName("release"), (IMP)release_fn, "");
100 class_addMethod(self, sel_registerName("autorelease"), (IMP)autorelease_fn, "");
101 class_addMethod(self, sel_registerName("retainCount"), (IMP)retaincount_fn, "");
102 class_addMethod(self, sel_registerName("copyWithZone:"), (IMP)copywithzone_fn, "");
104 class_addMethod(object_getClass(self), sel_registerName("retain"), (IMP)plusretain_fn, "");
105 class_addMethod(object_getClass(self), sel_registerName("release"), (IMP)plusrelease_fn, "");
106 class_addMethod(object_getClass(self), sel_registerName("autorelease"), (IMP)plusautorelease_fn, "");
107 class_addMethod(object_getClass(self), sel_registerName("retainCount"), (IMP)plusretaincount_fn, "");
112 OSAtomicIncrement32(&TestRootInitialize);
124 return object_getClass(self);
127 +(Class) superclass {
128 return class_getSuperclass(self);
131 -(Class) superclass {
132 return class_getSuperclass([self class]);
136 return [[self alloc] init];
140 OSAtomicIncrement32(&TestRootAlloc);
141 void * (*fn)(id __unsafe_unretained) = (typeof(fn))_objc_rootAlloc;
142 return objc_retainedObject(fn(self));
145 +(id) allocWithZone:(void *)zone {
146 OSAtomicIncrement32(&TestRootAllocWithZone);
147 void * (*fn)(id __unsafe_unretained, void *) = (typeof(fn))_objc_rootAllocWithZone;
148 return objc_retainedObject(fn(self, zone));
155 +(id) copyWithZone:(void *) __unused zone {
160 OSAtomicIncrement32(&TestRootCopy);
161 return [self copyWithZone:NULL];
164 +(id) mutableCopyWithZone:(void *) __unused zone {
165 fail("+mutableCopyWithZone: called");
169 OSAtomicIncrement32(&TestRootMutableCopy);
170 return [self mutableCopyWithZone:NULL];
173 -(id) mutableCopyWithZone:(void *) __unused zone {
174 OSAtomicIncrement32(&TestRootMutableCopyWithZone);
175 void * (*fn)(id __unsafe_unretained) = (typeof(fn))_objc_rootAlloc;
176 return objc_retainedObject(fn(object_getClass(self)));
180 OSAtomicIncrement32(&TestRootInit);
181 return _objc_rootInit(self);
185 fail("+dealloc called");
189 OSAtomicIncrement32(&TestRootDealloc);
190 _objc_rootDealloc(self);
194 fail("+finalize called");
198 OSAtomicIncrement32(&TestRootFinalize);
199 _objc_rootFinalize(self);
207 OSAtomicIncrement32(&TestRootTryRetain);
208 return _objc_rootTryRetain(self);
211 +(BOOL) _isDeallocating {
215 -(BOOL) _isDeallocating {
216 OSAtomicIncrement32(&TestRootIsDeallocating);
217 return _objc_rootIsDeallocating(self);
220 -(BOOL) allowsWeakReference {
221 return ! [self _isDeallocating];
224 -(BOOL) retainWeakReference {
225 return [self _tryRetain];