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
30 @interface Super { id isa; } @end
32 @interface Super (Forwarded)
34 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 (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 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)
76 __asm__ volatile("mov %0, x8" : "=r" (struct_addr) : : "x8");
79 testassert(self == receiver);
90 testassert(i10 == 10);
91 testassert(i11 == 11);
92 testassert(i12 == 12);
93 testassert(i13 == 13);
95 testassert(f1 == 1.0);
96 testassert(f2 == 2.0);
97 testassert(f3 == 3.0);
98 testassert(f4 == 4.0);
99 testassert(f5 == 5.0);
100 testassert(f6 == 6.0);
101 testassert(f7 == 7.0);
102 testassert(f8 == 8.0);
103 testassert(f9 == 9.0);
104 testassert(f10 == 10.0);
105 testassert(f11 == 11.0);
106 testassert(f12 == 12.0);
107 testassert(f13 == 13.0);
108 testassert(f14 == 14.0);
109 testassert(f15 == 15.0);
111 if (_cmd == @selector(idret::::::::::::::::::::::::::::) ||
112 _cmd == @selector(idre2::::::::::::::::::::::::::::) ||
113 _cmd == @selector(idre3::::::::::::::::::::::::::::))
119 testassert(state == 11);
121 result.idval = ID_RESULT;
124 else if (_cmd == @selector(llret::::::::::::::::::::::::::::) ||
125 _cmd == @selector(llre2::::::::::::::::::::::::::::) ||
126 _cmd == @selector(llre3::::::::::::::::::::::::::::))
128 testassert(state == 13);
132 else if (_cmd == @selector(fpret::::::::::::::::::::::::::::) ||
133 _cmd == @selector(fpre2::::::::::::::::::::::::::::) ||
134 _cmd == @selector(fpre3::::::::::::::::::::::::::::))
136 testassert(state == 15);
138 #if defined(__i386__)
139 __asm__ volatile("fldl %0" : : "m" (FP_RESULT));
140 #elif defined(__x86_64__)
141 __asm__ volatile("movsd %0, %%xmm0" : : "m" (FP_RESULT));
142 #elif defined(__arm__)
147 result.fpval = FP_RESULT;
149 #elif defined(__arm64__)
150 __asm__ volatile("ldr d0, %0" : : "m" (FP_RESULT));
152 # error unknown architecture
156 else if (_cmd == @selector(stret::::::::::::::::::::::::::::) ||
157 _cmd == @selector(stre2::::::::::::::::::::::::::::) ||
158 _cmd == @selector(stre3::::::::::::::::::::::::::::))
160 #if __i386__ || __x86_64__ || __arm__
161 fail("stret message sent to non-stret forward_handler");
163 testassert(state == 17);
165 memcpy(struct_addr, &STRET_RESULT, sizeof(STRET_RESULT));
168 # error unknown architecture
172 fail("unknown selector %s in forward_handler", sel_getName(_cmd));
177 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)
179 testassert(self == receiver);
190 testassert(i10 == 10);
191 testassert(i11 == 11);
192 testassert(i12 == 12);
193 testassert(i13 == 13);
195 testassert(f1 == 1.0);
196 testassert(f2 == 2.0);
197 testassert(f3 == 3.0);
198 testassert(f4 == 4.0);
199 testassert(f5 == 5.0);
200 testassert(f6 == 6.0);
201 testassert(f7 == 7.0);
202 testassert(f8 == 8.0);
203 testassert(f9 == 9.0);
204 testassert(f10 == 10.0);
205 testassert(f11 == 11.0);
206 testassert(f12 == 12.0);
207 testassert(f13 == 13.0);
208 testassert(f14 == 14.0);
209 testassert(f15 == 15.0);
211 if (_cmd == @selector(idret::::::::::::::::::::::::::::) ||
212 _cmd == @selector(idre2::::::::::::::::::::::::::::) ||
213 _cmd == @selector(idre3::::::::::::::::::::::::::::) ||
214 _cmd == @selector(llret::::::::::::::::::::::::::::) ||
215 _cmd == @selector(llre2::::::::::::::::::::::::::::) ||
216 _cmd == @selector(llre3::::::::::::::::::::::::::::) ||
217 _cmd == @selector(fpret::::::::::::::::::::::::::::) ||
218 _cmd == @selector(fpre2::::::::::::::::::::::::::::) ||
219 _cmd == @selector(fpre3::::::::::::::::::::::::::::))
221 fail("non-stret selector %s sent to forward_stret_handler", sel_getName(_cmd));
223 else if (_cmd == @selector(stret::::::::::::::::::::::::::::) ||
224 _cmd == @selector(stre2::::::::::::::::::::::::::::) ||
225 _cmd == @selector(stre3::::::::::::::::::::::::::::))
227 testassert(state == 17);
232 fail("unknown selector %s in forward_stret_handler", sel_getName(_cmd));
238 @implementation Super
239 +(void)initialize { }
240 +(id)class { return self; }
243 // forward:: not supported
245 -(long long) forward:(SEL)sel :(marg_list)args
250 struct stret *struct_addr;
252 #if defined(__i386__)
253 struct_addr = ((struct stret **)args)[-1];
254 #elif defined(__x86_64__)
255 struct_addr = *(struct stret **)((char *)args + 8*16+4*8);
256 #elif defined(__arm__)
257 struct_addr = *(struct stret **)((char *)args + 0);
259 # error unknown architecture
262 testassert(self == receiver);
263 testassert(_cmd == sel_registerName("forward::"));
266 #if defined(__x86_64__)
267 p += 8*16 + 4*8; // skip over xmm and linkage
268 if (sel == @selector(stret::::::::::::::::::::::::::::) ||
269 sel == @selector(stre2::::::::::::::::::::::::::::) ||
270 sel == @selector(stre3::::::::::::::::::::::::::::))
272 p += sizeof(void *); // struct return
274 #elif defined(__i386__)
276 #elif defined(__arm__)
277 if (sel == @selector(stret::::::::::::::::::::::::::::) ||
278 sel == @selector(stre2::::::::::::::::::::::::::::) ||
279 sel == @selector(stre3::::::::::::::::::::::::::::))
281 p += sizeof(void *); // struct return;
284 # error unknown architecture
287 testassert(*gp++ == (uintptr_t)self);
288 testassert(*gp++ == (uintptr_t)(void *)sel);
289 testassert(*gp++ == 1);
290 testassert(*gp++ == 2);
291 testassert(*gp++ == 3);
292 testassert(*gp++ == 4);
293 testassert(*gp++ == 5);
294 testassert(*gp++ == 6);
295 testassert(*gp++ == 7);
296 testassert(*gp++ == 8);
297 testassert(*gp++ == 9);
298 testassert(*gp++ == 10);
299 testassert(*gp++ == 11);
300 testassert(*gp++ == 12);
301 testassert(*gp++ == 13);
303 #if defined(__i386__) || defined(__arm__)
306 testassert(*fp++ == 1.0);
307 testassert(*fp++ == 2.0);
308 testassert(*fp++ == 3.0);
309 testassert(*fp++ == 4.0);
310 testassert(*fp++ == 5.0);
311 testassert(*fp++ == 6.0);
312 testassert(*fp++ == 7.0);
313 testassert(*fp++ == 8.0);
314 testassert(*fp++ == 9.0);
315 testassert(*fp++ == 10.0);
316 testassert(*fp++ == 11.0);
317 testassert(*fp++ == 12.0);
318 testassert(*fp++ == 13.0);
319 testassert(*fp++ == 14.0);
320 testassert(*fp++ == 15.0);
322 #elif defined(__x86_64__)
324 fp = (double *)args; // xmm, double-wide
325 testassert(*fp++ == 1.0); fp++;
326 testassert(*fp++ == 2.0); fp++;
327 testassert(*fp++ == 3.0); fp++;
328 testassert(*fp++ == 4.0); fp++;
329 testassert(*fp++ == 5.0); fp++;
330 testassert(*fp++ == 6.0); fp++;
331 testassert(*fp++ == 7.0); fp++;
332 testassert(*fp++ == 8.0); fp++;
334 testassert(*fp++ == 9.0);
335 testassert(*fp++ == 10.0);
336 testassert(*fp++ == 11.0);
337 testassert(*fp++ == 12.0);
338 testassert(*fp++ == 13.0);
339 testassert(*fp++ == 14.0);
340 testassert(*fp++ == 15.0);
343 # error unknown architecture
346 if (sel == @selector(idret::::::::::::::::::::::::::::) ||
347 sel == @selector(idre2::::::::::::::::::::::::::::) ||
348 sel == @selector(idre3::::::::::::::::::::::::::::))
354 testassert(state == 1);
356 result.idval = ID_RESULT;
358 } else if (sel == @selector(llret::::::::::::::::::::::::::::) ||
359 sel == @selector(llre2::::::::::::::::::::::::::::) ||
360 sel == @selector(llre3::::::::::::::::::::::::::::))
362 testassert(state == 3);
365 } else if (sel == @selector(fpret::::::::::::::::::::::::::::) ||
366 sel == @selector(fpre2::::::::::::::::::::::::::::) ||
367 sel == @selector(fpre3::::::::::::::::::::::::::::))
369 testassert(state == 5);
371 #if defined(__i386__)
372 __asm__ volatile("fldl %0" : : "m" (FP_RESULT));
373 #elif defined(__x86_64__)
374 __asm__ volatile("movsd %0, %%xmm0" : : "m" (FP_RESULT));
375 #elif defined(__arm__)
380 result.fpval = FP_RESULT;
383 # error unknown architecture
386 } else if (sel == @selector(stret::::::::::::::::::::::::::::) ||
387 sel == @selector(stre2::::::::::::::::::::::::::::) ||
388 sel == @selector(stre3::::::::::::::::::::::::::::))
390 testassert(state == 7);
392 *struct_addr = STRET_RESULT;
395 fail("unknown selector %s in forward::", sel_getName(sel));
404 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);
406 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);
408 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);
410 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);
413 typedef struct stret * (*fake_st_fn_t)(struct stret *, 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);
417 extern void *getSP(void);
420 #if defined(__x86_64__)
421 asm(".text \n _getSP: movq %rsp, %rax \n retq \n");
422 #elif defined(__i386__)
423 asm(".text \n _getSP: movl %esp, %eax \n ret \n");
424 #elif defined(__arm__)
425 asm(".text \n .thumb \n .thumb_func _getSP \n "
426 "_getSP: mov r0, sp \n bx lr \n");
427 #elif defined(__arm64__)
428 asm(".text \n _getSP: mov x0, sp \n ret \n");
430 # error unknown architecture
442 void *sp1 = (void*)1;
443 void *sp2 = (void*)2;
447 stret_fwd = (st_fn_t)_objc_msgForward;
449 stret_fwd = (st_fn_t)_objc_msgForward_stret;
452 receiver = [Super class];
455 // forward:: not supported
457 // Test default forward handler
461 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];
463 testassert(sp1 == sp2);
464 testassert(state == 2);
465 testassert(idval == ID_RESULT);
469 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];
471 testassert(sp1 == sp2);
472 testassert(state == 4);
473 testassert(llval == LL_RESULT);
477 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];
479 testassert(sp1 == sp2);
480 testassert(state == 6);
481 testassert(fpval == FP_RESULT);
485 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];
487 testassert(sp1 == sp2);
488 testassert(state == 8);
489 testassert(stret_equal(stval, STRET_RESULT));
492 // check stret return register
495 stptr = ((fake_st_fn_t)objc_msgSend_stret)(&stval, [Super class], @selector(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);
497 testassert(sp1 == sp2);
498 testassert(state == 8);
499 testassert(stret_equal(stval, STRET_RESULT));
500 testassert(stptr == &stval);
504 // Test default forward handler, cached
508 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];
510 testassert(sp1 == sp2);
511 testassert(state == 2);
512 testassert(idval == ID_RESULT);
516 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];
518 testassert(sp1 == sp2);
519 testassert(state == 4);
520 testassert(llval == LL_RESULT);
524 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];
526 testassert(sp1 == sp2);
527 testassert(state == 6);
528 testassert(fpval == FP_RESULT);
532 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];
534 testassert(sp1 == sp2);
535 testassert(state == 8);
536 testassert(stret_equal(stval, STRET_RESULT));
539 // check stret return register
542 stptr = ((fake_st_fn_t)objc_msgSend_stret)(&stval, [Super class], @selector(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);
544 testassert(sp1 == sp2);
545 testassert(state == 8);
546 testassert(stret_equal(stval, STRET_RESULT));
547 testassert(stptr == &stval);
551 // Test default forward handler, uncached but fixed-up
553 _objc_flush_caches(nil);
557 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];
559 testassert(sp1 == sp2);
560 testassert(state == 2);
561 testassert(idval == ID_RESULT);
565 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];
567 testassert(sp1 == sp2);
568 testassert(state == 4);
569 testassert(llval == LL_RESULT);
573 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];
575 testassert(sp1 == sp2);
576 testassert(state == 6);
577 testassert(fpval == FP_RESULT);
581 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];
583 testassert(sp1 == sp2);
584 testassert(state == 8);
585 testassert(stret_equal(stval, STRET_RESULT));
588 // check stret return register
591 stptr = ((fake_st_fn_t)objc_msgSend_stret)(&stval, [Super class], @selector(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);
593 testassert(sp1 == sp2);
594 testassert(state == 8);
595 testassert(stret_equal(stval, STRET_RESULT));
596 testassert(stptr == &stval);
600 // Test manual forwarding
604 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);
606 testassert(sp1 == sp2);
607 testassert(state == 2);
608 testassert(idval == ID_RESULT);
612 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);
614 testassert(sp1 == sp2);
615 testassert(state == 4);
616 testassert(llval == LL_RESULT);
620 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);
622 testassert(sp1 == sp2);
623 testassert(state == 6);
624 testassert(fpval == FP_RESULT);
628 stval = stret_fwd(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);
630 testassert(sp1 == sp2);
631 testassert(state == 8);
632 testassert(stret_equal(stval, STRET_RESULT));
635 // check stret return register
638 stptr = ((fake_st_fn_t)_objc_msgForward_stret)(&stval, 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);
640 testassert(sp1 == sp2);
641 testassert(state == 8);
642 testassert(stret_equal(stval, STRET_RESULT));
643 testassert(stptr == &stval);
647 // Test manual forwarding, cached
651 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);
653 testassert(sp1 == sp2);
654 testassert(state == 2);
655 testassert(idval == ID_RESULT);
659 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);
661 testassert(sp1 == sp2);
662 testassert(state == 4);
663 testassert(llval == LL_RESULT);
667 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);
669 testassert(sp1 == sp2);
670 testassert(state == 6);
671 testassert(fpval == FP_RESULT);
675 stval = stret_fwd(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);
677 testassert(sp1 == sp2);
678 testassert(state == 8);
679 testassert(stret_equal(stval, STRET_RESULT));
682 // check stret return register
685 stptr = ((fake_st_fn_t)_objc_msgForward_stret)(&stval, 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);
687 testassert(sp1 == sp2);
688 testassert(state == 8);
689 testassert(stret_equal(stval, STRET_RESULT));
690 testassert(stptr == &stval);
694 // Test manual forwarding, uncached but fixed-up
696 _objc_flush_caches(nil);
700 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);
702 testassert(sp1 == sp2);
703 testassert(state == 2);
704 testassert(idval == ID_RESULT);
708 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);
710 testassert(sp1 == sp2);
711 testassert(state == 4);
712 testassert(llval == LL_RESULT);
716 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);
718 testassert(sp1 == sp2);
719 testassert(state == 6);
720 testassert(fpval == FP_RESULT);
724 stval = stret_fwd(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);
726 testassert(sp1 == sp2);
727 testassert(state == 8);
728 testassert(stret_equal(stval, STRET_RESULT));
731 // check stret return register
734 stptr = ((fake_st_fn_t)_objc_msgForward_stret)(&stval, 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);
736 testassert(sp1 == sp2);
737 testassert(state == 8);
738 testassert(stret_equal(stval, STRET_RESULT));
739 testassert(stptr == &stval);
746 // Test user-defined forward handler
748 objc_setForwardHandler((void*)&forward_handler, (void*)&forward_stret_handler);
752 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];
754 testassert(sp1 == sp2);
755 testassert(state == 12);
756 testassert(idval == ID_RESULT);
760 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];
762 testassert(sp1 == sp2);
763 testassert(state == 14);
764 testassert(llval == LL_RESULT);
768 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];
770 testassert(sp1 == sp2);
771 testassert(state == 16);
772 testassert(fpval == FP_RESULT);
776 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];
778 testassert(sp1 == sp2);
779 testassert(state == 18);
780 testassert(stret_equal(stval, STRET_RESULT));
783 // check stret return register
786 stptr = ((fake_st_fn_t)objc_msgSend_stret)(&stval, [Super class], @selector(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);
788 testassert(sp1 == sp2);
789 testassert(state == 18);
790 testassert(stret_equal(stval, STRET_RESULT));
791 testassert(stptr == &stval);
795 // Test user-defined forward handler, cached
799 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];
801 testassert(sp1 == sp2);
802 testassert(state == 12);
803 testassert(idval == ID_RESULT);
807 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];
809 testassert(sp1 == sp2);
810 testassert(state == 14);
811 testassert(llval == LL_RESULT);
815 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];
817 testassert(sp1 == sp2);
818 testassert(state == 16);
819 testassert(fpval == FP_RESULT);
823 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];
825 testassert(sp1 == sp2);
826 testassert(state == 18);
827 testassert(stret_equal(stval, STRET_RESULT));
830 // check stret return register
833 stptr = ((fake_st_fn_t)objc_msgSend_stret)(&stval, [Super class], @selector(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);
835 testassert(sp1 == sp2);
836 testassert(state == 18);
837 testassert(stret_equal(stval, STRET_RESULT));
838 testassert(stptr == &stval);
842 // Test user-defined forward handler, uncached but fixed-up
844 _objc_flush_caches(nil);
848 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];
850 testassert(sp1 == sp2);
851 testassert(state == 12);
852 testassert(idval == ID_RESULT);
856 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];
858 testassert(sp1 == sp2);
859 testassert(state == 14);
860 testassert(llval == LL_RESULT);
864 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];
866 testassert(sp1 == sp2);
867 testassert(state == 16);
868 testassert(fpval == FP_RESULT);
872 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];
874 testassert(sp1 == sp2);
875 testassert(state == 18);
876 testassert(stret_equal(stval, STRET_RESULT));
879 // check stret return register
882 stptr = ((fake_st_fn_t)objc_msgSend_stret)(&stval, [Super class], @selector(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);
884 testassert(sp1 == sp2);
885 testassert(state == 18);
886 testassert(stret_equal(stval, STRET_RESULT));
887 testassert(stptr == &stval);
892 // Test user-defined forward handler, manual forwarding
896 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);
898 testassert(sp1 == sp2);
899 testassert(state == 12);
900 testassert(idval == ID_RESULT);
904 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);
906 testassert(sp1 == sp2);
907 testassert(state == 14);
908 testassert(llval == LL_RESULT);
912 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);
914 testassert(sp1 == sp2);
915 testassert(state == 16);
916 testassert(fpval == FP_RESULT);
920 stval = stret_fwd(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);
922 testassert(sp1 == sp2);
923 testassert(state == 18);
924 testassert(stret_equal(stval, STRET_RESULT));
927 // Test user-defined forward handler, manual forwarding, cached
931 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);
933 testassert(sp1 == sp2);
934 testassert(state == 12);
935 testassert(idval == ID_RESULT);
939 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);
941 testassert(sp1 == sp2);
942 testassert(state == 14);
943 testassert(llval == LL_RESULT);
947 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);
949 testassert(sp1 == sp2);
950 testassert(state == 16);
951 testassert(fpval == FP_RESULT);
955 stval = stret_fwd(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);
957 testassert(sp1 == sp2);
958 testassert(state == 18);
959 testassert(stret_equal(stval, STRET_RESULT));
962 // Test user-defined forward handler, manual forwarding, uncached but fixed-up
964 _objc_flush_caches(nil);
968 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);
970 testassert(sp1 == sp2);
971 testassert(state == 12);
972 testassert(idval == ID_RESULT);
976 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);
978 testassert(sp1 == sp2);
979 testassert(state == 14);
980 testassert(llval == LL_RESULT);
984 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);
986 testassert(sp1 == sp2);
987 testassert(state == 16);
988 testassert(fpval == FP_RESULT);
992 stval = stret_fwd(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);
994 testassert(sp1 == sp2);
995 testassert(state == 18);
996 testassert(stret_equal(stval, STRET_RESULT));