]> git.saurik.com Git - apple/objc4.git/blob - test/msgSend.m
objc4-437.tar.gz
[apple/objc4.git] / test / msgSend.m
1 #include "test.h"
2 #include <objc/objc.h>
3 #include <objc/objc-runtime.h>
4
5 @interface Super { id isa; }
6 +class;
7 @end
8
9 @interface Sub : Super @end
10
11 static int state = 0;
12
13 #if defined(__ppc__) || defined(__ppc64__)
14 // On ppc and ppc64, methods must be called with r12==IMP (i.e. indirect function call convention)
15 #define CHECK_R12(cls) \
16 do { \
17 IMP val; \
18 __asm__ volatile ("mr %[val], r12\n" : [val] "=r" (val)); \
19 testassert(val == method_getImplementation(class_getClassMethod([cls class], _cmd))); \
20 } while (0);
21 #else
22 #define CHECK_R12(cls) do {/* empty */} while (0)
23 #endif
24
25
26 #define CHECK_ARGS(cls, sel) \
27 do { \
28 testassert(self == [cls class]); \
29 testassert(_cmd == sel_registerName(#sel "::::::::::::::::::::::::::::"));\
30 testassert(i1 == 1); \
31 testassert(i2 == 2); \
32 testassert(i3 == 3); \
33 testassert(i4 == 4); \
34 testassert(i5 == 5); \
35 testassert(i6 == 6); \
36 testassert(i7 == 7); \
37 testassert(i8 == 8); \
38 testassert(i9 == 9); \
39 testassert(i10 == 10); \
40 testassert(i11 == 11); \
41 testassert(i12 == 12); \
42 testassert(i13 == 13); \
43 testassert(f1 == 1.0); \
44 testassert(f2 == 2.0); \
45 testassert(f3 == 3.0); \
46 testassert(f4 == 4.0); \
47 testassert(f5 == 5.0); \
48 testassert(f6 == 6.0); \
49 testassert(f7 == 7.0); \
50 testassert(f8 == 8.0); \
51 testassert(f9 == 9.0); \
52 testassert(f10 == 10.0); \
53 testassert(f11 == 11.0); \
54 testassert(f12 == 12.0); \
55 testassert(f13 == 13.0); \
56 testassert(f14 == 14.0); \
57 testassert(f15 == 15.0); \
58 } while (0)
59
60 struct stret {
61 int a;
62 int b;
63 int c;
64 int d;
65 int e;
66 int pad[32]; // force stack return on ppc64
67 };
68
69 BOOL stret_equal(struct stret a, struct stret b)
70 {
71 return (a.a == b.a &&
72 a.b == b.b &&
73 a.c == b.c &&
74 a.d == b.d &&
75 a.e == b.e);
76 }
77
78 id ID_RESULT = (id)0x12345678;
79 long long LL_RESULT = __LONG_LONG_MAX__ - 2LL*__INT_MAX__;
80 struct stret STRET_RESULT = {1, 2, 3, 4, 5, {0}};
81 double FP_RESULT = __DBL_MIN__ + __DBL_EPSILON__;
82 long double LFP_RESULT = __LDBL_MIN__ + __LDBL_EPSILON__;
83
84
85 @implementation Super
86 +class { return self; }
87 +(void)initialize { }
88
89 +(id)idret:
90 (int)i1:(int)i2:(int)i3:(int)i4:(int)i5:(int)i6:(int)i7:(int)i8:(int)i9:(int)i10:(int)i11:(int)i12:(int)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
91 {
92 CHECK_R12(Super);
93 if (state == 10) CHECK_ARGS(Sub, idret);
94 else CHECK_ARGS(Super, idret);
95 state = 1;
96 return ID_RESULT;
97 }
98
99 +(long long)llret:
100 (int)i1:(int)i2:(int)i3:(int)i4:(int)i5:(int)i6:(int)i7:(int)i8:(int)i9:(int)i10:(int)i11:(int)i12:(int)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
101 {
102 CHECK_R12(Super);
103 if (state == 10) CHECK_ARGS(Sub, llret);
104 else CHECK_ARGS(Super, llret);
105 state = 2;
106 return LL_RESULT;
107 }
108
109 +(struct stret)stret:
110 (int)i1:(int)i2:(int)i3:(int)i4:(int)i5:(int)i6:(int)i7:(int)i8:(int)i9:(int)i10:(int)i11:(int)i12:(int)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
111 {
112 CHECK_R12(Super);
113 if (state == 10) CHECK_ARGS(Sub, stret);
114 else CHECK_ARGS(Super, stret);
115 state = 3;
116 return STRET_RESULT;
117 }
118
119 +(double)fpret:
120 (int)i1:(int)i2:(int)i3:(int)i4:(int)i5:(int)i6:(int)i7:(int)i8:(int)i9:(int)i10:(int)i11:(int)i12:(int)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
121 {
122 CHECK_R12(Super);
123 if (state == 10) CHECK_ARGS(Sub, fpret);
124 else CHECK_ARGS(Super, fpret);
125 state = 4;
126 return FP_RESULT;
127 }
128
129 +(long double)lfpret:
130 (int)i1:(int)i2:(int)i3:(int)i4:(int)i5:(int)i6:(int)i7:(int)i8:(int)i9:(int)i10:(int)i11:(int)i12:(int)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
131 {
132 CHECK_R12(Super);
133 if (state == 10) CHECK_ARGS(Sub, lfpret);
134 else CHECK_ARGS(Super, lfpret);
135 state = 5;
136 return LFP_RESULT;
137 }
138
139
140 -(id)idret:
141 (int)i1:(int)i2:(int)i3:(int)i4:(int)i5:(int)i6:(int)i7:(int)i8:(int)i9:(int)i10:(int)i11:(int)i12:(int)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
142 {
143 fail("-idret called instead of +idret");
144 CHECK_ARGS(Super, idret);
145 }
146
147 -(long long)llret:
148 (int)i1:(int)i2:(int)i3:(int)i4:(int)i5:(int)i6:(int)i7:(int)i8:(int)i9:(int)i10:(int)i11:(int)i12:(int)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
149 {
150 fail("-llret called instead of +llret");
151 CHECK_ARGS(Super, llret);
152 }
153
154 -(struct stret)stret:
155 (int)i1:(int)i2:(int)i3:(int)i4:(int)i5:(int)i6:(int)i7:(int)i8:(int)i9:(int)i10:(int)i11:(int)i12:(int)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
156 {
157 fail("-stret called instead of +stret");
158 CHECK_ARGS(Super, stret);
159 }
160
161 -(double)fpret:
162 (int)i1:(int)i2:(int)i3:(int)i4:(int)i5:(int)i6:(int)i7:(int)i8:(int)i9:(int)i10:(int)i11:(int)i12:(int)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
163 {
164 fail("-fpret called instead of +fpret");
165 CHECK_ARGS(Super, fpret);
166 }
167
168 -(long double)lfpret:
169 (int)i1:(int)i2:(int)i3:(int)i4:(int)i5:(int)i6:(int)i7:(int)i8:(int)i9:(int)i10:(int)i11:(int)i12:(int)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
170 {
171 fail("-lfpret called instead of +lfpret");
172 CHECK_ARGS(Super, lfpret);
173 }
174
175 @end
176
177
178 @implementation Sub
179
180 +(id)idret:
181 (int)i1:(int)i2:(int)i3:(int)i4:(int)i5:(int)i6:(int)i7:(int)i8:(int)i9:(int)i10:(int)i11:(int)i12:(int)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
182 {
183 id result;
184 CHECK_R12(Sub);
185 CHECK_ARGS(Sub, idret);
186 state = 10;
187 result = [super idret:i1:i2:i3:i4:i5:i6:i7:i8:i9:i10:i11:i12:i13:f1:f2:f3:f4:f5:f6:f7:f8:f9:f10:f11:f12:f13:f14:f15];
188 testassert(state == 1);
189 testassert(result == ID_RESULT);
190 state = 11;
191 return result;
192 }
193
194 +(long long)llret:
195 (int)i1:(int)i2:(int)i3:(int)i4:(int)i5:(int)i6:(int)i7:(int)i8:(int)i9:(int)i10:(int)i11:(int)i12:(int)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
196 {
197 long long result;
198 CHECK_R12(Sub);
199 CHECK_ARGS(Sub, llret);
200 state = 10;
201 result = [super llret:i1:i2:i3:i4:i5:i6:i7:i8:i9:i10:i11:i12:i13:f1:f2:f3:f4:f5:f6:f7:f8:f9:f10:f11:f12:f13:f14:f15];
202 testassert(state == 2);
203 testassert(result == LL_RESULT);
204 state = 12;
205 return result;
206 }
207
208 +(struct stret)stret:
209 (int)i1:(int)i2:(int)i3:(int)i4:(int)i5:(int)i6:(int)i7:(int)i8:(int)i9:(int)i10:(int)i11:(int)i12:(int)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
210 {
211 struct stret result;
212 CHECK_R12(Sub);
213 CHECK_ARGS(Sub, stret);
214 state = 10;
215 result = [super stret:i1:i2:i3:i4:i5:i6:i7:i8:i9:i10:i11:i12:i13:f1:f2:f3:f4:f5:f6:f7:f8:f9:f10:f11:f12:f13:f14:f15];
216 testassert(state == 3);
217 testassert(stret_equal(result, STRET_RESULT));
218 state = 13;
219 return result;
220 }
221
222 +(double)fpret:
223 (int)i1:(int)i2:(int)i3:(int)i4:(int)i5:(int)i6:(int)i7:(int)i8:(int)i9:(int)i10:(int)i11:(int)i12:(int)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
224 {
225 double result;
226 CHECK_R12(Sub);
227 CHECK_ARGS(Sub, fpret);
228 state = 10;
229 result = [super fpret:i1:i2:i3:i4:i5:i6:i7:i8:i9:i10:i11:i12:i13:f1:f2:f3:f4:f5:f6:f7:f8:f9:f10:f11:f12:f13:f14:f15];
230 testassert(state == 4);
231 testassert(result == FP_RESULT);
232 state = 14;
233 return result;
234 }
235
236 +(long double)lfpret:
237 (int)i1:(int)i2:(int)i3:(int)i4:(int)i5:(int)i6:(int)i7:(int)i8:(int)i9:(int)i10:(int)i11:(int)i12:(int)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
238 {
239 long double result;
240 CHECK_R12(Sub);
241 CHECK_ARGS(Sub, lfpret);
242 state = 10;
243 result = [super lfpret:i1:i2:i3:i4:i5:i6:i7:i8:i9:i10:i11:i12:i13:f1:f2:f3:f4:f5:f6:f7:f8:f9:f10:f11:f12:f13:f14:f15];
244 testassert(state == 5);
245 testassert(result == LFP_RESULT);
246 state = 15;
247 return result;
248 }
249
250
251
252 // performance-test code (do nothing for better comparability)
253
254 +(id)idret_perf
255 {
256 return ID_RESULT;
257 }
258
259 +(long long)llret_perf
260 {
261 return LL_RESULT;
262 }
263
264 +(struct stret)stret_perf
265 {
266 return STRET_RESULT;
267 }
268
269 +(double)fpret_perf
270 {
271 return FP_RESULT;
272 }
273
274 +(long double)lfpret_perf
275 {
276 return LFP_RESULT;
277 }
278 @end
279
280
281 int main()
282 {
283 int i;
284
285 id idval;
286 long long llval;
287 struct stret stretval;
288 double fpval;
289 long double lfpval;
290
291 uint64_t startTime;
292 uint64_t totalTime;
293 uint64_t targetTime;
294
295 Method idmethod;
296 Method llmethod;
297 Method stretmethod;
298 Method fpmethod;
299 Method lfpmethod;
300
301 id (*idfn)(id, Method, int, int, int, int, int, int, int, int, int, int, int, int, int, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double);
302 long long (*llfn)(id, Method, int, int, int, int, int, int, int, int, int, int, int, int, int, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double);
303 struct stret (*stretfn)(id, Method, int, int, int, int, int, int, int, int, int, int, int, int, int, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double);
304 double (*fpfn)(id, Method, int, int, int, int, int, int, int, int, int, int, int, int, int, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double);
305 long double (*lfpfn)(id, Method, int, int, int, int, int, int, int, int, int, int, int, int, int, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double);
306
307 struct stret zero = {0, 0, 0, 0, 0, {0}};
308
309 // get +initialize out of the way
310 [Sub class];
311
312 idmethod = class_getClassMethod([Super class], @selector(idret::::::::::::::::::::::::::::));
313 testassert(idmethod);
314 llmethod = class_getClassMethod([Super class], @selector(llret::::::::::::::::::::::::::::));
315 testassert(llmethod);
316 stretmethod = class_getClassMethod([Super class], @selector(stret::::::::::::::::::::::::::::));
317 testassert(stretmethod);
318 fpmethod = class_getClassMethod([Super class], @selector(fpret::::::::::::::::::::::::::::));
319 testassert(fpmethod);
320 lfpmethod = class_getClassMethod([Super class], @selector(lfpret::::::::::::::::::::::::::::));
321 testassert(lfpmethod);
322
323 idfn = (id (*)(id, Method, int, int, int, int, int, int, int, int, int, int, int, int, int, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double)) method_invoke;
324 llfn = (long long (*)(id, Method, int, int, int, int, int, int, int, int, int, int, int, int, int, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double)) method_invoke;
325 stretfn = (struct stret (*)(id, Method, int, int, int, int, int, int, int, int, int, int, int, int, int, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double)) method_invoke_stret;
326 fpfn = (double (*)(id, Method, int, int, int, int, int, int, int, int, int, int, int, int, int, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double)) method_invoke;
327 lfpfn = (long double (*)(id, Method, int, int, int, int, int, int, int, int, int, int, int, int, int, double, double, double, double, double, double, double, double, double, double, double, double, double, double, double)) method_invoke;
328
329 // message uncached
330 // message uncached long long
331 // message uncached stret
332 // message uncached fpret
333 // message uncached fpret long double
334 // message cached
335 // message cached long long
336 // message cached stret
337 // message cached fpret
338 // message cached fpret long double
339 // fixme verify that uncached lookup didn't happen the 2nd time?
340 for (i = 0; i < 5; i++) {
341 state = 0;
342 idval = nil;
343 idval = [Sub 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];
344 testassert(state == 11);
345 testassert(idval == ID_RESULT);
346
347 llval = 0;
348 llval = [Sub 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];
349 testassert(state == 12);
350 testassert(llval == LL_RESULT);
351
352 stretval = zero;
353 stretval = [Sub 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];
354 testassert(state == 13);
355 testassert(stret_equal(stretval, STRET_RESULT));
356
357 fpval = 0;
358 fpval = [Sub 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];
359 testassert(state == 14);
360 testassert(fpval == FP_RESULT);
361
362 lfpval = 0;
363 lfpval = [Sub lfpret :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];
364 testassert(state == 15);
365 testassert(lfpval == LFP_RESULT);
366 }
367
368 // cached message performance
369 // catches failure to cache or (abi=2) failure to fixup (#5584187)
370 // fixme unless they all fail
371 // `.align 4` matches loop alignment to make -O0 work
372 #define COUNT 1000000
373 [Sub idret_perf];
374 startTime = mach_absolute_time();
375 asm(".align 4");
376 for (i = 0; i < COUNT; i++) {
377 [Sub idret_perf];
378 }
379 totalTime = mach_absolute_time() - startTime;
380 testprintf("idret %llu\n", totalTime);
381 targetTime = totalTime;
382
383 [Sub llret_perf];
384 startTime = mach_absolute_time();
385 asm(".align 4");
386 for (i = 0; i < COUNT; i++) {
387 [Sub llret_perf];
388 }
389 totalTime = mach_absolute_time() - startTime;
390 testprintf("llret %llu\n", totalTime);
391 timeassert(totalTime > targetTime * 0.8 && totalTime < targetTime * 2.0);
392
393 [Sub stret_perf];
394 startTime = mach_absolute_time();
395 asm(".align 4");
396 for (i = 0; i < COUNT; i++) {
397 [Sub stret_perf];
398 }
399 totalTime = mach_absolute_time() - startTime;
400 testprintf("stret %llu\n", totalTime);
401 timeassert(totalTime > targetTime * 0.8 && totalTime < targetTime * 5.0);
402
403 [Sub fpret_perf];
404 startTime = mach_absolute_time();
405 asm(".align 4");
406 for (i = 0; i < COUNT; i++) {
407 [Sub fpret_perf];
408 }
409 totalTime = mach_absolute_time() - startTime;
410 testprintf("fpret %llu\n", totalTime);
411 timeassert(totalTime > targetTime * 0.8 && totalTime < targetTime * 2.0);
412
413 [Sub lfpret_perf];
414 startTime = mach_absolute_time();
415 asm(".align 4");
416 for (i = 0; i < COUNT; i++) {
417 [Sub lfpret_perf];
418 }
419 totalTime = mach_absolute_time() - startTime;
420 testprintf("lfpret %llu\n", totalTime);
421 timeassert(totalTime > targetTime * 0.8 && totalTime < targetTime * 2.0);
422 #undef COUNT
423
424 // method_invoke
425 // method_invoke long long
426 // method_invoke_stret stret
427 // method_invoke_stret fpret
428 // method_invoke fpret long double
429
430 state = 0;
431 idval = nil;
432 idval = (*idfn)([Super class], idmethod, 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);
433 testassert(state == 1);
434 testassert(idval == ID_RESULT);
435
436 llval = 0;
437 llval = (*llfn)([Super class], llmethod, 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);
438 testassert(state == 2);
439 testassert(llval == LL_RESULT);
440
441 stretval = zero;
442 stretval = (*stretfn)([Super class], stretmethod, 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);
443 testassert(state == 3);
444 testassert(stret_equal(stretval, STRET_RESULT));
445
446 fpval = 0;
447 fpval = (*fpfn)([Super class], fpmethod, 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);
448 testassert(state == 4);
449 testassert(fpval == FP_RESULT);
450
451 lfpval = 0;
452 lfpval = (*lfpfn)([Super class], lfpmethod, 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);
453 testassert(state == 5);
454 testassert(lfpval == LFP_RESULT);
455
456
457 // message to nil
458 // message to nil long long
459 // message to nil stret
460 // message to nil fpret
461 // message to nil fpret long double
462 state = 0;
463 idval = ID_RESULT;
464 idval = [(id)nil 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];
465 testassert(state == 0);
466 testassert(idval == nil);
467
468 state = 0;
469 llval = LL_RESULT;
470 llval = [(id)nil 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];
471 testassert(state == 0);
472 testassert(llval == 0LL);
473
474 state = 0;
475 stretval = zero;
476 stretval = [(id)nil 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];
477 testassert(state == 0);
478 // no stret result guarantee
479
480 state = 0;
481 fpval = FP_RESULT;
482 fpval = [(id)nil 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];
483 testassert(state == 0);
484 testassert(fpval == 0.0);
485
486 state = 0;
487 lfpval = LFP_RESULT;
488 lfpval = [(id)nil lfpret :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];
489 testassert(state == 0);
490 testassert(lfpval == 0.0);
491
492
493 // message forwarded
494 // message forwarded long long
495 // message forwarded stret
496 // message forwarded fpret
497 // message forwarded fpret long double
498 // fixme
499
500 succeed(__FILE__);
501 }