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#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 177struct 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 404typedef 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 406typedef 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 408typedef 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 410typedef 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__ 413typedef 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 417extern 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 _getSP: mov r0, sp \n bx lr \n"); 426#elif defined(__arm64__) 427 asm(".text \n _getSP: mov x0, sp \n ret \n"); 428#else 429# error unknown architecture 430#endif 431 432int main() 433{ 434 id idval; 435 long long llval; 436 struct stret stval; 437#if __x86_64__ 438 struct stret *stptr; 439#endif 440 double fpval; 441 void *sp1 = (void*)1; 442 void *sp2 = (void*)2; 443 444 st_fn_t stret_fwd; 445#if __arm64__ 446 stret_fwd = (st_fn_t)_objc_msgForward; 447#else 448 stret_fwd = (st_fn_t)_objc_msgForward_stret; 449#endif 450 451 receiver = [Super class]; 452 453#if __OBJC2__ 454 // forward:: not supported 455#else 456 // Test default forward handler 457 458 state = 1; 459 sp1 = getSP(); 460 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]; 461 sp2 = getSP(); 462 testassert(sp1 == sp2); 463 testassert(state == 2); 464 testassert(idval == ID_RESULT); 465 466 state = 3; 467 sp1 = getSP(); 468 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]; 469 sp2 = getSP(); 470 testassert(sp1 == sp2); 471 testassert(state == 4); 472 testassert(llval == LL_RESULT); 473 474 state = 5; 475 sp1 = getSP(); 476 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]; 477 sp2 = getSP(); 478 testassert(sp1 == sp2); 479 testassert(state == 6); 480 testassert(fpval == FP_RESULT); 481 482 state = 7; 483 sp1 = getSP(); 484 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]; 485 sp2 = getSP(); 486 testassert(sp1 == sp2); 487 testassert(state == 8); 488 testassert(stret_equal(stval, STRET_RESULT)); 489 490#if __x86_64__ 491 // check stret return register 492 state = 7; 493 sp1 = getSP(); 494 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); 495 sp2 = getSP(); 496 testassert(sp1 == sp2); 497 testassert(state == 8); 498 testassert(stret_equal(stval, STRET_RESULT)); 499 testassert(stptr == &stval); 500#endif 501 502 503 // Test default forward handler, cached 504 505 state = 1; 506 sp1 = getSP(); 507 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]; 508 sp2 = getSP(); 509 testassert(sp1 == sp2); 510 testassert(state == 2); 511 testassert(idval == ID_RESULT); 512 513 state = 3; 514 sp1 = getSP(); 515 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]; 516 sp2 = getSP(); 517 testassert(sp1 == sp2); 518 testassert(state == 4); 519 testassert(llval == LL_RESULT); 520 521 state = 5; 522 sp1 = getSP(); 523 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]; 524 sp2 = getSP(); 525 testassert(sp1 == sp2); 526 testassert(state == 6); 527 testassert(fpval == FP_RESULT); 528 529 state = 7; 530 sp1 = getSP(); 531 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]; 532 sp2 = getSP(); 533 testassert(sp1 == sp2); 534 testassert(state == 8); 535 testassert(stret_equal(stval, STRET_RESULT)); 536 537#if __x86_64__ 538 // check stret return register 539 state = 7; 540 sp1 = getSP(); 541 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); 542 sp2 = getSP(); 543 testassert(sp1 == sp2); 544 testassert(state == 8); 545 testassert(stret_equal(stval, STRET_RESULT)); 546 testassert(stptr == &stval); 547#endif 548 549 550 // Test default forward handler, uncached but fixed-up 551 552 _objc_flush_caches(nil); 553 554 state = 1; 555 sp1 = getSP(); 556 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]; 557 sp2 = getSP(); 558 testassert(sp1 == sp2); 559 testassert(state == 2); 560 testassert(idval == ID_RESULT); 561 562 state = 3; 563 sp1 = getSP(); 564 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]; 565 sp2 = getSP(); 566 testassert(sp1 == sp2); 567 testassert(state == 4); 568 testassert(llval == LL_RESULT); 569 570 state = 5; 571 sp1 = getSP(); 572 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]; 573 sp2 = getSP(); 574 testassert(sp1 == sp2); 575 testassert(state == 6); 576 testassert(fpval == FP_RESULT); 577 578 state = 7; 579 sp1 = getSP(); 580 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]; 581 sp2 = getSP(); 582 testassert(sp1 == sp2); 583 testassert(state == 8); 584 testassert(stret_equal(stval, STRET_RESULT)); 585 586#if __x86_64__ 587 // check stret return register 588 state = 7; 589 sp1 = getSP(); 590 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); 591 sp2 = getSP(); 592 testassert(sp1 == sp2); 593 testassert(state == 8); 594 testassert(stret_equal(stval, STRET_RESULT)); 595 testassert(stptr == &stval); 596#endif 597 598 599 // Test manual forwarding 600 601 state = 1; 602 sp1 = getSP(); 603 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); 604 sp2 = getSP(); 605 testassert(sp1 == sp2); 606 testassert(state == 2); 607 testassert(idval == ID_RESULT); 608 609 state = 3; 610 sp1 = getSP(); 611 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); 612 sp2 = getSP(); 613 testassert(sp1 == sp2); 614 testassert(state == 4); 615 testassert(llval == LL_RESULT); 616 617 state = 5; 618 sp1 = getSP(); 619 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); 620 sp2 = getSP(); 621 testassert(sp1 == sp2); 622 testassert(state == 6); 623 testassert(fpval == FP_RESULT); 624 625 state = 7; 626 sp1 = getSP(); 627 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); 628 sp2 = getSP(); 629 testassert(sp1 == sp2); 630 testassert(state == 8); 631 testassert(stret_equal(stval, STRET_RESULT)); 632 633#if __x86_64__ 634 // check stret return register 635 state = 7; 636 sp1 = getSP(); 637 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); 638 sp2 = getSP(); 639 testassert(sp1 == sp2); 640 testassert(state == 8); 641 testassert(stret_equal(stval, STRET_RESULT)); 642 testassert(stptr == &stval); 643#endif 644 645 646 // Test manual forwarding, cached 647 648 state = 1; 649 sp1 = getSP(); 650 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); 651 sp2 = getSP(); 652 testassert(sp1 == sp2); 653 testassert(state == 2); 654 testassert(idval == ID_RESULT); 655 656 state = 3; 657 sp1 = getSP(); 658 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); 659 sp2 = getSP(); 660 testassert(sp1 == sp2); 661 testassert(state == 4); 662 testassert(llval == LL_RESULT); 663 664 state = 5; 665 sp1 = getSP(); 666 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); 667 sp2 = getSP(); 668 testassert(sp1 == sp2); 669 testassert(state == 6); 670 testassert(fpval == FP_RESULT); 671 672 state = 7; 673 sp1 = getSP(); 674 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); 675 sp2 = getSP(); 676 testassert(sp1 == sp2); 677 testassert(state == 8); 678 testassert(stret_equal(stval, STRET_RESULT)); 679 680#if __x86_64__ 681 // check stret return register 682 state = 7; 683 sp1 = getSP(); 684 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); 685 sp2 = getSP(); 686 testassert(sp1 == sp2); 687 testassert(state == 8); 688 testassert(stret_equal(stval, STRET_RESULT)); 689 testassert(stptr == &stval); 690#endif 691 692 693 // Test manual forwarding, uncached but fixed-up 694 695 _objc_flush_caches(nil); 696 697 state = 1; 698 sp1 = getSP(); 699 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); 700 sp2 = getSP(); 701 testassert(sp1 == sp2); 702 testassert(state == 2); 703 testassert(idval == ID_RESULT); 704 705 state = 3; 706 sp1 = getSP(); 707 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); 708 sp2 = getSP(); 709 testassert(sp1 == sp2); 710 testassert(state == 4); 711 testassert(llval == LL_RESULT); 712 713 state = 5; 714 sp1 = getSP(); 715 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); 716 sp2 = getSP(); 717 testassert(sp1 == sp2); 718 testassert(state == 6); 719 testassert(fpval == FP_RESULT); 720 721 state = 7; 722 sp1 = getSP(); 723 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); 724 sp2 = getSP(); 725 testassert(sp1 == sp2); 726 testassert(state == 8); 727 testassert(stret_equal(stval, STRET_RESULT)); 728 729#if __x86_64__ 730 // check stret return register 731 state = 7; 732 sp1 = getSP(); 733 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); 734 sp2 = getSP(); 735 testassert(sp1 == sp2); 736 testassert(state == 8); 737 testassert(stret_equal(stval, STRET_RESULT)); 738 testassert(stptr == &stval); 739#endif 740 741// !__OBJC2__ 742#endif 743 744 745 // Test user-defined forward handler 746 747 objc_setForwardHandler((void*)&forward_handler, (void*)&forward_stret_handler); 748 749 state = 11; 750 sp1 = getSP(); 751 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]; 752 sp2 = getSP(); 753 testassert(sp1 == sp2); 754 testassert(state == 12); 755 testassert(idval == ID_RESULT); 756 757 state = 13; 758 sp1 = getSP(); 759 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]; 760 sp2 = getSP(); 761 testassert(sp1 == sp2); 762 testassert(state == 14); 763 testassert(llval == LL_RESULT); 764 765 state = 15; 766 sp1 = getSP(); 767 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]; 768 sp2 = getSP(); 769 testassert(sp1 == sp2); 770 testassert(state == 16); 771 testassert(fpval == FP_RESULT); 772 773 state = 17; 774 sp1 = getSP(); 775 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]; 776 sp2 = getSP(); 777 testassert(sp1 == sp2); 778 testassert(state == 18); 779 testassert(stret_equal(stval, STRET_RESULT)); 780 781#if __x86_64__ 782 // check stret return register 783 state = 17; 784 sp1 = getSP(); 785 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); 786 sp2 = getSP(); 787 testassert(sp1 == sp2); 788 testassert(state == 18); 789 testassert(stret_equal(stval, STRET_RESULT)); 790 testassert(stptr == &stval); 791#endif 792 793 794 // Test user-defined forward handler, cached 795 796 state = 11; 797 sp1 = getSP(); 798 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]; 799 sp2 = getSP(); 800 testassert(sp1 == sp2); 801 testassert(state == 12); 802 testassert(idval == ID_RESULT); 803 804 state = 13; 805 sp1 = getSP(); 806 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]; 807 sp2 = getSP(); 808 testassert(sp1 == sp2); 809 testassert(state == 14); 810 testassert(llval == LL_RESULT); 811 812 state = 15; 813 sp1 = getSP(); 814 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]; 815 sp2 = getSP(); 816 testassert(sp1 == sp2); 817 testassert(state == 16); 818 testassert(fpval == FP_RESULT); 819 820 state = 17; 821 sp1 = getSP(); 822 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]; 823 sp2 = getSP(); 824 testassert(sp1 == sp2); 825 testassert(state == 18); 826 testassert(stret_equal(stval, STRET_RESULT)); 827 828#if __x86_64__ 829 // check stret return register 830 state = 17; 831 sp1 = getSP(); 832 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); 833 sp2 = getSP(); 834 testassert(sp1 == sp2); 835 testassert(state == 18); 836 testassert(stret_equal(stval, STRET_RESULT)); 837 testassert(stptr == &stval); 838#endif 839 840 841 // Test user-defined forward handler, uncached but fixed-up 842 843 _objc_flush_caches(nil); 844 845 state = 11; 846 sp1 = getSP(); 847 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]; 848 sp2 = getSP(); 849 testassert(sp1 == sp2); 850 testassert(state == 12); 851 testassert(idval == ID_RESULT); 852 853 state = 13; 854 sp1 = getSP(); 855 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]; 856 sp2 = getSP(); 857 testassert(sp1 == sp2); 858 testassert(state == 14); 859 testassert(llval == LL_RESULT); 860 861 state = 15; 862 sp1 = getSP(); 863 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]; 864 sp2 = getSP(); 865 testassert(sp1 == sp2); 866 testassert(state == 16); 867 testassert(fpval == FP_RESULT); 868 869 state = 17; 870 sp1 = getSP(); 871 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]; 872 sp2 = getSP(); 873 testassert(sp1 == sp2); 874 testassert(state == 18); 875 testassert(stret_equal(stval, STRET_RESULT)); 876 877#if __x86_64__ 878 // check stret return register 879 state = 17; 880 sp1 = getSP(); 881 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); 882 sp2 = getSP(); 883 testassert(sp1 == sp2); 884 testassert(state == 18); 885 testassert(stret_equal(stval, STRET_RESULT)); 886 testassert(stptr == &stval); 887#endif 888 889 890 891 // Test user-defined forward handler, manual forwarding 892 893 state = 11; 894 sp1 = getSP(); 895 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); 896 sp2 = getSP(); 897 testassert(sp1 == sp2); 898 testassert(state == 12); 899 testassert(idval == ID_RESULT); 900 901 state = 13; 902 sp1 = getSP(); 903 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); 904 sp2 = getSP(); 905 testassert(sp1 == sp2); 906 testassert(state == 14); 907 testassert(llval == LL_RESULT); 908 909 state = 15; 910 sp1 = getSP(); 911 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); 912 sp2 = getSP(); 913 testassert(sp1 == sp2); 914 testassert(state == 16); 915 testassert(fpval == FP_RESULT); 916 917 state = 17; 918 sp1 = getSP(); 919 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); 920 sp2 = getSP(); 921 testassert(sp1 == sp2); 922 testassert(state == 18); 923 testassert(stret_equal(stval, STRET_RESULT)); 924 925 926 // Test user-defined forward handler, manual forwarding, cached 927 928 state = 11; 929 sp1 = getSP(); 930 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); 931 sp2 = getSP(); 932 testassert(sp1 == sp2); 933 testassert(state == 12); 934 testassert(idval == ID_RESULT); 935 936 state = 13; 937 sp1 = getSP(); 938 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); 939 sp2 = getSP(); 940 testassert(sp1 == sp2); 941 testassert(state == 14); 942 testassert(llval == LL_RESULT); 943 944 state = 15; 945 sp1 = getSP(); 946 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); 947 sp2 = getSP(); 948 testassert(sp1 == sp2); 949 testassert(state == 16); 950 testassert(fpval == FP_RESULT); 951 952 state = 17; 953 sp1 = getSP(); 954 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); 955 sp2 = getSP(); 956 testassert(sp1 == sp2); 957 testassert(state == 18); 958 testassert(stret_equal(stval, STRET_RESULT)); 959 960 961 // Test user-defined forward handler, manual forwarding, uncached but fixed-up 962 963 _objc_flush_caches(nil); 964 965 state = 11; 966 sp1 = getSP(); 967 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); 968 sp2 = getSP(); 969 testassert(sp1 == sp2); 970 testassert(state == 12); 971 testassert(idval == ID_RESULT); 972 973 state = 13; 974 sp1 = getSP(); 975 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); 976 sp2 = getSP(); 977 testassert(sp1 == sp2); 978 testassert(state == 14); 979 testassert(llval == LL_RESULT); 980 981 state = 15; 982 sp1 = getSP(); 983 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); 984 sp2 = getSP(); 985 testassert(sp1 == sp2); 986 testassert(state == 16); 987 testassert(fpval == FP_RESULT); 988 989 state = 17; 990 sp1 = getSP(); 991 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); 992 sp2 = getSP(); 993 testassert(sp1 == sp2); 994 testassert(state == 18); 995 testassert(stret_equal(stval, STRET_RESULT)); 996 997 998 succeed(__FILE__); 999} 1000 1001#endif 1002