1 // TEST_CONFIG MEM=mrc,gc
2 // TEST_CFLAGS -Wno-deprecated-declarations
6 #if __cplusplus && !__clang__
10 // llvm-g++ is confused by @selector(foo::) and will never be fixed
16 #include <objc/runtime.h>
17 #include <objc/message.h>
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
29 @interface Super { id isa; } @end
31 @interface Super (Forwarded)
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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)
73 testassert(self == receiver);
84 testassert(i10 == 10);
85 testassert(i11 == 11);
86 testassert(i12 == 12);
87 testassert(i13 == 13);
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);
105 if (_cmd == @selector(idret::::::::::::::::::::::::::::) ||
106 _cmd == @selector(idre2::::::::::::::::::::::::::::) ||
107 _cmd == @selector(idre3::::::::::::::::::::::::::::))
113 testassert(state == 11);
115 result.idval = ID_RESULT;
117 } else if (_cmd == @selector(llret::::::::::::::::::::::::::::) ||
118 _cmd == @selector(llre2::::::::::::::::::::::::::::) ||
119 _cmd == @selector(llre3::::::::::::::::::::::::::::))
121 testassert(state == 13);
124 } else if (_cmd == @selector(fpret::::::::::::::::::::::::::::) ||
125 _cmd == @selector(fpre2::::::::::::::::::::::::::::) ||
126 _cmd == @selector(fpre3::::::::::::::::::::::::::::))
128 testassert(state == 15);
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__)
139 result.fpval = FP_RESULT;
142 # error unknown architecture
145 } else if (_cmd == @selector(stret::::::::::::::::::::::::::::) ||
146 _cmd == @selector(stre2::::::::::::::::::::::::::::) ||
147 _cmd == @selector(stre3::::::::::::::::::::::::::::))
149 fail("stret message sent to non-stret forward_handler");
151 fail("unknown selector %s in forward_handler", sel_getName(_cmd));
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)
158 testassert(self == receiver);
169 testassert(i10 == 10);
170 testassert(i11 == 11);
171 testassert(i12 == 12);
172 testassert(i13 == 13);
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);
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::::::::::::::::::::::::::::))
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::::::::::::::::::::::::::::))
205 testassert(state == 17);
209 fail("unknown selector %s in forward::", sel_getName(_cmd));
214 @implementation Super
215 +(void)initialize { }
216 +(id)class { return self; }
218 -(long long) forward:(SEL)sel :(marg_list)args
223 struct stret *struct_addr;
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);
232 # error unknown architecture
235 testassert(self == receiver);
236 testassert(_cmd == sel_registerName("forward::"));
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::::::::::::::::::::::::::::))
245 p += sizeof(void *); // struct return
247 #elif defined(__i386__)
249 #elif defined(__arm__)
250 if (sel == @selector(stret::::::::::::::::::::::::::::) ||
251 sel == @selector(stre2::::::::::::::::::::::::::::) ||
252 sel == @selector(stre3::::::::::::::::::::::::::::))
254 p += sizeof(void *); // struct return;
257 # error unknown architecture
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);
276 #if defined(__i386__) || defined(__arm__)
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);
295 #elif defined(__x86_64__)
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++;
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);
316 # error unknown architecture
319 if (sel == @selector(idret::::::::::::::::::::::::::::) ||
320 sel == @selector(idre2::::::::::::::::::::::::::::) ||
321 sel == @selector(idre3::::::::::::::::::::::::::::))
327 testassert(state == 1);
329 result.idval = ID_RESULT;
331 } else if (sel == @selector(llret::::::::::::::::::::::::::::) ||
332 sel == @selector(llre2::::::::::::::::::::::::::::) ||
333 sel == @selector(llre3::::::::::::::::::::::::::::))
335 testassert(state == 3);
338 } else if (sel == @selector(fpret::::::::::::::::::::::::::::) ||
339 sel == @selector(fpre2::::::::::::::::::::::::::::) ||
340 sel == @selector(fpre3::::::::::::::::::::::::::::))
342 testassert(state == 5);
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__)
353 result.fpval = FP_RESULT;
356 # error unknown architecture
359 } else if (sel == @selector(stret::::::::::::::::::::::::::::) ||
360 sel == @selector(stre2::::::::::::::::::::::::::::) ||
361 sel == @selector(stre3::::::::::::::::::::::::::::))
363 testassert(state == 7);
365 *struct_addr = STRET_RESULT;
368 fail("unknown selector %s in forward::", sel_getName(sel));
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);
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);
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);
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);
384 extern void *getSP(void);
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");
394 # error unknown architecture
403 void *sp1 = (void*)1;
404 void *sp2 = (void*)2;
406 receiver = [Super class];
408 // Test default forward handler
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];
414 testassert(sp1 == sp2);
415 testassert(state == 2);
416 testassert(idval == ID_RESULT);
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];
422 testassert(sp1 == sp2);
423 testassert(state == 4);
424 testassert(llval == LL_RESULT);
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];
430 testassert(sp1 == sp2);
431 testassert(state == 6);
432 testassert(fpval == FP_RESULT);
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];
438 testassert(sp1 == sp2);
439 testassert(state == 8);
440 testassert(stret_equal(stval, STRET_RESULT));
443 // Test default forward handler, cached
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];
449 testassert(sp1 == sp2);
450 testassert(state == 2);
451 testassert(idval == ID_RESULT);
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];
457 testassert(sp1 == sp2);
458 testassert(state == 4);
459 testassert(llval == LL_RESULT);
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];
465 testassert(sp1 == sp2);
466 testassert(state == 6);
467 testassert(fpval == FP_RESULT);
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];
473 testassert(sp1 == sp2);
474 testassert(state == 8);
475 testassert(stret_equal(stval, STRET_RESULT));
478 // Test default forward handler, uncached but fixed-up
480 _objc_flush_caches(nil);
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];
486 testassert(sp1 == sp2);
487 testassert(state == 2);
488 testassert(idval == ID_RESULT);
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];
494 testassert(sp1 == sp2);
495 testassert(state == 4);
496 testassert(llval == LL_RESULT);
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];
502 testassert(sp1 == sp2);
503 testassert(state == 6);
504 testassert(fpval == FP_RESULT);
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];
510 testassert(sp1 == sp2);
511 testassert(state == 8);
512 testassert(stret_equal(stval, STRET_RESULT));
515 // Test manual forwarding
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);
521 testassert(sp1 == sp2);
522 testassert(state == 2);
523 testassert(idval == ID_RESULT);
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);
529 testassert(sp1 == sp2);
530 testassert(state == 4);
531 testassert(llval == LL_RESULT);
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);
537 testassert(sp1 == sp2);
538 testassert(state == 6);
539 testassert(fpval == FP_RESULT);
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);
545 testassert(sp1 == sp2);
546 testassert(state == 8);
547 testassert(stret_equal(stval, STRET_RESULT));
550 // Test manual forwarding, cached
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);
556 testassert(sp1 == sp2);
557 testassert(state == 2);
558 testassert(idval == ID_RESULT);
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);
564 testassert(sp1 == sp2);
565 testassert(state == 4);
566 testassert(llval == LL_RESULT);
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);
572 testassert(sp1 == sp2);
573 testassert(state == 6);
574 testassert(fpval == FP_RESULT);
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);
580 testassert(sp1 == sp2);
581 testassert(state == 8);
582 testassert(stret_equal(stval, STRET_RESULT));
585 // Test manual forwarding, uncached but fixed-up
587 _objc_flush_caches(nil);
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);
593 testassert(sp1 == sp2);
594 testassert(state == 2);
595 testassert(idval == ID_RESULT);
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);
601 testassert(sp1 == sp2);
602 testassert(state == 4);
603 testassert(llval == LL_RESULT);
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);
609 testassert(sp1 == sp2);
610 testassert(state == 6);
611 testassert(fpval == FP_RESULT);
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);
617 testassert(sp1 == sp2);
618 testassert(state == 8);
619 testassert(stret_equal(stval, STRET_RESULT));
622 // Test user-defined forward handler
624 objc_setForwardHandler((void*)&forward_handler, (void*)&forward_stret_handler);
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];
630 testassert(sp1 == sp2);
631 testassert(state == 12);
632 testassert(idval == ID_RESULT);
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];
638 testassert(sp1 == sp2);
639 testassert(state == 14);
640 testassert(llval == LL_RESULT);
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];
646 testassert(sp1 == sp2);
647 testassert(state == 16);
648 testassert(fpval == FP_RESULT);
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];
654 testassert(sp1 == sp2);
655 testassert(state == 18);
656 testassert(stret_equal(stval, STRET_RESULT));
659 // Test user-defined forward handler, cached
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];
665 testassert(sp1 == sp2);
666 testassert(state == 12);
667 testassert(idval == ID_RESULT);
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];
673 testassert(sp1 == sp2);
674 testassert(state == 14);
675 testassert(llval == LL_RESULT);
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];
681 testassert(sp1 == sp2);
682 testassert(state == 16);
683 testassert(fpval == FP_RESULT);
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];
689 testassert(sp1 == sp2);
690 testassert(state == 18);
691 testassert(stret_equal(stval, STRET_RESULT));
694 // Test user-defined forward handler, uncached but fixed-up
696 _objc_flush_caches(nil);
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];
702 testassert(sp1 == sp2);
703 testassert(state == 12);
704 testassert(idval == ID_RESULT);
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];
710 testassert(sp1 == sp2);
711 testassert(state == 14);
712 testassert(llval == LL_RESULT);
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];
718 testassert(sp1 == sp2);
719 testassert(state == 16);
720 testassert(fpval == FP_RESULT);
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];
726 testassert(sp1 == sp2);
727 testassert(state == 18);
728 testassert(stret_equal(stval, STRET_RESULT));