annotate gcc/testsuite/objc.dg/gnu-api-2-resolve-method.m @ 138:fc828634a951

merge
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Thu, 08 Nov 2018 14:17:14 +0900
parents 04ced10e8804
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* Test the Modern GNU Objective-C Runtime API.
kono
parents:
diff changeset
2
kono
parents:
diff changeset
3 This is test 'resolve-method', covering +resolveClassMethod: and
kono
parents:
diff changeset
4 +resolveInstanceMethod:. */
kono
parents:
diff changeset
5
kono
parents:
diff changeset
6 /* { dg-do run } */
kono
parents:
diff changeset
7 /* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */
kono
parents:
diff changeset
8
kono
parents:
diff changeset
9 /* To get the modern GNU Objective-C Runtime API, you include
kono
parents:
diff changeset
10 objc/runtime.h. */
kono
parents:
diff changeset
11 #include <objc/runtime.h>
kono
parents:
diff changeset
12
kono
parents:
diff changeset
13 /* For __objc_msg_forward2. */
kono
parents:
diff changeset
14 #include <objc/message.h>
kono
parents:
diff changeset
15
kono
parents:
diff changeset
16 #include <stdlib.h>
kono
parents:
diff changeset
17 #include <stdio.h>
kono
parents:
diff changeset
18 #include <string.h>
kono
parents:
diff changeset
19
kono
parents:
diff changeset
20 @interface MyRootClass
kono
parents:
diff changeset
21 { Class isa; }
kono
parents:
diff changeset
22 + alloc;
kono
parents:
diff changeset
23 - init;
kono
parents:
diff changeset
24 @end
kono
parents:
diff changeset
25
kono
parents:
diff changeset
26 @implementation MyRootClass
kono
parents:
diff changeset
27 + alloc { return class_createInstance (self, 0); }
kono
parents:
diff changeset
28 - init { return self; }
kono
parents:
diff changeset
29 @end
kono
parents:
diff changeset
30
kono
parents:
diff changeset
31
kono
parents:
diff changeset
32 /* A number of tests will try invoking methods that don't exist. We
kono
parents:
diff changeset
33 want to record the fact, but not abort the program, so we supply
kono
parents:
diff changeset
34 our own fowarding implementation which will invoke the following
kono
parents:
diff changeset
35 function for any method that is not found. */
kono
parents:
diff changeset
36
kono
parents:
diff changeset
37 /* Keep track of how many times a non-existing method was executed. */
kono
parents:
diff changeset
38 static int nonExistingMethodCount = 0;
kono
parents:
diff changeset
39
kono
parents:
diff changeset
40 /* Inspired by nil_method in libobjc. */
kono
parents:
diff changeset
41 id nonExisting_method (id receiver __attribute__ ((__unused__)),
kono
parents:
diff changeset
42 SEL sel __attribute__ ((__unused__)))
kono
parents:
diff changeset
43 {
kono
parents:
diff changeset
44 nonExistingMethodCount++;
kono
parents:
diff changeset
45 return nil;
kono
parents:
diff changeset
46 }
kono
parents:
diff changeset
47
kono
parents:
diff changeset
48 /* Keep track of how many times the forwarding lookup was invoked. */
kono
parents:
diff changeset
49 static int forwardingCount = 0;
kono
parents:
diff changeset
50
kono
parents:
diff changeset
51 /* We install this forwarding hook to cause all failed method lookups
kono
parents:
diff changeset
52 to call our 'nonExisting_method' function. */
kono
parents:
diff changeset
53 IMP forward_everything_to_non_existing_method (id receiver __attribute__ ((__unused__)),
kono
parents:
diff changeset
54 SEL sel __attribute__ ((__unused__)))
kono
parents:
diff changeset
55 {
kono
parents:
diff changeset
56 forwardingCount++;
kono
parents:
diff changeset
57 return (IMP)nonExisting_method;
kono
parents:
diff changeset
58 }
kono
parents:
diff changeset
59
kono
parents:
diff changeset
60
kono
parents:
diff changeset
61 /* 'CountClass' is used to test that +resolveClassMethod: and
kono
parents:
diff changeset
62 +resolveInstanceMethod: are called when expected. They do nothing
kono
parents:
diff changeset
63 other than recording that they are called. */
kono
parents:
diff changeset
64 @interface CountClass : MyRootClass
kono
parents:
diff changeset
65 + (BOOL) resolveClassMethod: (SEL)selector;
kono
parents:
diff changeset
66 + (BOOL) resolveInstanceMethod: (SEL)selector;
kono
parents:
diff changeset
67 + (void) existingClassMethod;
kono
parents:
diff changeset
68 - (void) existingInstanceMethod;
kono
parents:
diff changeset
69 @end
kono
parents:
diff changeset
70
kono
parents:
diff changeset
71 /* Count how many times the methods are called for class
kono
parents:
diff changeset
72 'CountClass'. */
kono
parents:
diff changeset
73 static int resolveClassMethodCount = 0;
kono
parents:
diff changeset
74 static int resolveInstanceMethodCount = 0;
kono
parents:
diff changeset
75
kono
parents:
diff changeset
76 @implementation CountClass : MyRootClass
kono
parents:
diff changeset
77 + (BOOL) resolveClassMethod: (SEL)selector
kono
parents:
diff changeset
78 {
kono
parents:
diff changeset
79 resolveClassMethodCount++;
kono
parents:
diff changeset
80 return NO;
kono
parents:
diff changeset
81 }
kono
parents:
diff changeset
82 + (BOOL) resolveInstanceMethod: (SEL)selector
kono
parents:
diff changeset
83 {
kono
parents:
diff changeset
84 resolveInstanceMethodCount++;
kono
parents:
diff changeset
85 return NO;
kono
parents:
diff changeset
86 }
kono
parents:
diff changeset
87 + (void) existingClassMethod
kono
parents:
diff changeset
88 {
kono
parents:
diff changeset
89 return;
kono
parents:
diff changeset
90 }
kono
parents:
diff changeset
91 - (void) existingInstanceMethod
kono
parents:
diff changeset
92 {
kono
parents:
diff changeset
93 return;
kono
parents:
diff changeset
94 }
kono
parents:
diff changeset
95 @end
kono
parents:
diff changeset
96
kono
parents:
diff changeset
97 @protocol NonExistingStuff
kono
parents:
diff changeset
98 + (void) nonExistingClassMethod;
kono
parents:
diff changeset
99 - (void) nonExistingInstanceMethod;
kono
parents:
diff changeset
100 @end
kono
parents:
diff changeset
101
kono
parents:
diff changeset
102 /* Declare a category with some non existing methods, but don't
kono
parents:
diff changeset
103 actually implement them. */
kono
parents:
diff changeset
104 @interface CountClass (NonExistingStuff) <NonExistingStuff>
kono
parents:
diff changeset
105 @end
kono
parents:
diff changeset
106
kono
parents:
diff changeset
107
kono
parents:
diff changeset
108 /* 'SelfExtendingClass' is used to test that +resolveClassMethod: and
kono
parents:
diff changeset
109 +resolveInstanceMethod: can extend the class. Any time they are
kono
parents:
diff changeset
110 called, they install the requested method, mapping it to the same
kono
parents:
diff changeset
111 implementation as 'countHits'. */
kono
parents:
diff changeset
112 @interface SelfExtendingClass : MyRootClass
kono
parents:
diff changeset
113 + (int) countHits;
kono
parents:
diff changeset
114 + (BOOL) resolveClassMethod: (SEL)selector;
kono
parents:
diff changeset
115 + (BOOL) resolveInstanceMethod: (SEL)selector;
kono
parents:
diff changeset
116 @end
kono
parents:
diff changeset
117
kono
parents:
diff changeset
118 /* How many times the countHits method (or a clone) was called. */
kono
parents:
diff changeset
119 static int hitCount = 0;
kono
parents:
diff changeset
120
kono
parents:
diff changeset
121 @implementation SelfExtendingClass : MyRootClass
kono
parents:
diff changeset
122 + (int) countHits
kono
parents:
diff changeset
123 {
kono
parents:
diff changeset
124 hitCount++;
kono
parents:
diff changeset
125 return hitCount;
kono
parents:
diff changeset
126 }
kono
parents:
diff changeset
127 + (BOOL) resolveClassMethod: (SEL)selector
kono
parents:
diff changeset
128 {
kono
parents:
diff changeset
129 /* Duplicate the 'countHits' method into the new method. */
kono
parents:
diff changeset
130 Method method = class_getClassMethod (self, @selector (countHits));
kono
parents:
diff changeset
131 class_addMethod (object_getClass (self), selector,
kono
parents:
diff changeset
132 method_getImplementation (method),
kono
parents:
diff changeset
133 method_getTypeEncoding (method));
kono
parents:
diff changeset
134 resolveClassMethodCount++;
kono
parents:
diff changeset
135 return YES;
kono
parents:
diff changeset
136 }
kono
parents:
diff changeset
137 + (BOOL) resolveInstanceMethod: (SEL)selector
kono
parents:
diff changeset
138 {
kono
parents:
diff changeset
139 /* Duplicate the 'countHits' method into the new method. */
kono
parents:
diff changeset
140 Method method = class_getClassMethod (self, @selector (countHits));
kono
parents:
diff changeset
141 class_addMethod (self, selector,
kono
parents:
diff changeset
142 method_getImplementation (method),
kono
parents:
diff changeset
143 method_getTypeEncoding (method));
kono
parents:
diff changeset
144 resolveInstanceMethodCount++;
kono
parents:
diff changeset
145 return YES;
kono
parents:
diff changeset
146
kono
parents:
diff changeset
147 }
kono
parents:
diff changeset
148 @end
kono
parents:
diff changeset
149
kono
parents:
diff changeset
150 @protocol NonExistingStuff2
kono
parents:
diff changeset
151 + (int) nonExistingCountHitsMethod;
kono
parents:
diff changeset
152 - (int) nonExistingCountHitsMethod;
kono
parents:
diff changeset
153
kono
parents:
diff changeset
154 + (int) nonExistingCountHitsMethod2;
kono
parents:
diff changeset
155 - (int) nonExistingCountHitsMethod2;
kono
parents:
diff changeset
156
kono
parents:
diff changeset
157 + (int) nonExistingCountHitsMethod3;
kono
parents:
diff changeset
158 - (int) nonExistingCountHitsMethod3;
kono
parents:
diff changeset
159 @end
kono
parents:
diff changeset
160
kono
parents:
diff changeset
161 /* Declare a category with some non existing methods, but don't
kono
parents:
diff changeset
162 actually implement them. */
kono
parents:
diff changeset
163 @interface SelfExtendingClass (NonExistingStuff) <NonExistingStuff2>
kono
parents:
diff changeset
164 @end
kono
parents:
diff changeset
165
kono
parents:
diff changeset
166
kono
parents:
diff changeset
167 int main (int argc, void **args)
kono
parents:
diff changeset
168 {
kono
parents:
diff changeset
169 /* Functions are tested in alphabetical order. */
kono
parents:
diff changeset
170
kono
parents:
diff changeset
171 /* Install our test forwarding hook. */
kono
parents:
diff changeset
172 __objc_msg_forward2 = forward_everything_to_non_existing_method;
kono
parents:
diff changeset
173
kono
parents:
diff changeset
174 printf ("Testing [+resolveClassMethod:]...\n");
kono
parents:
diff changeset
175 {
kono
parents:
diff changeset
176 Method m;
kono
parents:
diff changeset
177 IMP i;
kono
parents:
diff changeset
178
kono
parents:
diff changeset
179 /** CountClass tests. **/
kono
parents:
diff changeset
180
kono
parents:
diff changeset
181 /* Call an existing method. No +resolveClassMethod and no
kono
parents:
diff changeset
182 forwarding should be triggered. */
kono
parents:
diff changeset
183 [CountClass existingClassMethod];
kono
parents:
diff changeset
184
kono
parents:
diff changeset
185 if (resolveClassMethodCount != 0)
kono
parents:
diff changeset
186 abort ();
kono
parents:
diff changeset
187
kono
parents:
diff changeset
188 if (forwardingCount != 0)
kono
parents:
diff changeset
189 abort ();
kono
parents:
diff changeset
190
kono
parents:
diff changeset
191 if (nonExistingMethodCount != 0)
kono
parents:
diff changeset
192 abort ();
kono
parents:
diff changeset
193
kono
parents:
diff changeset
194 /* Call a non-existing method. Both +resolveClassMethod and the
kono
parents:
diff changeset
195 forwarding should be triggered. */
kono
parents:
diff changeset
196 [CountClass nonExistingClassMethod];
kono
parents:
diff changeset
197
kono
parents:
diff changeset
198 if (resolveClassMethodCount != 1)
kono
parents:
diff changeset
199 abort ();
kono
parents:
diff changeset
200
kono
parents:
diff changeset
201 if (forwardingCount != 1)
kono
parents:
diff changeset
202 abort ();
kono
parents:
diff changeset
203
kono
parents:
diff changeset
204 if (nonExistingMethodCount != 1)
kono
parents:
diff changeset
205 abort ();
kono
parents:
diff changeset
206
kono
parents:
diff changeset
207 /* Now try the same tests with class_getClassMethod(), which
kono
parents:
diff changeset
208 should trigger the resolve methods too, but not the
kono
parents:
diff changeset
209 forwarding. */
kono
parents:
diff changeset
210 m = class_getClassMethod (objc_getClass ("CountClass"),
kono
parents:
diff changeset
211 @selector (existingClassMethod));
kono
parents:
diff changeset
212 if (resolveClassMethodCount != 1)
kono
parents:
diff changeset
213 abort ();
kono
parents:
diff changeset
214
kono
parents:
diff changeset
215 if (forwardingCount != 1)
kono
parents:
diff changeset
216 abort ();
kono
parents:
diff changeset
217
kono
parents:
diff changeset
218 if (nonExistingMethodCount != 1)
kono
parents:
diff changeset
219 abort ();
kono
parents:
diff changeset
220
kono
parents:
diff changeset
221 m = class_getClassMethod (objc_getClass ("CountClass"),
kono
parents:
diff changeset
222 @selector (nonExistingClassMethod));
kono
parents:
diff changeset
223 if (resolveClassMethodCount != 2)
kono
parents:
diff changeset
224 abort ();
kono
parents:
diff changeset
225
kono
parents:
diff changeset
226 if (forwardingCount != 1)
kono
parents:
diff changeset
227 abort ();
kono
parents:
diff changeset
228
kono
parents:
diff changeset
229 if (nonExistingMethodCount != 1)
kono
parents:
diff changeset
230 abort ();
kono
parents:
diff changeset
231
kono
parents:
diff changeset
232 /* Now try the same tests with class_getMethodImplementation(),
kono
parents:
diff changeset
233 which should trigger the resolve methods and the forwarding
kono
parents:
diff changeset
234 (but not execute the forwarding, obviously). */
kono
parents:
diff changeset
235 i = class_getMethodImplementation (object_getClass (objc_getClass ("CountClass")),
kono
parents:
diff changeset
236 @selector (existingClassMethod));
kono
parents:
diff changeset
237 if (resolveClassMethodCount != 2)
kono
parents:
diff changeset
238 abort ();
kono
parents:
diff changeset
239
kono
parents:
diff changeset
240 if (forwardingCount != 1)
kono
parents:
diff changeset
241 abort ();
kono
parents:
diff changeset
242
kono
parents:
diff changeset
243 if (nonExistingMethodCount != 1)
kono
parents:
diff changeset
244 abort ();
kono
parents:
diff changeset
245
kono
parents:
diff changeset
246 i = class_getMethodImplementation (object_getClass (objc_getClass ("CountClass")),
kono
parents:
diff changeset
247 @selector (nonExistingClassMethod));
kono
parents:
diff changeset
248 if (resolveClassMethodCount != 3)
kono
parents:
diff changeset
249 abort ();
kono
parents:
diff changeset
250
kono
parents:
diff changeset
251 if (forwardingCount != 2)
kono
parents:
diff changeset
252 abort ();
kono
parents:
diff changeset
253
kono
parents:
diff changeset
254 if (nonExistingMethodCount != 1)
kono
parents:
diff changeset
255 abort ();
kono
parents:
diff changeset
256
kono
parents:
diff changeset
257
kono
parents:
diff changeset
258 /* Reset the counters for the next test. */
kono
parents:
diff changeset
259 resolveClassMethodCount = 0;
kono
parents:
diff changeset
260 forwardingCount = 0;
kono
parents:
diff changeset
261 nonExistingMethodCount = 0;
kono
parents:
diff changeset
262
kono
parents:
diff changeset
263
kono
parents:
diff changeset
264 /** SelfExtendingClass tests. **/
kono
parents:
diff changeset
265
kono
parents:
diff changeset
266 /* Try the direct countHits method first. No resolving or
kono
parents:
diff changeset
267 forwarding should be triggered. */
kono
parents:
diff changeset
268 if ([SelfExtendingClass countHits] != 1)
kono
parents:
diff changeset
269 abort ();
kono
parents:
diff changeset
270
kono
parents:
diff changeset
271 if (resolveClassMethodCount != 0)
kono
parents:
diff changeset
272 abort ();
kono
parents:
diff changeset
273
kono
parents:
diff changeset
274 if (forwardingCount != 0)
kono
parents:
diff changeset
275 abort ();
kono
parents:
diff changeset
276
kono
parents:
diff changeset
277 if (nonExistingMethodCount != 0)
kono
parents:
diff changeset
278 abort ();
kono
parents:
diff changeset
279
kono
parents:
diff changeset
280 /* Now, try calling a non-existing count method; it should be
kono
parents:
diff changeset
281 installed and invoked. */
kono
parents:
diff changeset
282 if ([SelfExtendingClass nonExistingCountHitsMethod] != 2)
kono
parents:
diff changeset
283 abort ();
kono
parents:
diff changeset
284
kono
parents:
diff changeset
285 if (resolveClassMethodCount != 1)
kono
parents:
diff changeset
286 abort ();
kono
parents:
diff changeset
287
kono
parents:
diff changeset
288 if (forwardingCount != 0)
kono
parents:
diff changeset
289 abort ();
kono
parents:
diff changeset
290
kono
parents:
diff changeset
291 if (nonExistingMethodCount != 0)
kono
parents:
diff changeset
292 abort ();
kono
parents:
diff changeset
293
kono
parents:
diff changeset
294 /* Try it again. The method has now been installed, so it should
kono
parents:
diff changeset
295 be used and work, but with no additional resolving
kono
parents:
diff changeset
296 involved. */
kono
parents:
diff changeset
297 if ([SelfExtendingClass nonExistingCountHitsMethod] != 3)
kono
parents:
diff changeset
298 abort ();
kono
parents:
diff changeset
299
kono
parents:
diff changeset
300 if (resolveClassMethodCount != 1)
kono
parents:
diff changeset
301 abort ();
kono
parents:
diff changeset
302
kono
parents:
diff changeset
303 if (forwardingCount != 0)
kono
parents:
diff changeset
304 abort ();
kono
parents:
diff changeset
305
kono
parents:
diff changeset
306 if (nonExistingMethodCount != 0)
kono
parents:
diff changeset
307 abort ();
kono
parents:
diff changeset
308
kono
parents:
diff changeset
309
kono
parents:
diff changeset
310 /* Now try the same tests with class_getClassMethod(). */
kono
parents:
diff changeset
311 m = class_getClassMethod (objc_getClass ("SelfExtendingClass"),
kono
parents:
diff changeset
312 @selector (nonExistingCountHitsMethod2));
kono
parents:
diff changeset
313 if (resolveClassMethodCount != 2)
kono
parents:
diff changeset
314 abort ();
kono
parents:
diff changeset
315
kono
parents:
diff changeset
316 if (forwardingCount != 0)
kono
parents:
diff changeset
317 abort ();
kono
parents:
diff changeset
318
kono
parents:
diff changeset
319 if (nonExistingMethodCount != 0)
kono
parents:
diff changeset
320 abort ();
kono
parents:
diff changeset
321
kono
parents:
diff changeset
322 /* Try it again. The method has now been installed, so it should
kono
parents:
diff changeset
323 be used and work, but with no additional resolving
kono
parents:
diff changeset
324 involved. */
kono
parents:
diff changeset
325 if ([SelfExtendingClass nonExistingCountHitsMethod2] != 4)
kono
parents:
diff changeset
326 abort ();
kono
parents:
diff changeset
327
kono
parents:
diff changeset
328 if (resolveClassMethodCount != 2)
kono
parents:
diff changeset
329 abort ();
kono
parents:
diff changeset
330
kono
parents:
diff changeset
331 if (forwardingCount != 0)
kono
parents:
diff changeset
332 abort ();
kono
parents:
diff changeset
333
kono
parents:
diff changeset
334 if (nonExistingMethodCount != 0)
kono
parents:
diff changeset
335 abort ();
kono
parents:
diff changeset
336
kono
parents:
diff changeset
337
kono
parents:
diff changeset
338 /* Now try the same tests with class_getMethodImplementation(). */
kono
parents:
diff changeset
339 i = class_getMethodImplementation (object_getClass (objc_getClass ("SelfExtendingClass")),
kono
parents:
diff changeset
340 @selector (nonExistingCountHitsMethod3));
kono
parents:
diff changeset
341 if (resolveClassMethodCount != 3)
kono
parents:
diff changeset
342 abort ();
kono
parents:
diff changeset
343
kono
parents:
diff changeset
344 if (forwardingCount != 0)
kono
parents:
diff changeset
345 abort ();
kono
parents:
diff changeset
346
kono
parents:
diff changeset
347 if (nonExistingMethodCount != 0)
kono
parents:
diff changeset
348 abort ();
kono
parents:
diff changeset
349
kono
parents:
diff changeset
350 /* Try it again. The method has now been installed, so it should
kono
parents:
diff changeset
351 be used and work, but with no additional resolving
kono
parents:
diff changeset
352 involved. */
kono
parents:
diff changeset
353 if ([SelfExtendingClass nonExistingCountHitsMethod3] != 5)
kono
parents:
diff changeset
354 abort ();
kono
parents:
diff changeset
355
kono
parents:
diff changeset
356 if (resolveClassMethodCount != 3)
kono
parents:
diff changeset
357 abort ();
kono
parents:
diff changeset
358
kono
parents:
diff changeset
359 if (forwardingCount != 0)
kono
parents:
diff changeset
360 abort ();
kono
parents:
diff changeset
361
kono
parents:
diff changeset
362 if (nonExistingMethodCount != 0)
kono
parents:
diff changeset
363 abort ();
kono
parents:
diff changeset
364 }
kono
parents:
diff changeset
365
kono
parents:
diff changeset
366 /* Reset the counters for the next test. */
kono
parents:
diff changeset
367 nonExistingMethodCount = 0;
kono
parents:
diff changeset
368 forwardingCount = 0;
kono
parents:
diff changeset
369 hitCount = 0;
kono
parents:
diff changeset
370
kono
parents:
diff changeset
371 printf ("Testing [+resolveInstanceMethod:]...\n");
kono
parents:
diff changeset
372 {
kono
parents:
diff changeset
373 Method m;
kono
parents:
diff changeset
374 IMP i;
kono
parents:
diff changeset
375 CountClass *object = [[CountClass alloc] init];
kono
parents:
diff changeset
376 SelfExtendingClass *object2 = [[SelfExtendingClass alloc] init];
kono
parents:
diff changeset
377
kono
parents:
diff changeset
378 /** CountClass tests. **/
kono
parents:
diff changeset
379
kono
parents:
diff changeset
380 /* Call an existing method. No +resolveInstanceMethod and no
kono
parents:
diff changeset
381 forwarding should be triggered. */
kono
parents:
diff changeset
382 [object existingInstanceMethod];
kono
parents:
diff changeset
383
kono
parents:
diff changeset
384 if (resolveInstanceMethodCount != 0)
kono
parents:
diff changeset
385 abort ();
kono
parents:
diff changeset
386
kono
parents:
diff changeset
387 if (forwardingCount != 0)
kono
parents:
diff changeset
388 abort ();
kono
parents:
diff changeset
389
kono
parents:
diff changeset
390 if (nonExistingMethodCount != 0)
kono
parents:
diff changeset
391 abort ();
kono
parents:
diff changeset
392
kono
parents:
diff changeset
393 /* Call a non-existing method. Both +resolveInstanceMethod and the
kono
parents:
diff changeset
394 forwarding should be triggered. */
kono
parents:
diff changeset
395 [object nonExistingInstanceMethod];
kono
parents:
diff changeset
396
kono
parents:
diff changeset
397 if (resolveInstanceMethodCount != 1)
kono
parents:
diff changeset
398 abort ();
kono
parents:
diff changeset
399
kono
parents:
diff changeset
400 if (forwardingCount != 1)
kono
parents:
diff changeset
401 abort ();
kono
parents:
diff changeset
402
kono
parents:
diff changeset
403 if (nonExistingMethodCount != 1)
kono
parents:
diff changeset
404 abort ();
kono
parents:
diff changeset
405
kono
parents:
diff changeset
406 /* Now try the same tests with class_getInstanceMethod(), which
kono
parents:
diff changeset
407 should trigger the resolve methods too, but not the
kono
parents:
diff changeset
408 forwarding. */
kono
parents:
diff changeset
409 m = class_getInstanceMethod (objc_getClass ("CountClass"),
kono
parents:
diff changeset
410 @selector (existingInstanceMethod));
kono
parents:
diff changeset
411
kono
parents:
diff changeset
412 if (resolveInstanceMethodCount != 1)
kono
parents:
diff changeset
413 abort ();
kono
parents:
diff changeset
414
kono
parents:
diff changeset
415 if (forwardingCount != 1)
kono
parents:
diff changeset
416 abort ();
kono
parents:
diff changeset
417
kono
parents:
diff changeset
418 if (nonExistingMethodCount != 1)
kono
parents:
diff changeset
419 abort ();
kono
parents:
diff changeset
420
kono
parents:
diff changeset
421 m = class_getInstanceMethod (objc_getClass ("CountClass"),
kono
parents:
diff changeset
422 @selector (nonExistingInstanceMethod));
kono
parents:
diff changeset
423
kono
parents:
diff changeset
424 if (resolveInstanceMethodCount != 2)
kono
parents:
diff changeset
425 abort ();
kono
parents:
diff changeset
426
kono
parents:
diff changeset
427 if (forwardingCount != 1)
kono
parents:
diff changeset
428 abort ();
kono
parents:
diff changeset
429
kono
parents:
diff changeset
430 if (nonExistingMethodCount != 1)
kono
parents:
diff changeset
431 abort ();
kono
parents:
diff changeset
432
kono
parents:
diff changeset
433 /* Now try the same tests with class_getMethodImplementation(),
kono
parents:
diff changeset
434 which should trigger the resolve methods and the
kono
parents:
diff changeset
435 forwarding. */
kono
parents:
diff changeset
436 i = class_getMethodImplementation (objc_getClass ("CountClass"),
kono
parents:
diff changeset
437 @selector (existingInstanceMethod));
kono
parents:
diff changeset
438 if (resolveInstanceMethodCount != 2)
kono
parents:
diff changeset
439 abort ();
kono
parents:
diff changeset
440
kono
parents:
diff changeset
441 if (forwardingCount != 1)
kono
parents:
diff changeset
442 abort ();
kono
parents:
diff changeset
443
kono
parents:
diff changeset
444 if (nonExistingMethodCount != 1)
kono
parents:
diff changeset
445 abort ();
kono
parents:
diff changeset
446
kono
parents:
diff changeset
447 i = class_getMethodImplementation (objc_getClass ("CountClass"),
kono
parents:
diff changeset
448 @selector (nonExistingInstanceMethod));
kono
parents:
diff changeset
449 if (resolveInstanceMethodCount != 3)
kono
parents:
diff changeset
450 abort ();
kono
parents:
diff changeset
451
kono
parents:
diff changeset
452 if (forwardingCount != 2)
kono
parents:
diff changeset
453 abort ();
kono
parents:
diff changeset
454
kono
parents:
diff changeset
455 if (nonExistingMethodCount != 1)
kono
parents:
diff changeset
456 abort ();
kono
parents:
diff changeset
457
kono
parents:
diff changeset
458 /* Reset the counters for the next test. */
kono
parents:
diff changeset
459 resolveInstanceMethodCount = 0;
kono
parents:
diff changeset
460 forwardingCount = 0;
kono
parents:
diff changeset
461 nonExistingMethodCount = 0;
kono
parents:
diff changeset
462
kono
parents:
diff changeset
463
kono
parents:
diff changeset
464 /** SelfExtendingClass tests. **/
kono
parents:
diff changeset
465
kono
parents:
diff changeset
466 /* Try the direct countHits method first. No resolving or
kono
parents:
diff changeset
467 forwarding should be triggered. */
kono
parents:
diff changeset
468 if ([SelfExtendingClass countHits] != 1)
kono
parents:
diff changeset
469 abort ();
kono
parents:
diff changeset
470
kono
parents:
diff changeset
471 if (resolveInstanceMethodCount != 0)
kono
parents:
diff changeset
472 abort ();
kono
parents:
diff changeset
473
kono
parents:
diff changeset
474 if (forwardingCount != 0)
kono
parents:
diff changeset
475 abort ();
kono
parents:
diff changeset
476
kono
parents:
diff changeset
477 if (nonExistingMethodCount != 0)
kono
parents:
diff changeset
478 abort ();
kono
parents:
diff changeset
479
kono
parents:
diff changeset
480 /* Now, try calling a non-existing count method; it should be
kono
parents:
diff changeset
481 installed and invoked. */
kono
parents:
diff changeset
482 if ([object2 nonExistingCountHitsMethod] != 2)
kono
parents:
diff changeset
483 abort ();
kono
parents:
diff changeset
484
kono
parents:
diff changeset
485 if (resolveInstanceMethodCount != 1)
kono
parents:
diff changeset
486 abort ();
kono
parents:
diff changeset
487
kono
parents:
diff changeset
488 if (forwardingCount != 0)
kono
parents:
diff changeset
489 abort ();
kono
parents:
diff changeset
490
kono
parents:
diff changeset
491 if (nonExistingMethodCount != 0)
kono
parents:
diff changeset
492 abort ();
kono
parents:
diff changeset
493
kono
parents:
diff changeset
494 /* Try it again. The method has now been installed, so it should
kono
parents:
diff changeset
495 be used and work, but with no additional resolving
kono
parents:
diff changeset
496 involved. */
kono
parents:
diff changeset
497 if ([object2 nonExistingCountHitsMethod] != 3)
kono
parents:
diff changeset
498 abort ();
kono
parents:
diff changeset
499
kono
parents:
diff changeset
500 if (resolveInstanceMethodCount != 1)
kono
parents:
diff changeset
501 abort ();
kono
parents:
diff changeset
502
kono
parents:
diff changeset
503 if (forwardingCount != 0)
kono
parents:
diff changeset
504 abort ();
kono
parents:
diff changeset
505
kono
parents:
diff changeset
506 if (nonExistingMethodCount != 0)
kono
parents:
diff changeset
507 abort ();
kono
parents:
diff changeset
508
kono
parents:
diff changeset
509 /* Now try the same tests with class_getInstanceMethod(). */
kono
parents:
diff changeset
510 m = class_getInstanceMethod (objc_getClass ("SelfExtendingClass"),
kono
parents:
diff changeset
511 @selector (nonExistingCountHitsMethod2));
kono
parents:
diff changeset
512 if (resolveInstanceMethodCount != 2)
kono
parents:
diff changeset
513 abort ();
kono
parents:
diff changeset
514
kono
parents:
diff changeset
515 if (forwardingCount != 0)
kono
parents:
diff changeset
516 abort ();
kono
parents:
diff changeset
517
kono
parents:
diff changeset
518 if (nonExistingMethodCount != 0)
kono
parents:
diff changeset
519 abort ();
kono
parents:
diff changeset
520
kono
parents:
diff changeset
521 /* Try it again. The method has now been installed, so it should
kono
parents:
diff changeset
522 be used and work, but with no additional resolving
kono
parents:
diff changeset
523 involved. */
kono
parents:
diff changeset
524 if ([object2 nonExistingCountHitsMethod2] != 4)
kono
parents:
diff changeset
525 abort ();
kono
parents:
diff changeset
526
kono
parents:
diff changeset
527 if (resolveInstanceMethodCount != 2)
kono
parents:
diff changeset
528 abort ();
kono
parents:
diff changeset
529
kono
parents:
diff changeset
530 if (forwardingCount != 0)
kono
parents:
diff changeset
531 abort ();
kono
parents:
diff changeset
532
kono
parents:
diff changeset
533 if (nonExistingMethodCount != 0)
kono
parents:
diff changeset
534 abort ();
kono
parents:
diff changeset
535
kono
parents:
diff changeset
536
kono
parents:
diff changeset
537 /* Now try the same tests with class_getMethodImplementation(). */
kono
parents:
diff changeset
538 i = class_getMethodImplementation (objc_getClass ("SelfExtendingClass"),
kono
parents:
diff changeset
539 @selector (nonExistingCountHitsMethod3));
kono
parents:
diff changeset
540 if (resolveInstanceMethodCount != 3)
kono
parents:
diff changeset
541 abort ();
kono
parents:
diff changeset
542
kono
parents:
diff changeset
543 if (forwardingCount != 0)
kono
parents:
diff changeset
544 abort ();
kono
parents:
diff changeset
545
kono
parents:
diff changeset
546 if (nonExistingMethodCount != 0)
kono
parents:
diff changeset
547 abort ();
kono
parents:
diff changeset
548
kono
parents:
diff changeset
549 /* Try it again. The method has now been installed, so it should
kono
parents:
diff changeset
550 be used and work, but with no additional resolving
kono
parents:
diff changeset
551 involved. */
kono
parents:
diff changeset
552 if ([object2 nonExistingCountHitsMethod3] != 5)
kono
parents:
diff changeset
553 abort ();
kono
parents:
diff changeset
554
kono
parents:
diff changeset
555 if (resolveInstanceMethodCount != 3)
kono
parents:
diff changeset
556 abort ();
kono
parents:
diff changeset
557
kono
parents:
diff changeset
558 if (forwardingCount != 0)
kono
parents:
diff changeset
559 abort ();
kono
parents:
diff changeset
560
kono
parents:
diff changeset
561 if (nonExistingMethodCount != 0)
kono
parents:
diff changeset
562 abort ();
kono
parents:
diff changeset
563 }
kono
parents:
diff changeset
564
kono
parents:
diff changeset
565
kono
parents:
diff changeset
566 return 0;
kono
parents:
diff changeset
567 }