]> git.saurik.com Git - apple/objc4.git/blob - test/forward.m
objc4-532.tar.gz
[apple/objc4.git] / test / forward.m
1 // TEST_CONFIG MEM=mrc,gc
2 // TEST_CFLAGS -Wno-deprecated-declarations
3
4 #include "test.h"
5
6 #if __cplusplus && !__clang__
7
8 int main()
9 {
10 // llvm-g++ is confused by @selector(foo::) and will never be fixed
11 succeed(__FILE__);
12 }
13
14 #else
15
16 #include <objc/runtime.h>
17 #include <objc/message.h>
18
19 id ID_RESULT = (id)0x12345678;
20 long long LL_RESULT = __LONG_LONG_MAX__ - 2LL*__INT_MAX__;
21 double FP_RESULT = __DBL_MIN__ + __DBL_EPSILON__;
22 long double LFP_RESULT = __LDBL_MIN__ + __LDBL_EPSILON__;
23 // STRET_RESULT in test.h
24
25
26 static int state = 0;
27 static id receiver;
28
29 @interface Super { id isa; } @end
30
31 @interface Super (Forwarded)
32 +(id)idret:
33 (long)i1:(long)i2:(long)i3:(long)i4:(long)i5:(long)i6:(long)i7:(long)i8:(long)i9:(long)i10:(long)i11:(long)i12:(long)i13 :(double)f1:(double)f2:(double)f3:(double)f4:(double)f5:(double)f6:(double)f7:(double)f8:(double)f9:(double)f10:(double)f11:(double)f12:(double)f13:(double)f14:(double)f15;
34
35 +(id)idre2:
36 (long)i1:(long)i2:(long)i3:(long)i4:(long)i5:(long)i6:(long)i7:(long)i8:(long)i9:(long)i10:(long)i11:(long)i12:(long)i13 :(double)f1:(double)f2:(double)f3:(double)f4:(double)f5:(double)f6:(double)f7:(double)f8:(double)f9:(double)f10:(double)f11:(double)f12:(double)f13:(double)f14:(double)f15;
37
38 +(id)idre3:
39 (long)i1:(long)i2:(long)i3:(long)i4:(long)i5:(long)i6:(long)i7:(long)i8:(long)i9:(long)i10:(long)i11:(long)i12:(long)i13 :(double)f1:(double)f2:(double)f3:(double)f4:(double)f5:(double)f6:(double)f7:(double)f8:(double)f9:(double)f10:(double)f11:(double)f12:(double)f13:(double)f14:(double)f15;
40
41 +(long long)llret:
42 (long)i1:(long)i2:(long)i3:(long)i4:(long)i5:(long)i6:(long)i7:(long)i8:(long)i9:(long)i10:(long)i11:(long)i12:(long)i13 :(double)f1:(double)f2:(double)f3:(double)f4:(double)f5:(double)f6:(double)f7:(double)f8:(double)f9:(double)f10:(double)f11:(double)f12:(double)f13:(double)f14:(double)f15;
43
44 +(long long)llre2:
45 (long)i1:(long)i2:(long)i3:(long)i4:(long)i5:(long)i6:(long)i7:(long)i8:(long)i9:(long)i10:(long)i11:(long)i12:(long)i13 :(double)f1:(double)f2:(double)f3:(double)f4:(double)f5:(double)f6:(double)f7:(double)f8:(double)f9:(double)f10:(double)f11:(double)f12:(double)f13:(double)f14:(double)f15;
46
47 +(long long)llre3:
48 (long)i1:(long)i2:(long)i3:(long)i4:(long)i5:(long)i6:(long)i7:(long)i8:(long)i9:(long)i10:(long)i11:(long)i12:(long)i13 :(double)f1:(double)f2:(double)f3:(double)f4:(double)f5:(double)f6:(double)f7:(double)f8:(double)f9:(double)f10:(double)f11:(double)f12:(double)f13:(double)f14:(double)f15;
49
50 +(struct stret)stret:
51 (long)i1:(long)i2:(long)i3:(long)i4:(long)i5:(long)i6:(long)i7:(long)i8:(long)i9:(long)i10:(long)i11:(long)i12:(long)i13 :(double)f1:(double)f2:(double)f3:(double)f4:(double)f5:(double)f6:(double)f7:(double)f8:(double)f9:(double)f10:(double)f11:(double)f12:(double)f13:(double)f14:(double)f15;
52
53 +(struct stret)stre2:
54 (long)i1:(long)i2:(long)i3:(long)i4:(long)i5:(long)i6:(long)i7:(long)i8:(long)i9:(long)i10:(long)i11:(long)i12:(long)i13 :(double)f1:(double)f2:(double)f3:(double)f4:(double)f5:(double)f6:(double)f7:(double)f8:(double)f9:(double)f10:(double)f11:(double)f12:(double)f13:(double)f14:(double)f15;
55
56 +(struct stret)stre3:
57 (long)i1:(long)i2:(long)i3:(long)i4:(long)i5:(long)i6:(long)i7:(long)i8:(long)i9:(long)i10:(long)i11:(long)i12:(long)i13 :(double)f1:(double)f2:(double)f3:(double)f4:(double)f5:(double)f6:(double)f7:(double)f8:(double)f9:(double)f10:(double)f11:(double)f12:(double)f13:(double)f14:(double)f15;
58
59 +(double)fpret:
60 (long)i1:(long)i2:(long)i3:(long)i4:(long)i5:(long)i6:(long)i7:(long)i8:(long)i9:(long)i10:(long)i11:(long)i12:(long)i13 :(double)f1:(double)f2:(double)f3:(double)f4:(double)f5:(double)f6:(double)f7:(double)f8:(double)f9:(double)f10:(double)f11:(double)f12:(double)f13:(double)f14:(double)f15;
61
62 +(double)fpre2:
63 (long)i1:(long)i2:(long)i3:(long)i4:(long)i5:(long)i6:(long)i7:(long)i8:(long)i9:(long)i10:(long)i11:(long)i12:(long)i13 :(double)f1:(double)f2:(double)f3:(double)f4:(double)f5:(double)f6:(double)f7:(double)f8:(double)f9:(double)f10:(double)f11:(double)f12:(double)f13:(double)f14:(double)f15;
64
65 +(double)fpre3:
66 (long)i1:(long)i2:(long)i3:(long)i4:(long)i5:(long)i6:(long)i7:(long)i8:(long)i9:(long)i10:(long)i11:(long)i12:(long)i13 :(double)f1:(double)f2:(double)f3:(double)f4:(double)f5:(double)f6:(double)f7:(double)f8:(double)f9:(double)f10:(double)f11:(double)f12:(double)f13:(double)f14:(double)f15;
67
68 @end
69
70
71 long long forward_handler(id self, SEL _cmd, long i1, long i2, long i3, long i4, long i5, long i6, long i7, long i8, long i9, long i10, long i11, long i12, long i13, double f1, double f2, double f3, double f4, double f5, double f6, double f7, double f8, double f9, double f10, double f11, double f12, double f13, double f14, double f15)
72 {
73 testassert(self == receiver);
74
75 testassert(i1 == 1);
76 testassert(i2 == 2);
77 testassert(i3 == 3);
78 testassert(i4 == 4);
79 testassert(i5 == 5);
80 testassert(i6 == 6);
81 testassert(i7 == 7);
82 testassert(i8 == 8);
83 testassert(i9 == 9);
84 testassert(i10 == 10);
85 testassert(i11 == 11);
86 testassert(i12 == 12);
87 testassert(i13 == 13);
88
89 testassert(f1 == 1.0);
90 testassert(f2 == 2.0);
91 testassert(f3 == 3.0);
92 testassert(f4 == 4.0);
93 testassert(f5 == 5.0);
94 testassert(f6 == 6.0);
95 testassert(f7 == 7.0);
96 testassert(f8 == 8.0);
97 testassert(f9 == 9.0);
98 testassert(f10 == 10.0);
99 testassert(f11 == 11.0);
100 testassert(f12 == 12.0);
101 testassert(f13 == 13.0);
102 testassert(f14 == 14.0);
103 testassert(f15 == 15.0);
104
105 if (_cmd == @selector(idret::::::::::::::::::::::::::::) ||
106 _cmd == @selector(idre2::::::::::::::::::::::::::::) ||
107 _cmd == @selector(idre3::::::::::::::::::::::::::::))
108 {
109 union {
110 id idval;
111 long long llval;
112 } result;
113 testassert(state == 11);
114 state = 12;
115 result.idval = ID_RESULT;
116 return result.llval;
117 } else if (_cmd == @selector(llret::::::::::::::::::::::::::::) ||
118 _cmd == @selector(llre2::::::::::::::::::::::::::::) ||
119 _cmd == @selector(llre3::::::::::::::::::::::::::::))
120 {
121 testassert(state == 13);
122 state = 14;
123 return LL_RESULT;
124 } else if (_cmd == @selector(fpret::::::::::::::::::::::::::::) ||
125 _cmd == @selector(fpre2::::::::::::::::::::::::::::) ||
126 _cmd == @selector(fpre3::::::::::::::::::::::::::::))
127 {
128 testassert(state == 15);
129 state = 16;
130 #if defined(__i386__)
131 __asm__ volatile("fldl %0" : : "m" (FP_RESULT));
132 #elif defined(__x86_64__)
133 __asm__ volatile("movsd %0, %%xmm0" : : "m" (FP_RESULT));
134 #elif defined(__arm__)
135 union {
136 double fpval;
137 long long llval;
138 } result;
139 result.fpval = FP_RESULT;
140 return result.llval;
141 #else
142 # error unknown architecture
143 #endif
144 return 0;
145 } else if (_cmd == @selector(stret::::::::::::::::::::::::::::) ||
146 _cmd == @selector(stre2::::::::::::::::::::::::::::) ||
147 _cmd == @selector(stre3::::::::::::::::::::::::::::))
148 {
149 fail("stret message sent to non-stret forward_handler");
150 } else {
151 fail("unknown selector %s in forward_handler", sel_getName(_cmd));
152 }
153 }
154
155
156 struct stret forward_stret_handler(id self, SEL _cmd, long i1, long i2, long i3, long i4, long i5, long i6, long i7, long i8, long i9, long i10, long i11, long i12, long i13, double f1, double f2, double f3, double f4, double f5, double f6, double f7, double f8, double f9, double f10, double f11, double f12, double f13, double f14, double f15)
157 {
158 testassert(self == receiver);
159
160 testassert(i1 == 1);
161 testassert(i2 == 2);
162 testassert(i3 == 3);
163 testassert(i4 == 4);
164 testassert(i5 == 5);
165 testassert(i6 == 6);
166 testassert(i7 == 7);
167 testassert(i8 == 8);
168 testassert(i9 == 9);
169 testassert(i10 == 10);
170 testassert(i11 == 11);
171 testassert(i12 == 12);
172 testassert(i13 == 13);
173
174 testassert(f1 == 1.0);
175 testassert(f2 == 2.0);
176 testassert(f3 == 3.0);
177 testassert(f4 == 4.0);
178 testassert(f5 == 5.0);
179 testassert(f6 == 6.0);
180 testassert(f7 == 7.0);
181 testassert(f8 == 8.0);
182 testassert(f9 == 9.0);
183 testassert(f10 == 10.0);
184 testassert(f11 == 11.0);
185 testassert(f12 == 12.0);
186 testassert(f13 == 13.0);
187 testassert(f14 == 14.0);
188 testassert(f15 == 15.0);
189
190 if (_cmd == @selector(idret::::::::::::::::::::::::::::) ||
191 _cmd == @selector(idre2::::::::::::::::::::::::::::) ||
192 _cmd == @selector(idre3::::::::::::::::::::::::::::) ||
193 _cmd == @selector(llret::::::::::::::::::::::::::::) ||
194 _cmd == @selector(llre2::::::::::::::::::::::::::::) ||
195 _cmd == @selector(llre3::::::::::::::::::::::::::::) ||
196 _cmd == @selector(fpret::::::::::::::::::::::::::::) ||
197 _cmd == @selector(fpre2::::::::::::::::::::::::::::) ||
198 _cmd == @selector(fpre3::::::::::::::::::::::::::::))
199 {
200 fail("non-stret selector %s sent to forward_stret_handler", sel_getName(_cmd));
201 } else if (_cmd == @selector(stret::::::::::::::::::::::::::::) ||
202 _cmd == @selector(stre2::::::::::::::::::::::::::::) ||
203 _cmd == @selector(stre3::::::::::::::::::::::::::::))
204 {
205 testassert(state == 17);
206 state = 18;
207 return STRET_RESULT;
208 } else {
209 fail("unknown selector %s in forward::", sel_getName(_cmd));
210 }
211
212 }
213
214 @implementation Super
215 +(void)initialize { }
216 +(id)class { return self; }
217
218 -(long long) forward:(SEL)sel :(marg_list)args
219 {
220 char *p;
221 uintptr_t *gp;
222 double *fp;
223 struct stret *struct_addr;
224
225 #if defined(__i386__)
226 struct_addr = ((struct stret **)args)[-1];
227 #elif defined(__x86_64__)
228 struct_addr = *(struct stret **)((char *)args + 8*16+4*8);
229 #elif defined(__arm__)
230 struct_addr = *(struct stret **)((char *)args + 0);
231 #else
232 # error unknown architecture
233 #endif
234
235 testassert(self == receiver);
236 testassert(_cmd == sel_registerName("forward::"));
237
238 p = (char *)args;
239 #if defined(__x86_64__)
240 p += 8*16 + 4*8; // skip over xmm and linkage
241 if (sel == @selector(stret::::::::::::::::::::::::::::) ||
242 sel == @selector(stre2::::::::::::::::::::::::::::) ||
243 sel == @selector(stre3::::::::::::::::::::::::::::))
244 {
245 p += sizeof(void *); // struct return
246 }
247 #elif defined(__i386__)
248 // nothing to do
249 #elif defined(__arm__)
250 if (sel == @selector(stret::::::::::::::::::::::::::::) ||
251 sel == @selector(stre2::::::::::::::::::::::::::::) ||
252 sel == @selector(stre3::::::::::::::::::::::::::::))
253 {
254 p += sizeof(void *); // struct return;
255 }
256 #else
257 # error unknown architecture
258 #endif
259 gp = (uintptr_t *)p;
260 testassert(*gp++ == (uintptr_t)self);
261 testassert(*gp++ == (uintptr_t)sel);
262 testassert(*gp++ == 1);
263 testassert(*gp++ == 2);
264 testassert(*gp++ == 3);
265 testassert(*gp++ == 4);
266 testassert(*gp++ == 5);
267 testassert(*gp++ == 6);
268 testassert(*gp++ == 7);
269 testassert(*gp++ == 8);
270 testassert(*gp++ == 9);
271 testassert(*gp++ == 10);
272 testassert(*gp++ == 11);
273 testassert(*gp++ == 12);
274 testassert(*gp++ == 13);
275
276 #if defined(__i386__) || defined(__arm__)
277
278 fp = (double *)gp;
279 testassert(*fp++ == 1.0);
280 testassert(*fp++ == 2.0);
281 testassert(*fp++ == 3.0);
282 testassert(*fp++ == 4.0);
283 testassert(*fp++ == 5.0);
284 testassert(*fp++ == 6.0);
285 testassert(*fp++ == 7.0);
286 testassert(*fp++ == 8.0);
287 testassert(*fp++ == 9.0);
288 testassert(*fp++ == 10.0);
289 testassert(*fp++ == 11.0);
290 testassert(*fp++ == 12.0);
291 testassert(*fp++ == 13.0);
292 testassert(*fp++ == 14.0);
293 testassert(*fp++ == 15.0);
294
295 #elif defined(__x86_64__)
296
297 fp = (double *)args; // xmm, double-wide
298 testassert(*fp++ == 1.0); fp++;
299 testassert(*fp++ == 2.0); fp++;
300 testassert(*fp++ == 3.0); fp++;
301 testassert(*fp++ == 4.0); fp++;
302 testassert(*fp++ == 5.0); fp++;
303 testassert(*fp++ == 6.0); fp++;
304 testassert(*fp++ == 7.0); fp++;
305 testassert(*fp++ == 8.0); fp++;
306 fp = (double *)gp;
307 testassert(*fp++ == 9.0);
308 testassert(*fp++ == 10.0);
309 testassert(*fp++ == 11.0);
310 testassert(*fp++ == 12.0);
311 testassert(*fp++ == 13.0);
312 testassert(*fp++ == 14.0);
313 testassert(*fp++ == 15.0);
314
315 #else
316 # error unknown architecture
317 #endif
318
319 if (sel == @selector(idret::::::::::::::::::::::::::::) ||
320 sel == @selector(idre2::::::::::::::::::::::::::::) ||
321 sel == @selector(idre3::::::::::::::::::::::::::::))
322 {
323 union {
324 id idval;
325 long long llval;
326 } result;
327 testassert(state == 1);
328 state = 2;
329 result.idval = ID_RESULT;
330 return result.llval;
331 } else if (sel == @selector(llret::::::::::::::::::::::::::::) ||
332 sel == @selector(llre2::::::::::::::::::::::::::::) ||
333 sel == @selector(llre3::::::::::::::::::::::::::::))
334 {
335 testassert(state == 3);
336 state = 4;
337 return LL_RESULT;
338 } else if (sel == @selector(fpret::::::::::::::::::::::::::::) ||
339 sel == @selector(fpre2::::::::::::::::::::::::::::) ||
340 sel == @selector(fpre3::::::::::::::::::::::::::::))
341 {
342 testassert(state == 5);
343 state = 6;
344 #if defined(__i386__)
345 __asm__ volatile("fldl %0" : : "m" (FP_RESULT));
346 #elif defined(__x86_64__)
347 __asm__ volatile("movsd %0, %%xmm0" : : "m" (FP_RESULT));
348 #elif defined(__arm__)
349 union {
350 double fpval;
351 long long llval;
352 } result;
353 result.fpval = FP_RESULT;
354 return result.llval;
355 #else
356 # error unknown architecture
357 #endif
358 return 0;
359 } else if (sel == @selector(stret::::::::::::::::::::::::::::) ||
360 sel == @selector(stre2::::::::::::::::::::::::::::) ||
361 sel == @selector(stre3::::::::::::::::::::::::::::))
362 {
363 testassert(state == 7);
364 state = 8;
365 *struct_addr = STRET_RESULT;
366 return 0;
367 } else {
368 fail("unknown selector %s in forward::", sel_getName(sel));
369 }
370 return 0;
371 }
372
373 @end
374
375 typedef id (*id_fn_t)(id self, SEL _cmd, long i1, long i2, long i3, long i4, long i5, long i6, long i7, long i8, long i9, long i10, long i11, long i12, long i13, double f1, double f2, double f3, double f4, double f5, double f6, double f7, double f8, double f9, double f10, double f11, double f12, double f13, double f14, double f15);
376
377 typedef long long (*ll_fn_t)(id self, SEL _cmd, long i1, long i2, long i3, long i4, long i5, long i6, long i7, long i8, long i9, long i10, long i11, long i12, long i13, double f1, double f2, double f3, double f4, double f5, double f6, double f7, double f8, double f9, double f10, double f11, double f12, double f13, double f14, double f15);
378
379 typedef double (*fp_fn_t)(id self, SEL _cmd, long i1, long i2, long i3, long i4, long i5, long i6, long i7, long i8, long i9, long i10, long i11, long i12, long i13, double f1, double f2, double f3, double f4, double f5, double f6, double f7, double f8, double f9, double f10, double f11, double f12, double f13, double f14, double f15);
380
381 typedef struct stret (*st_fn_t)(id self, SEL _cmd, long i1, long i2, long i3, long i4, long i5, long i6, long i7, long i8, long i9, long i10, long i11, long i12, long i13, double f1, double f2, double f3, double f4, double f5, double f6, double f7, double f8, double f9, double f10, double f11, double f12, double f13, double f14, double f15);
382
383 __BEGIN_DECLS
384 extern void *getSP(void);
385 __END_DECLS
386
387 #if defined(__x86_64__)
388 asm(".text \n _getSP: movq %rsp, %rax \n retq \n");
389 #elif defined(__i386__)
390 asm(".text \n _getSP: movl %esp, %eax \n ret \n");
391 #elif defined(__arm__)
392 asm(".text \n _getSP: mov r0, sp \n bx lr \n");
393 #else
394 # error unknown architecture
395 #endif
396
397 int main()
398 {
399 id idval;
400 long long llval;
401 struct stret stval;
402 double fpval;
403 void *sp1 = (void*)1;
404 void *sp2 = (void*)2;
405
406 receiver = [Super class];
407
408 // Test default forward handler
409
410 state = 1;
411 sp1 = getSP();
412 idval = [Super idret:1:2:3:4:5:6:7:8:9:10:11:12:13:1.0:2.0:3.0:4.0:5.0:6.0:7.0:8.0:9.0:10.0:11.0:12.0:13.0:14.0:15.0];
413 sp2 = getSP();
414 testassert(sp1 == sp2);
415 testassert(state == 2);
416 testassert(idval == ID_RESULT);
417
418 state = 3;
419 sp1 = getSP();
420 llval = [Super llret:1:2:3:4:5:6:7:8:9:10:11:12:13:1.0:2.0:3.0:4.0:5.0:6.0:7.0:8.0:9.0:10.0:11.0:12.0:13.0:14.0:15.0];
421 sp2 = getSP();
422 testassert(sp1 == sp2);
423 testassert(state == 4);
424 testassert(llval == LL_RESULT);
425
426 state = 5;
427 sp1 = getSP();
428 fpval = [Super fpret:1:2:3:4:5:6:7:8:9:10:11:12:13:1.0:2.0:3.0:4.0:5.0:6.0:7.0:8.0:9.0:10.0:11.0:12.0:13.0:14.0:15.0];
429 sp2 = getSP();
430 testassert(sp1 == sp2);
431 testassert(state == 6);
432 testassert(fpval == FP_RESULT);
433
434 state = 7;
435 sp1 = getSP();
436 stval = [Super stret:1:2:3:4:5:6:7:8:9:10:11:12:13:1.0:2.0:3.0:4.0:5.0:6.0:7.0:8.0:9.0:10.0:11.0:12.0:13.0:14.0:15.0];
437 sp2 = getSP();
438 testassert(sp1 == sp2);
439 testassert(state == 8);
440 testassert(stret_equal(stval, STRET_RESULT));
441
442
443 // Test default forward handler, cached
444
445 state = 1;
446 sp1 = getSP();
447 idval = [Super idret:1:2:3:4:5:6:7:8:9:10:11:12:13:1.0:2.0:3.0:4.0:5.0:6.0:7.0:8.0:9.0:10.0:11.0:12.0:13.0:14.0:15.0];
448 sp2 = getSP();
449 testassert(sp1 == sp2);
450 testassert(state == 2);
451 testassert(idval == ID_RESULT);
452
453 state = 3;
454 sp1 = getSP();
455 llval = [Super llret:1:2:3:4:5:6:7:8:9:10:11:12:13:1.0:2.0:3.0:4.0:5.0:6.0:7.0:8.0:9.0:10.0:11.0:12.0:13.0:14.0:15.0];
456 sp2 = getSP();
457 testassert(sp1 == sp2);
458 testassert(state == 4);
459 testassert(llval == LL_RESULT);
460
461 state = 5;
462 sp1 = getSP();
463 fpval = [Super fpret:1:2:3:4:5:6:7:8:9:10:11:12:13:1.0:2.0:3.0:4.0:5.0:6.0:7.0:8.0:9.0:10.0:11.0:12.0:13.0:14.0:15.0];
464 sp2 = getSP();
465 testassert(sp1 == sp2);
466 testassert(state == 6);
467 testassert(fpval == FP_RESULT);
468
469 state = 7;
470 sp1 = getSP();
471 stval = [Super stret:1:2:3:4:5:6:7:8:9:10:11:12:13:1.0:2.0:3.0:4.0:5.0:6.0:7.0:8.0:9.0:10.0:11.0:12.0:13.0:14.0:15.0];
472 sp2 = getSP();
473 testassert(sp1 == sp2);
474 testassert(state == 8);
475 testassert(stret_equal(stval, STRET_RESULT));
476
477
478 // Test default forward handler, uncached but fixed-up
479
480 _objc_flush_caches(nil);
481
482 state = 1;
483 sp1 = getSP();
484 idval = [Super idret:1:2:3:4:5:6:7:8:9:10:11:12:13:1.0:2.0:3.0:4.0:5.0:6.0:7.0:8.0:9.0:10.0:11.0:12.0:13.0:14.0:15.0];
485 sp2 = getSP();
486 testassert(sp1 == sp2);
487 testassert(state == 2);
488 testassert(idval == ID_RESULT);
489
490 state = 3;
491 sp1 = getSP();
492 llval = [Super llret:1:2:3:4:5:6:7:8:9:10:11:12:13:1.0:2.0:3.0:4.0:5.0:6.0:7.0:8.0:9.0:10.0:11.0:12.0:13.0:14.0:15.0];
493 sp2 = getSP();
494 testassert(sp1 == sp2);
495 testassert(state == 4);
496 testassert(llval == LL_RESULT);
497
498 state = 5;
499 sp1 = getSP();
500 fpval = [Super fpret:1:2:3:4:5:6:7:8:9:10:11:12:13:1.0:2.0:3.0:4.0:5.0:6.0:7.0:8.0:9.0:10.0:11.0:12.0:13.0:14.0:15.0];
501 sp2 = getSP();
502 testassert(sp1 == sp2);
503 testassert(state == 6);
504 testassert(fpval == FP_RESULT);
505
506 state = 7;
507 sp1 = getSP();
508 stval = [Super stret:1:2:3:4:5:6:7:8:9:10:11:12:13:1.0:2.0:3.0:4.0:5.0:6.0:7.0:8.0:9.0:10.0:11.0:12.0:13.0:14.0:15.0];
509 sp2 = getSP();
510 testassert(sp1 == sp2);
511 testassert(state == 8);
512 testassert(stret_equal(stval, STRET_RESULT));
513
514
515 // Test manual forwarding
516
517 state = 1;
518 sp1 = getSP();
519 idval = ((id_fn_t)_objc_msgForward)(receiver, @selector(idre2::::::::::::::::::::::::::::), 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0);
520 sp2 = getSP();
521 testassert(sp1 == sp2);
522 testassert(state == 2);
523 testassert(idval == ID_RESULT);
524
525 state = 3;
526 sp1 = getSP();
527 llval = ((ll_fn_t)_objc_msgForward)(receiver, @selector(llre2::::::::::::::::::::::::::::), 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0);
528 sp2 = getSP();
529 testassert(sp1 == sp2);
530 testassert(state == 4);
531 testassert(llval == LL_RESULT);
532
533 state = 5;
534 sp1 = getSP();
535 fpval = ((fp_fn_t)_objc_msgForward)(receiver, @selector(fpre2::::::::::::::::::::::::::::), 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0);
536 sp2 = getSP();
537 testassert(sp1 == sp2);
538 testassert(state == 6);
539 testassert(fpval == FP_RESULT);
540
541 state = 7;
542 sp1 = getSP();
543 stval = ((st_fn_t)_objc_msgForward_stret)(receiver, @selector(stre2::::::::::::::::::::::::::::), 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0);
544 sp2 = getSP();
545 testassert(sp1 == sp2);
546 testassert(state == 8);
547 testassert(stret_equal(stval, STRET_RESULT));
548
549
550 // Test manual forwarding, cached
551
552 state = 1;
553 sp1 = getSP();
554 idval = ((id_fn_t)_objc_msgForward)(receiver, @selector(idre2::::::::::::::::::::::::::::), 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0);
555 sp2 = getSP();
556 testassert(sp1 == sp2);
557 testassert(state == 2);
558 testassert(idval == ID_RESULT);
559
560 state = 3;
561 sp1 = getSP();
562 llval = ((ll_fn_t)_objc_msgForward)(receiver, @selector(llre2::::::::::::::::::::::::::::), 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0);
563 sp2 = getSP();
564 testassert(sp1 == sp2);
565 testassert(state == 4);
566 testassert(llval == LL_RESULT);
567
568 state = 5;
569 sp1 = getSP();
570 fpval = ((fp_fn_t)_objc_msgForward)(receiver, @selector(fpre2::::::::::::::::::::::::::::), 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0);
571 sp2 = getSP();
572 testassert(sp1 == sp2);
573 testassert(state == 6);
574 testassert(fpval == FP_RESULT);
575
576 state = 7;
577 sp1 = getSP();
578 stval = ((st_fn_t)_objc_msgForward_stret)(receiver, @selector(stre2::::::::::::::::::::::::::::), 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0);
579 sp2 = getSP();
580 testassert(sp1 == sp2);
581 testassert(state == 8);
582 testassert(stret_equal(stval, STRET_RESULT));
583
584
585 // Test manual forwarding, uncached but fixed-up
586
587 _objc_flush_caches(nil);
588
589 state = 1;
590 sp1 = getSP();
591 idval = ((id_fn_t)_objc_msgForward)(receiver, @selector(idre2::::::::::::::::::::::::::::), 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0);
592 sp2 = getSP();
593 testassert(sp1 == sp2);
594 testassert(state == 2);
595 testassert(idval == ID_RESULT);
596
597 state = 3;
598 sp1 = getSP();
599 llval = ((ll_fn_t)_objc_msgForward)(receiver, @selector(llre2::::::::::::::::::::::::::::), 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0);
600 sp2 = getSP();
601 testassert(sp1 == sp2);
602 testassert(state == 4);
603 testassert(llval == LL_RESULT);
604
605 state = 5;
606 sp1 = getSP();
607 fpval = ((fp_fn_t)_objc_msgForward)(receiver, @selector(fpre2::::::::::::::::::::::::::::), 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0);
608 sp2 = getSP();
609 testassert(sp1 == sp2);
610 testassert(state == 6);
611 testassert(fpval == FP_RESULT);
612
613 state = 7;
614 sp1 = getSP();
615 stval = ((st_fn_t)_objc_msgForward_stret)(receiver, @selector(stre2::::::::::::::::::::::::::::), 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0);
616 sp2 = getSP();
617 testassert(sp1 == sp2);
618 testassert(state == 8);
619 testassert(stret_equal(stval, STRET_RESULT));
620
621
622 // Test user-defined forward handler
623
624 objc_setForwardHandler((void*)&forward_handler, (void*)&forward_stret_handler);
625
626 state = 11;
627 sp1 = getSP();
628 idval = [Super idre3:1:2:3:4:5:6:7:8:9:10:11:12:13:1.0:2.0:3.0:4.0:5.0:6.0:7.0:8.0:9.0:10.0:11.0:12.0:13.0:14.0:15.0];
629 sp2 = getSP();
630 testassert(sp1 == sp2);
631 testassert(state == 12);
632 testassert(idval == ID_RESULT);
633
634 state = 13;
635 sp1 = getSP();
636 llval = [Super llre3:1:2:3:4:5:6:7:8:9:10:11:12:13:1.0:2.0:3.0:4.0:5.0:6.0:7.0:8.0:9.0:10.0:11.0:12.0:13.0:14.0:15.0];
637 sp2 = getSP();
638 testassert(sp1 == sp2);
639 testassert(state == 14);
640 testassert(llval == LL_RESULT);
641
642 state = 15;
643 sp1 = getSP();
644 fpval = [Super fpre3:1:2:3:4:5:6:7:8:9:10:11:12:13:1.0:2.0:3.0:4.0:5.0:6.0:7.0:8.0:9.0:10.0:11.0:12.0:13.0:14.0:15.0];
645 sp2 = getSP();
646 testassert(sp1 == sp2);
647 testassert(state == 16);
648 testassert(fpval == FP_RESULT);
649
650 state = 17;
651 sp1 = getSP();
652 stval = [Super stre3:1:2:3:4:5:6:7:8:9:10:11:12:13:1.0:2.0:3.0:4.0:5.0:6.0:7.0:8.0:9.0:10.0:11.0:12.0:13.0:14.0:15.0];
653 sp2 = getSP();
654 testassert(sp1 == sp2);
655 testassert(state == 18);
656 testassert(stret_equal(stval, STRET_RESULT));
657
658
659 // Test user-defined forward handler, cached
660
661 state = 11;
662 sp1 = getSP();
663 idval = [Super idre3:1:2:3:4:5:6:7:8:9:10:11:12:13:1.0:2.0:3.0:4.0:5.0:6.0:7.0:8.0:9.0:10.0:11.0:12.0:13.0:14.0:15.0];
664 sp2 = getSP();
665 testassert(sp1 == sp2);
666 testassert(state == 12);
667 testassert(idval == ID_RESULT);
668
669 state = 13;
670 sp1 = getSP();
671 llval = [Super llre3:1:2:3:4:5:6:7:8:9:10:11:12:13:1.0:2.0:3.0:4.0:5.0:6.0:7.0:8.0:9.0:10.0:11.0:12.0:13.0:14.0:15.0];
672 sp2 = getSP();
673 testassert(sp1 == sp2);
674 testassert(state == 14);
675 testassert(llval == LL_RESULT);
676
677 state = 15;
678 sp1 = getSP();
679 fpval = [Super fpre3:1:2:3:4:5:6:7:8:9:10:11:12:13:1.0:2.0:3.0:4.0:5.0:6.0:7.0:8.0:9.0:10.0:11.0:12.0:13.0:14.0:15.0];
680 sp2 = getSP();
681 testassert(sp1 == sp2);
682 testassert(state == 16);
683 testassert(fpval == FP_RESULT);
684
685 state = 17;
686 sp1 = getSP();
687 stval = [Super stre3:1:2:3:4:5:6:7:8:9:10:11:12:13:1.0:2.0:3.0:4.0:5.0:6.0:7.0:8.0:9.0:10.0:11.0:12.0:13.0:14.0:15.0];
688 sp2 = getSP();
689 testassert(sp1 == sp2);
690 testassert(state == 18);
691 testassert(stret_equal(stval, STRET_RESULT));
692
693
694 // Test user-defined forward handler, uncached but fixed-up
695
696 _objc_flush_caches(nil);
697
698 state = 11;
699 sp1 = getSP();
700 idval = [Super idre3:1:2:3:4:5:6:7:8:9:10:11:12:13:1.0:2.0:3.0:4.0:5.0:6.0:7.0:8.0:9.0:10.0:11.0:12.0:13.0:14.0:15.0];
701 sp2 = getSP();
702 testassert(sp1 == sp2);
703 testassert(state == 12);
704 testassert(idval == ID_RESULT);
705
706 state = 13;
707 sp1 = getSP();
708 llval = [Super llre3:1:2:3:4:5:6:7:8:9:10:11:12:13:1.0:2.0:3.0:4.0:5.0:6.0:7.0:8.0:9.0:10.0:11.0:12.0:13.0:14.0:15.0];
709 sp2 = getSP();
710 testassert(sp1 == sp2);
711 testassert(state == 14);
712 testassert(llval == LL_RESULT);
713
714 state = 15;
715 sp1 = getSP();
716 fpval = [Super fpre3:1:2:3:4:5:6:7:8:9:10:11:12:13:1.0:2.0:3.0:4.0:5.0:6.0:7.0:8.0:9.0:10.0:11.0:12.0:13.0:14.0:15.0];
717 sp2 = getSP();
718 testassert(sp1 == sp2);
719 testassert(state == 16);
720 testassert(fpval == FP_RESULT);
721
722 state = 17;
723 sp1 = getSP();
724 stval = [Super stre3:1:2:3:4:5:6:7:8:9:10:11:12:13:1.0:2.0:3.0:4.0:5.0:6.0:7.0:8.0:9.0:10.0:11.0:12.0:13.0:14.0:15.0];
725 sp2 = getSP();
726 testassert(sp1 == sp2);
727 testassert(state == 18);
728 testassert(stret_equal(stval, STRET_RESULT));
729
730
731 succeed(__FILE__);
732 }
733
734 #endif