]> git.saurik.com Git - apple/objc4.git/blob - test/runtime.m
objc4-781.2.tar.gz
[apple/objc4.git] / test / runtime.m
1 /*
2 TEST_BUILD_OUTPUT
3 .*runtime.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\](\n.* note: expanded from macro 'testassert')?
4 .*runtime.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\](\n.* note: expanded from macro 'testassert')?
5 .*runtime.m:\d+:\d+: warning: null passed to a callee that requires a non-null argument \[-Wnonnull\](\n.* note: expanded from macro 'testassert')?
6 END
7
8 TEST_RUN_OUTPUT
9 objc\[\d+\]: class `SwiftV1Class\' not linked into application
10 objc\[\d+\]: class `DoesNotExist\' not linked into application
11 OK: runtime.m
12 OR
13 confused by Foundation
14 OK: runtime.m
15 END
16 */
17
18
19 #include "test.h"
20 #include "testroot.i"
21 #include <string.h>
22 #include <dlfcn.h>
23 #include <mach-o/ldsyms.h>
24 #include <objc/objc-runtime.h>
25
26 #if __has_feature(objc_arc)
27
28 int main()
29 {
30 // provoke the same nullability warnings as the real test
31 objc_getClass(nil);
32 objc_getClass(nil);
33 objc_getClass(nil);
34
35 testwarn("rdar://11368528 confused by Foundation");
36 fprintf(stderr, "confused by Foundation\n");
37 succeed(__FILE__);
38 }
39
40 #else
41
42 @interface Sub : TestRoot @end
43 @implementation Sub @end
44
45 #define SwiftV1MangledName "_TtC6Module12SwiftV1Class"
46 #define SwiftV1MangledName2 "_TtC2Sw13SwiftV1Class2"
47 #define SwiftV1MangledName3 "_TtCs13SwiftV1Class3"
48 #define SwiftV1MangledName4 "_TtC6Swiftt13SwiftV1Class4"
49
50 __attribute__((objc_runtime_name(SwiftV1MangledName)))
51 @interface SwiftV1Class : TestRoot @end
52 @implementation SwiftV1Class @end
53
54 __attribute__((objc_runtime_name(SwiftV1MangledName2)))
55 @interface SwiftV1Class2 : TestRoot @end
56 @implementation SwiftV1Class2 @end
57
58 __attribute__((objc_runtime_name(SwiftV1MangledName3)))
59 @interface SwiftV1Class3 : TestRoot @end
60 @implementation SwiftV1Class3 @end
61
62 __attribute__((objc_runtime_name(SwiftV1MangledName4)))
63 @interface SwiftV1Class4 : TestRoot @end
64 @implementation SwiftV1Class4 @end
65
66
67 int main()
68 {
69 Class list[100];
70 Class *list2;
71 unsigned int count, count0, count2;
72 unsigned int i;
73 int foundTestRoot;
74 int foundSub;
75 int foundSwiftV1;
76 int foundSwiftV1class2;
77 int foundSwiftV1class3;
78 int foundSwiftV1class4;
79 const char **names;
80 const char **namesFromHeader;
81 Dl_info info;
82
83 [TestRoot class];
84
85 // This shouldn't touch any classes.
86 dladdr(&_mh_execute_header, &info);
87 names = objc_copyClassNamesForImage(info.dli_fname, &count);
88 testassert(names);
89 testassert(count == 6);
90 testassert(names[count] == NULL);
91 foundTestRoot = 0;
92 foundSub = 0;
93 foundSwiftV1 = 0;
94 foundSwiftV1class2 = 0;
95 foundSwiftV1class3 = 0;
96 foundSwiftV1class4 = 0;
97 for (i = 0; i < count; i++) {
98 if (0 == strcmp(names[i], "TestRoot")) foundTestRoot++;
99 if (0 == strcmp(names[i], "Sub")) foundSub++;
100 if (0 == strcmp(names[i], "Module.SwiftV1Class")) foundSwiftV1++;
101 if (0 == strcmp(names[i], "Sw.SwiftV1Class2")) foundSwiftV1class2++;
102 if (0 == strcmp(names[i], "Swift.SwiftV1Class3")) foundSwiftV1class3++;
103 if (0 == strcmp(names[i], "Swiftt.SwiftV1Class4")) foundSwiftV1class4++;
104 }
105 testassert(foundTestRoot == 1);
106 testassert(foundSub == 1);
107 testassert(foundSwiftV1 == 1);
108 testassert(foundSwiftV1class2 == 1);
109 testassert(foundSwiftV1class3 == 1);
110 testassert(foundSwiftV1class4 == 1);
111
112 // Getting the names using the header should give us the same list.
113 namesFromHeader = objc_copyClassNamesForImage(info.dli_fname, &count0);
114 testassert(namesFromHeader);
115 testassert(count == count0);
116 for (i = 0; i < count; i++) {
117 testassert(!strcmp(names[i], namesFromHeader[i]));
118 }
119
120
121 // class Sub hasn't been touched - make sure it's in the class list too
122 count0 = objc_getClassList(NULL, 0);
123 testassert(count0 >= 2 && count0 < 100);
124
125 list[count0-1] = NULL;
126 count = objc_getClassList(list, count0-1);
127 testassert(list[count0-1] == NULL);
128 testassert(count == count0);
129
130 // So that demangling works, fake what would have happened with Swift
131 // and force the "Swift" bit on the class
132 ((uintptr_t *)objc_getClass(SwiftV1MangledName))[4] |= 2;
133 ((uintptr_t *)objc_getClass(SwiftV1MangledName2))[4] |= 2;
134 ((uintptr_t *)objc_getClass(SwiftV1MangledName3))[4] |= 2;
135 ((uintptr_t *)objc_getClass(SwiftV1MangledName4))[4] |= 2;
136
137 count = objc_getClassList(list, count0);
138 testassert(count == count0);
139
140 for (i = 0; i < count; i++) {
141 testprintf("%s\n", class_getName(list[i]));
142 }
143
144 foundTestRoot = 0;
145 foundSub = 0;
146 foundSwiftV1 = 0;
147 foundSwiftV1class2 = 0;
148 foundSwiftV1class3 = 0;
149 foundSwiftV1class4 = 0;
150 for (i = 0; i < count; i++) {
151 if (0 == strcmp(class_getName(list[i]), "TestRoot")) foundTestRoot++;
152 if (0 == strcmp(class_getName(list[i]), "Sub")) foundSub++;
153 if (0 == strcmp(class_getName(list[i]), "Module.SwiftV1Class")) foundSwiftV1++;
154 if (0 == strcmp(class_getName(list[i]), "Sw.SwiftV1Class2")) foundSwiftV1class2++;
155 if (0 == strcmp(class_getName(list[i]), "Swift.SwiftV1Class3")) foundSwiftV1class3++;
156 if (0 == strcmp(class_getName(list[i]), "Swiftt.SwiftV1Class4")) foundSwiftV1class4++;
157 // list should be non-meta classes only
158 testassert(!class_isMetaClass(list[i]));
159 }
160 testassert(foundTestRoot == 1);
161 testassert(foundSub == 1);
162 testassert(foundSwiftV1 == 1);
163 testassert(foundSwiftV1class2 == 1);
164 testassert(foundSwiftV1class3 == 1);
165 testassert(foundSwiftV1class4 == 1);
166
167 // fixme check class handler
168 testassert(objc_getClass("TestRoot") == [TestRoot class]);
169 testassert(objc_getClass("Module.SwiftV1Class") == [SwiftV1Class class]);
170 testassert(objc_getClass(SwiftV1MangledName) == [SwiftV1Class class]);
171 testassert(objc_getClass("Sw.SwiftV1Class2") == [SwiftV1Class2 class]);
172 testassert(objc_getClass(SwiftV1MangledName2) == [SwiftV1Class2 class]);
173 testassert(objc_getClass("Swift.SwiftV1Class3") == [SwiftV1Class3 class]);
174 testassert(objc_getClass(SwiftV1MangledName3) == [SwiftV1Class3 class]);
175 testassert(objc_getClass("Swiftt.SwiftV1Class4") == [SwiftV1Class4 class]);
176 testassert(objc_getClass(SwiftV1MangledName4) == [SwiftV1Class4 class]);
177 testassert(objc_getClass("SwiftV1Class") == nil);
178 testassert(objc_getClass("DoesNotExist") == nil);
179 testassert(objc_getClass(NULL) == nil);
180
181 testassert(objc_getMetaClass("TestRoot") == object_getClass([TestRoot class]));
182 testassert(objc_getMetaClass("Module.SwiftV1Class") == object_getClass([SwiftV1Class class]));
183 testassert(objc_getMetaClass(SwiftV1MangledName) == object_getClass([SwiftV1Class class]));
184 testassert(objc_getMetaClass("SwiftV1Class") == nil);
185 testassert(objc_getMetaClass("DoesNotExist") == nil);
186 testassert(objc_getMetaClass(NULL) == nil);
187
188 // fixme check class no handler
189 testassert(objc_lookUpClass("TestRoot") == [TestRoot class]);
190 testassert(objc_lookUpClass("Module.SwiftV1Class") == [SwiftV1Class class]);
191 testassert(objc_lookUpClass(SwiftV1MangledName) == [SwiftV1Class class]);
192 testassert(objc_lookUpClass("SwiftV1Class") == nil);
193 testassert(objc_lookUpClass("DoesNotExist") == nil);
194 testassert(objc_lookUpClass(NULL) == nil);
195
196 testassert(! object_isClass(nil));
197 testassert(! object_isClass([TestRoot new]));
198 testassert(object_isClass([TestRoot class]));
199 testassert(object_isClass(object_getClass([TestRoot class])));
200 testassert(object_isClass([Sub class]));
201 testassert(object_isClass(object_getClass([Sub class])));
202 testassert(object_isClass([SwiftV1Class class]));
203 testassert(object_isClass(object_getClass([SwiftV1Class class])));
204
205 list2 = objc_copyClassList(&count2);
206 testassert(count2 == count);
207 testassert(list2);
208 testassert(malloc_size(list2) >= (1+count2) * sizeof(Class));
209 for (i = 0; i < count; i++) {
210 testassert(list[i] == list2[i]);
211 }
212 testassert(list2[count] == NULL);
213 free(list2);
214 free(objc_copyClassList(NULL));
215
216 // Make sure metaclasses get demangled too.
217 testassert(strcmp(class_getName([TestRoot class]), class_getName(object_getClass([TestRoot class]))) == 0);
218 testassert(strcmp(class_getName([Sub class]), class_getName(object_getClass([Sub class]))) == 0);
219 testassert(strcmp(class_getName([SwiftV1Class class]), class_getName(object_getClass([SwiftV1Class class]))) == 0);
220 testassert(strcmp(class_getName([SwiftV1Class2 class]), class_getName(object_getClass([SwiftV1Class2 class]))) == 0);
221 testassert(strcmp(class_getName([SwiftV1Class3 class]), class_getName(object_getClass([SwiftV1Class3 class]))) == 0);
222 testassert(strcmp(class_getName([SwiftV1Class4 class]), class_getName(object_getClass([SwiftV1Class4 class]))) == 0);
223
224 succeed(__FILE__);
225 }
226
227 #endif