]> git.saurik.com Git - apple/objc4.git/blob - test/forward.m
objc4-680.tar.gz
[apple/objc4.git] / test / forward.m
1 // TEST_CONFIG MEM=mrc,gc
2 // TEST_CFLAGS -Wno-deprecated-declarations
3
4 #include "test.h"
5
6 #if __cplusplus && !__clang__
7
8 int main()
9 {
10 // llvm-g++ is confused by @selector(foo::) and will never be fixed
11 succeed(__FILE__);
12 }
13
14 #else
15
16 #include <objc/runtime.h>
17 #include <objc/message.h>
18
19 id ID_RESULT = (id)0x12345678;
20 long long LL_RESULT = __LONG_LONG_MAX__ - 2LL*__INT_MAX__;
21 double FP_RESULT = __DBL_MIN__ + __DBL_EPSILON__;
22 long double LFP_RESULT = __LDBL_MIN__ + __LDBL_EPSILON__;
23 // STRET_RESULT in test.h
24
25
26 static int state = 0;
27 static id receiver;
28
29 OBJC_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
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)
73 {
74 #if __arm64__
75 void *struct_addr;
76 __asm__ volatile("mov %0, x8" : "=r" (struct_addr) : : "x8");
77 #endif
78
79 testassert(self == receiver);
80
81 testassert(i1 == 1);
82 testassert(i2 == 2);
83 testassert(i3 == 3);
84 testassert(i4 == 4);
85 testassert(i5 == 5);
86 testassert(i6 == 6);
87 testassert(i7 == 7);
88 testassert(i8 == 8);
89 testassert(i9 == 9);
90 testassert(i10 == 10);
91 testassert(i11 == 11);
92 testassert(i12 == 12);
93 testassert(i13 == 13);
94
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);
110
111 if (_cmd == @selector(idret::::::::::::::::::::::::::::) ||
112 _cmd == @selector(idre2::::::::::::::::::::::::::::) ||
113 _cmd == @selector(idre3::::::::::::::::::::::::::::))
114 {
115 union {
116 id idval;
117 long long llval;
118 } result;
119 testassert(state == 11);
120 state = 12;
121 result.idval = ID_RESULT;
122 return result.llval;
123 }
124 else if (_cmd == @selector(llret::::::::::::::::::::::::::::) ||
125 _cmd == @selector(llre2::::::::::::::::::::::::::::) ||
126 _cmd == @selector(llre3::::::::::::::::::::::::::::))
127 {
128 testassert(state == 13);
129 state = 14;
130 return LL_RESULT;
131 }
132 else if (_cmd == @selector(fpret::::::::::::::::::::::::::::) ||
133 _cmd == @selector(fpre2::::::::::::::::::::::::::::) ||
134 _cmd == @selector(fpre3::::::::::::::::::::::::::::))
135 {
136 testassert(state == 15);
137 state = 16;
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__)
143 union {
144 double fpval;
145 long long llval;
146 } result;
147 result.fpval = FP_RESULT;
148 return result.llval;
149 #elif defined(__arm64__)
150 __asm__ volatile("ldr d0, %0" : : "m" (FP_RESULT));
151 #else
152 # error unknown architecture
153 #endif
154 return 0;
155 }
156 else if (_cmd == @selector(stret::::::::::::::::::::::::::::) ||
157 _cmd == @selector(stre2::::::::::::::::::::::::::::) ||
158 _cmd == @selector(stre3::::::::::::::::::::::::::::))
159 {
160 #if __i386__ || __x86_64__ || __arm__
161 fail("stret message sent to non-stret forward_handler");
162 #elif __arm64__
163 testassert(state == 17);
164 state = 18;
165 memcpy(struct_addr, &STRET_RESULT, sizeof(STRET_RESULT));
166 return 0;
167 #else
168 # error unknown architecture
169 #endif
170 }
171 else {
172 fail("unknown selector %s in forward_handler", sel_getName(_cmd));
173 }
174 }
175
176
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)
178 {
179 testassert(self == receiver);
180
181 testassert(i1 == 1);
182 testassert(i2 == 2);
183 testassert(i3 == 3);
184 testassert(i4 == 4);
185 testassert(i5 == 5);
186 testassert(i6 == 6);
187 testassert(i7 == 7);
188 testassert(i8 == 8);
189 testassert(i9 == 9);
190 testassert(i10 == 10);
191 testassert(i11 == 11);
192 testassert(i12 == 12);
193 testassert(i13 == 13);
194
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);
210
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::::::::::::::::::::::::::::))
220 {
221 fail("non-stret selector %s sent to forward_stret_handler", sel_getName(_cmd));
222 }
223 else if (_cmd == @selector(stret::::::::::::::::::::::::::::) ||
224 _cmd == @selector(stre2::::::::::::::::::::::::::::) ||
225 _cmd == @selector(stre3::::::::::::::::::::::::::::))
226 {
227 testassert(state == 17);
228 state = 18;
229 return STRET_RESULT;
230 }
231 else {
232 fail("unknown selector %s in forward_stret_handler", sel_getName(_cmd));
233 }
234
235 }
236
237
238 @implementation Super
239 +(void)initialize { }
240 +(id)class { return self; }
241
242 #if __OBJC2__
243 // forward:: not supported
244 #else
245 -(long long) forward:(SEL)sel :(marg_list)args
246 {
247 char *p;
248 uintptr_t *gp;
249 double *fp;
250 struct stret *struct_addr;
251
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);
258 #else
259 # error unknown architecture
260 #endif
261
262 testassert(self == receiver);
263 testassert(_cmd == sel_registerName("forward::"));
264
265 p = (char *)args;
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::::::::::::::::::::::::::::))
271 {
272 p += sizeof(void *); // struct return
273 }
274 #elif defined(__i386__)
275 // nothing to do
276 #elif defined(__arm__)
277 if (sel == @selector(stret::::::::::::::::::::::::::::) ||
278 sel == @selector(stre2::::::::::::::::::::::::::::) ||
279 sel == @selector(stre3::::::::::::::::::::::::::::))
280 {
281 p += sizeof(void *); // struct return;
282 }
283 #else
284 # error unknown architecture
285 #endif
286 gp = (uintptr_t *)p;
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);
302
303 #if defined(__i386__) || defined(__arm__)
304
305 fp = (double *)gp;
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);
321
322 #elif defined(__x86_64__)
323
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++;
333 fp = (double *)gp;
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);
341
342 #else
343 # error unknown architecture
344 #endif
345
346 if (sel == @selector(idret::::::::::::::::::::::::::::) ||
347 sel == @selector(idre2::::::::::::::::::::::::::::) ||
348 sel == @selector(idre3::::::::::::::::::::::::::::))
349 {
350 union {
351 id idval;
352 long long llval;
353 } result;
354 testassert(state == 1);
355 state = 2;
356 result.idval = ID_RESULT;
357 return result.llval;
358 } else if (sel == @selector(llret::::::::::::::::::::::::::::) ||
359 sel == @selector(llre2::::::::::::::::::::::::::::) ||
360 sel == @selector(llre3::::::::::::::::::::::::::::))
361 {
362 testassert(state == 3);
363 state = 4;
364 return LL_RESULT;
365 } else if (sel == @selector(fpret::::::::::::::::::::::::::::) ||
366 sel == @selector(fpre2::::::::::::::::::::::::::::) ||
367 sel == @selector(fpre3::::::::::::::::::::::::::::))
368 {
369 testassert(state == 5);
370 state = 6;
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__)
376 union {
377 double fpval;
378 long long llval;
379 } result;
380 result.fpval = FP_RESULT;
381 return result.llval;
382 #else
383 # error unknown architecture
384 #endif
385 return 0;
386 } else if (sel == @selector(stret::::::::::::::::::::::::::::) ||
387 sel == @selector(stre2::::::::::::::::::::::::::::) ||
388 sel == @selector(stre3::::::::::::::::::::::::::::))
389 {
390 testassert(state == 7);
391 state = 8;
392 *struct_addr = STRET_RESULT;
393 return 0;
394 } else {
395 fail("unknown selector %s in forward::", sel_getName(sel));
396 }
397 return 0;
398 }
399
400 #endif
401
402 @end
403
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);
405
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);
407
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);
409
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);
411
412 #if __x86_64__
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);
414 #endif
415
416 __BEGIN_DECLS
417 extern void *getSP(void);
418 __END_DECLS
419
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");
429 #else
430 # error unknown architecture
431 #endif
432
433 int main()
434 {
435 id idval;
436 long long llval;
437 struct stret stval;
438 #if __x86_64__
439 struct stret *stptr;
440 #endif
441 double fpval;
442 void *sp1 = (void*)1;
443 void *sp2 = (void*)2;
444
445 st_fn_t stret_fwd;
446 #if __arm64__
447 stret_fwd = (st_fn_t)_objc_msgForward;
448 #else
449 stret_fwd = (st_fn_t)_objc_msgForward_stret;
450 #endif
451
452 receiver = [Super class];
453
454 #if __OBJC2__
455 // forward:: not supported
456 #else
457 // Test default forward handler
458
459 state = 1;
460 sp1 = getSP();
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];
462 sp2 = getSP();
463 testassert(sp1 == sp2);
464 testassert(state == 2);
465 testassert(idval == ID_RESULT);
466
467 state = 3;
468 sp1 = getSP();
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];
470 sp2 = getSP();
471 testassert(sp1 == sp2);
472 testassert(state == 4);
473 testassert(llval == LL_RESULT);
474
475 state = 5;
476 sp1 = getSP();
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];
478 sp2 = getSP();
479 testassert(sp1 == sp2);
480 testassert(state == 6);
481 testassert(fpval == FP_RESULT);
482
483 state = 7;
484 sp1 = getSP();
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];
486 sp2 = getSP();
487 testassert(sp1 == sp2);
488 testassert(state == 8);
489 testassert(stret_equal(stval, STRET_RESULT));
490
491 #if __x86_64__
492 // check stret return register
493 state = 7;
494 sp1 = getSP();
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);
496 sp2 = getSP();
497 testassert(sp1 == sp2);
498 testassert(state == 8);
499 testassert(stret_equal(stval, STRET_RESULT));
500 testassert(stptr == &stval);
501 #endif
502
503
504 // Test default forward handler, cached
505
506 state = 1;
507 sp1 = getSP();
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];
509 sp2 = getSP();
510 testassert(sp1 == sp2);
511 testassert(state == 2);
512 testassert(idval == ID_RESULT);
513
514 state = 3;
515 sp1 = getSP();
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];
517 sp2 = getSP();
518 testassert(sp1 == sp2);
519 testassert(state == 4);
520 testassert(llval == LL_RESULT);
521
522 state = 5;
523 sp1 = getSP();
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];
525 sp2 = getSP();
526 testassert(sp1 == sp2);
527 testassert(state == 6);
528 testassert(fpval == FP_RESULT);
529
530 state = 7;
531 sp1 = getSP();
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];
533 sp2 = getSP();
534 testassert(sp1 == sp2);
535 testassert(state == 8);
536 testassert(stret_equal(stval, STRET_RESULT));
537
538 #if __x86_64__
539 // check stret return register
540 state = 7;
541 sp1 = getSP();
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);
543 sp2 = getSP();
544 testassert(sp1 == sp2);
545 testassert(state == 8);
546 testassert(stret_equal(stval, STRET_RESULT));
547 testassert(stptr == &stval);
548 #endif
549
550
551 // Test default forward handler, uncached but fixed-up
552
553 _objc_flush_caches(nil);
554
555 state = 1;
556 sp1 = getSP();
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];
558 sp2 = getSP();
559 testassert(sp1 == sp2);
560 testassert(state == 2);
561 testassert(idval == ID_RESULT);
562
563 state = 3;
564 sp1 = getSP();
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];
566 sp2 = getSP();
567 testassert(sp1 == sp2);
568 testassert(state == 4);
569 testassert(llval == LL_RESULT);
570
571 state = 5;
572 sp1 = getSP();
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];
574 sp2 = getSP();
575 testassert(sp1 == sp2);
576 testassert(state == 6);
577 testassert(fpval == FP_RESULT);
578
579 state = 7;
580 sp1 = getSP();
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];
582 sp2 = getSP();
583 testassert(sp1 == sp2);
584 testassert(state == 8);
585 testassert(stret_equal(stval, STRET_RESULT));
586
587 #if __x86_64__
588 // check stret return register
589 state = 7;
590 sp1 = getSP();
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);
592 sp2 = getSP();
593 testassert(sp1 == sp2);
594 testassert(state == 8);
595 testassert(stret_equal(stval, STRET_RESULT));
596 testassert(stptr == &stval);
597 #endif
598
599
600 // Test manual forwarding
601
602 state = 1;
603 sp1 = getSP();
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);
605 sp2 = getSP();
606 testassert(sp1 == sp2);
607 testassert(state == 2);
608 testassert(idval == ID_RESULT);
609
610 state = 3;
611 sp1 = getSP();
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);
613 sp2 = getSP();
614 testassert(sp1 == sp2);
615 testassert(state == 4);
616 testassert(llval == LL_RESULT);
617
618 state = 5;
619 sp1 = getSP();
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);
621 sp2 = getSP();
622 testassert(sp1 == sp2);
623 testassert(state == 6);
624 testassert(fpval == FP_RESULT);
625
626 state = 7;
627 sp1 = getSP();
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);
629 sp2 = getSP();
630 testassert(sp1 == sp2);
631 testassert(state == 8);
632 testassert(stret_equal(stval, STRET_RESULT));
633
634 #if __x86_64__
635 // check stret return register
636 state = 7;
637 sp1 = getSP();
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);
639 sp2 = getSP();
640 testassert(sp1 == sp2);
641 testassert(state == 8);
642 testassert(stret_equal(stval, STRET_RESULT));
643 testassert(stptr == &stval);
644 #endif
645
646
647 // Test manual forwarding, cached
648
649 state = 1;
650 sp1 = getSP();
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);
652 sp2 = getSP();
653 testassert(sp1 == sp2);
654 testassert(state == 2);
655 testassert(idval == ID_RESULT);
656
657 state = 3;
658 sp1 = getSP();
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);
660 sp2 = getSP();
661 testassert(sp1 == sp2);
662 testassert(state == 4);
663 testassert(llval == LL_RESULT);
664
665 state = 5;
666 sp1 = getSP();
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);
668 sp2 = getSP();
669 testassert(sp1 == sp2);
670 testassert(state == 6);
671 testassert(fpval == FP_RESULT);
672
673 state = 7;
674 sp1 = getSP();
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);
676 sp2 = getSP();
677 testassert(sp1 == sp2);
678 testassert(state == 8);
679 testassert(stret_equal(stval, STRET_RESULT));
680
681 #if __x86_64__
682 // check stret return register
683 state = 7;
684 sp1 = getSP();
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);
686 sp2 = getSP();
687 testassert(sp1 == sp2);
688 testassert(state == 8);
689 testassert(stret_equal(stval, STRET_RESULT));
690 testassert(stptr == &stval);
691 #endif
692
693
694 // Test manual forwarding, uncached but fixed-up
695
696 _objc_flush_caches(nil);
697
698 state = 1;
699 sp1 = getSP();
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);
701 sp2 = getSP();
702 testassert(sp1 == sp2);
703 testassert(state == 2);
704 testassert(idval == ID_RESULT);
705
706 state = 3;
707 sp1 = getSP();
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);
709 sp2 = getSP();
710 testassert(sp1 == sp2);
711 testassert(state == 4);
712 testassert(llval == LL_RESULT);
713
714 state = 5;
715 sp1 = getSP();
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);
717 sp2 = getSP();
718 testassert(sp1 == sp2);
719 testassert(state == 6);
720 testassert(fpval == FP_RESULT);
721
722 state = 7;
723 sp1 = getSP();
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);
725 sp2 = getSP();
726 testassert(sp1 == sp2);
727 testassert(state == 8);
728 testassert(stret_equal(stval, STRET_RESULT));
729
730 #if __x86_64__
731 // check stret return register
732 state = 7;
733 sp1 = getSP();
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);
735 sp2 = getSP();
736 testassert(sp1 == sp2);
737 testassert(state == 8);
738 testassert(stret_equal(stval, STRET_RESULT));
739 testassert(stptr == &stval);
740 #endif
741
742 // !__OBJC2__
743 #endif
744
745
746 // Test user-defined forward handler
747
748 objc_setForwardHandler((void*)&forward_handler, (void*)&forward_stret_handler);
749
750 state = 11;
751 sp1 = getSP();
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];
753 sp2 = getSP();
754 testassert(sp1 == sp2);
755 testassert(state == 12);
756 testassert(idval == ID_RESULT);
757
758 state = 13;
759 sp1 = getSP();
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];
761 sp2 = getSP();
762 testassert(sp1 == sp2);
763 testassert(state == 14);
764 testassert(llval == LL_RESULT);
765
766 state = 15;
767 sp1 = getSP();
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];
769 sp2 = getSP();
770 testassert(sp1 == sp2);
771 testassert(state == 16);
772 testassert(fpval == FP_RESULT);
773
774 state = 17;
775 sp1 = getSP();
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];
777 sp2 = getSP();
778 testassert(sp1 == sp2);
779 testassert(state == 18);
780 testassert(stret_equal(stval, STRET_RESULT));
781
782 #if __x86_64__
783 // check stret return register
784 state = 17;
785 sp1 = getSP();
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);
787 sp2 = getSP();
788 testassert(sp1 == sp2);
789 testassert(state == 18);
790 testassert(stret_equal(stval, STRET_RESULT));
791 testassert(stptr == &stval);
792 #endif
793
794
795 // Test user-defined forward handler, cached
796
797 state = 11;
798 sp1 = getSP();
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];
800 sp2 = getSP();
801 testassert(sp1 == sp2);
802 testassert(state == 12);
803 testassert(idval == ID_RESULT);
804
805 state = 13;
806 sp1 = getSP();
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];
808 sp2 = getSP();
809 testassert(sp1 == sp2);
810 testassert(state == 14);
811 testassert(llval == LL_RESULT);
812
813 state = 15;
814 sp1 = getSP();
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];
816 sp2 = getSP();
817 testassert(sp1 == sp2);
818 testassert(state == 16);
819 testassert(fpval == FP_RESULT);
820
821 state = 17;
822 sp1 = getSP();
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];
824 sp2 = getSP();
825 testassert(sp1 == sp2);
826 testassert(state == 18);
827 testassert(stret_equal(stval, STRET_RESULT));
828
829 #if __x86_64__
830 // check stret return register
831 state = 17;
832 sp1 = getSP();
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);
834 sp2 = getSP();
835 testassert(sp1 == sp2);
836 testassert(state == 18);
837 testassert(stret_equal(stval, STRET_RESULT));
838 testassert(stptr == &stval);
839 #endif
840
841
842 // Test user-defined forward handler, uncached but fixed-up
843
844 _objc_flush_caches(nil);
845
846 state = 11;
847 sp1 = getSP();
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];
849 sp2 = getSP();
850 testassert(sp1 == sp2);
851 testassert(state == 12);
852 testassert(idval == ID_RESULT);
853
854 state = 13;
855 sp1 = getSP();
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];
857 sp2 = getSP();
858 testassert(sp1 == sp2);
859 testassert(state == 14);
860 testassert(llval == LL_RESULT);
861
862 state = 15;
863 sp1 = getSP();
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];
865 sp2 = getSP();
866 testassert(sp1 == sp2);
867 testassert(state == 16);
868 testassert(fpval == FP_RESULT);
869
870 state = 17;
871 sp1 = getSP();
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];
873 sp2 = getSP();
874 testassert(sp1 == sp2);
875 testassert(state == 18);
876 testassert(stret_equal(stval, STRET_RESULT));
877
878 #if __x86_64__
879 // check stret return register
880 state = 17;
881 sp1 = getSP();
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);
883 sp2 = getSP();
884 testassert(sp1 == sp2);
885 testassert(state == 18);
886 testassert(stret_equal(stval, STRET_RESULT));
887 testassert(stptr == &stval);
888 #endif
889
890
891
892 // Test user-defined forward handler, manual forwarding
893
894 state = 11;
895 sp1 = getSP();
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);
897 sp2 = getSP();
898 testassert(sp1 == sp2);
899 testassert(state == 12);
900 testassert(idval == ID_RESULT);
901
902 state = 13;
903 sp1 = getSP();
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);
905 sp2 = getSP();
906 testassert(sp1 == sp2);
907 testassert(state == 14);
908 testassert(llval == LL_RESULT);
909
910 state = 15;
911 sp1 = getSP();
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);
913 sp2 = getSP();
914 testassert(sp1 == sp2);
915 testassert(state == 16);
916 testassert(fpval == FP_RESULT);
917
918 state = 17;
919 sp1 = getSP();
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);
921 sp2 = getSP();
922 testassert(sp1 == sp2);
923 testassert(state == 18);
924 testassert(stret_equal(stval, STRET_RESULT));
925
926
927 // Test user-defined forward handler, manual forwarding, cached
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 = 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);
956 sp2 = getSP();
957 testassert(sp1 == sp2);
958 testassert(state == 18);
959 testassert(stret_equal(stval, STRET_RESULT));
960
961
962 // Test user-defined forward handler, manual forwarding, uncached but fixed-up
963
964 _objc_flush_caches(nil);
965
966 state = 11;
967 sp1 = getSP();
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);
969 sp2 = getSP();
970 testassert(sp1 == sp2);
971 testassert(state == 12);
972 testassert(idval == ID_RESULT);
973
974 state = 13;
975 sp1 = getSP();
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);
977 sp2 = getSP();
978 testassert(sp1 == sp2);
979 testassert(state == 14);
980 testassert(llval == LL_RESULT);
981
982 state = 15;
983 sp1 = getSP();
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);
985 sp2 = getSP();
986 testassert(sp1 == sp2);
987 testassert(state == 16);
988 testassert(fpval == FP_RESULT);
989
990 state = 17;
991 sp1 = getSP();
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);
993 sp2 = getSP();
994 testassert(sp1 == sp2);
995 testassert(state == 18);
996 testassert(stret_equal(stval, STRET_RESULT));
997
998
999 succeed(__FILE__);
1000 }
1001
1002 #endif