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