5 #include <objc/runtime.h>
6 #include <objc/message.h>
8 id ID_RESULT = (id)0x12345678;
9 long long LL_RESULT = __LONG_LONG_MAX__ - 2LL*__INT_MAX__;
10 double FP_RESULT = __DBL_MIN__ + __DBL_EPSILON__;
11 long double LFP_RESULT = __LDBL_MIN__ + __LDBL_EPSILON__;
12 // STRET_RESULT in test.h
19 @interface Super { id isa; } @end
21 @interface Super (Forwarded)
23 (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;
26 (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;
29 (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;
32 (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;
35 (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;
38 (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;
41 (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;
44 (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;
47 (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;
50 (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;
53 (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;
56 (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 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)
65 # define p "x" // true arm64
67 # define p "w" // arm64_32
70 __asm__ volatile("mov %" p "0, " p "8" : "=r" (struct_addr) : : p "8");
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;
118 else if (_cmd == @selector(llret::::::::::::::::::::::::::::) ||
119 _cmd == @selector(llre2::::::::::::::::::::::::::::) ||
120 _cmd == @selector(llre3::::::::::::::::::::::::::::))
122 testassert(state == 13);
126 else if (_cmd == @selector(fpret::::::::::::::::::::::::::::) ||
127 _cmd == @selector(fpre2::::::::::::::::::::::::::::) ||
128 _cmd == @selector(fpre3::::::::::::::::::::::::::::))
130 testassert(state == 15);
132 #if defined(__i386__)
133 __asm__ volatile("fldl %0" : : "m" (FP_RESULT));
134 #elif defined(__x86_64__)
135 __asm__ volatile("movsd %0, %%xmm0" : : "m" (FP_RESULT));
136 #elif defined(__arm64__)
137 __asm__ volatile("ldr d0, %0" : : "m" (FP_RESULT));
138 #elif defined(__arm__) && __ARM_ARCH_7K__
139 __asm__ volatile("vld1.64 {d0}, %0" : : "m" (FP_RESULT));
140 #elif defined(__arm__)
145 result.fpval = FP_RESULT;
148 # error unknown architecture
152 else if (_cmd == @selector(stret::::::::::::::::::::::::::::) ||
153 _cmd == @selector(stre2::::::::::::::::::::::::::::) ||
154 _cmd == @selector(stre3::::::::::::::::::::::::::::))
156 #if __i386__ || __x86_64__ || __arm__
157 fail("stret message sent to non-stret forward_handler");
158 #elif __arm64_32__ || __arm64__
159 testassert(state == 17);
161 memcpy(struct_addr, &STRET_RESULT, sizeof(STRET_RESULT));
164 # error unknown architecture
168 fail("unknown selector %s in forward_handler", sel_getName(_cmd));
173 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)
175 testassert(self == receiver);
186 testassert(i10 == 10);
187 testassert(i11 == 11);
188 testassert(i12 == 12);
189 testassert(i13 == 13);
191 testassert(f1 == 1.0);
192 testassert(f2 == 2.0);
193 testassert(f3 == 3.0);
194 testassert(f4 == 4.0);
195 testassert(f5 == 5.0);
196 testassert(f6 == 6.0);
197 testassert(f7 == 7.0);
198 testassert(f8 == 8.0);
199 testassert(f9 == 9.0);
200 testassert(f10 == 10.0);
201 testassert(f11 == 11.0);
202 testassert(f12 == 12.0);
203 testassert(f13 == 13.0);
204 testassert(f14 == 14.0);
205 testassert(f15 == 15.0);
207 if (_cmd == @selector(idret::::::::::::::::::::::::::::) ||
208 _cmd == @selector(idre2::::::::::::::::::::::::::::) ||
209 _cmd == @selector(idre3::::::::::::::::::::::::::::) ||
210 _cmd == @selector(llret::::::::::::::::::::::::::::) ||
211 _cmd == @selector(llre2::::::::::::::::::::::::::::) ||
212 _cmd == @selector(llre3::::::::::::::::::::::::::::) ||
213 _cmd == @selector(fpret::::::::::::::::::::::::::::) ||
214 _cmd == @selector(fpre2::::::::::::::::::::::::::::) ||
215 _cmd == @selector(fpre3::::::::::::::::::::::::::::))
217 fail("non-stret selector %s sent to forward_stret_handler", sel_getName(_cmd));
219 else if (_cmd == @selector(stret::::::::::::::::::::::::::::) ||
220 _cmd == @selector(stre2::::::::::::::::::::::::::::) ||
221 _cmd == @selector(stre3::::::::::::::::::::::::::::))
223 testassert(state == 17);
228 fail("unknown selector %s in forward_stret_handler", sel_getName(_cmd));
234 @implementation Super
235 +(void)initialize { }
236 +(id)class { return self; }
239 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);
241 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);
243 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);
245 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);
248 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);
252 extern void *getSP(void);
255 #if defined(__x86_64__)
256 asm(".text \n _getSP: movq %rsp, %rax \n retq \n");
257 #elif defined(__i386__)
258 asm(".text \n _getSP: movl %esp, %eax \n ret \n");
259 #elif defined(__arm__)
260 asm(".text \n .thumb \n .thumb_func _getSP \n "
261 "_getSP: mov r0, sp \n bx lr \n");
262 #elif defined(__arm64__)
263 asm(".text \n _getSP: mov x0, sp \n ret \n");
265 # error unknown architecture
277 void *sp1 = (void*)1;
278 void *sp2 = (void*)2;
282 stret_fwd = (st_fn_t)_objc_msgForward;
284 stret_fwd = (st_fn_t)_objc_msgForward_stret;
287 receiver = [Super class];
289 // Test user-defined forward handler
291 objc_setForwardHandler((void*)&forward_handler, (void*)&forward_stret_handler);
295 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];
297 testassert(sp1 == sp2);
298 testassert(state == 12);
299 testassert(idval == ID_RESULT);
303 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];
305 testassert(sp1 == sp2);
306 testassert(state == 14);
307 testassert(llval == LL_RESULT);
311 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];
313 testassert(sp1 == sp2);
314 testassert(state == 16);
315 testassert(fpval == FP_RESULT);
319 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];
321 testassert(sp1 == sp2);
322 testassert(state == 18);
323 testassert(stret_equal(stval, STRET_RESULT));
326 // check stret return register
329 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);
331 testassert(sp1 == sp2);
332 testassert(state == 18);
333 testassert(stret_equal(stval, STRET_RESULT));
334 testassert(stptr == &stval);
338 // Test user-defined forward handler, cached
342 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];
344 testassert(sp1 == sp2);
345 testassert(state == 12);
346 testassert(idval == ID_RESULT);
350 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];
352 testassert(sp1 == sp2);
353 testassert(state == 14);
354 testassert(llval == LL_RESULT);
358 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];
360 testassert(sp1 == sp2);
361 testassert(state == 16);
362 testassert(fpval == FP_RESULT);
366 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];
368 testassert(sp1 == sp2);
369 testassert(state == 18);
370 testassert(stret_equal(stval, STRET_RESULT));
373 // check stret return register
376 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);
378 testassert(sp1 == sp2);
379 testassert(state == 18);
380 testassert(stret_equal(stval, STRET_RESULT));
381 testassert(stptr == &stval);
385 // Test user-defined forward handler, uncached but fixed-up
387 _objc_flush_caches(nil);
391 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];
393 testassert(sp1 == sp2);
394 testassert(state == 12);
395 testassert(idval == ID_RESULT);
399 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];
401 testassert(sp1 == sp2);
402 testassert(state == 14);
403 testassert(llval == LL_RESULT);
407 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];
409 testassert(sp1 == sp2);
410 testassert(state == 16);
411 testassert(fpval == FP_RESULT);
415 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];
417 testassert(sp1 == sp2);
418 testassert(state == 18);
419 testassert(stret_equal(stval, STRET_RESULT));
422 // check stret return register
425 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);
427 testassert(sp1 == sp2);
428 testassert(state == 18);
429 testassert(stret_equal(stval, STRET_RESULT));
430 testassert(stptr == &stval);
435 // Test user-defined forward handler, manual forwarding
439 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);
441 testassert(sp1 == sp2);
442 testassert(state == 12);
443 testassert(idval == ID_RESULT);
447 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);
449 testassert(sp1 == sp2);
450 testassert(state == 14);
451 testassert(llval == LL_RESULT);
455 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);
457 testassert(sp1 == sp2);
458 testassert(state == 16);
459 testassert(fpval == FP_RESULT);
463 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);
465 testassert(sp1 == sp2);
466 testassert(state == 18);
467 testassert(stret_equal(stval, STRET_RESULT));
470 // Test user-defined forward handler, manual forwarding, cached
474 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);
476 testassert(sp1 == sp2);
477 testassert(state == 12);
478 testassert(idval == ID_RESULT);
482 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);
484 testassert(sp1 == sp2);
485 testassert(state == 14);
486 testassert(llval == LL_RESULT);
490 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);
492 testassert(sp1 == sp2);
493 testassert(state == 16);
494 testassert(fpval == FP_RESULT);
498 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);
500 testassert(sp1 == sp2);
501 testassert(state == 18);
502 testassert(stret_equal(stval, STRET_RESULT));
505 // Test user-defined forward handler, manual forwarding, uncached but fixed-up
507 _objc_flush_caches(nil);
511 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);
513 testassert(sp1 == sp2);
514 testassert(state == 12);
515 testassert(idval == ID_RESULT);
519 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);
521 testassert(sp1 == sp2);
522 testassert(state == 14);
523 testassert(llval == LL_RESULT);
527 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);
529 testassert(sp1 == sp2);
530 testassert(state == 16);
531 testassert(fpval == FP_RESULT);
535 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);
537 testassert(sp1 == sp2);
538 testassert(state == 18);
539 testassert(stret_equal(stval, STRET_RESULT));