1// TEST_CONFIG MEM=mrc,gc
2// TEST_CFLAGS -Wno-deprecated-declarations
3
4#include "test.h"
5
6#if __cplusplus  &&  !__clang__
7
8int 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
19id ID_RESULT = (id)0x12345678;
20long long LL_RESULT = __LONG_LONG_MAX__ - 2LL*__INT_MAX__;
21double FP_RESULT = __DBL_MIN__ + __DBL_EPSILON__;
22long double LFP_RESULT = __LDBL_MIN__ + __LDBL_EPSILON__;
23// STRET_RESULT in test.h
24
25
26static int state = 0;
27static id receiver;
28
29OBJC_ROOT_CLASS
30@interface Super { id isa; } @end
31
32@interface Super (Forwarded) 
33+(id)idret: 
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;
35
36+(id)idre2: 
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;
38
39+(id)idre3: 
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;
41
42+(long long)llret: 
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;
44
45+(long long)llre2: 
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;
47
48+(long long)llre3: 
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;
50
51+(struct stret)stret: 
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;
53
54+(struct stret)stre2: 
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;
56
57+(struct stret)stre3: 
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;
59
60+(double)fpret: 
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;
62
63+(double)fpre2: 
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;
65
66+(double)fpre3: 
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;
68
69@end
70
71
72long 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{
74    testassert(self == receiver);
75
76    testassert(i1 == 1);
77    testassert(i2 == 2);
78    testassert(i3 == 3);
79    testassert(i4 == 4);
80    testassert(i5 == 5);
81    testassert(i6 == 6);
82    testassert(i7 == 7);
83    testassert(i8 == 8);
84    testassert(i9 == 9);
85    testassert(i10 == 10);
86    testassert(i11 == 11);
87    testassert(i12 == 12);
88    testassert(i13 == 13);
89
90    testassert(f1 == 1.0);
91    testassert(f2 == 2.0);
92    testassert(f3 == 3.0);
93    testassert(f4 == 4.0);
94    testassert(f5 == 5.0);
95    testassert(f6 == 6.0);
96    testassert(f7 == 7.0);
97    testassert(f8 == 8.0);
98    testassert(f9 == 9.0);
99    testassert(f10 == 10.0);
100    testassert(f11 == 11.0);
101    testassert(f12 == 12.0);
102    testassert(f13 == 13.0);
103    testassert(f14 == 14.0);
104    testassert(f15 == 15.0);
105
106    if (_cmd == @selector(idret::::::::::::::::::::::::::::)  ||  
107        _cmd == @selector(idre2::::::::::::::::::::::::::::)  ||  
108        _cmd == @selector(idre3::::::::::::::::::::::::::::)) 
109    {
110        union {
111            id idval;
112            long long llval;
113        } result;
114        testassert(state == 11);
115        state = 12;
116        result.idval = ID_RESULT;
117        return result.llval;
118    }
119    else if (_cmd == @selector(llret::::::::::::::::::::::::::::)  ||  
120             _cmd == @selector(llre2::::::::::::::::::::::::::::)  ||  
121             _cmd == @selector(llre3::::::::::::::::::::::::::::)) 
122    {
123        testassert(state == 13);
124        state = 14;
125        return LL_RESULT;
126    }
127    else if (_cmd == @selector(fpret::::::::::::::::::::::::::::)  ||  
128             _cmd == @selector(fpre2::::::::::::::::::::::::::::)  ||  
129             _cmd == @selector(fpre3::::::::::::::::::::::::::::)) 
130    {
131        testassert(state == 15);
132        state = 16;
133#if defined(__i386__)
134        __asm__ volatile("fldl %0" : : "m" (FP_RESULT));
135#elif defined(__x86_64__)
136        __asm__ volatile("movsd %0, %%xmm0" : : "m" (FP_RESULT));
137#elif defined(__arm__)
138        union {
139            double fpval;
140            long long llval;
141        } result;
142        result.fpval = FP_RESULT;
143        return result.llval;
144#else
145#       error unknown architecture
146#endif
147        return 0;
148    }
149    else if (_cmd == @selector(stret::::::::::::::::::::::::::::)  ||  
150             _cmd == @selector(stre2::::::::::::::::::::::::::::)  ||  
151             _cmd == @selector(stre3::::::::::::::::::::::::::::)) 
152    {
153        fail("stret message sent to non-stret forward_handler");
154    } 
155    else {
156        fail("unknown selector %s in forward_handler", sel_getName(_cmd));
157    }
158}
159
160
161struct 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)
162{
163    testassert(self == receiver);
164
165    testassert(i1 == 1);
166    testassert(i2 == 2);
167    testassert(i3 == 3);
168    testassert(i4 == 4);
169    testassert(i5 == 5);
170    testassert(i6 == 6);
171    testassert(i7 == 7);
172    testassert(i8 == 8);
173    testassert(i9 == 9);
174    testassert(i10 == 10);
175    testassert(i11 == 11);
176    testassert(i12 == 12);
177    testassert(i13 == 13);
178
179    testassert(f1 == 1.0);
180    testassert(f2 == 2.0);
181    testassert(f3 == 3.0);
182    testassert(f4 == 4.0);
183    testassert(f5 == 5.0);
184    testassert(f6 == 6.0);
185    testassert(f7 == 7.0);
186    testassert(f8 == 8.0);
187    testassert(f9 == 9.0);
188    testassert(f10 == 10.0);
189    testassert(f11 == 11.0);
190    testassert(f12 == 12.0);
191    testassert(f13 == 13.0);
192    testassert(f14 == 14.0);
193    testassert(f15 == 15.0);
194
195    if (_cmd == @selector(idret::::::::::::::::::::::::::::)  ||
196        _cmd == @selector(idre2::::::::::::::::::::::::::::)  ||
197        _cmd == @selector(idre3::::::::::::::::::::::::::::)  ||
198        _cmd == @selector(llret::::::::::::::::::::::::::::)  ||
199        _cmd == @selector(llre2::::::::::::::::::::::::::::)  ||
200        _cmd == @selector(llre3::::::::::::::::::::::::::::)  ||
201        _cmd == @selector(fpret::::::::::::::::::::::::::::)  ||
202        _cmd == @selector(fpre2::::::::::::::::::::::::::::)  ||
203        _cmd == @selector(fpre3::::::::::::::::::::::::::::))
204    {
205        fail("non-stret selector %s sent to forward_stret_handler", sel_getName(_cmd));
206    }
207    else if (_cmd == @selector(stret::::::::::::::::::::::::::::)  ||  
208             _cmd == @selector(stre2::::::::::::::::::::::::::::)  ||  
209             _cmd == @selector(stre3::::::::::::::::::::::::::::)) 
210    {
211        testassert(state == 17);
212        state = 18;
213        return STRET_RESULT;
214    }
215    else {
216        fail("unknown selector %s in forward_stret_handler", sel_getName(_cmd));
217    }
218
219}
220
221
222@implementation Super
223+(void)initialize { }
224+(id)class { return self; }
225
226-(long long) forward:(SEL)sel :(marg_list)args
227{
228    char *p;
229    uintptr_t *gp;
230    double *fp;
231    struct stret *struct_addr;
232    
233#if defined(__i386__)
234    struct_addr = ((struct stret **)args)[-1];
235#elif defined(__x86_64__)
236    struct_addr = *(struct stret **)((char *)args + 8*16+4*8);
237#elif defined(__arm__)
238    struct_addr = *(struct stret **)((char *)args + 0);
239#else
240#   error unknown architecture
241#endif
242
243    testassert(self == receiver);
244    testassert(_cmd == sel_registerName("forward::"));
245
246    p = (char *)args;
247#if defined(__x86_64__)
248    p += 8*16 + 4*8;  // skip over xmm and linkage
249    if (sel == @selector(stret::::::::::::::::::::::::::::)  ||  
250        sel == @selector(stre2::::::::::::::::::::::::::::)  ||  
251        sel == @selector(stre3::::::::::::::::::::::::::::)) 
252    {
253        p += sizeof(void *);  // struct return
254    }
255#elif defined(__i386__)
256    // nothing to do
257#elif defined(__arm__)
258    if (sel == @selector(stret::::::::::::::::::::::::::::)  ||  
259        sel == @selector(stre2::::::::::::::::::::::::::::)  ||  
260        sel == @selector(stre3::::::::::::::::::::::::::::)) 
261    {
262        p += sizeof(void *);  // struct return;
263    }
264#else
265#   error unknown architecture
266#endif
267    gp = (uintptr_t *)p;
268    testassert(*gp++ == (uintptr_t)self);
269    testassert(*gp++ == (uintptr_t)(void *)sel);
270    testassert(*gp++ == 1);
271    testassert(*gp++ == 2);
272    testassert(*gp++ == 3);
273    testassert(*gp++ == 4);
274    testassert(*gp++ == 5);
275    testassert(*gp++ == 6);
276    testassert(*gp++ == 7);
277    testassert(*gp++ == 8);
278    testassert(*gp++ == 9);
279    testassert(*gp++ == 10);
280    testassert(*gp++ == 11);
281    testassert(*gp++ == 12);
282    testassert(*gp++ == 13);
283
284#if defined(__i386__)  ||  defined(__arm__)
285
286    fp = (double *)gp;
287    testassert(*fp++ == 1.0);
288    testassert(*fp++ == 2.0);
289    testassert(*fp++ == 3.0);
290    testassert(*fp++ == 4.0);
291    testassert(*fp++ == 5.0);
292    testassert(*fp++ == 6.0);
293    testassert(*fp++ == 7.0);
294    testassert(*fp++ == 8.0);
295    testassert(*fp++ == 9.0);
296    testassert(*fp++ == 10.0);
297    testassert(*fp++ == 11.0);
298    testassert(*fp++ == 12.0);
299    testassert(*fp++ == 13.0);
300    testassert(*fp++ == 14.0);
301    testassert(*fp++ == 15.0);
302
303#elif defined(__x86_64__)
304
305    fp = (double *)args;  // xmm, double-wide
306    testassert(*fp++ == 1.0); fp++;
307    testassert(*fp++ == 2.0); fp++;
308    testassert(*fp++ == 3.0); fp++;
309    testassert(*fp++ == 4.0); fp++;
310    testassert(*fp++ == 5.0); fp++;
311    testassert(*fp++ == 6.0); fp++;
312    testassert(*fp++ == 7.0); fp++;
313    testassert(*fp++ == 8.0); fp++;
314    fp = (double *)gp;
315    testassert(*fp++ == 9.0);
316    testassert(*fp++ == 10.0);
317    testassert(*fp++ == 11.0);
318    testassert(*fp++ == 12.0);
319    testassert(*fp++ == 13.0);
320    testassert(*fp++ == 14.0);
321    testassert(*fp++ == 15.0);
322
323#else
324#   error unknown architecture
325#endif
326
327    if (sel == @selector(idret::::::::::::::::::::::::::::)  ||  
328        sel == @selector(idre2::::::::::::::::::::::::::::)  ||  
329        sel == @selector(idre3::::::::::::::::::::::::::::)) 
330    {
331        union {
332            id idval;
333            long long llval;
334        } result;
335        testassert(state == 1);
336        state = 2;
337        result.idval = ID_RESULT;
338        return result.llval;
339    } else if (sel == @selector(llret::::::::::::::::::::::::::::)  ||  
340               sel == @selector(llre2::::::::::::::::::::::::::::)  ||  
341               sel == @selector(llre3::::::::::::::::::::::::::::)) 
342    {
343        testassert(state == 3);
344        state = 4;
345        return LL_RESULT;
346    } else if (sel == @selector(fpret::::::::::::::::::::::::::::)  ||  
347               sel == @selector(fpre2::::::::::::::::::::::::::::)  ||  
348               sel == @selector(fpre3::::::::::::::::::::::::::::)) 
349    {
350        testassert(state == 5);
351        state = 6;
352#if defined(__i386__)
353        __asm__ volatile("fldl %0" : : "m" (FP_RESULT));
354#elif defined(__x86_64__)
355        __asm__ volatile("movsd %0, %%xmm0" : : "m" (FP_RESULT));
356#elif defined(__arm__)
357        union {
358            double fpval;
359            long long llval;
360        } result;
361        result.fpval = FP_RESULT;
362        return result.llval;
363#else
364#       error unknown architecture
365#endif
366        return 0;
367    } else if (sel == @selector(stret::::::::::::::::::::::::::::)  ||  
368               sel == @selector(stre2::::::::::::::::::::::::::::)  ||  
369               sel == @selector(stre3::::::::::::::::::::::::::::)) 
370    {
371        testassert(state == 7);
372        state = 8;
373        *struct_addr = STRET_RESULT;
374        return 0;
375    } else {
376        fail("unknown selector %s in forward::", sel_getName(sel));
377    }
378    return 0;
379}
380
381@end
382
383typedef 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);
384
385typedef 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);
386
387typedef 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);
388
389typedef 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);
390
391#if __x86_64__
392typedef 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);
393#endif
394
395__BEGIN_DECLS
396extern void *getSP(void);
397__END_DECLS
398
399#if defined(__x86_64__)
400    asm(".text \n _getSP: movq %rsp, %rax \n retq \n");
401#elif defined(__i386__)
402    asm(".text \n _getSP: movl %esp, %eax \n ret \n");
403#elif defined(__arm__)
404    asm(".text \n _getSP: mov r0, sp \n bx lr \n");
405#else
406#   error unknown architecture
407#endif
408
409int main()
410{
411    id idval;
412    long long llval;
413    struct stret stval;
414#if __x86_64__
415    struct stret *stptr;
416#endif
417    double fpval;
418    void *sp1 = (void*)1;
419    void *sp2 = (void*)2;
420
421    receiver = [Super class];
422
423    // Test default forward handler
424
425    state = 1;
426    sp1 = getSP();
427    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];
428    sp2 = getSP();
429    testassert(sp1 == sp2);
430    testassert(state == 2);
431    testassert(idval == ID_RESULT);
432
433    state = 3;
434    sp1 = getSP();
435    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];
436    sp2 = getSP();
437    testassert(sp1 == sp2);
438    testassert(state == 4);
439    testassert(llval == LL_RESULT);
440
441    state = 5;
442    sp1 = getSP();
443    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];
444    sp2 = getSP();
445    testassert(sp1 == sp2);
446    testassert(state == 6);
447    testassert(fpval == FP_RESULT);
448
449    state = 7;
450    sp1 = getSP();
451    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];
452    sp2 = getSP();
453    testassert(sp1 == sp2);
454    testassert(state == 8);
455    testassert(stret_equal(stval, STRET_RESULT));
456
457#if __x86_64__
458    // check stret return register
459    state = 7;
460    sp1 = getSP();
461    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);
462    sp2 = getSP();
463    testassert(sp1 == sp2);
464    testassert(state == 8);
465    testassert(stret_equal(stval, STRET_RESULT));
466    testassert(stptr == &stval);    
467#endif
468
469
470    // Test default forward handler, cached
471
472    state = 1;
473    sp1 = getSP();
474    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];
475    sp2 = getSP();
476    testassert(sp1 == sp2);
477    testassert(state == 2);
478    testassert(idval == ID_RESULT);
479
480    state = 3;
481    sp1 = getSP();
482    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];
483    sp2 = getSP();
484    testassert(sp1 == sp2);
485    testassert(state == 4);
486    testassert(llval == LL_RESULT);
487
488    state = 5;
489    sp1 = getSP();
490    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];
491    sp2 = getSP();
492    testassert(sp1 == sp2);
493    testassert(state == 6);
494    testassert(fpval == FP_RESULT);
495
496    state = 7;
497    sp1 = getSP();
498    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];
499    sp2 = getSP();
500    testassert(sp1 == sp2);
501    testassert(state == 8);
502    testassert(stret_equal(stval, STRET_RESULT));
503
504#if __x86_64__
505    // check stret return register
506    state = 7;
507    sp1 = getSP();
508    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);
509    sp2 = getSP();
510    testassert(sp1 == sp2);
511    testassert(state == 8);
512    testassert(stret_equal(stval, STRET_RESULT));
513    testassert(stptr == &stval);    
514#endif
515
516
517    // Test default forward handler, uncached but fixed-up
518
519    _objc_flush_caches(nil);
520
521    state = 1;
522    sp1 = getSP();
523    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];
524    sp2 = getSP();
525    testassert(sp1 == sp2);
526    testassert(state == 2);
527    testassert(idval == ID_RESULT);
528
529    state = 3;
530    sp1 = getSP();
531    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];
532    sp2 = getSP();
533    testassert(sp1 == sp2);
534    testassert(state == 4);
535    testassert(llval == LL_RESULT);
536
537    state = 5;
538    sp1 = getSP();
539    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];
540    sp2 = getSP();
541    testassert(sp1 == sp2);
542    testassert(state == 6);
543    testassert(fpval == FP_RESULT);
544
545    state = 7;
546    sp1 = getSP();
547    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];
548    sp2 = getSP();
549    testassert(sp1 == sp2);
550    testassert(state == 8);
551    testassert(stret_equal(stval, STRET_RESULT));
552
553#if __x86_64__
554    // check stret return register
555    state = 7;
556    sp1 = getSP();
557    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);
558    sp2 = getSP();
559    testassert(sp1 == sp2);
560    testassert(state == 8);
561    testassert(stret_equal(stval, STRET_RESULT));
562    testassert(stptr == &stval);    
563#endif
564
565
566    // Test manual forwarding
567
568    state = 1;
569    sp1 = getSP();
570    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);
571    sp2 = getSP();
572    testassert(sp1 == sp2);
573    testassert(state == 2);
574    testassert(idval == ID_RESULT);
575
576    state = 3;
577    sp1 = getSP();
578    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);
579    sp2 = getSP();
580    testassert(sp1 == sp2);
581    testassert(state == 4);
582    testassert(llval == LL_RESULT);
583
584    state = 5;
585    sp1 = getSP();
586    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);
587    sp2 = getSP();
588    testassert(sp1 == sp2);
589    testassert(state == 6);
590    testassert(fpval == FP_RESULT);
591
592    state = 7;
593    sp1 = getSP();
594    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);
595    sp2 = getSP();
596    testassert(sp1 == sp2);
597    testassert(state == 8);
598    testassert(stret_equal(stval, STRET_RESULT));
599
600#if __x86_64__
601    // check stret return register
602    state = 7;
603    sp1 = getSP();
604    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);
605    sp2 = getSP();
606    testassert(sp1 == sp2);
607    testassert(state == 8);
608    testassert(stret_equal(stval, STRET_RESULT));
609    testassert(stptr == &stval);    
610#endif
611
612
613    // Test manual forwarding, cached
614
615    state = 1;
616    sp1 = getSP();
617    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);
618    sp2 = getSP();
619    testassert(sp1 == sp2);
620    testassert(state == 2);
621    testassert(idval == ID_RESULT);
622
623    state = 3;
624    sp1 = getSP();
625    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);
626    sp2 = getSP();
627    testassert(sp1 == sp2);
628    testassert(state == 4);
629    testassert(llval == LL_RESULT);
630
631    state = 5;
632    sp1 = getSP();
633    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);
634    sp2 = getSP();
635    testassert(sp1 == sp2);
636    testassert(state == 6);
637    testassert(fpval == FP_RESULT);
638
639    state = 7;
640    sp1 = getSP();
641    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);
642    sp2 = getSP();
643    testassert(sp1 == sp2);
644    testassert(state == 8);
645    testassert(stret_equal(stval, STRET_RESULT));
646
647#if __x86_64__
648    // check stret return register
649    state = 7;
650    sp1 = getSP();
651    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);
652    sp2 = getSP();
653    testassert(sp1 == sp2);
654    testassert(state == 8);
655    testassert(stret_equal(stval, STRET_RESULT));
656    testassert(stptr == &stval);    
657#endif
658
659
660    // Test manual forwarding, uncached but fixed-up
661
662    _objc_flush_caches(nil);
663
664    state = 1;
665    sp1 = getSP();
666    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);
667    sp2 = getSP();
668    testassert(sp1 == sp2);
669    testassert(state == 2);
670    testassert(idval == ID_RESULT);
671
672    state = 3;
673    sp1 = getSP();
674    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);
675    sp2 = getSP();
676    testassert(sp1 == sp2);
677    testassert(state == 4);
678    testassert(llval == LL_RESULT);
679
680    state = 5;
681    sp1 = getSP();
682    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);
683    sp2 = getSP();
684    testassert(sp1 == sp2);
685    testassert(state == 6);
686    testassert(fpval == FP_RESULT);
687
688    state = 7;
689    sp1 = getSP();
690    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);
691    sp2 = getSP();
692    testassert(sp1 == sp2);
693    testassert(state == 8);
694    testassert(stret_equal(stval, STRET_RESULT));
695
696#if __x86_64__
697    // check stret return register
698    state = 7;
699    sp1 = getSP();
700    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);
701    sp2 = getSP();
702    testassert(sp1 == sp2);
703    testassert(state == 8);
704    testassert(stret_equal(stval, STRET_RESULT));
705    testassert(stptr == &stval);    
706#endif
707
708
709    // Test user-defined forward handler
710
711    objc_setForwardHandler((void*)&forward_handler, (void*)&forward_stret_handler);
712
713    state = 11;
714    sp1 = getSP();
715    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];
716    sp2 = getSP();
717    testassert(sp1 == sp2);
718    testassert(state == 12);
719    testassert(idval == ID_RESULT);
720
721    state = 13;
722    sp1 = getSP();
723    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];
724    sp2 = getSP();
725    testassert(sp1 == sp2);
726    testassert(state == 14);
727    testassert(llval == LL_RESULT);
728
729    state = 15;
730    sp1 = getSP();
731    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];
732    sp2 = getSP();
733    testassert(sp1 == sp2);
734    testassert(state == 16);
735    testassert(fpval == FP_RESULT);
736
737    state = 17;
738    sp1 = getSP();
739    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];
740    sp2 = getSP();
741    testassert(sp1 == sp2);
742    testassert(state == 18);
743    testassert(stret_equal(stval, STRET_RESULT));
744
745#if __x86_64__
746    // check stret return register
747    state = 17;
748    sp1 = getSP();
749    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);
750    sp2 = getSP();
751    testassert(sp1 == sp2);
752    testassert(state == 18);
753    testassert(stret_equal(stval, STRET_RESULT));
754    testassert(stptr == &stval);    
755#endif
756
757
758    // Test user-defined forward handler, cached
759
760    state = 11;
761    sp1 = getSP();
762    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];
763    sp2 = getSP();
764    testassert(sp1 == sp2);
765    testassert(state == 12);
766    testassert(idval == ID_RESULT);
767
768    state = 13;
769    sp1 = getSP();
770    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];
771    sp2 = getSP();
772    testassert(sp1 == sp2);
773    testassert(state == 14);
774    testassert(llval == LL_RESULT);
775
776    state = 15;
777    sp1 = getSP();
778    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];
779    sp2 = getSP();
780    testassert(sp1 == sp2);
781    testassert(state == 16);
782    testassert(fpval == FP_RESULT);
783
784    state = 17;
785    sp1 = getSP();
786    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];
787    sp2 = getSP();
788    testassert(sp1 == sp2);
789    testassert(state == 18);
790    testassert(stret_equal(stval, STRET_RESULT));
791
792#if __x86_64__
793    // check stret return register
794    state = 17;
795    sp1 = getSP();
796    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);
797    sp2 = getSP();
798    testassert(sp1 == sp2);
799    testassert(state == 18);
800    testassert(stret_equal(stval, STRET_RESULT));
801    testassert(stptr == &stval);    
802#endif
803
804
805    // Test user-defined forward handler, uncached but fixed-up
806
807    _objc_flush_caches(nil);
808
809    state = 11;
810    sp1 = getSP();
811    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];
812    sp2 = getSP();
813    testassert(sp1 == sp2);
814    testassert(state == 12);
815    testassert(idval == ID_RESULT);
816
817    state = 13;
818    sp1 = getSP();
819    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];
820    sp2 = getSP();
821    testassert(sp1 == sp2);
822    testassert(state == 14);
823    testassert(llval == LL_RESULT);
824
825    state = 15;
826    sp1 = getSP();
827    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];
828    sp2 = getSP();
829    testassert(sp1 == sp2);
830    testassert(state == 16);
831    testassert(fpval == FP_RESULT);
832
833    state = 17;
834    sp1 = getSP();
835    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];
836    sp2 = getSP();
837    testassert(sp1 == sp2);
838    testassert(state == 18);
839    testassert(stret_equal(stval, STRET_RESULT));
840
841#if __x86_64__
842    // check stret return register
843    state = 17;
844    sp1 = getSP();
845    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);
846    sp2 = getSP();
847    testassert(sp1 == sp2);
848    testassert(state == 18);
849    testassert(stret_equal(stval, STRET_RESULT));
850    testassert(stptr == &stval);    
851#endif
852
853
854
855    // Test user-defined forward handler, manual forwarding
856
857    state = 11;
858    sp1 = getSP();
859    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);
860    sp2 = getSP();
861    testassert(sp1 == sp2);
862    testassert(state == 12);
863    testassert(idval == ID_RESULT);
864
865    state = 13;
866    sp1 = getSP();
867    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);
868    sp2 = getSP();
869    testassert(sp1 == sp2);
870    testassert(state == 14);
871    testassert(llval == LL_RESULT);
872
873    state = 15;
874    sp1 = getSP();
875    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);
876    sp2 = getSP();
877    testassert(sp1 == sp2);
878    testassert(state == 16);
879    testassert(fpval == FP_RESULT);
880
881    state = 17;
882    sp1 = getSP();
883    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);
884    sp2 = getSP();
885    testassert(sp1 == sp2);
886    testassert(state == 18);
887    testassert(stret_equal(stval, STRET_RESULT));
888
889
890    // Test user-defined forward handler, manual forwarding, cached
891
892    state = 11;
893    sp1 = getSP();
894    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);
895    sp2 = getSP();
896    testassert(sp1 == sp2);
897    testassert(state == 12);
898    testassert(idval == ID_RESULT);
899
900    state = 13;
901    sp1 = getSP();
902    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);
903    sp2 = getSP();
904    testassert(sp1 == sp2);
905    testassert(state == 14);
906    testassert(llval == LL_RESULT);
907
908    state = 15;
909    sp1 = getSP();
910    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);
911    sp2 = getSP();
912    testassert(sp1 == sp2);
913    testassert(state == 16);
914    testassert(fpval == FP_RESULT);
915
916    state = 17;
917    sp1 = getSP();
918    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);
919    sp2 = getSP();
920    testassert(sp1 == sp2);
921    testassert(state == 18);
922    testassert(stret_equal(stval, STRET_RESULT));
923
924
925    // Test user-defined forward handler, manual forwarding, uncached but fixed-up
926
927    _objc_flush_caches(nil);
928
929    state = 11;
930    sp1 = getSP();
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);
932    sp2 = getSP();
933    testassert(sp1 == sp2);
934    testassert(state == 12);
935    testassert(idval == ID_RESULT);
936
937    state = 13;
938    sp1 = getSP();
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);
940    sp2 = getSP();
941    testassert(sp1 == sp2);
942    testassert(state == 14);
943    testassert(llval == LL_RESULT);
944
945    state = 15;
946    sp1 = getSP();
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);
948    sp2 = getSP();
949    testassert(sp1 == sp2);
950    testassert(state == 16);
951    testassert(fpval == FP_RESULT);
952
953    state = 17;
954    sp1 = getSP();
955    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);
956    sp2 = getSP();
957    testassert(sp1 == sp2);
958    testassert(state == 18);
959    testassert(stret_equal(stval, STRET_RESULT));
960
961
962    succeed(__FILE__);
963}
964
965#endif
966