]> git.saurik.com Git - apple/objc4.git/blob - test/testroot.i
objc4-532.tar.gz
[apple/objc4.git] / test / testroot.i
1 // testroot.i
2 // Implementation of class TestRoot
3 // Include this file into your main test file to use it.
4
5 #include "test.h"
6 #include <dlfcn.h>
7 #include <objc/objc-internal.h>
8
9 int TestRootLoad = 0;
10 int TestRootInitialize = 0;
11 int TestRootAlloc = 0;
12 int TestRootAllocWithZone = 0;
13 int TestRootCopy = 0;
14 int TestRootCopyWithZone = 0;
15 int TestRootMutableCopy = 0;
16 int TestRootMutableCopyWithZone = 0;
17 int TestRootInit = 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;
30
31
32 @implementation TestRoot
33
34 // These all use void* pending rdar://9310005.
35
36 static void *
37 retain_fn(void *self, SEL _cmd __unused) {
38 OSAtomicIncrement32(&TestRootRetain);
39 void * (*fn)(void *) = (typeof(fn))_objc_rootRetain;
40 return fn(self);
41 }
42
43 static void
44 release_fn(void *self, SEL _cmd __unused) {
45 OSAtomicIncrement32(&TestRootRelease);
46 void (*fn)(void *) = (typeof(fn))_objc_rootRelease;
47 fn(self);
48 }
49
50 static void *
51 autorelease_fn(void *self, SEL _cmd __unused) {
52 OSAtomicIncrement32(&TestRootAutorelease);
53 void * (*fn)(void *) = (typeof(fn))_objc_rootAutorelease;
54 return fn(self);
55 }
56
57 static unsigned long
58 retaincount_fn(void *self, SEL _cmd __unused) {
59 OSAtomicIncrement32(&TestRootRetainCount);
60 unsigned long (*fn)(void *) = (typeof(fn))_objc_rootRetainCount;
61 return fn(self);
62 }
63
64 static void *
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);
69 }
70
71 static void *
72 plusretain_fn(void *self __unused, SEL _cmd __unused) {
73 OSAtomicIncrement32(&TestRootPlusRetain);
74 return self;
75 }
76
77 static void
78 plusrelease_fn(void *self __unused, SEL _cmd __unused) {
79 OSAtomicIncrement32(&TestRootPlusRelease);
80 }
81
82 static void *
83 plusautorelease_fn(void *self, SEL _cmd __unused) {
84 OSAtomicIncrement32(&TestRootPlusAutorelease);
85 return self;
86 }
87
88 static unsigned long
89 plusretaincount_fn(void *self __unused, SEL _cmd __unused) {
90 OSAtomicIncrement32(&TestRootPlusRetainCount);
91 return ULONG_MAX;
92 }
93
94 +(void) load {
95 OSAtomicIncrement32(&TestRootLoad);
96
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, "");
103
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, "");
108 }
109
110
111 +(void) initialize {
112 OSAtomicIncrement32(&TestRootInitialize);
113 }
114
115 -(id) self {
116 return self;
117 }
118
119 +(Class) class {
120 return self;
121 }
122
123 -(Class) class {
124 return object_getClass(self);
125 }
126
127 +(Class) superclass {
128 return class_getSuperclass(self);
129 }
130
131 -(Class) superclass {
132 return class_getSuperclass([self class]);
133 }
134
135 +(id) new {
136 return [[self alloc] init];
137 }
138
139 +(id) alloc {
140 OSAtomicIncrement32(&TestRootAlloc);
141 void * (*fn)(id __unsafe_unretained) = (typeof(fn))_objc_rootAlloc;
142 return objc_retainedObject(fn(self));
143 }
144
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));
149 }
150
151 +(id) copy {
152 return self;
153 }
154
155 +(id) copyWithZone:(void *) __unused zone {
156 return self;
157 }
158
159 -(id) copy {
160 OSAtomicIncrement32(&TestRootCopy);
161 return [self copyWithZone:NULL];
162 }
163
164 +(id) mutableCopyWithZone:(void *) __unused zone {
165 fail("+mutableCopyWithZone: called");
166 }
167
168 -(id) mutableCopy {
169 OSAtomicIncrement32(&TestRootMutableCopy);
170 return [self mutableCopyWithZone:NULL];
171 }
172
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)));
177 }
178
179 -(id) init {
180 OSAtomicIncrement32(&TestRootInit);
181 return _objc_rootInit(self);
182 }
183
184 +(void) dealloc {
185 fail("+dealloc called");
186 }
187
188 -(void) dealloc {
189 OSAtomicIncrement32(&TestRootDealloc);
190 _objc_rootDealloc(self);
191 }
192
193 +(void) finalize {
194 fail("+finalize called");
195 }
196
197 -(void) finalize {
198 OSAtomicIncrement32(&TestRootFinalize);
199 _objc_rootFinalize(self);
200 }
201
202 +(BOOL) _tryRetain {
203 return YES;
204 }
205
206 -(BOOL) _tryRetain {
207 OSAtomicIncrement32(&TestRootTryRetain);
208 return _objc_rootTryRetain(self);
209 }
210
211 +(BOOL) _isDeallocating {
212 return NO;
213 }
214
215 -(BOOL) _isDeallocating {
216 OSAtomicIncrement32(&TestRootIsDeallocating);
217 return _objc_rootIsDeallocating(self);
218 }
219
220 -(BOOL) allowsWeakReference {
221 return ! [self _isDeallocating];
222 }
223
224 -(BOOL) retainWeakReference {
225 return [self _tryRetain];
226 }
227
228
229 @end