]> git.saurik.com Git - apple/objc4.git/blob - test/testroot.i
objc4-779.1.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 atomic_int TestRootLoad;
10 atomic_int TestRootInitialize;
11 atomic_int TestRootAlloc;
12 atomic_int TestRootAllocWithZone;
13 atomic_int TestRootCopy;
14 atomic_int TestRootCopyWithZone;
15 atomic_int TestRootMutableCopy;
16 atomic_int TestRootMutableCopyWithZone;
17 atomic_int TestRootInit;
18 atomic_int TestRootDealloc;
19 atomic_int TestRootRetain;
20 atomic_int TestRootRelease;
21 atomic_int TestRootAutorelease;
22 atomic_int TestRootRetainCount;
23 atomic_int TestRootTryRetain;
24 atomic_int TestRootIsDeallocating;
25 atomic_int TestRootPlusRetain;
26 atomic_int TestRootPlusRelease;
27 atomic_int TestRootPlusAutorelease;
28 atomic_int TestRootPlusRetainCount;
29
30
31 @implementation TestRoot
32
33 // These all use void* pending rdar://9310005.
34
35 static void *
36 retain_fn(void *self, SEL _cmd __unused) {
37 atomic_fetch_add_explicit(&TestRootRetain, 1, memory_order_relaxed);
38 void * (*fn)(void *) = (typeof(fn))_objc_rootRetain;
39 return fn(self);
40 }
41
42 static void
43 release_fn(void *self, SEL _cmd __unused) {
44 atomic_fetch_add_explicit(&TestRootRelease, 1, memory_order_relaxed);
45 void (*fn)(void *) = (typeof(fn))_objc_rootRelease;
46 fn(self);
47 }
48
49 static void *
50 autorelease_fn(void *self, SEL _cmd __unused) {
51 atomic_fetch_add_explicit(&TestRootAutorelease, 1, memory_order_relaxed);
52 void * (*fn)(void *) = (typeof(fn))_objc_rootAutorelease;
53 return fn(self);
54 }
55
56 static unsigned long
57 retaincount_fn(void *self, SEL _cmd __unused) {
58 atomic_fetch_add_explicit(&TestRootRetainCount, 1, memory_order_relaxed);
59 unsigned long (*fn)(void *) = (typeof(fn))_objc_rootRetainCount;
60 return fn(self);
61 }
62
63 static void *
64 copywithzone_fn(void *self, SEL _cmd __unused, void *zone) {
65 atomic_fetch_add_explicit(&TestRootCopyWithZone, 1, memory_order_relaxed);
66 void * (*fn)(void *, void *) =
67 (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 atomic_fetch_add_explicit(&TestRootPlusRetain, 1, memory_order_relaxed);
74 return self;
75 }
76
77 static void
78 plusrelease_fn(void *self __unused, SEL _cmd __unused) {
79 atomic_fetch_add_explicit(&TestRootPlusRelease, 1, memory_order_relaxed);
80 }
81
82 static void *
83 plusautorelease_fn(void *self, SEL _cmd __unused) {
84 atomic_fetch_add_explicit(&TestRootPlusAutorelease, 1, memory_order_relaxed);
85 return self;
86 }
87
88 static unsigned long
89 plusretaincount_fn(void *self __unused, SEL _cmd __unused) {
90 atomic_fetch_add_explicit(&TestRootPlusRetainCount, 1, memory_order_relaxed);
91 return ULONG_MAX;
92 }
93
94 +(void) load {
95 atomic_fetch_add_explicit(&TestRootLoad, 1, memory_order_relaxed);
96
97 // install methods that ARC 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 atomic_fetch_add_explicit(&TestRootInitialize, 1, memory_order_relaxed);
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 atomic_fetch_add_explicit(&TestRootAlloc, 1, memory_order_relaxed);
141 void * (*fn)(id __unsafe_unretained) = (typeof(fn))_objc_rootAlloc;
142 return (__bridge_transfer id)(fn(self));
143 }
144
145 +(id) allocWithZone:(void *)zone {
146 atomic_fetch_add_explicit(&TestRootAllocWithZone, 1, memory_order_relaxed);
147 void * (*fn)(id __unsafe_unretained, void *) = (typeof(fn))_objc_rootAllocWithZone;
148 return (__bridge_transfer id)(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 atomic_fetch_add_explicit(&TestRootCopy, 1, memory_order_relaxed);
161 return [self copyWithZone:NULL];
162 }
163
164 +(id) mutableCopyWithZone:(void *) __unused zone {
165 fail("+mutableCopyWithZone: called");
166 }
167
168 -(id) mutableCopy {
169 atomic_fetch_add_explicit(&TestRootMutableCopy, 1, memory_order_relaxed);
170 return [self mutableCopyWithZone:NULL];
171 }
172
173 -(id) mutableCopyWithZone:(void *) __unused zone {
174 atomic_fetch_add_explicit(&TestRootMutableCopyWithZone, 1, memory_order_relaxed);
175 void * (*fn)(id __unsafe_unretained) = (typeof(fn))_objc_rootAlloc;
176 return (__bridge_transfer id)(fn(object_getClass(self)));
177 }
178
179 -(id) init {
180 atomic_fetch_add_explicit(&TestRootInit, 1, memory_order_relaxed);
181 return _objc_rootInit(self);
182 }
183
184 +(void) dealloc {
185 fail("+dealloc called");
186 }
187
188 -(void) dealloc {
189 atomic_fetch_add_explicit(&TestRootDealloc, 1, memory_order_relaxed);
190 _objc_rootDealloc(self);
191 }
192
193 +(BOOL) _tryRetain {
194 return YES;
195 }
196
197 -(BOOL) _tryRetain {
198 atomic_fetch_add_explicit(&TestRootTryRetain, 1, memory_order_relaxed);
199 return _objc_rootTryRetain(self);
200 }
201
202 +(BOOL) _isDeallocating {
203 return NO;
204 }
205
206 -(BOOL) _isDeallocating {
207 atomic_fetch_add_explicit(&TestRootIsDeallocating, 1, memory_order_relaxed);
208 return _objc_rootIsDeallocating(self);
209 }
210
211 -(BOOL) allowsWeakReference {
212 return ! [self _isDeallocating];
213 }
214
215 -(BOOL) retainWeakReference {
216 return [self _tryRetain];
217 }
218
219
220 @end