Merge pull request #3016 from lewurm/small-arm-cleanup
[mono.git] / mono / tests / libtest.c
1 #include <config.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <glib.h>
6 #include <gmodule.h>
7 #include <errno.h>
8 #include <time.h>
9 #include <math.h>
10
11 #ifdef WIN32
12 #include <windows.h>
13 #include "initguid.h"
14 #else
15 #include <pthread.h>
16 #endif
17
18 #ifdef WIN32
19 #define STDCALL __stdcall
20 #else
21 #define STDCALL
22 #endif
23
24 #ifdef __GNUC__
25 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
26 #endif
27
28 #ifdef WIN32
29 extern __declspec(dllimport) void __stdcall CoTaskMemFree(void *ptr);
30 #endif
31
32 typedef int (STDCALL *SimpleDelegate) (int a);
33
34 #if defined(WIN32) && defined (_MSC_VER)
35 #define LIBTEST_API __declspec(dllexport)
36 #elif defined(__GNUC__)
37 #define LIBTEST_API  __attribute__ ((visibility ("default")))
38 #else
39 #define LIBTEST_API
40 #endif
41
42 static void marshal_free (void *ptr)
43 {
44 #ifdef WIN32
45         CoTaskMemFree (ptr);
46 #else
47         g_free (ptr);
48 #endif
49 }
50
51 static void* marshal_alloc (gsize size)
52 {
53 #ifdef WIN32
54         return CoTaskMemAlloc (size);
55 #else
56         return g_malloc (size);
57 #endif
58 }
59
60 static void* marshal_alloc0 (gsize size)
61 {
62 #ifdef WIN32
63         void* ptr = CoTaskMemAlloc (size);
64         memset(ptr, 0, size);
65         return ptr;
66 #else
67         return g_malloc0 (size);
68 #endif
69 }
70
71 static char* marshal_strdup (const char *str)
72 {
73 #ifdef WIN32
74         int len;
75         char *buf;
76
77         if (!str)
78                 return NULL;
79
80         len = strlen (str);
81         buf = (char *) CoTaskMemAlloc (len + 1);
82         return strcpy (buf, str);
83 #else
84         return g_strdup (str);
85 #endif
86 }
87
88 static gunichar2* marshal_bstr_alloc(const gchar* str)
89 {
90 #ifdef WIN32
91         gunichar2* ret = NULL;
92         gunichar2* temp = NULL;
93         temp = g_utf8_to_utf16 (str, -1, NULL, NULL, NULL);
94         ret = SysAllocString (temp);
95         g_free (temp);
96         return ret;
97 #else
98         gchar* ret = NULL;
99         int slen = strlen (str);
100         gunichar2* temp;
101         /* allocate len + 1 utf16 characters plus 4 byte integer for length*/
102         ret = (gchar *)g_malloc ((slen + 1) * sizeof(gunichar2) + sizeof(guint32));
103         if (ret == NULL)
104                 return NULL;
105         temp = g_utf8_to_utf16 (str, -1, NULL, NULL, NULL);
106         memcpy (ret + sizeof(guint32), temp, slen * sizeof(gunichar2));
107         * ((guint32 *) ret) = slen * sizeof(gunichar2);
108         ret [4 + slen * sizeof(gunichar2)] = 0;
109         ret [5 + slen * sizeof(gunichar2)] = 0;
110
111         return (gunichar2*)(ret + 4);
112 #endif
113 }
114
115 #define marshal_new0(type,size)       ((type *) marshal_alloc0 (sizeof (type)* (size)))
116
117 LIBTEST_API int STDCALL
118 mono_cominterop_is_supported (void)
119 {
120 #if defined(TARGET_X86) || defined(TARGET_AMD64)
121         return 1;
122 #endif
123         return 0;
124 }
125
126 LIBTEST_API unsigned short* STDCALL
127 test_lpwstr_marshal (unsigned short* chars, long length)
128 {
129         int i = 0;
130         unsigned short *res;
131
132         res = (unsigned short *)marshal_alloc (2 * (length + 1));
133
134         // printf("test_lpwstr_marshal()\n");
135         
136         while ( i < length ) {
137                 // printf("X|%u|\n", chars[i]);
138                 res [i] = chars[i];
139                 i++;
140         }
141
142         res [i] = 0;
143
144         return res;
145 }
146
147
148 LIBTEST_API void STDCALL
149 test_lpwstr_marshal_out (unsigned short** chars)
150 {
151         int i = 0;
152         const char abc[] = "ABC";
153         glong len = strlen(abc);
154
155         *chars = (unsigned short *)marshal_alloc (2 * (len + 1));
156         
157         while ( i < len ) {
158                 (*chars) [i] = abc[i];
159                 i++;
160         }
161
162         (*chars) [i] = 0;
163 }
164
165 typedef struct {
166         int b;
167         int a;
168         int c;
169 } union_test_1_type;
170
171 LIBTEST_API int STDCALL  
172 mono_union_test_1 (union_test_1_type u1) {
173         // printf ("Got values %d %d %d\n", u1.b, u1.a, u1.c);
174         return u1.a + u1.b + u1.c;
175 }
176
177 LIBTEST_API int STDCALL  
178 mono_return_int (int a) {
179         // printf ("Got value %d\n", a);
180         return a;
181 }
182
183 LIBTEST_API float STDCALL  
184 mono_test_marshal_pass_return_float (float f) {
185         return f + 1.0;
186 }
187
188 struct ss
189 {
190         int i;
191 };
192
193 LIBTEST_API int STDCALL 
194 mono_return_int_ss (struct ss a) {
195         // printf ("Got value %d\n", a.i);
196         return a.i;
197 }
198
199 LIBTEST_API struct ss STDCALL
200 mono_return_ss (struct ss a) {
201         // printf ("Got value %d\n", a.i);
202         a.i++;
203         return a;
204 }
205
206 struct sc1
207 {
208         char c[1];
209 };
210
211 LIBTEST_API struct sc1 STDCALL
212 mono_return_sc1 (struct sc1 a) {
213         // printf ("Got value %d\n", a.c[0]);
214         a.c[0]++;
215         return a;
216 }
217
218
219 struct sc3
220 {
221         char c[3];
222 };
223
224 LIBTEST_API struct sc3 STDCALL 
225 mono_return_sc3 (struct sc3 a) {
226         // printf ("Got values %d %d %d\n", a.c[0], a.c[1], a.c[2]);
227         a.c[0]++;
228         a.c[1] += 2;
229         a.c[2] += 3;
230         return a;
231 }
232
233 struct sc5
234 {
235         char c[5];
236 };
237
238 LIBTEST_API struct sc5 STDCALL 
239 mono_return_sc5 (struct sc5 a) {
240         // printf ("Got values %d %d %d %d %d\n", a.c[0], a.c[1], a.c[2], a.c[3], a.c[4]);
241         a.c[0]++;
242         a.c[1] += 2;
243         a.c[2] += 3;
244         a.c[3] += 4;
245         a.c[4] += 5;
246         return a;
247 }
248
249 union su
250 {
251         int i1;
252         int i2;
253 };
254
255 LIBTEST_API int STDCALL  
256 mono_return_int_su (union su a) {
257         // printf ("Got value %d\n", a.i1);
258         return a.i1;
259 }
260
261 struct FI {
262         float f1;
263         float f2;
264         float f3;
265 };
266
267 struct NestedFloat {
268         struct FI fi;
269         float f4;
270 };
271
272 LIBTEST_API struct NestedFloat STDCALL
273 mono_return_nested_float (void)
274 {
275         struct NestedFloat f;
276         f.fi.f1 = 1.0;
277         f.fi.f2 = 2.0;
278         f.fi.f3 = 3.0;
279         f.f4 = 4.0;
280         return f;
281 }
282
283 LIBTEST_API int STDCALL  
284 mono_test_many_int_arguments (int a, int b, int c, int d, int e,
285                                                           int f, int g, int h, int i, int j);
286 LIBTEST_API short STDCALL 
287 mono_test_many_short_arguments (short a, short b, short c, short d, short e,
288                                                                 short f, short g, short h, short i, short j);
289 LIBTEST_API char STDCALL 
290 mono_test_many_char_arguments (char a, char b, char c, char d, char e,
291                                                            char f, char g, char h, char i, char j);
292
293 LIBTEST_API int STDCALL 
294 mono_test_many_int_arguments (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j)
295 {
296         return a + b + c + d + e + f + g + h + i + j;
297 }
298
299 LIBTEST_API short STDCALL 
300 mono_test_many_short_arguments (short a, short b, short c, short d, short e, short f, short g, short h, short i, short j)
301 {
302         return a + b + c + d + e + f + g + h + i + j;
303 }
304
305 LIBTEST_API char STDCALL 
306 mono_test_many_byte_arguments (char a, char b, char c, char d, char e, char f, char g, char h, char i, char j)
307 {
308         return a + b + c + d + e + f + g + h + i + j;
309 }
310
311 LIBTEST_API float STDCALL 
312 mono_test_many_float_arguments (float a, float b, float c, float d, float e, float f, float g, float h, float i, float j)
313 {
314         return a + b + c + d + e + f + g + h + i + j;
315 }
316
317 LIBTEST_API double STDCALL 
318 mono_test_many_double_arguments (double a, double b, double c, double d, double e, double f, double g, double h, double i, double j)
319 {
320         return a + b + c + d + e + f + g + h + i + j;
321 }
322
323 LIBTEST_API double STDCALL 
324 mono_test_split_double_arguments (double a, double b, float c, double d, double e)
325 {
326         return a + b + c + d + e;
327 }
328
329 LIBTEST_API int STDCALL 
330 mono_test_puts_static (char *s)
331 {
332         // printf ("TEST %s\n", s);
333         return 1;
334 }
335
336 typedef int (STDCALL *SimpleDelegate3) (int a, int b);
337
338 LIBTEST_API int STDCALL 
339 mono_invoke_delegate (SimpleDelegate3 delegate)
340 {
341         int res;
342
343         // printf ("start invoke %p\n", delegate);
344
345         res = delegate (2, 3);
346
347         // printf ("end invoke\n");
348
349         return res;
350 }
351
352 LIBTEST_API int STDCALL
353 mono_invoke_simple_delegate (SimpleDelegate d)
354 {
355         return d (4);
356 }
357
358 LIBTEST_API int STDCALL  
359 mono_test_marshal_char (short a1)
360 {
361         if (a1 == 'a')
362                 return 0;
363         
364         return 1;
365 }
366
367 LIBTEST_API void STDCALL
368 mono_test_marshal_char_array (gunichar2 *s)
369 {
370         const char m[] = "abcdef";
371         gunichar2* s2;
372         glong len;
373
374         s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
375         
376         len = (len * 2) + 2;
377         memcpy (s, s2, len);
378
379         g_free (s2);
380 }
381
382 LIBTEST_API int STDCALL
383 mono_test_marshal_ansi_char_array (char *s)
384 {
385         const char m[] = "abcdef";
386
387         if (strncmp ("qwer", s, 4))
388                 return 1;
389
390         memcpy (s, m, sizeof (m));
391         return 0;
392 }
393
394 LIBTEST_API int STDCALL
395 mono_test_marshal_unicode_char_array (gunichar2 *s)
396 {
397         const char m[] = "abcdef";
398         const char expected[] = "qwer";
399         gunichar2 *s1, *s2;
400         glong len1, len2;
401
402         s1 = g_utf8_to_utf16 (m, -1, NULL, &len1, NULL);
403         s2 = g_utf8_to_utf16 (expected, -1, NULL, &len2, NULL);
404         len1 = (len1 * 2);
405         len2 = (len2 * 2);
406
407         if (memcmp (s, s2, len2))
408                 return 1;
409
410         memcpy (s, s1, len1);
411         return 0;
412 }
413
414 LIBTEST_API int STDCALL 
415 mono_test_empty_pinvoke (int i)
416 {
417         return i;
418 }
419
420 LIBTEST_API int STDCALL  
421 mono_test_marshal_bool_byref (int a, int *b, int c)
422 {
423     int res = *b;
424
425         *b = 1;
426
427         return res;
428 }
429
430 LIBTEST_API int STDCALL 
431 mono_test_marshal_bool_in_as_I1_U1 (char bTrue, char bFalse)
432 {
433         if (!bTrue)
434                 return 1;
435         if (bFalse)
436                 return 2;
437         return 0;
438 }
439
440 LIBTEST_API int STDCALL 
441 mono_test_marshal_bool_out_as_I1_U1 (char* bTrue, char* bFalse)
442 {
443         if (!bTrue || !bFalse)
444                 return 3;
445
446         *bTrue = 1;
447         *bFalse = 0;
448
449         return 0;
450 }
451
452 LIBTEST_API int STDCALL 
453 mono_test_marshal_bool_ref_as_I1_U1 (char* bTrue, char* bFalse)
454 {
455         if (!bTrue || !bFalse)
456                 return 4;
457
458         if (!(*bTrue))
459                 return 5;
460         if (*bFalse)
461                 return 6;
462
463         *bFalse = 1;
464         *bTrue = 0;
465
466         return 0;
467 }
468
469 LIBTEST_API int STDCALL  
470 mono_test_marshal_array (int *a1)
471 {
472         int i, sum = 0;
473
474         for (i = 0; i < 50; i++)
475                 sum += a1 [i];
476         
477         return sum;
478 }
479
480 LIBTEST_API int STDCALL  
481 mono_test_marshal_inout_array (int *a1)
482 {
483         int i, sum = 0;
484
485         for (i = 0; i < 50; i++) {
486                 sum += a1 [i];
487                 a1 [i] = 50 - a1 [i];
488         }
489         
490         return sum;
491 }
492
493 LIBTEST_API int /* cdecl */
494 mono_test_marshal_inout_array_cdecl (int *a1)
495 {
496         return mono_test_marshal_inout_array (a1);
497 }
498
499 LIBTEST_API int STDCALL  
500 mono_test_marshal_out_array (int *a1)
501 {
502         int i;
503
504         for (i = 0; i < 50; i++) {
505                 a1 [i] = i;
506         }
507         
508         return 0;
509 }
510
511 LIBTEST_API int STDCALL
512 mono_test_marshal_out_byref_array_out_size_param (int **out_arr, int *out_len)
513 {
514         int *arr;
515         int i, len;
516
517         len = 4;
518         arr = (gint32 *)marshal_alloc (sizeof (gint32) * len);
519         for (i = 0; i < len; ++i)
520                 arr [i] = i;
521         *out_arr = arr;
522         *out_len = len;
523
524         return 0;
525 }
526
527 LIBTEST_API int STDCALL
528 mono_test_marshal_out_lparray_out_size_param (int *arr, int *out_len)
529 {
530         int i, len;
531
532         len = 4;
533         for (i = 0; i < len; ++i)
534                 arr [i] = i;
535         *out_len = len;
536
537         return 0;
538 }
539
540 LIBTEST_API int STDCALL  
541 mono_test_marshal_inout_nonblittable_array (gunichar2 *a1)
542 {
543         int i, sum = 0;
544
545         for (i = 0; i < 10; i++) {
546                 a1 [i] = 'F';
547         }
548         
549         return sum;
550 }
551
552 typedef struct {
553         int a;
554         int b;
555         int c;
556         const char *d;
557         gunichar2 *d2;
558 } simplestruct;
559
560 typedef struct {
561         double x;
562         double y;
563 } point;
564
565 LIBTEST_API simplestruct STDCALL 
566 mono_test_return_vtype (int i)
567 {
568         simplestruct res;
569         static gunichar2 test2 [] = { 'T', 'E', 'S', 'T', '2', 0 };
570
571         res.a = 0;
572         res.b = 1;
573         res.c = 0;
574         res.d = "TEST";
575         res.d2 = test2;
576
577         return res;
578 }
579
580 LIBTEST_API void STDCALL
581 mono_test_delegate_struct (void)
582 {
583         // printf ("TEST\n");
584 }
585
586 typedef char* (STDCALL *ReturnStringDelegate) (const char *s);
587
588 LIBTEST_API char * STDCALL 
589 mono_test_return_string (ReturnStringDelegate func)
590 {
591         char *res;
592
593         // printf ("mono_test_return_string\n");
594
595         res = func ("TEST");
596         marshal_free (res);
597
598         // printf ("got string: %s\n", res);
599         return marshal_strdup ("12345");
600 }
601
602 typedef int (STDCALL *RefVTypeDelegate) (int a, simplestruct *ss, int b);
603
604 LIBTEST_API int STDCALL 
605 mono_test_ref_vtype (int a, simplestruct *ss, int b, RefVTypeDelegate func)
606 {
607         if (a == 1 && b == 2 && ss->a == 0 && ss->b == 1 && ss->c == 0 &&
608             !strcmp (ss->d, "TEST1")) {
609                 ss->a = 1;
610                 ss->b = 0;
611                 ss->c = 1;
612                 ss->d = "TEST2";
613
614                 return func (a, ss, b);
615         }
616
617         return 1;
618 }
619
620 typedef int (STDCALL *OutVTypeDelegate) (int a, simplestruct *ss, int b);
621
622 LIBTEST_API int STDCALL 
623 mono_test_marshal_out_struct (int a, simplestruct *ss, int b, OutVTypeDelegate func)
624 {
625         /* Check that the input pointer is ignored */
626         ss->d = (const char *)0x12345678;
627
628         func (a, ss, b);
629
630         if (ss->a && ss->b && ss->c && !strcmp (ss->d, "TEST3"))
631                 return 0;
632         else
633                 return 1;
634 }
635
636 typedef int (STDCALL *InVTypeDelegate) (int a, simplestruct *ss, int b);
637
638 LIBTEST_API int STDCALL 
639 mono_test_marshal_in_struct (int a, simplestruct *ss, int b, InVTypeDelegate func)
640 {
641         simplestruct ss2;
642         int res;
643
644         memcpy (&ss2, ss, sizeof (simplestruct));
645
646         res = func (a, ss, b);
647         if (res) {
648                 printf ("mono_test_marshal_in_struct () failed: %d\n", res);
649                 return 1;
650         }
651
652         /* Check that no modifications is made to the struct */
653         if (ss2.a == ss->a && ss2.b == ss->b && ss2.c == ss->c && ss2.d == ss->d)
654                 return 0;
655         else
656                 return 1;
657 }
658
659 typedef struct {
660         int a;
661         SimpleDelegate func, func2, func3;
662 } DelegateStruct;
663
664 LIBTEST_API DelegateStruct STDCALL 
665 mono_test_marshal_delegate_struct (DelegateStruct ds)
666 {
667         DelegateStruct res;
668
669         res.a = ds.func (ds.a) + ds.func2 (ds.a) + (ds.func3 == NULL ? 0 : 1);
670         res.func = ds.func;
671         res.func2 = ds.func2;
672         res.func3 = NULL;
673
674         return res;
675 }
676
677 LIBTEST_API int STDCALL  
678 mono_test_marshal_struct (simplestruct ss)
679 {
680         if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
681             !strcmp (ss.d, "TEST"))
682                 return 0;
683
684         return 1;
685 }
686
687 LIBTEST_API int STDCALL 
688 mono_test_marshal_byref_struct (simplestruct *ss, int a, int b, int c, char *d)
689 {
690         gboolean res = (ss->a == a && ss->b == b && ss->c == c && strcmp (ss->d, d) == 0);
691
692         marshal_free ((char*)ss->d);
693
694         ss->a = !ss->a;
695         ss->b = !ss->b;
696         ss->c = !ss->c;
697         ss->d = marshal_strdup ("DEF");
698
699         return res ? 0 : 1;
700 }
701
702 typedef struct {
703         int a;
704         int b;
705         int c;
706         char *d;
707         unsigned char e;
708         double f;
709         unsigned char g;
710         guint64 h;
711 } simplestruct2;
712
713 LIBTEST_API int STDCALL 
714 mono_test_marshal_struct2 (simplestruct2 ss)
715 {
716         if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
717             !strcmp (ss.d, "TEST") && 
718             ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
719                 return 0;
720
721         return 1;
722 }
723
724 /* on HP some of the struct should be on the stack and not in registers */
725 LIBTEST_API int STDCALL 
726 mono_test_marshal_struct2_2 (int i, int j, int k, simplestruct2 ss)
727 {
728         if (i != 10 || j != 11 || k != 12)
729                 return 1;
730         if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
731             !strcmp (ss.d, "TEST") && 
732             ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
733                 return 0;
734
735         return 1;
736 }
737
738 LIBTEST_API int STDCALL  
739 mono_test_marshal_lpstruct (simplestruct *ss)
740 {
741         if (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
742             !strcmp (ss->d, "TEST"))
743                 return 0;
744
745         return 1;
746 }
747
748 LIBTEST_API int STDCALL  
749 mono_test_marshal_lpstruct_blittable (point *p)
750 {
751         if (p->x == 1.0 && p->y == 2.0)
752                 return 0;
753         else
754                 return 1;
755 }
756
757 LIBTEST_API int STDCALL 
758 mono_test_marshal_struct_array (simplestruct2 *ss)
759 {
760         if (! (ss[0].a == 0 && ss[0].b == 1 && ss[0].c == 0 &&
761                    !strcmp (ss[0].d, "TEST") && 
762                    ss[0].e == 99 && ss[0].f == 1.5 && ss[0].g == 42 && ss[0].h == (guint64)123))
763                 return 1;
764
765         if (! (ss[1].a == 0 && ss[1].b == 0 && ss[1].c == 0 &&
766                    !strcmp (ss[1].d, "TEST2") && 
767                    ss[1].e == 100 && ss[1].f == 2.5 && ss[1].g == 43 && ss[1].h == (guint64)124))
768                 return 1;
769
770         return 0;
771 }
772
773 typedef struct long_align_struct {
774         gint32 a;
775         gint64 b;
776         gint64 c;
777 } long_align_struct;
778
779 LIBTEST_API int STDCALL 
780 mono_test_marshal_long_align_struct_array (long_align_struct *ss)
781 {
782         return ss[0].a + ss[0].b + ss[0].c + ss[1].a + ss[1].b + ss[1].c;
783 }
784
785 LIBTEST_API simplestruct2 * STDCALL 
786 mono_test_marshal_class (int i, int j, int k, simplestruct2 *ss, int l)
787 {
788         simplestruct2 *res;
789
790         if (!ss)
791                 return NULL;
792
793         if (i != 10 || j != 11 || k != 12 || l != 14)
794                 return NULL;
795         if (! (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
796                    !strcmp (ss->d, "TEST") && 
797                    ss->e == 99 && ss->f == 1.5 && ss->g == 42 && ss->h == (guint64)123))
798                 return NULL;
799
800         res = marshal_new0 (simplestruct2, 1);
801         memcpy (res, ss, sizeof (simplestruct2));
802         res->d = marshal_strdup ("TEST");
803         return res;
804 }
805
806 LIBTEST_API int STDCALL 
807 mono_test_marshal_byref_class (simplestruct2 **ssp)
808 {
809         simplestruct2 *ss = *ssp;
810         simplestruct2 *res;
811         
812         if (! (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
813                    !strcmp (ss->d, "TEST") && 
814                    ss->e == 99 && ss->f == 1.5 && ss->g == 42 && ss->h == (guint64)123))
815                 return 1;
816
817         res = marshal_new0 (simplestruct2, 1);
818         memcpy (res, ss, sizeof (simplestruct2));
819         res->d = marshal_strdup ("TEST-RES");
820
821         *ssp = res;
822         return 0;
823 }
824
825 static void *
826 get_sp (void)
827 {
828         int i;
829         void *p;
830
831         /* Yes, this is correct, we are only trying to determine the value of the stack here */
832         p = &i;
833         return p;
834 }
835
836 LIBTEST_API int STDCALL 
837 reliable_delegate (int a)
838 {
839         return a;
840 }
841
842 /*
843  * Checks whether get_sp() works as expected. It doesn't work with gcc-2.95.3 on linux.
844  */
845 static gboolean
846 is_get_sp_reliable (void)
847 {
848         void *sp1, *sp2;
849
850         reliable_delegate(1);
851         sp1 = get_sp();
852         reliable_delegate(1);
853         sp2 = get_sp();
854         return sp1 == sp2;
855
856
857 LIBTEST_API int STDCALL 
858 mono_test_marshal_delegate (SimpleDelegate delegate)
859 {
860         void *sp1, *sp2;
861
862         /* Check that the delegate wrapper is stdcall */
863         delegate (2);
864         sp1 = get_sp ();
865         delegate (2);
866         sp2 = get_sp ();
867         if (is_get_sp_reliable())
868                 g_assert (sp1 == sp2);
869
870         return delegate (2);
871 }
872
873 static int STDCALL inc_cb (int i)
874 {
875         return i + 1;
876 }
877
878 LIBTEST_API int STDCALL 
879 mono_test_marshal_out_delegate (SimpleDelegate *delegate)
880 {
881         *delegate = inc_cb;
882
883         return 0;
884 }
885
886 LIBTEST_API SimpleDelegate STDCALL 
887 mono_test_marshal_return_delegate (SimpleDelegate delegate)
888 {
889         return delegate;
890 }
891
892 typedef int DelegateByrefDelegate (void *);
893
894 LIBTEST_API int STDCALL
895 mono_test_marshal_delegate_ref_delegate (DelegateByrefDelegate del)
896 {
897         int (*ptr) (int i);
898
899         del (&ptr);
900
901         return ptr (54);
902 }
903
904 static int STDCALL
905 return_plus_one (int i)
906 {
907         return i + 1;
908 }
909
910 LIBTEST_API SimpleDelegate STDCALL 
911 mono_test_marshal_return_delegate_2 (void)
912 {
913         return return_plus_one;
914 }
915
916 typedef simplestruct (STDCALL *SimpleDelegate2) (simplestruct ss);
917
918 static gboolean
919 is_utf16_equals (gunichar2 *s1, const char *s2)
920 {
921         char *s;
922         int res;
923
924         s = g_utf16_to_utf8 (s1, -1, NULL, NULL, NULL);
925         res = strcmp (s, s2);
926         g_free (s);
927
928         return res == 0;
929 }
930
931 LIBTEST_API int STDCALL 
932 mono_test_marshal_delegate2 (SimpleDelegate2 delegate)
933 {
934         simplestruct ss, res;
935
936         ss.a = 0;
937         ss.b = 1;
938         ss.c = 0;
939         ss.d = "TEST";
940         ss.d2 = g_utf8_to_utf16 ("TEST2", -1, NULL, NULL, NULL); 
941
942         res = delegate (ss);
943         if (! (res.a && !res.b && res.c && !strcmp (res.d, "TEST-RES") && is_utf16_equals (res.d2, "TEST2-RES")))
944                 return 1;
945
946         return 0;
947 }
948
949 typedef simplestruct* (STDCALL *SimpleDelegate4) (simplestruct *ss);
950
951 LIBTEST_API int STDCALL 
952 mono_test_marshal_delegate4 (SimpleDelegate4 delegate)
953 {
954         simplestruct ss;
955         simplestruct *res;
956
957         ss.a = 0;
958         ss.b = 1;
959         ss.c = 0;
960         ss.d = "TEST";
961
962         /* Check argument */
963         res = delegate (&ss);
964         if (!res)
965                 return 1;
966
967         /* Check return value */
968         if (! (!res->a && res->b && !res->c && !strcmp (res->d, "TEST")))
969                 return 2;
970
971         /* Check NULL argument and NULL result */
972         res = delegate (NULL);
973         if (res)
974                 return 3;
975
976         return 0;
977 }
978
979 typedef int (STDCALL *SimpleDelegate5) (simplestruct **ss);
980
981 LIBTEST_API int STDCALL 
982 mono_test_marshal_delegate5 (SimpleDelegate5 delegate)
983 {
984         simplestruct ss;
985         int res;
986         simplestruct *ptr;
987
988         ss.a = 0;
989         ss.b = 1;
990         ss.c = 0;
991         ss.d = "TEST";
992
993         ptr = &ss;
994
995         res = delegate (&ptr);
996         if (res != 0)
997                 return 1;
998
999         if (!(ptr->a && !ptr->b && ptr->c && !strcmp (ptr->d, "RES")))
1000                 return 2;
1001
1002         return 0;
1003 }
1004
1005 LIBTEST_API int STDCALL 
1006 mono_test_marshal_delegate6 (SimpleDelegate5 delegate)
1007 {
1008         delegate (NULL);
1009         return 0;
1010 }
1011
1012 typedef int (STDCALL *SimpleDelegate7) (simplestruct **ss);
1013
1014 LIBTEST_API int STDCALL 
1015 mono_test_marshal_delegate7 (SimpleDelegate7 delegate)
1016 {
1017         int res;
1018         simplestruct *ptr;
1019
1020         /* Check that the input pointer is ignored */
1021         ptr = (simplestruct *)0x12345678;
1022
1023         res = delegate (&ptr);
1024         if (res != 0)
1025                 return 1;
1026
1027         if (!(ptr->a && !ptr->b && ptr->c && !strcmp (ptr->d, "RES")))
1028                 return 2;
1029
1030         return 0;
1031 }
1032
1033 typedef int (STDCALL *InOutByvalClassDelegate) (simplestruct *ss);
1034
1035 LIBTEST_API int STDCALL 
1036 mono_test_marshal_inout_byval_class_delegate (InOutByvalClassDelegate delegate)
1037 {
1038         int res;
1039         simplestruct ss;
1040
1041         ss.a = FALSE;
1042         ss.b = TRUE;
1043         ss.c = FALSE;
1044         ss.d = g_strdup_printf ("%s", "FOO");
1045
1046         res = delegate (&ss);
1047         if (res != 0)
1048                 return 1;
1049
1050         if (!(ss.a && !ss.b && ss.c && !strcmp (ss.d, "RES")))
1051                 return 2;
1052
1053         return 0;
1054 }
1055
1056 typedef int (STDCALL *SimpleDelegate8) (gunichar2 *s);
1057
1058 LIBTEST_API int STDCALL 
1059 mono_test_marshal_delegate8 (SimpleDelegate8 delegate, gunichar2 *s)
1060 {
1061         return delegate (s);
1062 }
1063
1064 typedef int (STDCALL *return_int_fnt) (int i);
1065 typedef int (STDCALL *SimpleDelegate9) (return_int_fnt d);
1066
1067 LIBTEST_API int STDCALL 
1068 mono_test_marshal_delegate9 (SimpleDelegate9 delegate, gpointer ftn)
1069 {
1070         return delegate ((return_int_fnt)ftn);
1071 }
1072
1073 static int STDCALL 
1074 return_self (int i)
1075 {
1076         return i;
1077 }
1078
1079 LIBTEST_API int STDCALL 
1080 mono_test_marshal_delegate10 (SimpleDelegate9 delegate)
1081 {
1082         return delegate (return_self);
1083 }
1084
1085 typedef int (STDCALL *PrimitiveByrefDelegate) (int *i);
1086
1087 LIBTEST_API int STDCALL 
1088 mono_test_marshal_primitive_byref_delegate (PrimitiveByrefDelegate delegate)
1089 {
1090         int i = 1;
1091
1092         int res = delegate (&i);
1093         if (res != 0)
1094                 return res;
1095
1096         if (i != 2)
1097                 return 2;
1098
1099         return 0;
1100 }
1101
1102 typedef int (STDCALL *return_int_delegate) (int i);
1103
1104 typedef return_int_delegate (STDCALL *ReturnDelegateDelegate) (void);
1105
1106 LIBTEST_API int STDCALL 
1107 mono_test_marshal_return_delegate_delegate (ReturnDelegateDelegate d)
1108 {
1109         return (d ()) (55);
1110 }
1111
1112 typedef int (STDCALL *VirtualDelegate) (int);
1113
1114 LIBTEST_API int STDCALL
1115 mono_test_marshal_virtual_delegate (VirtualDelegate del)
1116 {
1117         return del (42);
1118 }
1119
1120 typedef char* (STDCALL *IcallDelegate) (const char *);
1121 LIBTEST_API int STDCALL
1122 mono_test_marshal_icall_delegate (IcallDelegate del)
1123 {
1124         char *res = del ("ABC");
1125         return strcmp (res, "ABC") == 0 ? 0 : 1;
1126 }
1127
1128 LIBTEST_API int STDCALL  
1129 mono_test_marshal_stringbuilder (char *s, int n)
1130 {
1131         const char m[] = "This is my message.  Isn't it nice?";
1132
1133         if (strcmp (s, "ABCD") != 0)
1134                 return 1;
1135         strncpy(s, m, n);
1136         s [n] = '\0';
1137         return 0;
1138 }
1139
1140 LIBTEST_API int STDCALL  
1141 mono_test_marshal_stringbuilder_append (char *s, int length)
1142 {
1143         const char out_sentinel[] = "CSHARP_";
1144         const char out_len = strlen (out_sentinel);
1145
1146         for (int i=0; i < length; i++) {
1147                 s [i] = out_sentinel [i % out_len];
1148         }
1149
1150         s [length] = '\0';
1151
1152
1153         return 0;
1154 }
1155
1156 LIBTEST_API int STDCALL  
1157 mono_test_marshal_stringbuilder_default (char *s, int n)
1158 {
1159         const char m[] = "This is my message.  Isn't it nice?";
1160
1161         strncpy(s, m, n);
1162         s [n] = '\0';
1163         return 0;
1164 }
1165
1166 LIBTEST_API int STDCALL  
1167 mono_test_marshal_stringbuilder_unicode (gunichar2 *s, int n)
1168 {
1169         const char m[] = "This is my message.  Isn't it nice?";
1170         gunichar2* s2;
1171         glong len;
1172
1173         s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
1174         
1175         len = (len * 2) + 2;
1176         if (len > (n * 2))
1177                 len = n * 2;
1178         memcpy (s, s2, len);
1179
1180         g_free (s2);
1181
1182         return 0;
1183 }
1184
1185 LIBTEST_API void STDCALL
1186 mono_test_marshal_stringbuilder_out (char **s)
1187 {
1188         const char m[] = "This is my message.  Isn't it nice?";
1189         char *str;
1190
1191         str = (char *)marshal_alloc (strlen (m) + 1);
1192         memcpy (str, m, strlen (m) + 1);
1193         
1194         *s = str;
1195 }
1196
1197 LIBTEST_API int STDCALL  
1198 mono_test_marshal_stringbuilder_out_unicode (gunichar2 **s)
1199 {
1200         const char m[] = "This is my message.  Isn't it nice?";
1201         gunichar2 *s2;
1202         glong len;
1203
1204         s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
1205         
1206         len = (len * 2) + 2;
1207         *s = (gunichar2 *)marshal_alloc (len);
1208         memcpy (*s, s2, len);
1209
1210         g_free (s2);
1211
1212         return 0;
1213 }
1214
1215 LIBTEST_API int STDCALL
1216 mono_test_marshal_stringbuilder_ref (char **s)
1217 {
1218         const char m[] = "This is my message.  Isn't it nice?";
1219         char *str;
1220
1221         if (strcmp (*s, "ABC"))
1222                 return 1;
1223
1224         str = (char *)marshal_alloc (strlen (m) + 1);
1225         memcpy (str, m, strlen (m) + 1);
1226         
1227         *s = str;
1228         return 0;
1229 }
1230
1231 #pragma GCC diagnostic push
1232 #pragma GCC diagnostic ignored "-Wc++-compat"
1233 typedef struct {
1234 #ifndef __GNUC__
1235     char a;
1236 #endif
1237 } EmptyStruct;
1238 #pragma GCC diagnostic pop
1239
1240 LIBTEST_API int STDCALL 
1241 mono_test_marshal_empty_string_array (char **array)
1242 {
1243         return (array == NULL) ? 0 : 1;
1244 }
1245
1246 LIBTEST_API int STDCALL 
1247 mono_test_marshal_string_array (char **array)
1248 {
1249         if (strcmp (array [0], "ABC"))
1250                 return 1;
1251         if (strcmp (array [1], "DEF"))
1252                 return 2;
1253
1254         if (array [2] != NULL)
1255                 return 3;
1256
1257         return 0;
1258 }
1259
1260 LIBTEST_API int STDCALL 
1261 mono_test_marshal_byref_string_array (char ***array)
1262 {
1263         if (*array == NULL)
1264                 return 0;
1265
1266         if (strcmp ((*array) [0], "Alpha"))
1267                 return 2;
1268         if (strcmp ((*array) [1], "Beta"))
1269                 return 2;
1270         if (strcmp ((*array) [2], "Gamma"))
1271                 return 2;
1272
1273         return 1;
1274 }
1275
1276 LIBTEST_API int STDCALL 
1277 mono_test_marshal_stringbuilder_array (char **array)
1278 {
1279         if (strcmp (array [0], "ABC"))
1280                 return 1;
1281         if (strcmp (array [1], "DEF"))
1282                 return 2;
1283
1284         strcpy (array [0], "DEF");
1285         strcpy (array [1], "ABC");
1286
1287         return 0;
1288 }
1289
1290 LIBTEST_API int STDCALL 
1291 mono_test_marshal_unicode_string_array (gunichar2 **array, char **array2)
1292 {
1293         GError *error = NULL;
1294         char *s;
1295         
1296         s = g_utf16_to_utf8 (array [0], -1, NULL, NULL, &error);
1297         if (strcmp (s, "ABC")) {
1298                 g_free (s);
1299                 return 1;
1300         }
1301         else
1302                 g_free (s);
1303
1304         s = g_utf16_to_utf8 (array [1], -1, NULL, NULL, &error);
1305         if (strcmp (s, "DEF")) {
1306                 g_free (s);
1307                 return 2;
1308         }
1309         else
1310                 g_free (s);
1311
1312         if (strcmp (array2 [0], "ABC"))
1313                 return 3;
1314
1315         if (strcmp (array2 [1], "DEF")) 
1316                 return 4;
1317
1318         return 0;
1319 }
1320
1321 /* this does not work on Redhat gcc 2.96 */
1322 LIBTEST_API int STDCALL  
1323 mono_test_empty_struct (int a, EmptyStruct es, int b)
1324 {
1325         // printf ("mono_test_empty_struct %d %d\n", a, b);
1326
1327         // Intel icc on ia64 passes 'es' in 2 registers
1328 #if defined(__ia64) && defined(__INTEL_COMPILER)
1329         return 0;
1330 #else
1331         if (a == 1 && b == 2)
1332                 return 0;
1333         return 1;
1334 #endif
1335 }
1336
1337 LIBTEST_API EmptyStruct STDCALL
1338 mono_test_return_empty_struct (int a)
1339 {
1340         EmptyStruct s;
1341
1342         memset (&s, 0, sizeof (s));
1343
1344         g_assert (a == 42);
1345
1346         return s;
1347 }
1348
1349 typedef struct {
1350        char a[100];
1351 } ByValStrStruct;
1352
1353 LIBTEST_API ByValStrStruct * STDCALL 
1354 mono_test_byvalstr_gen (void)
1355 {
1356         ByValStrStruct *ret;
1357        
1358         ret = (ByValStrStruct *)malloc (sizeof (ByValStrStruct));
1359         memset(ret, 'a', sizeof(ByValStrStruct)-1);
1360         ret->a[sizeof(ByValStrStruct)-1] = 0;
1361
1362         return ret;
1363 }
1364
1365 LIBTEST_API int STDCALL 
1366 mono_test_byvalstr_check (ByValStrStruct* data, char* correctString)
1367 {
1368         int ret;
1369
1370         ret = strcmp(data->a, correctString);
1371         // printf ("T1: %s\n", data->a);
1372         // printf ("T2: %s\n", correctString);
1373
1374         /* we need g_free because the allocation was performed by mono_test_byvalstr_gen */
1375         g_free (data);
1376         return (ret != 0);
1377 }
1378
1379 typedef struct {
1380         guint16 a[4];
1381         int  flag;
1382 } ByValStrStruct_Unicode;
1383
1384 LIBTEST_API int STDCALL 
1385 mono_test_byvalstr_check_unicode (ByValStrStruct_Unicode *ref, int test)
1386 {
1387         if (ref->flag != 0x1234abcd){
1388                 printf ("overwritten data");
1389                 return 1;
1390         }
1391             
1392         if (test == 1 || test == 3){
1393                 if (ref->a [0] != '1' ||
1394                     ref->a [1] != '2'   ||
1395                     ref->a [2] != '3')
1396                         return 1;
1397                 return 0;
1398         }
1399         if (test == 2){
1400                 if (ref->a [0] != '1' ||
1401                     ref->a [1] != '2')
1402                         return 1;
1403                 return 0;
1404         }
1405         return 10;
1406 }
1407
1408 LIBTEST_API int STDCALL 
1409 NameManglingAnsi (char *data)
1410 {
1411         return data [0] + data [1] + data [2];
1412 }
1413
1414 LIBTEST_API int STDCALL 
1415 NameManglingAnsiA (char *data)
1416 {
1417         g_assert_not_reached ();
1418 }
1419
1420 LIBTEST_API int STDCALL 
1421 NameManglingAnsiW (char *data)
1422 {
1423         g_assert_not_reached ();
1424 }
1425
1426 LIBTEST_API int STDCALL 
1427 NameManglingAnsi2A (char *data)
1428 {
1429         return data [0] + data [1] + data [2];
1430 }
1431
1432 LIBTEST_API int STDCALL 
1433 NameManglingAnsi2W (char *data)
1434 {
1435         g_assert_not_reached ();
1436 }
1437
1438 LIBTEST_API int STDCALL 
1439 NameManglingUnicode (char *data)
1440 {
1441         g_assert_not_reached ();
1442 }
1443
1444 LIBTEST_API int STDCALL 
1445 NameManglingUnicodeW (gunichar2 *data)
1446 {
1447         return data [0] + data [1] + data [2];
1448 }
1449
1450 LIBTEST_API int STDCALL 
1451 NameManglingUnicode2 (gunichar2 *data)
1452 {
1453         return data [0] + data [1] + data [2];
1454 }
1455
1456 LIBTEST_API int STDCALL 
1457 NameManglingAutoW (char *data)
1458 {
1459 #ifdef WIN32
1460         return (data [0] + data [1] + data [2]) == 131 ? 0 : 1;
1461 #else
1462         g_assert_not_reached ();
1463 #endif
1464 }
1465
1466 LIBTEST_API int STDCALL 
1467 NameManglingAuto (char *data)
1468 {
1469 #ifndef WIN32
1470         return (data [0] + data [1] + data [2]) == 198 ? 0 : 1;
1471 #else
1472         g_assert_not_reached ();
1473 #endif
1474 }
1475
1476 typedef int (STDCALL *intcharFunc)(const char*);
1477
1478 LIBTEST_API void STDCALL 
1479 callFunction (intcharFunc f)
1480 {
1481         f ("ABC");
1482 }
1483
1484 typedef struct {
1485         const char* str;
1486         int i;
1487 } SimpleObj;
1488
1489 LIBTEST_API int STDCALL 
1490 class_marshal_test0 (SimpleObj *obj1)
1491 {
1492         // printf ("class_marshal_test0 %s %d\n", obj1->str, obj1->i);
1493
1494         if (strcmp(obj1->str, "T1"))
1495                 return -1;
1496         if (obj1->i != 4)
1497                 return -2;
1498
1499         return 0;
1500 }
1501
1502 LIBTEST_API int STDCALL 
1503 class_marshal_test4 (SimpleObj *obj1)
1504 {
1505         if (obj1)
1506                 return -1;
1507
1508         return 0;
1509 }
1510
1511 LIBTEST_API void STDCALL
1512 class_marshal_test1 (SimpleObj **obj1)
1513 {
1514         SimpleObj *res = (SimpleObj *)malloc (sizeof (SimpleObj));
1515
1516         res->str = marshal_strdup ("ABC");
1517         res->i = 5;
1518
1519         *obj1 = res;
1520 }
1521
1522 LIBTEST_API int STDCALL 
1523 class_marshal_test2 (SimpleObj **obj1)
1524 {
1525         // printf ("class_marshal_test2 %s %d\n", (*obj1)->str, (*obj1)->i);
1526
1527         if (strcmp((*obj1)->str, "ABC"))
1528                 return -1;
1529         if ((*obj1)->i != 5)
1530                 return -2;
1531
1532         return 0;
1533 }
1534
1535 LIBTEST_API int STDCALL 
1536 string_marshal_test0 (char *str)
1537 {
1538         if (strcmp (str, "TEST0"))
1539                 return -1;
1540
1541         return 0;
1542 }
1543
1544 LIBTEST_API void STDCALL
1545 string_marshal_test1 (const char **str)
1546 {
1547         *str = marshal_strdup ("TEST1");
1548 }
1549
1550 LIBTEST_API int STDCALL 
1551 string_marshal_test2 (char **str)
1552 {
1553         // printf ("string_marshal_test2 %s\n", *str);
1554
1555         if (strcmp (*str, "TEST1"))
1556                 return -1;
1557
1558         *str = marshal_strdup ("TEST2");
1559
1560         return 0;
1561 }
1562
1563 LIBTEST_API int STDCALL 
1564 string_marshal_test3 (char *str)
1565 {
1566         if (str)
1567                 return -1;
1568
1569         return 0;
1570 }
1571
1572 typedef struct {
1573         int a;
1574         int b;
1575 } BlittableClass;
1576
1577 LIBTEST_API BlittableClass* STDCALL 
1578 TestBlittableClass (BlittableClass *vl)
1579 {
1580         BlittableClass *res;
1581
1582         // printf ("TestBlittableClass %d %d\n", vl->a, vl->b);
1583
1584         if (vl) {
1585                 vl->a++;
1586                 vl->b++;
1587
1588                 res = marshal_new0 (BlittableClass, 1);
1589                 memcpy (res, vl, sizeof (BlittableClass));
1590         } else {
1591                 res = marshal_new0 (BlittableClass, 1);
1592                 res->a = 42;
1593                 res->b = 43;
1594         }
1595
1596         return res;
1597 }
1598
1599 typedef struct OSVERSIONINFO_STRUCT
1600
1601         int a; 
1602         int b; 
1603 } OSVERSIONINFO_STRUCT;
1604
1605 LIBTEST_API int STDCALL  
1606 MyGetVersionEx (OSVERSIONINFO_STRUCT *osvi)
1607 {
1608
1609         // printf ("GOT %d %d\n", osvi->a, osvi->b);
1610
1611         osvi->a += 1;
1612         osvi->b += 1;
1613
1614         return osvi->a + osvi->b;
1615 }
1616
1617 LIBTEST_API int STDCALL  
1618 BugGetVersionEx (int a, int b, int c, int d, int e, int f, int g, int h, OSVERSIONINFO_STRUCT *osvi)
1619 {
1620
1621         // printf ("GOT %d %d\n", osvi->a, osvi->b);
1622
1623         osvi->a += 1;
1624         osvi->b += 1;
1625
1626         return osvi->a + osvi->b;
1627 }
1628
1629 LIBTEST_API int STDCALL 
1630 mono_test_marshal_point (point pt)
1631 {
1632         // printf("point %g %g\n", pt.x, pt.y);
1633         if (pt.x == 1.25 && pt.y == 3.5)
1634                 return 0;
1635
1636         return 1;
1637 }
1638
1639 typedef struct {
1640         int x;
1641         double y;
1642 } mixed_point;
1643
1644 LIBTEST_API int STDCALL 
1645 mono_test_marshal_mixed_point (mixed_point pt)
1646 {
1647         // printf("mixed point %d %g\n", pt.x, pt.y);
1648         if (pt.x == 5 && pt.y == 6.75)
1649                 return 0;
1650
1651         return 1;
1652 }
1653
1654 LIBTEST_API int STDCALL 
1655 mono_test_marshal_mixed_point_2 (mixed_point *pt)
1656 {
1657         if (pt->x != 5 || pt->y != 6.75)
1658                 return 1;
1659
1660         pt->x = 10;
1661         pt->y = 12.35;
1662
1663         return 0;
1664 }
1665
1666 LIBTEST_API int STDCALL  
1667 marshal_test_ref_bool(int i, char *b1, short *b2, int *b3)
1668 {
1669     int res = 1;
1670     if (*b1 != 0 && *b1 != 1)
1671         return 1;
1672     if (*b2 != 0 && *b2 != -1) /* variant_bool */
1673         return 1;
1674     if (*b3 != 0 && *b3 != 1)
1675         return 1;
1676     if (i == ((*b1 << 2) | (-*b2 << 1) | *b3))
1677         res = 0;
1678     *b1 = !*b1;
1679     *b2 = ~*b2;
1680     *b3 = !*b3;
1681     return res;
1682 }
1683
1684 struct BoolStruct
1685 {
1686     int i;
1687     char b1;
1688     short b2; /* variant_bool */
1689     int b3;
1690 };
1691
1692 LIBTEST_API int STDCALL  
1693 marshal_test_bool_struct(struct BoolStruct *s)
1694 {
1695     int res = 1;
1696     if (s->b1 != 0 && s->b1 != 1)
1697         return 1;
1698     if (s->b2 != 0 && s->b2 != -1)
1699         return 1;
1700     if (s->b3 != 0 && s->b3 != 1)
1701         return 1;
1702     if (s->i == ((s->b1 << 2) | (-s->b2 << 1) | s->b3))
1703         res = 0;
1704     s->b1 = !s->b1;
1705     s->b2 = ~s->b2;
1706     s->b3 = !s->b3;
1707     return res;
1708 }
1709
1710 typedef struct {
1711         gint64 l;
1712 } LongStruct2;
1713
1714 typedef struct {
1715         int i;
1716         LongStruct2 l;
1717 } LongStruct;
1718
1719 LIBTEST_API int STDCALL
1720 mono_test_marshal_long_struct (LongStruct *s)
1721 {
1722         return s->i + s->l.l;
1723 }
1724
1725 LIBTEST_API void STDCALL
1726 mono_test_last_error (int err)
1727 {
1728 #ifdef WIN32
1729         SetLastError (err);
1730 #else
1731         errno = err;
1732 #endif
1733 }
1734
1735 LIBTEST_API int STDCALL 
1736 mono_test_asany (void *ptr, int what)
1737 {
1738         switch (what) {
1739         case 1:
1740                 return (*(int*)ptr == 5) ? 0 : 1;
1741         case 2:
1742                 return strcmp (ptr, "ABC") == 0 ? 0 : 1;
1743         case 3: {
1744                 simplestruct2 ss = *(simplestruct2*)ptr;
1745
1746                 if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
1747             !strcmp (ss.d, "TEST") && 
1748             ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
1749                         return 0;
1750                 else
1751                         return 1;
1752         }
1753         case 4: {
1754                 GError *error = NULL;
1755                 char *s;
1756
1757                 s = g_utf16_to_utf8 ((const gunichar2 *)ptr, -1, NULL, NULL, &error);
1758
1759                 if (!s)
1760                         return 1;
1761
1762                 if (!strcmp (s, "ABC")) {
1763                         g_free (s);
1764                         return 0;
1765                 }
1766                 else {
1767                         g_free (s);
1768                         return 1;
1769                 }
1770         }
1771         default:
1772                 g_assert_not_reached ();
1773         }
1774
1775         return 1;
1776 }
1777
1778 typedef struct
1779 {
1780         int i;
1781         int j;
1782         int k;
1783         char *s;
1784 } AsAnyStruct;
1785
1786 LIBTEST_API int STDCALL 
1787 mono_test_marshal_asany_in (void* ptr)
1788 {
1789         AsAnyStruct *asAny = (AsAnyStruct *)ptr;
1790         int res = asAny->i + asAny->j + asAny->k;
1791
1792         return res;
1793 }
1794
1795 LIBTEST_API int STDCALL 
1796 mono_test_marshal_asany_inout (void* ptr)
1797 {
1798         AsAnyStruct *asAny = (AsAnyStruct *)ptr;
1799         int res = asAny->i + asAny->j + asAny->k;
1800
1801         marshal_free (asAny->s);
1802
1803         asAny->i = 10;
1804         asAny->j = 20;
1805         asAny->k = 30;
1806         asAny->s = 0;
1807
1808         return res;
1809 }
1810
1811 LIBTEST_API int STDCALL 
1812 mono_test_marshal_asany_out (void* ptr)
1813 {
1814         AsAnyStruct *asAny = (AsAnyStruct *)ptr;
1815         int res = asAny->i + asAny->j + asAny->k;
1816
1817         asAny->i = 10;
1818         asAny->j = 20;
1819         asAny->k = 30;
1820         asAny->s = 0;
1821
1822         return res;
1823 }
1824
1825 /*
1826  * AMD64 marshalling tests.
1827  */
1828
1829 typedef struct amd64_struct1 {
1830         int i;
1831         int j;
1832         int k;
1833         int l;
1834 } amd64_struct1;
1835
1836 LIBTEST_API amd64_struct1 STDCALL 
1837 mono_test_marshal_amd64_pass_return_struct1 (amd64_struct1 s)
1838 {
1839         s.i ++;
1840         s.j ++;
1841         s.k ++;
1842         s.l ++;
1843
1844         return s;
1845 }
1846
1847 LIBTEST_API amd64_struct1 STDCALL 
1848 mono_test_marshal_amd64_pass_return_struct1_many_args (amd64_struct1 s, int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8)
1849 {
1850         s.i ++;
1851         s.j ++;
1852         s.k ++;
1853         s.l += 1 + i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8;
1854
1855         return s;
1856 }
1857
1858 typedef struct amd64_struct2 {
1859         int i;
1860         int j;
1861 } amd64_struct2;
1862
1863 LIBTEST_API amd64_struct2 STDCALL 
1864 mono_test_marshal_amd64_pass_return_struct2 (amd64_struct2 s)
1865 {
1866         s.i ++;
1867         s.j ++;
1868
1869         return s;
1870 }
1871
1872 typedef struct amd64_struct3 {
1873         int i;
1874 } amd64_struct3;
1875
1876 LIBTEST_API amd64_struct3 STDCALL 
1877 mono_test_marshal_amd64_pass_return_struct3 (amd64_struct3 s)
1878 {
1879         s.i ++;
1880
1881         return s;
1882 }
1883
1884 typedef struct amd64_struct4 {
1885         double d1, d2;
1886 } amd64_struct4;
1887
1888 LIBTEST_API amd64_struct4 STDCALL 
1889 mono_test_marshal_amd64_pass_return_struct4 (amd64_struct4 s)
1890 {
1891         s.d1 ++;
1892         s.d2 ++;
1893
1894         return s;
1895 }
1896
1897 /*
1898  * IA64 marshalling tests.
1899  */
1900 typedef struct test_struct5 {
1901         float d1, d2;
1902 } test_struct5;
1903
1904 LIBTEST_API test_struct5 STDCALL 
1905 mono_test_marshal_ia64_pass_return_struct5 (double d1, double d2, test_struct5 s, int i, double d3, double d4)
1906 {
1907         s.d1 += d1 + d2 + i;
1908         s.d2 += d3 + d4 + i;
1909
1910         return s;
1911 }
1912
1913 typedef struct test_struct6 {
1914         double d1, d2;
1915 } test_struct6;
1916
1917 LIBTEST_API test_struct6 STDCALL 
1918 mono_test_marshal_ia64_pass_return_struct6 (double d1, double d2, test_struct6 s, int i, double d3, double d4)
1919 {
1920         s.d1 += d1 + d2 + i;
1921         s.d2 += d3 + d4;
1922
1923         return s;
1924 }
1925
1926 static guint32 custom_res [2];
1927
1928 LIBTEST_API void* STDCALL
1929 mono_test_marshal_pass_return_custom (int i, guint32 *ptr, int j)
1930 {
1931         /* ptr will be freed by CleanupNative, so make a copy */
1932         custom_res [0] = 0; /* not allocated by AllocHGlobal */
1933         custom_res [1] = ptr [1];
1934
1935         return &custom_res;
1936 }
1937
1938 LIBTEST_API int STDCALL 
1939 mono_test_marshal_pass_out_custom (int i, guint32 **ptr, int j)
1940 {
1941         custom_res [0] = 0;
1942         custom_res [1] = i + j + 10;
1943
1944         *ptr = custom_res;
1945
1946         return 0;
1947 }
1948
1949 LIBTEST_API int STDCALL 
1950 mono_test_marshal_pass_inout_custom (int i, guint32 *ptr, int j)
1951 {
1952         ptr [0] = 0;
1953         ptr [1] = i + ptr [1] + j;
1954
1955         return 0;
1956 }
1957
1958 LIBTEST_API int STDCALL 
1959 mono_test_marshal_pass_out_byval_custom (int i, guint32 *ptr, int j)
1960 {
1961         return ptr == NULL ? 0 : 1;
1962 }
1963
1964 LIBTEST_API int STDCALL 
1965 mono_test_marshal_pass_byref_custom (int i, guint32 **ptr, int j)
1966 {
1967         (*ptr)[1] += i + j;
1968
1969         return 0;
1970 }
1971
1972 LIBTEST_API void* STDCALL
1973 mono_test_marshal_pass_return_custom2 (int i, guint32 *ptr, int j)
1974 {
1975         g_assert_not_reached ();
1976
1977         return NULL;
1978 }
1979
1980 LIBTEST_API void* STDCALL
1981 mono_test_marshal_pass_return_custom_null (int i, guint32 *ptr, int j)
1982 {
1983         g_assert (ptr == NULL);
1984
1985         return NULL;
1986 }
1987
1988 typedef void *(STDCALL *PassReturnPtrDelegate) (void *ptr);
1989
1990 LIBTEST_API int STDCALL 
1991 mono_test_marshal_pass_return_custom_in_delegate (PassReturnPtrDelegate del)
1992 {
1993         guint32 buf [2];
1994         guint32 res;
1995         guint32 *ptr;
1996
1997         buf [0] = 0;
1998         buf [1] = 10;
1999
2000         ptr = (guint32 *)del (&buf);
2001
2002         res = ptr [1];
2003
2004 #ifdef WIN32
2005         /* FIXME: Freed with FreeHGlobal */
2006 #else
2007         g_free (ptr);
2008 #endif
2009
2010         return res;
2011 }
2012
2013 LIBTEST_API int STDCALL 
2014 mono_test_marshal_pass_return_custom_null_in_delegate (PassReturnPtrDelegate del)
2015 {
2016         void *ptr = del (NULL);
2017
2018         return (ptr == NULL) ? 15 : 0;
2019 }
2020
2021 typedef void (STDCALL *CustomOutParamDelegate) (void **pptr);
2022
2023 LIBTEST_API int STDCALL 
2024 mono_test_marshal_custom_out_param_delegate (CustomOutParamDelegate del)
2025 {
2026         void* pptr = del;
2027
2028         del (&pptr);
2029
2030         if(pptr != NULL)
2031                 return 1;
2032
2033         return 0;
2034 }
2035
2036 typedef int (STDCALL *ReturnEnumDelegate) (int e);
2037
2038 LIBTEST_API int STDCALL 
2039 mono_test_marshal_return_enum_delegate (ReturnEnumDelegate func)
2040 {
2041         return func (1);
2042 }
2043
2044 typedef struct {
2045         int a, b, c;
2046         gint64 d;
2047 } BlittableStruct;
2048         
2049 typedef BlittableStruct (STDCALL *SimpleDelegate10) (BlittableStruct ss);
2050
2051 LIBTEST_API int STDCALL 
2052 mono_test_marshal_blittable_struct_delegate (SimpleDelegate10 delegate)
2053 {
2054         BlittableStruct ss, res;
2055
2056         ss.a = 1;
2057         ss.b = 2;
2058         ss.c = 3;
2059         ss.d = 55;
2060
2061         res = delegate (ss);
2062         if (! ((res.a == -1) && (res.b == -2) && (res.c == -3) && (res.d == -55)))
2063                 return 1;
2064
2065         return 0;
2066 }
2067
2068 LIBTEST_API int STDCALL 
2069 mono_test_stdcall_name_mangling (int a, int b, int c)
2070 {
2071         return a + b + c;
2072 }
2073
2074 LIBTEST_API int
2075 mono_test_stdcall_mismatch_1 (int a, int b, int c)
2076 {
2077         return a + b + c;
2078 }
2079
2080 LIBTEST_API int STDCALL
2081 mono_test_stdcall_mismatch_2 (int a, int b, int c)
2082 {
2083         return a + b + c;
2084 }
2085
2086 /*
2087  * PASSING AND RETURNING SMALL STRUCTURES FROM DELEGATES TESTS
2088  */
2089
2090 typedef struct {
2091         int i;
2092 } SmallStruct1;
2093         
2094 typedef SmallStruct1 (STDCALL *SmallStructDelegate1) (SmallStruct1 ss);
2095
2096 LIBTEST_API int STDCALL 
2097 mono_test_marshal_small_struct_delegate1 (SmallStructDelegate1 delegate)
2098 {
2099         SmallStruct1 ss, res;
2100
2101         ss.i = 1;
2102
2103         res = delegate (ss);
2104         if (! (res.i == -1))
2105                 return 1;
2106
2107         return 0;
2108 }
2109
2110 typedef struct {
2111         gint16 i, j;
2112 } SmallStruct2;
2113         
2114 typedef SmallStruct2 (STDCALL *SmallStructDelegate2) (SmallStruct2 ss);
2115
2116 LIBTEST_API int STDCALL 
2117 mono_test_marshal_small_struct_delegate2 (SmallStructDelegate2 delegate)
2118 {
2119         SmallStruct2 ss, res;
2120
2121         ss.i = 2;
2122         ss.j = 3;
2123
2124         res = delegate (ss);
2125         if (! ((res.i == -2) && (res.j == -3)))
2126                 return 1;
2127
2128         return 0;
2129 }
2130
2131 typedef struct {
2132         gint16 i;
2133         gint8 j;
2134 } SmallStruct3;
2135         
2136 typedef SmallStruct3 (STDCALL *SmallStructDelegate3) (SmallStruct3 ss);
2137
2138 LIBTEST_API int STDCALL 
2139 mono_test_marshal_small_struct_delegate3 (SmallStructDelegate3 delegate)
2140 {
2141         SmallStruct3 ss, res;
2142
2143         ss.i = 1;
2144         ss.j = 2;
2145
2146         res = delegate (ss);
2147         if (! ((res.i == -1) && (res.j == -2)))
2148                 return 1;
2149
2150         return 0;
2151 }
2152
2153 typedef struct {
2154         gint16 i;
2155 } SmallStruct4;
2156         
2157 typedef SmallStruct4 (STDCALL *SmallStructDelegate4) (SmallStruct4 ss);
2158
2159 LIBTEST_API int STDCALL 
2160 mono_test_marshal_small_struct_delegate4 (SmallStructDelegate4 delegate)
2161 {
2162         SmallStruct4 ss, res;
2163
2164         ss.i = 1;
2165
2166         res = delegate (ss);
2167         if (! (res.i == -1))
2168                 return 1;
2169
2170         return 0;
2171 }
2172
2173 typedef struct {
2174         gint64 i;
2175 } SmallStruct5;
2176         
2177 typedef SmallStruct5 (STDCALL *SmallStructDelegate5) (SmallStruct5 ss);
2178
2179 LIBTEST_API int STDCALL 
2180 mono_test_marshal_small_struct_delegate5 (SmallStructDelegate5 delegate)
2181 {
2182         SmallStruct5 ss, res;
2183
2184         ss.i = 5;
2185
2186         res = delegate (ss);
2187         if (! (res.i == -5))
2188                 return 1;
2189
2190         return 0;
2191 }
2192
2193 typedef struct {
2194         int i, j;
2195 } SmallStruct6;
2196         
2197 typedef SmallStruct6 (STDCALL *SmallStructDelegate6) (SmallStruct6 ss);
2198
2199 LIBTEST_API int STDCALL 
2200 mono_test_marshal_small_struct_delegate6 (SmallStructDelegate6 delegate)
2201 {
2202         SmallStruct6 ss, res;
2203
2204         ss.i = 1;
2205         ss.j = 2;
2206
2207         res = delegate (ss);
2208         if (! ((res.i == -1) && (res.j == -2)))
2209                 return 1;
2210
2211         return 0;
2212 }
2213
2214 typedef struct {
2215         int i;
2216         gint16 j;
2217 } SmallStruct7;
2218         
2219 typedef SmallStruct7 (STDCALL *SmallStructDelegate7) (SmallStruct7 ss);
2220
2221 LIBTEST_API int STDCALL 
2222 mono_test_marshal_small_struct_delegate7 (SmallStructDelegate7 delegate)
2223 {
2224         SmallStruct7 ss, res;
2225
2226         ss.i = 1;
2227         ss.j = 2;
2228
2229         res = delegate (ss);
2230         if (! ((res.i == -1) && (res.j == -2)))
2231                 return 1;
2232
2233         return 0;
2234 }
2235
2236 typedef struct {
2237         float i;
2238 } SmallStruct8;
2239         
2240 typedef SmallStruct8 (STDCALL *SmallStructDelegate8) (SmallStruct8 ss);
2241
2242 LIBTEST_API int STDCALL 
2243 mono_test_marshal_small_struct_delegate8 (SmallStructDelegate8 delegate)
2244 {
2245         SmallStruct8 ss, res;
2246
2247         ss.i = 1.0;
2248
2249         res = delegate (ss);
2250         if (! ((res.i == -1.0)))
2251                 return 1;
2252
2253         return 0;
2254 }
2255
2256 typedef struct {
2257         double i;
2258 } SmallStruct9;
2259         
2260 typedef SmallStruct9 (STDCALL *SmallStructDelegate9) (SmallStruct9 ss);
2261
2262 LIBTEST_API int STDCALL 
2263 mono_test_marshal_small_struct_delegate9 (SmallStructDelegate9 delegate)
2264 {
2265         SmallStruct9 ss, res;
2266
2267         ss.i = 1.0;
2268
2269         res = delegate (ss);
2270         if (! ((res.i == -1.0)))
2271                 return 1;
2272
2273         return 0;
2274 }
2275
2276 typedef struct {
2277         float i, j;
2278 } SmallStruct10;
2279         
2280 typedef SmallStruct10 (STDCALL *SmallStructDelegate10) (SmallStruct10 ss);
2281
2282 LIBTEST_API int STDCALL 
2283 mono_test_marshal_small_struct_delegate10 (SmallStructDelegate10 delegate)
2284 {
2285         SmallStruct10 ss, res;
2286
2287         ss.i = 1.0;
2288         ss.j = 2.0;
2289
2290         res = delegate (ss);
2291         if (! ((res.i == -1.0) && (res.j == -2.0)))
2292                 return 1;
2293
2294         return 0;
2295 }
2296
2297 typedef struct {
2298         float i;
2299         int j;
2300 } SmallStruct11;
2301         
2302 typedef SmallStruct11 (STDCALL *SmallStructDelegate11) (SmallStruct11 ss);
2303
2304 LIBTEST_API int STDCALL 
2305 mono_test_marshal_small_struct_delegate11 (SmallStructDelegate11 delegate)
2306 {
2307         SmallStruct11 ss, res;
2308
2309         ss.i = 1.0;
2310         ss.j = 2;
2311
2312         res = delegate (ss);
2313         if (! ((res.i == -1.0) && (res.j == -2)))
2314                 return 1;
2315
2316         return 0;
2317 }
2318
2319 typedef int (STDCALL *ArrayDelegate) (int i, char *j, void *arr);
2320
2321 LIBTEST_API int STDCALL 
2322 mono_test_marshal_array_delegate (void *arr, int len, ArrayDelegate del)
2323 {
2324         return del (len, NULL, arr);
2325 }
2326
2327 typedef int (STDCALL *ArrayDelegateLong) (gint64 i, char *j, void *arr);
2328
2329 LIBTEST_API int STDCALL 
2330 mono_test_marshal_array_delegate_long (void *arr, gint64 len, ArrayDelegateLong del)
2331 {
2332         return del (len, NULL, arr);
2333 }
2334
2335 LIBTEST_API int STDCALL 
2336 mono_test_marshal_out_array_delegate (int *arr, int len, ArrayDelegate del)
2337 {
2338         del (len, NULL, arr);
2339
2340         if ((arr [0] != 1) || (arr [1] != 2))
2341                 return 1;
2342         else
2343                 return 0;
2344 }
2345
2346 typedef gunichar2* (STDCALL *UnicodeStringDelegate) (gunichar2 *message);
2347
2348 LIBTEST_API int STDCALL 
2349 mono_test_marshal_return_unicode_string_delegate (UnicodeStringDelegate del)
2350 {
2351         const char m[] = "abcdef";
2352         gunichar2 *s2, *res;
2353         glong len;
2354
2355         s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
2356
2357         res = del (s2);
2358
2359         marshal_free (res);
2360
2361         return 0;
2362 }
2363
2364 LIBTEST_API int STDCALL 
2365 mono_test_marshal_out_string_array_delegate (char **arr, int len, ArrayDelegate del)
2366 {
2367         del (len, NULL, arr);
2368
2369         if (!strcmp (arr [0], "ABC") && !strcmp (arr [1], "DEF"))
2370                 return 0;
2371         else
2372                 return 1;
2373 }
2374
2375 typedef int (*CdeclDelegate) (int i, int j);
2376
2377 LIBTEST_API int STDCALL 
2378 mono_test_marshal_cdecl_delegate (CdeclDelegate del)
2379 {
2380         int i;
2381
2382         for (i = 0; i < 1000; ++i)
2383                 del (1, 2);
2384
2385         return 0;
2386 }
2387
2388 typedef char** (STDCALL *ReturnStringArrayDelegate) (int i);
2389
2390 LIBTEST_API int STDCALL 
2391 mono_test_marshal_return_string_array_delegate (ReturnStringArrayDelegate d)
2392 {
2393         char **arr = d (2);
2394         int res;
2395
2396         if (arr == NULL)
2397                 return 3;
2398
2399         if (strcmp (arr [0], "ABC") || strcmp (arr [1], "DEF"))
2400                 res = 1;
2401         else
2402                 res = 0;
2403
2404         marshal_free (arr);
2405
2406         return res;
2407 }
2408
2409 typedef int (STDCALL *ByrefStringDelegate) (char **s);
2410
2411 LIBTEST_API int STDCALL 
2412 mono_test_marshal_byref_string_delegate (ByrefStringDelegate d)
2413 {
2414         char *s = (char*)"ABC";
2415         int res;
2416
2417         res = d (&s);
2418         if (res != 0)
2419                 return res;
2420
2421         if (!strcmp (s, "DEF"))
2422                 res = 0;
2423         else
2424                 res = 2;
2425
2426         marshal_free (s);
2427
2428         return res;
2429 }
2430
2431 LIBTEST_API int STDCALL 
2432 add_delegate (int i, int j)
2433 {
2434         return i + j;
2435 }
2436
2437 LIBTEST_API gpointer STDCALL 
2438 mono_test_marshal_return_fnptr (void)
2439 {
2440         return &add_delegate;
2441 }
2442
2443 LIBTEST_API int STDCALL 
2444 mono_xr (int code)
2445 {
2446         printf ("codigo %x\n", code);
2447         return code + 1234;
2448 }
2449
2450 typedef struct {
2451         int handle;
2452 } HandleRef;
2453
2454 LIBTEST_API HandleRef STDCALL 
2455 mono_xr_as_handle (int code)
2456 {
2457         HandleRef ref;
2458
2459         memset (&ref, 0, sizeof (ref));
2460
2461         return ref;
2462 }
2463  
2464 typedef struct {
2465         int   a;
2466         void *handle1;
2467         void *handle2;
2468         int   b;
2469 } HandleStructs;
2470
2471 LIBTEST_API int STDCALL 
2472 mono_safe_handle_struct_ref (HandleStructs *x)
2473 {
2474         printf ("Dingus Ref! \n");
2475         printf ("Values: %d %d %p %p\n", x->a, x->b, x->handle1, x->handle2);
2476         if (x->a != 1234)
2477                 return 1;
2478         if (x->b != 8743)
2479                 return 2;
2480
2481         if (x->handle1 != (void*) 0x7080feed)
2482                 return 3;
2483
2484         if (x->handle2 != (void*) 0x1234abcd)
2485                 return 4;
2486
2487         return 0xf00d;
2488 }
2489
2490 LIBTEST_API int STDCALL 
2491 mono_safe_handle_struct (HandleStructs x)
2492 {
2493         printf ("Dingus Standard! \n");
2494         printf ("Values: %d %d %p %p\n", x.a, x.b, x.handle1, x.handle2);
2495         if (x.a != 1234)
2496                 return 1;
2497         if (x.b != 8743)
2498                 return 2;
2499
2500         if (x.handle1 != (void*) 0x7080feed)
2501                 return 3;
2502
2503         if (x.handle2 != (void*) 0x1234abcd)
2504                 return 4;
2505         
2506         return 0xf00f;
2507 }
2508
2509 typedef struct {
2510         void *a;
2511 } TrivialHandle;
2512
2513 LIBTEST_API int STDCALL 
2514 mono_safe_handle_struct_simple (TrivialHandle x)
2515 {
2516         printf ("The value is %p\n", x.a);
2517         return ((int)(gsize)x.a) * 2;
2518 }
2519
2520 LIBTEST_API int STDCALL 
2521 mono_safe_handle_return (void)
2522 {
2523         return 0x1000f00d;
2524 }
2525
2526 LIBTEST_API void STDCALL
2527 mono_safe_handle_ref (void **handle)
2528 {
2529         if (*handle != 0){
2530                 *handle = (void *) 0xbad;
2531                 return;
2532         }
2533
2534         *handle = (void *) 0x800d;
2535 }
2536
2537 LIBTEST_API double STDCALL
2538 mono_test_marshal_date_time (double d, double *d2)
2539 {
2540         *d2 = d;
2541         return d;
2542 }
2543
2544 /*
2545  * COM INTEROP TESTS
2546  */
2547
2548 #ifndef WIN32
2549
2550 typedef struct {
2551         guint16 vt;
2552         guint16 wReserved1;
2553         guint16 wReserved2;
2554         guint16 wReserved3;
2555         union {
2556                 gint64 llVal;
2557                 gint32 lVal;
2558                 guint8  bVal;
2559                 gint16 iVal;
2560                 float  fltVal;
2561                 double dblVal;
2562                 gint16 boolVal;
2563                 gunichar2* bstrVal;
2564                 gint8 cVal;
2565                 guint16 uiVal;
2566                 guint32 ulVal;
2567                 guint64 ullVal;
2568                 gpointer byref;
2569                 struct {
2570                         gpointer pvRecord;
2571                         gpointer pRecInfo;
2572                 };
2573         };
2574 } VARIANT;
2575
2576 typedef enum {
2577         VARIANT_TRUE = -1,
2578         VARIANT_FALSE = 0
2579 } VariantBool;
2580
2581 typedef enum {
2582         VT_EMPTY = 0,
2583         VT_NULL = 1,
2584         VT_I2 = 2,
2585         VT_I4 = 3,
2586         VT_R4 = 4,
2587         VT_R8 = 5,
2588         VT_CY = 6,
2589         VT_DATE = 7,
2590         VT_BSTR = 8,
2591         VT_DISPATCH = 9,
2592         VT_ERROR = 10,
2593         VT_BOOL = 11,
2594         VT_VARIANT = 12,
2595         VT_UNKNOWN = 13,
2596         VT_DECIMAL = 14,
2597         VT_I1 = 16,
2598         VT_UI1 = 17,
2599         VT_UI2 = 18,
2600         VT_UI4 = 19,
2601         VT_I8 = 20,
2602         VT_UI8 = 21,
2603         VT_INT = 22,
2604         VT_UINT = 23,
2605         VT_VOID = 24,
2606         VT_HRESULT = 25,
2607         VT_PTR = 26,
2608         VT_SAFEARRAY = 27,
2609         VT_CARRAY = 28,
2610         VT_USERDEFINED = 29,
2611         VT_LPSTR = 30,
2612         VT_LPWSTR = 31,
2613         VT_RECORD = 36,
2614         VT_FILETIME = 64,
2615         VT_BLOB = 65,
2616         VT_STREAM = 66,
2617         VT_STORAGE = 67,
2618         VT_STREAMED_OBJECT = 68,
2619         VT_STORED_OBJECT = 69,
2620         VT_BLOB_OBJECT = 70,
2621         VT_CF = 71,
2622         VT_CLSID = 72,
2623         VT_VECTOR = 4096,
2624         VT_ARRAY = 8192,
2625         VT_BYREF = 16384
2626 } VarEnum;
2627
2628 void VariantInit(VARIANT* vt)
2629 {
2630         vt->vt = VT_EMPTY;
2631 }
2632
2633 typedef struct
2634 {
2635         guint32 a;
2636         guint16 b;
2637         guint16 c;
2638         guint8 d[8];
2639 } GUID;
2640
2641 #define S_OK 0
2642
2643 #endif
2644
2645 LIBTEST_API int STDCALL 
2646 mono_test_marshal_bstr_in(gunichar2* bstr)
2647 {
2648         gint32 result = 0;
2649         gchar* bstr_utf8 = g_utf16_to_utf8 (bstr, -1, NULL, NULL, NULL);
2650         result = strcmp("mono_test_marshal_bstr_in", bstr_utf8);
2651         g_free(bstr_utf8);
2652         if (result == 0)
2653                 return 0;
2654         return 1;
2655 }
2656
2657 LIBTEST_API int STDCALL 
2658 mono_test_marshal_bstr_out(gunichar2** bstr)
2659 {
2660         *bstr = marshal_bstr_alloc ("mono_test_marshal_bstr_out");
2661         return 0;
2662 }
2663
2664 LIBTEST_API int STDCALL 
2665 mono_test_marshal_bstr_in_null(gunichar2* bstr)
2666 {
2667         if (!bstr)
2668                 return 0;
2669         return 1;
2670 }
2671
2672 LIBTEST_API int STDCALL 
2673 mono_test_marshal_bstr_out_null(gunichar2** bstr)
2674 {
2675         *bstr = NULL;
2676         return 0;
2677 }
2678
2679 LIBTEST_API int STDCALL 
2680 mono_test_marshal_variant_in_sbyte(VARIANT variant)
2681 {
2682         if (variant.vt == VT_I1 && variant.cVal == 100)
2683                 return 0;
2684         return 1;
2685 }
2686
2687 LIBTEST_API int STDCALL 
2688 mono_test_marshal_variant_in_byte(VARIANT variant)
2689 {
2690         if (variant.vt == VT_UI1 && variant.bVal == 100)
2691                 return 0;
2692         return 1;
2693 }
2694
2695 LIBTEST_API int STDCALL 
2696 mono_test_marshal_variant_in_short(VARIANT variant)
2697 {
2698         if (variant.vt == VT_I2 && variant.iVal == 314)
2699                 return 0;
2700         return 1;
2701 }
2702
2703 LIBTEST_API int STDCALL 
2704 mono_test_marshal_variant_in_ushort(VARIANT variant)
2705 {
2706         if (variant.vt == VT_UI2 && variant.uiVal == 314)
2707                 return 0;
2708         return 1;
2709 }
2710
2711 LIBTEST_API int STDCALL 
2712 mono_test_marshal_variant_in_int(VARIANT variant)
2713 {
2714         if (variant.vt == VT_I4 && variant.lVal == 314)
2715                 return 0;
2716         return 1;
2717 }
2718
2719 LIBTEST_API int STDCALL 
2720 mono_test_marshal_variant_in_uint(VARIANT variant)
2721 {
2722         if (variant.vt == VT_UI4 && variant.ulVal == 314)
2723                 return 0;
2724         return 1;
2725 }
2726
2727 LIBTEST_API int STDCALL 
2728 mono_test_marshal_variant_in_long(VARIANT variant)
2729 {
2730         if (variant.vt == VT_I8 && variant.llVal == 314)
2731                 return 0;
2732         return 1;
2733 }
2734
2735 LIBTEST_API int STDCALL 
2736 mono_test_marshal_variant_in_ulong(VARIANT variant)
2737 {
2738         if (variant.vt == VT_UI8 && variant.ullVal == 314)
2739                 return 0;
2740         return 1;
2741 }
2742
2743 LIBTEST_API int STDCALL 
2744 mono_test_marshal_variant_in_float(VARIANT variant)
2745 {
2746         if (variant.vt == VT_R4 && (variant.fltVal - 3.14)/3.14 < .001)
2747                 return 0;
2748         return 1;
2749 }
2750
2751 LIBTEST_API int STDCALL 
2752 mono_test_marshal_variant_in_double(VARIANT variant)
2753 {
2754         if (variant.vt == VT_R8 && (variant.dblVal - 3.14)/3.14 < .001)
2755                 return 0;
2756         return 1;
2757 }
2758
2759 LIBTEST_API int STDCALL 
2760 mono_test_marshal_variant_in_bstr(VARIANT variant)
2761 {
2762         gint32 result = 0;
2763         gchar* bstr_utf8 = g_utf16_to_utf8 (variant.bstrVal, -1, NULL, NULL, NULL);
2764         result = strcmp("PI", bstr_utf8);
2765         g_free(bstr_utf8);
2766
2767         if (variant.vt == VT_BSTR && !result)
2768                 return 0;
2769         return 1;
2770 }
2771
2772 LIBTEST_API int STDCALL 
2773 mono_test_marshal_variant_in_bool_true (VARIANT variant)
2774 {
2775         if (variant.vt == VT_BOOL && variant.boolVal == VARIANT_TRUE)
2776                 return 0;
2777         return 1;
2778 }
2779
2780 LIBTEST_API int STDCALL 
2781 mono_test_marshal_variant_in_bool_false (VARIANT variant)
2782 {
2783         if (variant.vt == VT_BOOL && variant.boolVal == VARIANT_FALSE)
2784                 return 0;
2785         return 1;
2786 }
2787
2788 LIBTEST_API int STDCALL 
2789 mono_test_marshal_variant_out_sbyte(VARIANT* variant)
2790 {
2791         variant->vt = VT_I1;
2792         variant->cVal = 100;
2793
2794         return 0;
2795 }
2796
2797 LIBTEST_API int STDCALL 
2798 mono_test_marshal_variant_out_sbyte_byref(VARIANT* variant)
2799 {
2800         variant->vt = VT_I1|VT_BYREF;
2801         variant->byref = marshal_alloc(1);
2802         *((gint8*)variant->byref) = 100;
2803
2804         return 0;
2805 }
2806
2807 LIBTEST_API int STDCALL 
2808 mono_test_marshal_variant_out_byte(VARIANT* variant)
2809 {       
2810         variant->vt = VT_UI1;
2811         variant->bVal = 100;
2812
2813         return 0;
2814 }
2815
2816 LIBTEST_API int STDCALL 
2817 mono_test_marshal_variant_out_byte_byref(VARIANT* variant)
2818 {       
2819         variant->vt = VT_UI1|VT_BYREF;
2820         variant->byref = marshal_alloc(1);
2821         *((gint8*)variant->byref) = 100;
2822
2823         return 0;
2824 }
2825
2826 LIBTEST_API int STDCALL 
2827 mono_test_marshal_variant_out_short(VARIANT* variant)
2828 {
2829         variant->vt = VT_I2;
2830         variant->iVal = 314;
2831
2832         return 0;
2833 }
2834
2835 LIBTEST_API int STDCALL 
2836 mono_test_marshal_variant_out_short_byref(VARIANT* variant)
2837 {
2838         variant->vt = VT_I2|VT_BYREF;
2839         variant->byref = marshal_alloc(2);
2840         *((gint16*)variant->byref) = 314;
2841
2842         return 0;
2843 }
2844
2845 LIBTEST_API int STDCALL 
2846 mono_test_marshal_variant_out_ushort(VARIANT* variant)
2847 {
2848         variant->vt = VT_UI2;
2849         variant->uiVal = 314;
2850
2851         return 0;
2852 }
2853
2854 LIBTEST_API int STDCALL 
2855 mono_test_marshal_variant_out_ushort_byref(VARIANT* variant)
2856 {
2857         variant->vt = VT_UI2|VT_BYREF;
2858         variant->byref = marshal_alloc(2);
2859         *((guint16*)variant->byref) = 314;
2860
2861         return 0;
2862 }
2863
2864 LIBTEST_API int STDCALL 
2865 mono_test_marshal_variant_out_int(VARIANT* variant)
2866 {
2867         variant->vt = VT_I4;
2868         variant->lVal = 314;
2869
2870         return 0;
2871 }
2872
2873 LIBTEST_API int STDCALL 
2874 mono_test_marshal_variant_out_int_byref(VARIANT* variant)
2875 {
2876         variant->vt = VT_I4|VT_BYREF;
2877         variant->byref = marshal_alloc(4);
2878         *((gint32*)variant->byref) = 314;
2879
2880         return 0;
2881 }
2882
2883 LIBTEST_API int STDCALL 
2884 mono_test_marshal_variant_out_uint(VARIANT* variant)
2885 {
2886         variant->vt = VT_UI4;
2887         variant->ulVal = 314;
2888
2889         return 0;
2890 }
2891
2892 LIBTEST_API int STDCALL 
2893 mono_test_marshal_variant_out_uint_byref(VARIANT* variant)
2894 {
2895         variant->vt = VT_UI4|VT_BYREF;
2896         variant->byref = marshal_alloc(4);
2897         *((guint32*)variant->byref) = 314;
2898
2899         return 0;
2900 }
2901
2902 LIBTEST_API int STDCALL 
2903 mono_test_marshal_variant_out_long(VARIANT* variant)
2904 {
2905         variant->vt = VT_I8;
2906         variant->llVal = 314;
2907
2908         return 0;
2909 }
2910
2911 LIBTEST_API int STDCALL 
2912 mono_test_marshal_variant_out_long_byref(VARIANT* variant)
2913 {
2914         variant->vt = VT_I8|VT_BYREF;
2915         variant->byref = marshal_alloc(8);
2916         *((gint64*)variant->byref) = 314;
2917
2918         return 0;
2919 }
2920
2921 LIBTEST_API int STDCALL 
2922 mono_test_marshal_variant_out_ulong(VARIANT* variant)
2923 {
2924         variant->vt = VT_UI8;
2925         variant->ullVal = 314;
2926
2927         return 0;
2928 }
2929
2930 LIBTEST_API int STDCALL 
2931 mono_test_marshal_variant_out_ulong_byref(VARIANT* variant)
2932 {
2933         variant->vt = VT_UI8|VT_BYREF;
2934         variant->byref = marshal_alloc(8);
2935         *((guint64*)variant->byref) = 314;
2936
2937         return 0;
2938 }
2939
2940 LIBTEST_API int STDCALL 
2941 mono_test_marshal_variant_out_float(VARIANT* variant)
2942 {
2943         variant->vt = VT_R4;
2944         variant->fltVal = 3.14;
2945
2946         return 0;
2947 }
2948
2949 LIBTEST_API int STDCALL 
2950 mono_test_marshal_variant_out_float_byref(VARIANT* variant)
2951 {
2952         variant->vt = VT_R4|VT_BYREF;
2953         variant->byref = marshal_alloc(4);
2954         *((float*)variant->byref) = 3.14;
2955
2956         return 0;
2957 }
2958
2959 LIBTEST_API int STDCALL 
2960 mono_test_marshal_variant_out_double(VARIANT* variant)
2961 {
2962         variant->vt = VT_R8;
2963         variant->dblVal = 3.14;
2964
2965         return 0;
2966 }
2967
2968 LIBTEST_API int STDCALL 
2969 mono_test_marshal_variant_out_double_byref(VARIANT* variant)
2970 {
2971         variant->vt = VT_R8|VT_BYREF;
2972         variant->byref = marshal_alloc(8);
2973         *((double*)variant->byref) = 3.14;
2974
2975         return 0;
2976 }
2977
2978 LIBTEST_API int STDCALL 
2979 mono_test_marshal_variant_out_bstr(VARIANT* variant)
2980 {
2981         variant->vt = VT_BSTR;
2982         variant->bstrVal = marshal_bstr_alloc("PI");
2983
2984         return 0;
2985 }
2986
2987 LIBTEST_API int STDCALL 
2988 mono_test_marshal_variant_out_bstr_byref(VARIANT* variant)
2989 {
2990         variant->vt = VT_BSTR|VT_BYREF;
2991         variant->byref = marshal_alloc(sizeof(gpointer));
2992         *((gunichar**)variant->byref) = (gunichar*)marshal_bstr_alloc("PI");
2993
2994         return 0;
2995 }
2996
2997 LIBTEST_API int STDCALL 
2998 mono_test_marshal_variant_out_bool_true (VARIANT* variant)
2999 {
3000         variant->vt = VT_BOOL;
3001         variant->boolVal = VARIANT_TRUE;
3002
3003         return 0;
3004 }
3005
3006 LIBTEST_API int STDCALL 
3007 mono_test_marshal_variant_out_bool_true_byref (VARIANT* variant)
3008 {
3009         variant->vt = VT_BOOL|VT_BYREF;
3010         variant->byref = marshal_alloc(2);
3011         *((gint16*)variant->byref) = VARIANT_TRUE;
3012
3013         return 0;
3014 }
3015
3016 LIBTEST_API int STDCALL 
3017 mono_test_marshal_variant_out_bool_false (VARIANT* variant)
3018 {
3019         variant->vt = VT_BOOL;
3020         variant->boolVal = VARIANT_FALSE;
3021
3022         return 0;
3023 }
3024
3025 LIBTEST_API int STDCALL 
3026 mono_test_marshal_variant_out_bool_false_byref (VARIANT* variant)
3027 {
3028         variant->vt = VT_BOOL|VT_BYREF;
3029         variant->byref = marshal_alloc(2);
3030         *((gint16*)variant->byref) = VARIANT_FALSE;
3031
3032         return 0;
3033 }
3034
3035 typedef int (STDCALL *VarFunc) (int vt, VARIANT variant);
3036 typedef int (STDCALL *VarRefFunc) (int vt, VARIANT* variant);
3037
3038 LIBTEST_API int STDCALL 
3039 mono_test_marshal_variant_in_sbyte_unmanaged(VarFunc func)
3040 {
3041         VARIANT vt;
3042         vt.vt = VT_I1;
3043         vt.cVal = -100;
3044         return func (VT_I1, vt);
3045 }
3046
3047 LIBTEST_API int STDCALL 
3048 mono_test_marshal_variant_in_byte_unmanaged(VarFunc func)
3049 {
3050         VARIANT vt;
3051         vt.vt = VT_UI1;
3052         vt.bVal = 100;
3053         return func (VT_UI1, vt);
3054 }
3055
3056 LIBTEST_API int STDCALL 
3057 mono_test_marshal_variant_in_short_unmanaged(VarFunc func)
3058 {
3059         VARIANT vt;
3060         vt.vt = VT_I2;
3061         vt.iVal = -100;
3062         return func (VT_I2, vt);
3063 }
3064
3065 LIBTEST_API int STDCALL 
3066 mono_test_marshal_variant_in_ushort_unmanaged(VarFunc func)
3067 {
3068         VARIANT vt;
3069         vt.vt = VT_UI2;
3070         vt.uiVal = 100;
3071         return func (VT_UI2, vt);
3072 }
3073
3074 LIBTEST_API int STDCALL 
3075 mono_test_marshal_variant_in_int_unmanaged(VarFunc func)
3076 {
3077         VARIANT vt;
3078         vt.vt = VT_I4;
3079         vt.lVal = -100;
3080         return func (VT_I4, vt);
3081 }
3082
3083 LIBTEST_API int STDCALL 
3084 mono_test_marshal_variant_in_uint_unmanaged(VarFunc func)
3085 {
3086         VARIANT vt;
3087         vt.vt = VT_UI4;
3088         vt.ulVal = 100;
3089         return func (VT_UI4, vt);
3090 }
3091
3092 LIBTEST_API int STDCALL 
3093 mono_test_marshal_variant_in_long_unmanaged(VarFunc func)
3094 {
3095         VARIANT vt;
3096         vt.vt = VT_I8;
3097         vt.llVal = -100;
3098         return func (VT_I8, vt);
3099 }
3100
3101 LIBTEST_API int STDCALL 
3102 mono_test_marshal_variant_in_ulong_unmanaged(VarFunc func)
3103 {
3104         VARIANT vt;
3105         vt.vt = VT_UI8;
3106         vt.ullVal = 100;
3107         return func (VT_UI8, vt);
3108 }
3109
3110 LIBTEST_API int STDCALL 
3111 mono_test_marshal_variant_in_float_unmanaged(VarFunc func)
3112 {
3113         VARIANT vt;
3114         vt.vt = VT_R4;
3115         vt.fltVal = 3.14;
3116         return func (VT_R4, vt);
3117 }
3118
3119 LIBTEST_API int STDCALL 
3120 mono_test_marshal_variant_in_double_unmanaged(VarFunc func)
3121 {
3122         VARIANT vt;
3123         vt.vt = VT_R8;
3124         vt.dblVal = 3.14;
3125         return func (VT_R8, vt);
3126 }
3127
3128 LIBTEST_API int STDCALL 
3129 mono_test_marshal_variant_in_bstr_unmanaged(VarFunc func)
3130 {
3131         VARIANT vt;
3132         vt.vt = VT_BSTR;
3133         vt.bstrVal = marshal_bstr_alloc("PI");
3134         return func (VT_BSTR, vt);
3135 }
3136
3137 LIBTEST_API int STDCALL 
3138 mono_test_marshal_variant_in_bool_true_unmanaged(VarFunc func)
3139 {
3140         VARIANT vt;
3141         vt.vt = VT_BOOL;
3142         vt.boolVal = VARIANT_TRUE;
3143         return func (VT_BOOL, vt);
3144 }
3145
3146 LIBTEST_API int STDCALL 
3147 mono_test_marshal_variant_in_bool_false_unmanaged(VarFunc func)
3148 {
3149         VARIANT vt;
3150         vt.vt = VT_BOOL;
3151         vt.boolVal = VARIANT_FALSE;
3152         return func (VT_BOOL, vt);
3153 }
3154
3155 LIBTEST_API int STDCALL 
3156 mono_test_marshal_variant_out_sbyte_unmanaged(VarRefFunc func)
3157 {
3158         VARIANT vt;
3159         VariantInit (&vt);
3160         func (VT_I1, &vt);
3161         if (vt.vt == VT_I1 && vt.cVal == -100)
3162                 return 0;
3163         return 1;
3164 }
3165
3166 LIBTEST_API int STDCALL 
3167 mono_test_marshal_variant_out_byte_unmanaged(VarRefFunc func)
3168 {
3169         VARIANT vt;
3170         VariantInit (&vt);
3171         func (VT_UI1, &vt);
3172         if (vt.vt == VT_UI1 && vt.bVal == 100)
3173                 return 0;
3174         return 1;
3175 }
3176
3177 LIBTEST_API int STDCALL 
3178 mono_test_marshal_variant_out_short_unmanaged(VarRefFunc func)
3179 {
3180         VARIANT vt;
3181         VariantInit (&vt);
3182         func (VT_I2, &vt);
3183         if (vt.vt == VT_I2 && vt.iVal == -100)
3184                 return 0;
3185         return 1;
3186 }
3187
3188 LIBTEST_API int STDCALL 
3189 mono_test_marshal_variant_out_ushort_unmanaged(VarRefFunc func)
3190 {
3191         VARIANT vt;
3192         VariantInit (&vt);
3193         func (VT_UI2, &vt);
3194         if (vt.vt == VT_UI2 && vt.uiVal == 100)
3195                 return 0;
3196         return 1;
3197 }
3198
3199 LIBTEST_API int STDCALL 
3200 mono_test_marshal_variant_out_int_unmanaged(VarRefFunc func)
3201 {
3202         VARIANT vt;
3203         VariantInit (&vt);
3204         func (VT_I4, &vt);
3205         if (vt.vt == VT_I4 && vt.lVal == -100)
3206                 return 0;
3207         return 1;
3208 }
3209
3210 LIBTEST_API int STDCALL 
3211 mono_test_marshal_variant_out_uint_unmanaged(VarRefFunc func)
3212 {
3213         VARIANT vt;
3214         VariantInit (&vt);
3215         func (VT_UI4, &vt);
3216         if (vt.vt == VT_UI4 && vt.ulVal == 100)
3217                 return 0;
3218         return 1;
3219 }
3220
3221 LIBTEST_API int STDCALL 
3222 mono_test_marshal_variant_out_long_unmanaged(VarRefFunc func)
3223 {
3224         VARIANT vt;
3225         VariantInit (&vt);
3226         func (VT_I8, &vt);
3227         if (vt.vt == VT_I8 && vt.llVal == -100)
3228                 return 0;
3229         return 1;
3230 }
3231
3232 LIBTEST_API int STDCALL 
3233 mono_test_marshal_variant_out_ulong_unmanaged(VarRefFunc func)
3234 {
3235         VARIANT vt;
3236         VariantInit (&vt);
3237         func (VT_UI8, &vt);
3238         if (vt.vt == VT_UI8 && vt.ullVal == 100)
3239                 return 0;
3240         return 1;
3241 }
3242
3243 LIBTEST_API int STDCALL 
3244 mono_test_marshal_variant_out_float_unmanaged(VarRefFunc func)
3245 {
3246         VARIANT vt;
3247         VariantInit (&vt);
3248         func (VT_R4, &vt);
3249         if (vt.vt == VT_R4 && fabs (vt.fltVal - 3.14f) < 1e-10)
3250                 return 0;
3251         return 1;
3252 }
3253
3254 LIBTEST_API int STDCALL 
3255 mono_test_marshal_variant_out_double_unmanaged(VarRefFunc func)
3256 {
3257         VARIANT vt;
3258         VariantInit (&vt);
3259         func (VT_R8, &vt);
3260         if (vt.vt == VT_R8 && fabs (vt.dblVal - 3.14) < 1e-10)
3261                 return 0;
3262         return 1;
3263 }
3264
3265 LIBTEST_API int STDCALL 
3266 mono_test_marshal_variant_out_bstr_unmanaged(VarRefFunc func)
3267 {
3268         VARIANT vt;
3269         gchar* bstr_utf8;
3270         gint32 result = 0;
3271
3272
3273         VariantInit (&vt);
3274         func (VT_BSTR, &vt);
3275         bstr_utf8 = g_utf16_to_utf8 (vt.bstrVal, -1, NULL, NULL, NULL);
3276         result = strcmp("PI", bstr_utf8);
3277         g_free(bstr_utf8);
3278         if (vt.vt == VT_BSTR && !result)
3279                 return 0;
3280         return 1;
3281 }
3282
3283 LIBTEST_API int STDCALL 
3284 mono_test_marshal_variant_out_bool_true_unmanaged(VarRefFunc func)
3285 {
3286         VARIANT vt;
3287         VariantInit (&vt);
3288         func (VT_BOOL, &vt);
3289         if (vt.vt == VT_BOOL && vt.boolVal == VARIANT_TRUE)
3290                 return 0;
3291         return 1;
3292 }
3293
3294 LIBTEST_API int STDCALL 
3295 mono_test_marshal_variant_out_bool_false_unmanaged(VarRefFunc func)
3296 {
3297         VARIANT vt;
3298         VariantInit (&vt);
3299         func (VT_BOOL, &vt);
3300         if (vt.vt == VT_BOOL && vt.boolVal == VARIANT_TRUE)
3301                 return 0;
3302         return 1;
3303 }
3304
3305 typedef struct MonoComObject MonoComObject;
3306
3307 typedef struct
3308 {
3309         int (STDCALL *QueryInterface)(MonoComObject* pUnk, gpointer riid, gpointer* ppv);
3310         int (STDCALL *AddRef)(MonoComObject* pUnk);
3311         int (STDCALL *Release)(MonoComObject* pUnk);
3312         int (STDCALL *get_ITest)(MonoComObject* pUnk, MonoComObject* *ppUnk);
3313         int (STDCALL *SByteIn)(MonoComObject* pUnk, char a);
3314         int (STDCALL *ByteIn)(MonoComObject* pUnk, unsigned char a);
3315         int (STDCALL *ShortIn)(MonoComObject* pUnk, short a);
3316         int (STDCALL *UShortIn)(MonoComObject* pUnk, unsigned short a);
3317         int (STDCALL *IntIn)(MonoComObject* pUnk, int a);
3318         int (STDCALL *UIntIn)(MonoComObject* pUnk, unsigned int a);
3319         int (STDCALL *LongIn)(MonoComObject* pUnk, gint64 a);
3320         int (STDCALL *ULongIn)(MonoComObject* pUnk, guint64 a);
3321         int (STDCALL *FloatIn)(MonoComObject* pUnk, float a);
3322         int (STDCALL *DoubleIn)(MonoComObject* pUnk, double a);
3323         int (STDCALL *ITestIn)(MonoComObject* pUnk, MonoComObject* pUnk2);
3324         int (STDCALL *ITestOut)(MonoComObject* pUnk, MonoComObject* *ppUnk);
3325 } MonoIUnknown;
3326
3327 struct MonoComObject
3328 {
3329         MonoIUnknown* vtbl;
3330         int m_ref;
3331 };
3332
3333 static GUID IID_ITest = {0, 0, 0, {0,0,0,0,0,0,0,1}};
3334 static GUID IID_IMonoUnknown = {0, 0, 0, {0xc0,0,0,0,0,0,0,0x46}};
3335 static GUID IID_IMonoDispatch = {0x00020400, 0, 0, {0xc0,0,0,0,0,0,0,0x46}};
3336
3337 LIBTEST_API int STDCALL
3338 MonoQueryInterface(MonoComObject* pUnk, gpointer riid, gpointer* ppv)
3339 {
3340
3341         *ppv = NULL;
3342         if (!memcmp(riid, &IID_IMonoUnknown, sizeof(GUID))) {
3343                 *ppv = pUnk;
3344                 return S_OK;
3345         }
3346         else if (!memcmp(riid, &IID_ITest, sizeof(GUID))) {
3347                 *ppv = pUnk;
3348                 return S_OK;
3349         }
3350         else if (!memcmp(riid, &IID_IMonoDispatch, sizeof(GUID))) {
3351                 *ppv = pUnk;
3352                 return S_OK;
3353         }
3354         return 0x80004002; //E_NOINTERFACE;
3355 }
3356
3357 LIBTEST_API int STDCALL 
3358 MonoAddRef(MonoComObject* pUnk)
3359 {
3360         return ++(pUnk->m_ref);
3361 }
3362
3363 LIBTEST_API int STDCALL 
3364 MonoRelease(MonoComObject* pUnk)
3365 {
3366         return --(pUnk->m_ref);
3367 }
3368
3369 LIBTEST_API int STDCALL 
3370 SByteIn(MonoComObject* pUnk, char a)
3371 {
3372         return S_OK;
3373 }
3374
3375 LIBTEST_API int STDCALL 
3376 ByteIn(MonoComObject* pUnk, unsigned char a)
3377 {
3378         return S_OK;
3379 }
3380
3381 LIBTEST_API int STDCALL 
3382 ShortIn(MonoComObject* pUnk, short a)
3383 {
3384         return S_OK;
3385 }
3386
3387 LIBTEST_API int STDCALL 
3388 UShortIn(MonoComObject* pUnk, unsigned short a)
3389 {
3390         return S_OK;
3391 }
3392
3393 LIBTEST_API int STDCALL 
3394 IntIn(MonoComObject* pUnk, int a)
3395 {
3396         return S_OK;
3397 }
3398
3399 LIBTEST_API int STDCALL 
3400 UIntIn(MonoComObject* pUnk, unsigned int a)
3401 {
3402         return S_OK;
3403 }
3404
3405 LIBTEST_API int STDCALL 
3406 LongIn(MonoComObject* pUnk, gint64 a)
3407 {
3408         return S_OK;
3409 }
3410
3411 LIBTEST_API int STDCALL 
3412 ULongIn(MonoComObject* pUnk, guint64 a)
3413 {
3414         return S_OK;
3415 }
3416
3417 LIBTEST_API int STDCALL 
3418 FloatIn(MonoComObject* pUnk, float a)
3419 {
3420         return S_OK;
3421 }
3422
3423 LIBTEST_API int STDCALL 
3424 DoubleIn(MonoComObject* pUnk, double a)
3425 {
3426         return S_OK;
3427 }
3428
3429 LIBTEST_API int STDCALL 
3430 ITestIn(MonoComObject* pUnk, MonoComObject *pUnk2)
3431 {
3432         return S_OK;
3433 }
3434
3435 LIBTEST_API int STDCALL 
3436 ITestOut(MonoComObject* pUnk, MonoComObject* *ppUnk)
3437 {
3438         return S_OK;
3439 }
3440
3441 static void create_com_object (MonoComObject** pOut);
3442
3443 LIBTEST_API int STDCALL 
3444 get_ITest(MonoComObject* pUnk, MonoComObject* *ppUnk)
3445 {
3446         create_com_object (ppUnk);
3447         return S_OK;
3448 }
3449
3450 static void create_com_object (MonoComObject** pOut)
3451 {
3452         *pOut = marshal_new0 (MonoComObject, 1);
3453         (*pOut)->vtbl = marshal_new0 (MonoIUnknown, 1);
3454
3455         (*pOut)->m_ref = 1;
3456         (*pOut)->vtbl->QueryInterface = MonoQueryInterface;
3457         (*pOut)->vtbl->AddRef = MonoAddRef;
3458         (*pOut)->vtbl->Release = MonoRelease;
3459         (*pOut)->vtbl->SByteIn = SByteIn;
3460         (*pOut)->vtbl->ByteIn = ByteIn;
3461         (*pOut)->vtbl->ShortIn = ShortIn;
3462         (*pOut)->vtbl->UShortIn = UShortIn;
3463         (*pOut)->vtbl->IntIn = IntIn;
3464         (*pOut)->vtbl->UIntIn = UIntIn;
3465         (*pOut)->vtbl->LongIn = LongIn;
3466         (*pOut)->vtbl->ULongIn = ULongIn;
3467         (*pOut)->vtbl->FloatIn = FloatIn;
3468         (*pOut)->vtbl->DoubleIn = DoubleIn;
3469         (*pOut)->vtbl->ITestIn = ITestIn;
3470         (*pOut)->vtbl->ITestOut = ITestOut;
3471         (*pOut)->vtbl->get_ITest = get_ITest;
3472 }
3473
3474 static MonoComObject* same_object = NULL;
3475
3476 LIBTEST_API int STDCALL 
3477 mono_test_marshal_com_object_create(MonoComObject* *pUnk)
3478 {
3479         create_com_object (pUnk);
3480
3481         if (!same_object)
3482                 same_object = *pUnk;
3483
3484         return 0;
3485 }
3486
3487 LIBTEST_API int STDCALL 
3488 mono_test_marshal_com_object_same(MonoComObject* *pUnk)
3489 {
3490         *pUnk = same_object;
3491
3492         return 0;
3493 }
3494
3495 LIBTEST_API int STDCALL 
3496 mono_test_marshal_com_object_destroy(MonoComObject *pUnk)
3497 {
3498         int ref = --(pUnk->m_ref);
3499         g_free(pUnk->vtbl);
3500         g_free(pUnk);
3501
3502         return ref;
3503 }
3504
3505 LIBTEST_API int STDCALL 
3506 mono_test_marshal_com_object_ref_count(MonoComObject *pUnk)
3507 {
3508         return pUnk->m_ref;
3509 }
3510
3511 LIBTEST_API int STDCALL 
3512 mono_test_marshal_ccw_itest (MonoComObject *pUnk)
3513 {
3514         int hr = 0;
3515         MonoComObject* pTest;
3516
3517         if (!pUnk)
3518                 return 1;
3519
3520         hr = pUnk->vtbl->SByteIn (pUnk, -100);
3521         if (hr != 0)
3522                 return 2;
3523         hr = pUnk->vtbl->ByteIn (pUnk, 100);
3524         if (hr != 0)
3525                 return 3;
3526         hr = pUnk->vtbl->ShortIn (pUnk, -100);
3527         if (hr != 0)
3528                 return 4;
3529         hr = pUnk->vtbl->UShortIn (pUnk, 100);
3530         if (hr != 0)
3531                 return 5;
3532         hr = pUnk->vtbl->IntIn (pUnk, -100);
3533         if (hr != 0)
3534                 return 6;
3535         hr = pUnk->vtbl->UIntIn (pUnk, 100);
3536         if (hr != 0)
3537                 return 7;
3538         hr = pUnk->vtbl->LongIn (pUnk, -100);
3539         if (hr != 0)
3540                 return 8;
3541         hr = pUnk->vtbl->ULongIn (pUnk, 100);
3542         if (hr != 0)
3543                 return 9;
3544         hr = pUnk->vtbl->FloatIn (pUnk, 3.14f);
3545         if (hr != 0)
3546                 return 10;
3547         hr = pUnk->vtbl->DoubleIn (pUnk, 3.14);
3548         if (hr != 0)
3549                 return 11;
3550         hr = pUnk->vtbl->ITestIn (pUnk, pUnk);
3551         if (hr != 0)
3552                 return 12;
3553         hr = pUnk->vtbl->ITestOut (pUnk, &pTest);
3554         if (hr != 0)
3555                 return 13;
3556
3557         return 0;
3558 }
3559
3560 /*
3561  * mono_method_get_unmanaged_thunk tests
3562  */
3563
3564 #if defined(__GNUC__) && ((defined(__i386__) && (defined(__linux__) || defined (__APPLE__)) || defined (__FreeBSD__) || defined(__OpenBSD__)) || (defined(__ppc__) && defined(__APPLE__)))
3565 #define ALIGN(size) __attribute__ ((aligned(size)))
3566 #else
3567 #define ALIGN(size)
3568 #endif
3569
3570
3571 /* thunks.cs:TestStruct */
3572 typedef struct _TestStruct {
3573         int A;
3574         double B;
3575 } TestStruct;
3576
3577 /* Searches for mono symbols in all loaded modules */
3578 static gpointer
3579 lookup_mono_symbol (const char *symbol_name)
3580 {
3581         gpointer symbol;
3582         if (g_module_symbol (g_module_open (NULL, G_MODULE_BIND_LAZY), symbol_name, &symbol))
3583                 return symbol;
3584         else
3585                 return NULL;
3586 }
3587
3588 LIBTEST_API gpointer STDCALL
3589 mono_test_marshal_lookup_symbol (const char *symbol_name)
3590 {
3591         return lookup_mono_symbol (symbol_name);
3592 }
3593
3594 #define MONO_BEGIN_EFRAME { void *__dummy; void *__region_cookie = mono_threads_enter_gc_unsafe_region ? mono_threads_enter_gc_unsafe_region (&__dummy) : NULL;
3595 #define MONO_END_EFRAME if (mono_threads_exit_gc_unsafe_region) mono_threads_exit_gc_unsafe_region (__region_cookie, &__dummy); }
3596
3597 /**
3598  * test_method_thunk:
3599  *
3600  * @test_id: the test number
3601  * @test_method_handle: MonoMethod* of the C# test method
3602  * @create_object_method_handle: MonoMethod* of thunks.cs:Test.CreateObject
3603  */
3604 LIBTEST_API int STDCALL  
3605 test_method_thunk (int test_id, gpointer test_method_handle, gpointer create_object_method_handle)
3606 {
3607         int ret = 0;
3608
3609         gpointer (*mono_method_get_unmanaged_thunk)(gpointer)
3610                 = (gpointer (*)(gpointer))lookup_mono_symbol ("mono_method_get_unmanaged_thunk");
3611
3612         gpointer (*mono_string_new_wrapper)(const char *)
3613                 = (gpointer (*)(const char *))lookup_mono_symbol ("mono_string_new_wrapper");
3614
3615         char *(*mono_string_to_utf8)(gpointer)
3616                 = (char *(*)(gpointer))lookup_mono_symbol ("mono_string_to_utf8");
3617
3618         gpointer (*mono_object_unbox)(gpointer)
3619                 = (gpointer (*)(gpointer))lookup_mono_symbol ("mono_object_unbox");
3620
3621         gpointer (*mono_threads_enter_gc_unsafe_region) (gpointer)
3622                 = (gpointer (*)(gpointer))lookup_mono_symbol ("mono_threads_enter_gc_unsafe_region");
3623
3624         void (*mono_threads_exit_gc_unsafe_region) (gpointer, gpointer)
3625                 = (void (*)(gpointer, gpointer))lookup_mono_symbol ("mono_threads_exit_gc_unsafe_region");
3626
3627         
3628
3629         gpointer test_method, ex = NULL;
3630         gpointer (STDCALL *CreateObject)(gpointer*);
3631
3632         MONO_BEGIN_EFRAME;
3633
3634         if (!mono_method_get_unmanaged_thunk) {
3635                 ret = 1;
3636                 goto done;
3637         }
3638
3639         test_method =  mono_method_get_unmanaged_thunk (test_method_handle);
3640         if (!test_method) {
3641                 ret = 2;
3642                 goto done;
3643         }
3644
3645         CreateObject = (gpointer (STDCALL *)(gpointer *))mono_method_get_unmanaged_thunk (create_object_method_handle);
3646         if (!CreateObject) {
3647                 ret = 3;
3648                 goto done;
3649         }
3650         
3651
3652         switch (test_id) {
3653
3654         case 0: {
3655                 /* thunks.cs:Test.Test0 */
3656                 void (STDCALL *F)(gpointer *) = (void (STDCALL *)(gpointer *))test_method;
3657                 F (&ex);
3658                 break;
3659         }
3660
3661         case 1: {
3662                 /* thunks.cs:Test.Test1 */
3663                 int (STDCALL *F)(gpointer *) = (int (STDCALL *)(gpointer *))test_method;
3664                 if (F (&ex) != 42) {
3665                         ret = 4;
3666                         goto done;
3667                 }
3668                 break;
3669         }
3670
3671         case 2: {
3672                 /* thunks.cs:Test.Test2 */
3673                 gpointer (STDCALL *F)(gpointer, gpointer*) = (gpointer (STDCALL *)(gpointer, gpointer *))test_method;
3674                 gpointer str = mono_string_new_wrapper ("foo");
3675                 if (str != F (str, &ex)) {
3676                         ret = 4;
3677                         goto done;
3678                 }
3679                 break;
3680         }
3681
3682         case 3: {
3683                 /* thunks.cs:Test.Test3 */
3684                 gpointer (STDCALL *F)(gpointer, gpointer, gpointer*);
3685                 gpointer obj;
3686                 gpointer str;
3687
3688                 F = (gpointer (STDCALL *)(gpointer, gpointer, gpointer *))test_method;
3689                 obj = CreateObject (&ex);
3690                 str = mono_string_new_wrapper ("bar");
3691
3692                 if (str != F (obj, str, &ex)) {
3693                         ret = 4;
3694                         goto done;
3695                 }
3696                 break;
3697         }
3698
3699         case 4: {
3700                 /* thunks.cs:Test.Test4 */
3701                 int (STDCALL *F)(gpointer, gpointer, int, gpointer*);
3702                 gpointer obj;
3703                 gpointer str;
3704
3705                 F = (int (STDCALL *)(gpointer, gpointer, int, gpointer *))test_method;
3706                 obj = CreateObject (&ex);
3707                 str = mono_string_new_wrapper ("bar");
3708
3709                 if (42 != F (obj, str, 42, &ex)) {
3710                         ret = 4;
3711                         goto done;
3712                 }
3713
3714                 break;
3715         }
3716
3717         case 5: {
3718                 /* thunks.cs:Test.Test5 */
3719                 int (STDCALL *F)(gpointer, gpointer, int, gpointer*);
3720                 gpointer obj;
3721                 gpointer str;
3722
3723                 F = (int (STDCALL *)(gpointer, gpointer, int, gpointer *))test_method;
3724                 obj = CreateObject (&ex);
3725                 str = mono_string_new_wrapper ("bar");
3726
3727                 F (obj, str, 42, &ex);
3728                 if (!ex) {
3729                         ret = 4;
3730                         goto done;
3731                 }
3732
3733                 break;
3734         }
3735
3736         case 6: {
3737                 /* thunks.cs:Test.Test6 */
3738                 int (STDCALL *F)(gpointer, guint8, gint16, gint32, gint64, float, double,
3739                                  gpointer, gpointer*);
3740                 gpointer obj;
3741                 gpointer str = mono_string_new_wrapper ("Test6");
3742                 int res;
3743
3744                 F = (int (STDCALL *)(gpointer, guint8, gint16, gint32, gint64, float, double, gpointer, gpointer *))test_method;
3745                 obj = CreateObject (&ex);
3746
3747                 res = F (obj, 254, 32700, -245378, 6789600, 3.1415, 3.1415, str, &ex);
3748                 if (ex) {
3749                         ret = 4;
3750                         goto done;
3751                 }
3752
3753                 if (!res) {
3754                         ret = 5;
3755                         goto done;
3756                 }
3757
3758                 break;
3759         }
3760
3761         case 7: {
3762                 /* thunks.cs:Test.Test7 */
3763                 gint64 (STDCALL *F)(gpointer*) = (gint64 (STDCALL *)(gpointer *))test_method;
3764                 if (F (&ex) != G_MAXINT64) {
3765                         ret = 4;
3766                         goto done;
3767                 }
3768                 break;
3769         }
3770
3771         case 8: {
3772                 /* thunks.cs:Test.Test8 */
3773                 void (STDCALL *F)(guint8*, gint16*, gint32*, gint64*, float*, double*,
3774                                  gpointer*, gpointer*);
3775
3776                 guint8 a1;
3777                 gint16 a2;
3778                 gint32 a3;
3779                 gint64 a4;
3780                 float a5;
3781                 double a6;
3782                 gpointer a7;
3783
3784                 F = (void (STDCALL *)(guint8 *, gint16 *, gint32 *, gint64 *, float *, double *,
3785                         gpointer *, gpointer *))test_method;
3786
3787                 F (&a1, &a2, &a3, &a4, &a5, &a6, &a7, &ex);
3788                 if (ex) {
3789                         ret = 4;
3790                         goto done;
3791                 }
3792
3793                 if (!(a1 == 254 &&
3794                       a2 == 32700 &&
3795                       a3 == -245378 &&
3796                       a4 == 6789600 &&
3797                       (fabs (a5 - 3.1415) < 0.001) &&
3798                       (fabs (a6 - 3.1415) < 0.001) &&
3799                       strcmp (mono_string_to_utf8 (a7), "Test8") == 0)){
3800                                 ret = 5;
3801                                 goto done;
3802                         }
3803
3804                 break;
3805         }
3806
3807         case 9: {
3808                 /* thunks.cs:Test.Test9 */
3809                 void (STDCALL *F)(guint8*, gint16*, gint32*, gint64*, float*, double*,
3810                         gpointer*, gpointer*);
3811
3812                 guint8 a1;
3813                 gint16 a2;
3814                 gint32 a3;
3815                 gint64 a4;
3816                 float a5;
3817                 double a6;
3818                 gpointer a7;
3819
3820                 F = (void (STDCALL *)(guint8 *, gint16 *, gint32 *, gint64 *, float *, double *,
3821                         gpointer *, gpointer *))test_method;
3822
3823                 F (&a1, &a2, &a3, &a4, &a5, &a6, &a7, &ex);
3824                 if (!ex) {
3825                         ret = 4;
3826                         goto done;
3827                 }
3828
3829                 break;
3830         }
3831
3832         case 10: {
3833                 /* thunks.cs:Test.Test10 */
3834                 void (STDCALL *F)(gpointer*, gpointer*);
3835
3836                 gpointer obj1, obj2;
3837
3838                 obj1 = obj2 = CreateObject (&ex);
3839                 if (ex) {
3840                         ret = 4;
3841                         goto done;
3842                 }
3843
3844                 F = (void (STDCALL *)(gpointer *, gpointer *))test_method;
3845
3846                 F (&obj1, &ex);
3847                 if (ex) {
3848                         ret = 5;
3849                         goto done;
3850                 }
3851
3852                 if (obj1 == obj2) {
3853                         ret = 6;
3854                         goto done;
3855                 }
3856
3857                 break;
3858         }
3859
3860         case 100: {
3861                 /* thunks.cs:TestStruct.Test0 */
3862                 int (STDCALL *F)(gpointer*, gpointer*);
3863
3864                 gpointer obj;
3865                 TestStruct *a1;
3866                 int res;
3867
3868                 obj = CreateObject (&ex);
3869                 if (ex) {
3870                         ret = 4;
3871                         goto done;
3872                 }
3873
3874                 if (!obj) {
3875                         ret = 5;
3876                         goto done;
3877                 }
3878
3879                 a1 = (TestStruct *)mono_object_unbox (obj);
3880                 if (!a1) {
3881                         ret = 6;
3882                         goto done;
3883                 }
3884
3885                 a1->A = 42;
3886                 a1->B = 3.1415;
3887
3888                 F = (int (STDCALL *)(gpointer *, gpointer *))test_method;
3889
3890                 res = F ((gpointer *)obj, &ex);
3891                 if (ex) {
3892                         ret = 7;
3893                         goto done;
3894                 }
3895
3896                 if (!res) {
3897                         ret = 8;
3898                         goto done;
3899                 }
3900
3901                 /* check whether the call was really by value */
3902                 if (a1->A != 42 || a1->B != 3.1415) {
3903                         ret = 9;
3904                         goto done;
3905                 }
3906
3907                 break;
3908         }
3909
3910         case 101: {
3911                 /* thunks.cs:TestStruct.Test1 */
3912                 void (STDCALL *F)(gpointer, gpointer*);
3913
3914                 TestStruct *a1;
3915                 gpointer obj;
3916
3917                 obj = CreateObject (&ex);
3918                 if (ex) {
3919                         ret = 4;
3920                         goto done;
3921                 }
3922
3923                 if (!obj) {
3924                         ret = 5;
3925                         goto done;
3926                 }
3927
3928                 a1 = (TestStruct *)mono_object_unbox (obj);
3929                 if (!a1) {
3930                         ret = 6;
3931                         goto done;
3932                 }
3933
3934                 F = (void (STDCALL *)(gpointer, gpointer *))test_method;
3935
3936                 F (obj, &ex);
3937                 if (ex) {
3938                         ret = 7;
3939                         goto done;
3940                 }
3941
3942                 if (a1->A != 42) {
3943                         ret = 8;
3944                         goto done;
3945                 }
3946
3947                 if (!(fabs (a1->B - 3.1415) < 0.001)) {
3948                         ret = 9;
3949                         goto done;
3950                 }
3951
3952                 break;
3953         }
3954
3955         case 102: {
3956                 /* thunks.cs:TestStruct.Test2 */
3957                 gpointer (STDCALL *F)(gpointer*);
3958
3959                 TestStruct *a1;
3960                 gpointer obj;
3961
3962                 F = (gpointer (STDCALL *)(gpointer *))test_method;
3963
3964                 obj = F (&ex);
3965                 if (ex) {
3966                         ret = 4;
3967                         goto done;
3968                 }
3969
3970                 if (!obj) {
3971                         ret = 5;
3972                         goto done;
3973                 }
3974
3975                 a1 = (TestStruct *)mono_object_unbox (obj);
3976
3977                 if (a1->A != 42) {
3978                         ret = 5;
3979                         goto done;
3980                 }
3981
3982                 if (!(fabs (a1->B - 3.1415) < 0.001)) {
3983                         ret = 6;
3984                         goto done;
3985                 }
3986
3987                 break;
3988         }
3989
3990         case 103: {
3991                 /* thunks.cs:TestStruct.Test3 */
3992                 void (STDCALL *F)(gpointer, gpointer*);
3993
3994                 TestStruct *a1;
3995                 gpointer obj;
3996
3997                 obj = CreateObject (&ex);
3998                 if (ex) {
3999                         ret = 4;
4000                         goto done;
4001                 }
4002
4003                 if (!obj) {
4004                         ret = 5;
4005                         goto done;
4006                 }
4007                 
4008                 a1 = (TestStruct *)mono_object_unbox (obj);
4009
4010                 if (!a1) {
4011                         ret = 6;
4012                         goto done;
4013                 }
4014
4015                 a1->A = 42;
4016                 a1->B = 3.1415;
4017
4018                 F = (void (STDCALL *)(gpointer, gpointer *))test_method;
4019
4020                 F (obj, &ex);
4021                 if (ex) {
4022                         ret = 4;
4023                         goto done;
4024                 }
4025
4026                 if (a1->A != 1) {
4027                         ret = 5;
4028                         goto done;
4029                 }
4030
4031                 if (a1->B != 17) {
4032                         ret = 6;
4033                         goto done;
4034                 }
4035
4036                 break;
4037         }
4038
4039         default:
4040                 ret = 9;
4041
4042         }
4043 done:
4044         MONO_END_EFRAME;
4045
4046         return ret;
4047 }
4048
4049 typedef struct 
4050 {
4051         char a;
4052 } winx64_struct1;
4053
4054 LIBTEST_API int STDCALL  
4055 mono_test_Winx64_struct1_in (winx64_struct1 var)
4056 {
4057         if (var.a != 123)
4058                 return 1;
4059         return 0;
4060 }
4061
4062 typedef struct
4063 {
4064         char a;
4065         char b;
4066 } winx64_struct2;
4067
4068 LIBTEST_API int STDCALL  
4069 mono_test_Winx64_struct2_in (winx64_struct2 var)
4070 {
4071         if (var.a != 4)
4072                 return 1;
4073         if (var.b != 5)
4074                 return 2;
4075         return 0;
4076 }
4077
4078
4079 typedef struct
4080 {
4081         char a;
4082         char b;
4083         short c;
4084 } winx64_struct3;
4085
4086 LIBTEST_API int STDCALL  
4087 mono_test_Winx64_struct3_in (winx64_struct3 var)
4088 {
4089         if (var.a != 4)
4090                 return 1;
4091         if (var.b != 5)
4092                 return 2;
4093         if (var.c != 0x1234)
4094                 return 3;
4095         return 0;
4096 }
4097
4098 typedef struct
4099 {
4100         char a;
4101         char b;
4102         short c;
4103         unsigned int d;
4104 } winx64_struct4;
4105
4106 LIBTEST_API int STDCALL  
4107 mono_test_Winx64_struct4_in (winx64_struct4 var)
4108 {
4109         if (var.a != 4)
4110                 return 1;
4111         if (var.b != 5)
4112                 return 2;
4113         if (var.c != 0x1234)
4114                 return 3;
4115         if (var.d != 0x87654321)
4116                 return 4;
4117         return 0;
4118 }
4119
4120 typedef struct
4121 {
4122         char a;
4123         char b;
4124         char c;
4125 } winx64_struct5;
4126
4127 LIBTEST_API int STDCALL  
4128 mono_test_Winx64_struct5_in (winx64_struct5 var)
4129 {
4130         if (var.a != 4)
4131                 return 1;
4132         if (var.b != 5)
4133                 return 2;
4134         if (var.c != 6)
4135                 return 3;
4136         return 0;
4137 }
4138
4139 typedef struct
4140 {
4141         winx64_struct1 a;
4142         short b;
4143         char c;
4144 } winx64_struct6;
4145
4146 LIBTEST_API int STDCALL  
4147 mono_test_Winx64_struct6_in (winx64_struct6 var)
4148 {
4149         if (var.a.a != 4)
4150                 return 1;
4151         if (var.b != 5)
4152                 return 2;
4153         if (var.c != 6)
4154                 return 3;
4155         return 0;
4156 }
4157
4158 LIBTEST_API int STDCALL  
4159 mono_test_Winx64_structs_in1 (winx64_struct1 var1,
4160                          winx64_struct2 var2,
4161                          winx64_struct3 var3,
4162                          winx64_struct4 var4)
4163 {
4164         if (var1.a != 123)
4165                 return 1;
4166         
4167         if (var2.a != 4)
4168                 return 2;
4169         if (var2.b != 5)
4170                 return 3;
4171         
4172         if (var3.a != 4)
4173                 return 4;
4174         if (var3.b != 5)
4175                 return 2;
4176         if (var3.c != 0x1234)
4177                 return 5;
4178         
4179         if (var4.a != 4)
4180                 return 6;
4181         if (var4.b != 5)
4182                 return 7;
4183         if (var4.c != 0x1234)
4184                 return 8;
4185         if (var4.d != 0x87654321)
4186                 return 9;
4187         return 0;
4188 }
4189
4190 LIBTEST_API int STDCALL  
4191 mono_test_Winx64_structs_in2 (winx64_struct1 var1,
4192                          winx64_struct1 var2,
4193                          winx64_struct1 var3,
4194                          winx64_struct1 var4,
4195                          winx64_struct1 var5)
4196 {
4197         if (var1.a != 1)
4198                 return 1;
4199         if (var2.a != 2)
4200                 return 2;
4201         if (var3.a != 3)
4202                 return 3;
4203         if (var4.a != 4)
4204                 return 4;
4205         if (var5.a != 5)
4206                 return 5;
4207         
4208         return 0;
4209 }
4210
4211 LIBTEST_API int STDCALL  
4212 mono_test_Winx64_structs_in3 (winx64_struct1 var1,
4213                          winx64_struct5 var2,
4214                          winx64_struct1 var3,
4215                          winx64_struct5 var4,
4216                          winx64_struct1 var5,
4217                          winx64_struct5 var6)
4218 {
4219         if (var1.a != 1)
4220                 return 1;
4221         
4222         if (var2.a != 2)
4223                 return 2;
4224         if (var2.b != 3)
4225                 return 2;
4226         if (var2.c != 4)
4227                 return 4;
4228         
4229         if (var3.a != 5)
4230                 return 5;
4231         
4232         if (var4.a != 6)
4233                 return 6;
4234         if (var4.b != 7)
4235                 return 7;
4236         if (var4.c != 8)
4237                 return 8;
4238         
4239         if (var5.a != 9)
4240                 return 9;
4241
4242         if (var6.a != 10)
4243                 return 10;
4244         if (var6.b != 11)
4245                 return 11;
4246         if (var6.c != 12)
4247                 return 12;
4248         
4249         return 0;
4250 }
4251
4252 LIBTEST_API winx64_struct1 STDCALL  
4253 mono_test_Winx64_struct1_ret (void)
4254 {
4255         winx64_struct1 ret;
4256         ret.a = 123;
4257         return ret;
4258 }
4259
4260 LIBTEST_API winx64_struct2 STDCALL  
4261 mono_test_Winx64_struct2_ret (void)
4262 {
4263         winx64_struct2 ret;
4264         ret.a = 4;
4265         ret.b = 5;
4266         return ret;
4267 }
4268
4269 LIBTEST_API winx64_struct3 STDCALL  
4270 mono_test_Winx64_struct3_ret (void)
4271 {
4272         winx64_struct3 ret;
4273         ret.a = 4;
4274         ret.b = 5;
4275         ret.c = 0x1234;
4276         return ret;
4277 }
4278
4279 LIBTEST_API winx64_struct4 STDCALL  
4280 mono_test_Winx64_struct4_ret (void)
4281 {
4282         winx64_struct4 ret;
4283         ret.a = 4;
4284         ret.b = 5;
4285         ret.c = 0x1234;
4286         ret.d = 0x87654321;
4287         return ret;
4288 }
4289
4290 LIBTEST_API winx64_struct5 STDCALL  
4291 mono_test_Winx64_struct5_ret (void)
4292 {
4293         winx64_struct5 ret;
4294         ret.a = 4;
4295         ret.b = 5;
4296         ret.c = 6;
4297         return ret;
4298 }
4299
4300 LIBTEST_API winx64_struct1 STDCALL  
4301 mono_test_Winx64_struct1_ret_5_args (char a, char b, char c, char d, char e)
4302 {
4303         winx64_struct1 ret;
4304         ret.a = a + b + c + d + e;
4305         return ret;
4306 }
4307
4308 LIBTEST_API winx64_struct5 STDCALL
4309 mono_test_Winx64_struct5_ret6_args (char a, char b, char c, char d, char e)
4310 {
4311         winx64_struct5 ret;
4312         ret.a = a + b;
4313         ret.b = c + d;
4314         ret.c = e;
4315         return ret;
4316 }
4317
4318 typedef struct
4319 {
4320         float a;
4321         float b;
4322 } winx64_floatStruct;
4323
4324 LIBTEST_API int STDCALL  
4325 mono_test_Winx64_floatStruct (winx64_floatStruct a)
4326 {
4327         if (a.a > 5.6 || a.a < 5.4)
4328                 return 1;
4329
4330         if (a.b > 9.6 || a.b < 9.4)
4331                 return 2;
4332         
4333         return 0;
4334 }
4335
4336 typedef struct
4337 {
4338         double a;
4339 } winx64_doubleStruct;
4340
4341 LIBTEST_API int STDCALL  
4342 mono_test_Winx64_doubleStruct (winx64_doubleStruct a)
4343 {
4344         if (a.a > 5.6 || a.a < 5.4)
4345                 return 1;
4346         
4347         return 0;
4348 }
4349
4350 typedef int (STDCALL *managed_struct1_delegate) (winx64_struct1 a);
4351
4352 LIBTEST_API int STDCALL 
4353 mono_test_managed_Winx64_struct1_in(managed_struct1_delegate func)
4354 {
4355         winx64_struct1 val;
4356         val.a = 5;
4357         return func (val);
4358 }
4359
4360 typedef int (STDCALL *managed_struct5_delegate) (winx64_struct5 a);
4361
4362 LIBTEST_API int STDCALL 
4363 mono_test_managed_Winx64_struct5_in(managed_struct5_delegate func)
4364 {
4365         winx64_struct5 val;
4366         val.a = 5;
4367         val.b = 0x10;
4368         val.c = 0x99;
4369         return func (val);
4370 }
4371
4372 typedef int (STDCALL *managed_struct1_struct5_delegate) (winx64_struct1 a, winx64_struct5 b,
4373                                                          winx64_struct1 c, winx64_struct5 d,
4374                                                          winx64_struct1 e, winx64_struct5 f);
4375
4376 LIBTEST_API int STDCALL 
4377 mono_test_managed_Winx64_struct1_struct5_in(managed_struct1_struct5_delegate func)
4378 {
4379         winx64_struct1 a, c, e;
4380         winx64_struct5 b, d, f;
4381         a.a = 1;
4382         b.a = 2; b.b = 3; b.c = 4;
4383         c.a = 5;
4384         d.a = 6; d.b = 7; d.c = 8;
4385         e.a = 9;
4386         f.a = 10; f.b = 11; f.c = 12;
4387
4388         return func (a, b, c, d, e, f);
4389 }
4390
4391 typedef winx64_struct1 (STDCALL *managed_struct1_ret_delegate) (void);
4392
4393 LIBTEST_API int STDCALL 
4394 mono_test_Winx64_struct1_ret_managed (managed_struct1_ret_delegate func)
4395 {
4396         winx64_struct1 ret;
4397
4398         ret = func ();
4399
4400         if (ret.a != 0x45)
4401                 return 1;
4402         
4403         return 0;
4404 }
4405
4406 typedef winx64_struct5 (STDCALL *managed_struct5_ret_delegate) (void);
4407
4408 LIBTEST_API int STDCALL 
4409 mono_test_Winx64_struct5_ret_managed (managed_struct5_ret_delegate func)
4410 {
4411         winx64_struct5 ret;
4412
4413         ret = func ();
4414
4415         if (ret.a != 0x12)
4416                 return 1;
4417         if (ret.b != 0x34)
4418                 return 2;
4419         if (ret.c != 0x56)
4420                 return 3;
4421         
4422         return 0;
4423 }
4424
4425 LIBTEST_API int STDCALL 
4426 mono_test_marshal_bool_in (int arg, unsigned int expected, unsigned int bDefaultMarsh, unsigned int bBoolCustMarsh,
4427                            char bI1CustMarsh, unsigned char bU1CustMarsh, short bVBCustMarsh)
4428 {
4429         switch (arg) {
4430         case 1: 
4431                 if (bDefaultMarsh != expected)
4432                         return 1;
4433                 break;
4434         case 2: 
4435                 if (bBoolCustMarsh != expected)
4436                         return 2;
4437                 break;
4438         case 3: 
4439                 if (bI1CustMarsh != expected)
4440                         return 3;
4441                 break;
4442         case 4: 
4443                 if (bU1CustMarsh != expected)
4444                         return 4;
4445                 break;
4446         case 5: 
4447                 if (bVBCustMarsh != expected)
4448                         return 5;
4449                 break;
4450         default:
4451                 return 999;             
4452         }
4453         return 0;
4454 }
4455
4456 LIBTEST_API int STDCALL 
4457 mono_test_marshal_bool_out (int arg, unsigned int testVal, unsigned int* bDefaultMarsh, unsigned int* bBoolCustMarsh,
4458                            char* bI1CustMarsh, unsigned char* bU1CustMarsh, unsigned short* bVBCustMarsh)
4459 {
4460         switch (arg) {
4461         case 1: 
4462                 if (!bDefaultMarsh)
4463                         return 1;
4464                 *bDefaultMarsh = testVal;
4465                 break;  
4466         case 2: 
4467                 if (!bBoolCustMarsh)
4468                         return 2;
4469                 *bBoolCustMarsh = testVal;
4470                 break;  
4471         case 3: 
4472                 if (!bI1CustMarsh)
4473                         return 3;
4474                 *bI1CustMarsh = (char)testVal;
4475                 break;  
4476         case 4: 
4477                 if (!bU1CustMarsh)
4478                         return 4;
4479                 *bU1CustMarsh = (unsigned char)testVal;
4480                 break;  
4481         case 5: 
4482                 if (!bVBCustMarsh)
4483                         return 5;
4484                 *bVBCustMarsh = (unsigned short)testVal;
4485                 break;  
4486         default:
4487                 return 999;
4488         }
4489         return 0;
4490 }
4491
4492 LIBTEST_API int STDCALL 
4493 mono_test_marshal_bool_ref (int arg, unsigned int expected, unsigned int testVal, unsigned int* bDefaultMarsh,
4494                             unsigned int* bBoolCustMarsh, char* bI1CustMarsh, unsigned char* bU1CustMarsh, 
4495                             unsigned short* bVBCustMarsh)
4496 {
4497         switch (arg) {
4498         case 1: 
4499                 if (!bDefaultMarsh)
4500                         return 1;
4501                 if (*bDefaultMarsh != expected)
4502                         return 2;
4503                 *bDefaultMarsh = testVal;
4504                 break;
4505         case 2: 
4506                 if (!bBoolCustMarsh)
4507                         return 3;
4508                 if (*bBoolCustMarsh != expected)
4509                         return 4;
4510                 *bBoolCustMarsh = testVal;
4511                 break;
4512         case 3: 
4513                 if (!bI1CustMarsh)
4514                         return 5;
4515                 if (*bI1CustMarsh != expected)
4516                         return 6;
4517                 *bI1CustMarsh = (char)testVal;
4518                 break;
4519         case 4: 
4520                 if (!bU1CustMarsh)
4521                         return 7;
4522                 if (*bU1CustMarsh != expected)
4523                         return 8;
4524                 *bU1CustMarsh = (unsigned char)testVal;
4525                 break;
4526         case 5: 
4527                 if (!bVBCustMarsh)
4528                         return 9;
4529                 if (*bVBCustMarsh != expected)
4530                         return 10;
4531                 *bVBCustMarsh = (unsigned short)testVal;
4532                 break;
4533         default:
4534                 return 999;             
4535         }
4536         return 0;
4537 }
4538
4539
4540 typedef int (STDCALL *MarshalBoolInDelegate) (int arg, unsigned int expected, unsigned int bDefaultMarsh,
4541         unsigned int bBoolCustMarsh, char bI1CustMarsh, unsigned char bU1CustMarsh, unsigned short bVBCustMarsh);
4542
4543 LIBTEST_API int STDCALL 
4544 mono_test_managed_marshal_bool_in (int arg, unsigned int expected, unsigned int testVal, MarshalBoolInDelegate pfcn)
4545 {
4546         if (!pfcn)
4547                 return 0x9900;
4548
4549         switch (arg) {
4550         case 1:
4551                 return pfcn (arg, expected, testVal, 0, 0, 0, 0);
4552         case 2:
4553                 return pfcn (arg, expected, 0, testVal,  0, 0, 0);
4554         case 3:
4555                 return pfcn (arg, expected, 0, 0, testVal, 0, 0);
4556         case 4:
4557                 return pfcn (arg, expected, 0, 0, 0, testVal, 0);
4558         case 5:
4559                 return pfcn (arg, expected, 0, 0, 0, 0, testVal);
4560         default:
4561                 return 0x9800;
4562         }
4563
4564         return 0;
4565 }
4566
4567 typedef int (STDCALL *MarshalBoolOutDelegate) (int arg, unsigned int expected, unsigned int* bDefaultMarsh,
4568         unsigned int* bBoolCustMarsh, char* bI1CustMarsh, unsigned char* bU1CustMarsh, unsigned short* bVBCustMarsh);
4569
4570 LIBTEST_API int STDCALL 
4571 mono_test_managed_marshal_bool_out (int arg, unsigned int expected, unsigned int testVal, MarshalBoolOutDelegate pfcn)
4572 {
4573         int ret;
4574         unsigned int lDefaultMarsh, lBoolCustMarsh;
4575         char lI1CustMarsh = 0;
4576         unsigned char lU1CustMarsh = 0;
4577         unsigned short lVBCustMarsh = 0;
4578         lDefaultMarsh = lBoolCustMarsh = 0;
4579
4580         if (!pfcn)
4581                 return 0x9900;
4582
4583         switch (arg) {
4584         case 1: {
4585                 unsigned int ltVal = 0;
4586                 ret = pfcn (arg, testVal, &ltVal, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4587                 if (ret)
4588                         return 0x0100 + ret;
4589                 if (expected != ltVal)
4590                         return 0x0200;
4591                 break;
4592         }
4593         case 2: {
4594                 unsigned int ltVal = 0;
4595                 ret = pfcn (arg, testVal, &lDefaultMarsh, &ltVal, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4596                 if (ret)
4597                         return 0x0300 + ret;
4598                 if (expected != ltVal)
4599                         return 0x0400;
4600                 break;
4601         }
4602         case 3: {
4603                 char ltVal = 0;
4604                 ret = pfcn (arg, testVal, &lDefaultMarsh, &lBoolCustMarsh, &ltVal, &lU1CustMarsh, &lVBCustMarsh);
4605                 if (ret)
4606                         return 0x0500 + ret;
4607                 if (expected != ltVal)
4608                         return 0x0600;
4609                 break;
4610         }
4611         case 4: {
4612                 unsigned char ltVal = 0;
4613                 ret = pfcn (arg, testVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &ltVal, &lVBCustMarsh);
4614                 if (ret)
4615                         return 0x0700 + ret;
4616                 if (expected != ltVal)
4617                         return 0x0800;
4618                 break;
4619         }
4620         case 5: {
4621                 unsigned short ltVal = 0;
4622                 ret = pfcn (arg, testVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &ltVal);
4623                 if (ret)
4624                         return 0x0900 + ret;
4625                 if (expected != ltVal)
4626                         return 0x1000;
4627                 break;
4628         }
4629         default:
4630                 return 0x9800;
4631         }
4632
4633         return 0;
4634 }
4635
4636 typedef int (STDCALL *MarshalBoolRefDelegate) (int arg, unsigned int expected, unsigned int testVal, unsigned int* bDefaultMarsh,
4637         unsigned int* bBoolCustMarsh, char* bI1CustMarsh, unsigned char* bU1CustMarsh, unsigned short* bVBCustMarsh);
4638
4639 LIBTEST_API int STDCALL 
4640 mono_test_managed_marshal_bool_ref (int arg, unsigned int expected, unsigned int testVal, unsigned int outExpected,
4641                                     unsigned int outTestVal, MarshalBoolRefDelegate pfcn)
4642 {
4643         int ret;
4644         unsigned int lDefaultMarsh, lBoolCustMarsh;
4645         char lI1CustMarsh = 0;
4646         unsigned char lU1CustMarsh = 0;
4647         unsigned short lVBCustMarsh = 0;
4648         lDefaultMarsh = lBoolCustMarsh = 0;
4649
4650         if (!pfcn)
4651                 return 0x9900;
4652
4653         switch (arg) {
4654         case 1:
4655         {
4656                 unsigned int ltestVal = testVal;
4657                 ret = pfcn (arg, expected, outTestVal, &ltestVal, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4658                 if (ret)
4659                         return 0x0100 + ret;
4660                 if (outExpected != ltestVal)
4661                         return 0x0200;
4662                 break;
4663         }
4664         case 2:
4665         {
4666                 unsigned int ltestVal = testVal;
4667                 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &ltestVal, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4668                 if (ret)
4669                         return 0x0300 + ret;
4670                 if (outExpected != ltestVal)
4671                         return 0x0400;
4672                 break;
4673         }
4674         case 3:
4675         {
4676                 char ltestVal = testVal;
4677                 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &lBoolCustMarsh, &ltestVal, &lU1CustMarsh, &lVBCustMarsh);
4678                 if (ret)
4679                         return 0x0500 + ret;
4680                 if (outExpected != ltestVal)
4681                         return 0x0600;
4682                 break;
4683         }
4684         case 4:
4685         {
4686                 unsigned char ltestVal = testVal;
4687                 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &ltestVal, &lVBCustMarsh);
4688                 if (ret)
4689                         return 0x0700 + ret;
4690                 if (outExpected != ltestVal)
4691                         return 0x0800;
4692                 break;
4693         }
4694         case 5:
4695         {
4696                 unsigned short ltestVal = testVal;
4697                 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &ltestVal);
4698                 if (ret)
4699                         return 0x0900 + ret;
4700                 if (outExpected != ltestVal)
4701                         return 0x1000;
4702                 break;
4703         }
4704         default:
4705                 return 0x9800;
4706         }
4707
4708         return 0;
4709 }
4710
4711 #ifdef WIN32
4712
4713 LIBTEST_API int STDCALL 
4714 mono_test_marshal_safearray_out_1dim_vt_bstr_empty (SAFEARRAY** safearray)
4715 {
4716         /* Create an empty one-dimensional array of variants */
4717         SAFEARRAY *pSA;
4718         SAFEARRAYBOUND dimensions [1];
4719
4720         dimensions [0].lLbound = 0;
4721         dimensions [0].cElements = 0;
4722
4723         pSA= SafeArrayCreate (VT_VARIANT, 1, dimensions);
4724         *safearray = pSA;
4725         return S_OK;
4726 }
4727
4728 LIBTEST_API int STDCALL 
4729 mono_test_marshal_safearray_out_1dim_vt_bstr (SAFEARRAY** safearray)
4730 {
4731         /* Create a one-dimensional array of 10 variants filled with "0" to "9" */
4732         SAFEARRAY *pSA;
4733         SAFEARRAYBOUND dimensions [1];
4734         long i;
4735         gchar buffer [20];
4736         HRESULT hr = S_OK;
4737         long indices [1];
4738
4739         dimensions [0].lLbound = 0;
4740         dimensions [0].cElements = 10;
4741
4742         pSA= SafeArrayCreate (VT_VARIANT, 1, dimensions);
4743         for (i= dimensions [0].lLbound; i< (dimensions [0].cElements + dimensions [0].lLbound); i++) {
4744                 VARIANT vOut;
4745                 VariantInit (&vOut);
4746                 vOut.vt = VT_BSTR;
4747                 _ltoa (i,buffer,10);
4748                 vOut.bstrVal= marshal_bstr_alloc (buffer);
4749                 indices [0] = i;
4750                 if ((hr = SafeArrayPutElement (pSA, indices, &vOut)) != S_OK) {
4751                         VariantClear (&vOut);
4752                         SafeArrayDestroy (pSA);
4753                         return hr;
4754                 }
4755                 VariantClear (&vOut);
4756         }
4757         *safearray = pSA;
4758         return hr;
4759 }
4760
4761 LIBTEST_API int STDCALL 
4762 mono_test_marshal_safearray_out_2dim_vt_i4 (SAFEARRAY** safearray)
4763 {
4764         /* Create a two-dimensional array of 4x3 variants filled with 11, 12, 13, etc. */
4765         SAFEARRAY *pSA;
4766         SAFEARRAYBOUND dimensions [2];
4767         long i, j;
4768         HRESULT hr = S_OK;
4769         long indices [2];
4770
4771         dimensions [0].lLbound = 0;
4772         dimensions [0].cElements = 4;
4773         dimensions [1].lLbound = 0;
4774         dimensions [1].cElements = 3;
4775
4776         pSA= SafeArrayCreate(VT_VARIANT, 2, dimensions);
4777         for (i= dimensions [0].lLbound; i< (dimensions [0].cElements + dimensions [0].lLbound); i++) {
4778                 for (j= dimensions [1].lLbound; j< (dimensions [1].cElements + dimensions [1].lLbound); j++) {
4779                         VARIANT vOut;
4780                         VariantInit (&vOut);
4781                         vOut.vt = VT_I4;
4782                         vOut.lVal = (i+1)*10+(j+1);
4783                         indices [0] = i;
4784                         indices [1] = j;
4785                         if ((hr = SafeArrayPutElement (pSA, indices, &vOut)) != S_OK) {
4786                                 VariantClear (&vOut);
4787                                 SafeArrayDestroy (pSA);
4788                                 return hr;
4789                         }
4790                         VariantClear (&vOut);  // does a deep destroy of source VARIANT 
4791                 }
4792         }
4793         *safearray = pSA;
4794         return hr;
4795 }
4796
4797 LIBTEST_API int STDCALL 
4798 mono_test_marshal_safearray_out_4dim_vt_i4 (SAFEARRAY** safearray)
4799 {
4800         /* Create a four-dimensional array of 10x3x6x7 variants filled with their indices */
4801         /* Also use non zero lower bounds                                                 */
4802         SAFEARRAY *pSA;
4803         SAFEARRAYBOUND dimensions [4];
4804         long i;
4805         HRESULT hr = S_OK;
4806         VARIANT *pData;
4807
4808         dimensions [0].lLbound = 15;
4809         dimensions [0].cElements = 10;
4810         dimensions [1].lLbound = 20;
4811         dimensions [1].cElements = 3;
4812         dimensions [2].lLbound = 5;
4813         dimensions [2].cElements = 6;
4814         dimensions [3].lLbound = 12;
4815         dimensions [3].cElements = 7;
4816
4817         pSA= SafeArrayCreate (VT_VARIANT, 4, dimensions);
4818
4819         SafeArrayAccessData (pSA, (void **)&pData);
4820
4821         for (i= 0; i< 10*3*6*7; i++) {
4822                 VariantInit(&pData [i]);
4823                 pData [i].vt = VT_I4;
4824                 pData [i].lVal = i;
4825         }
4826         SafeArrayUnaccessData (pSA);
4827         *safearray = pSA;
4828         return hr;
4829 }
4830
4831 LIBTEST_API int STDCALL 
4832 mono_test_marshal_safearray_in_byval_1dim_empty (SAFEARRAY* safearray)
4833 {
4834         /* Check that array is one dimensional and empty */
4835
4836         UINT dim;
4837         long lbound, ubound;
4838         
4839         dim = SafeArrayGetDim (safearray);
4840         if (dim != 1)
4841                 return 1;
4842
4843         SafeArrayGetLBound (safearray, 1, &lbound);
4844         SafeArrayGetUBound (safearray, 1, &ubound);
4845
4846         if ((lbound > 0) || (ubound > 0))
4847                 return 1;
4848
4849         return 0;
4850 }
4851
4852 LIBTEST_API int STDCALL 
4853 mono_test_marshal_safearray_in_byval_1dim_vt_i4 (SAFEARRAY* safearray)
4854 {
4855         /* Check that array is one dimensional containing integers from 1 to 10 */
4856
4857         UINT dim;
4858         long lbound, ubound;
4859         VARIANT *pData; 
4860         long i;
4861         int result=0;
4862
4863         dim = SafeArrayGetDim (safearray);
4864         if (dim != 1)
4865                 return 1;
4866
4867         SafeArrayGetLBound (safearray, 1, &lbound);
4868         SafeArrayGetUBound (safearray, 1, &ubound);
4869
4870         if ((lbound != 0) || (ubound != 9))
4871                 return 1;
4872
4873         SafeArrayAccessData (safearray, (void **)&pData);
4874         for (i= lbound; i <= ubound; i++) {
4875                 if ((VariantChangeType (&pData [i], &pData [i], VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK) || (pData [i].lVal != i + 1))
4876                         result = 1;
4877         }
4878         SafeArrayUnaccessData (safearray);
4879
4880         return result;
4881 }
4882
4883 LIBTEST_API int STDCALL 
4884 mono_test_marshal_safearray_in_byval_1dim_vt_mixed (SAFEARRAY* safearray)
4885 {
4886         /* Check that array is one dimensional containing integers mixed with strings from 0 to 12 */
4887
4888         UINT dim;
4889         long lbound, ubound;
4890         VARIANT *pData; 
4891         long i;
4892         long indices [1];
4893         VARIANT element;
4894         int result=0;
4895
4896         VariantInit (&element);
4897
4898         dim = SafeArrayGetDim (safearray);
4899         if (dim != 1)
4900                 return 1;
4901
4902         SafeArrayGetLBound (safearray, 1, &lbound);
4903         SafeArrayGetUBound (safearray, 1, &ubound);
4904                 
4905         if ((lbound != 0) || (ubound != 12))
4906                 return 1;
4907
4908         SafeArrayAccessData (safearray, (void **)&pData);
4909         for (i= lbound; i <= ubound; i++) {
4910                 if ((i%2 == 0) && (pData [i].vt != VT_I4))
4911                         result = 1;
4912                 if ((i%2 == 1) && (pData [i].vt != VT_BSTR))
4913                         result = 1;
4914                 if ((VariantChangeType (&pData [i], &pData [i], VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK) || (pData [i].lVal != i))
4915                         result = 1;
4916         }
4917         SafeArrayUnaccessData (safearray);
4918
4919         /* Change the first element of the array to verify that [in] parameters are not marshalled back to the managed side */
4920
4921         indices [0] = 0;
4922         element.vt = VT_I4;
4923         element.lVal = 333;
4924         SafeArrayPutElement (safearray, indices, &element);
4925         VariantClear (&element);
4926
4927         return result;
4928 }
4929
4930 LIBTEST_API int STDCALL 
4931 mono_test_marshal_safearray_in_byval_2dim_vt_i4 (SAFEARRAY* safearray)
4932 {
4933         /* Check that array is one dimensional containing integers mixed with strings from 0 to 12 */
4934
4935         UINT dim;
4936         long lbound1, ubound1, lbound2, ubound2;
4937         long i, j, failed;
4938         long indices [2];
4939         VARIANT element;
4940
4941         VariantInit (&element);
4942
4943         dim = SafeArrayGetDim (safearray);
4944         if (dim != 2)
4945                 return 1;
4946
4947         SafeArrayGetLBound (safearray, 1, &lbound1);
4948         SafeArrayGetUBound (safearray, 1, &ubound1);
4949
4950         if ((lbound1 != 0) || (ubound1 != 1))
4951                 return 1;
4952
4953         SafeArrayGetLBound (safearray, 2, &lbound2);
4954         SafeArrayGetUBound (safearray, 2, &ubound2);
4955
4956         if ((lbound2 != 0) || (ubound2 != 3)) {
4957                 return 1;
4958         }
4959
4960         for (i= lbound1; i <= ubound1; i++) {
4961                 indices [0] = i;
4962                 for (j= lbound2; j <= ubound2; j++) {
4963                         indices [1] = j;
4964                         if (SafeArrayGetElement (safearray, indices, &element) != S_OK)
4965                                 return 1;
4966                         failed = ((element.vt != VT_I4) || (element.lVal != 10*(i+1)+(j+1)));
4967                         VariantClear (&element);
4968                         if (failed)
4969                                 return 1;
4970                 }
4971         }
4972
4973         /* Change the first element of the array to verify that [in] parameters are not marshalled back to the managed side */
4974
4975         indices [0] = 0;
4976         indices [1] = 0;
4977         element.vt = VT_I4;
4978         element.lVal = 333;
4979         SafeArrayPutElement (safearray, indices, &element);
4980         VariantClear (&element);
4981
4982         return 0;
4983 }
4984
4985 LIBTEST_API int STDCALL 
4986 mono_test_marshal_safearray_in_byval_3dim_vt_bstr (SAFEARRAY* safearray)
4987 {
4988         /* Check that array is one dimensional containing integers mixed with strings from 0 to 12 */
4989
4990         UINT dim;
4991         long lbound1, ubound1, lbound2, ubound2, lbound3, ubound3;
4992         long i, j, k, failed;
4993         long indices [3];
4994         VARIANT element;
4995
4996         VariantInit (&element);
4997
4998         dim = SafeArrayGetDim (safearray);
4999         if (dim != 3)
5000                 return 1;
5001
5002         SafeArrayGetLBound (safearray, 1, &lbound1);
5003         SafeArrayGetUBound (safearray, 1, &ubound1);
5004
5005         if ((lbound1 != 0) || (ubound1 != 1))
5006                 return 1;
5007
5008         SafeArrayGetLBound (safearray, 2, &lbound2);
5009         SafeArrayGetUBound (safearray, 2, &ubound2);
5010
5011         if ((lbound2 != 0) || (ubound2 != 1))
5012                 return 1;
5013
5014         SafeArrayGetLBound (safearray, 3, &lbound3);
5015         SafeArrayGetUBound (safearray, 3, &ubound3);
5016
5017         if ((lbound3 != 0) || (ubound3 != 2))
5018                 return 1;
5019
5020         for (i= lbound1; i <= ubound1; i++) {
5021                 indices [0] = i;
5022                 for (j= lbound2; j <= ubound2; j++) {
5023                         indices [1] = j;
5024                 for (k= lbound3; k <= ubound3; k++) {
5025                                 indices [2] = k;
5026                                 if (SafeArrayGetElement (safearray, indices, &element) != S_OK)
5027                                         return 1;
5028                                 failed = ((element.vt != VT_BSTR) 
5029                                         || (VariantChangeType (&element, &element, VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK) 
5030                                         || (element.lVal != 100*(i+1)+10*(j+1)+(k+1)));
5031                                 VariantClear (&element);
5032                                 if (failed)
5033                                         return 1;
5034                         }
5035                 }
5036         }
5037
5038         /* Change the first element of the array to verify that [in] parameters are not marshalled back to the managed side */
5039
5040         indices [0] = 0;
5041         indices [1] = 0;
5042         indices [2] = 0;
5043         element.vt = VT_BSTR;
5044         element.bstrVal = SysAllocString(L"Should not be copied");
5045         SafeArrayPutElement (safearray, indices, &element);
5046         VariantClear (&element);
5047
5048         return 0;
5049 }
5050
5051 LIBTEST_API int STDCALL 
5052 mono_test_marshal_safearray_in_byref_3dim_vt_bstr (SAFEARRAY** safearray)
5053 {
5054         return mono_test_marshal_safearray_in_byval_3dim_vt_bstr (*safearray);
5055 }
5056
5057 LIBTEST_API int STDCALL 
5058 mono_test_marshal_safearray_in_out_byref_1dim_empty (SAFEARRAY** safearray)
5059 {
5060         /* Check that the input array is what is expected and change it so the caller can check */
5061         /* correct marshalling back to managed code                                             */
5062
5063         UINT dim;
5064         long lbound, ubound;
5065         SAFEARRAYBOUND dimensions [1];
5066         long i;
5067         wchar_t buffer [20];
5068         HRESULT hr = S_OK;
5069         long indices [1];
5070
5071         /* Check that in array is one dimensional and empty */
5072
5073         dim = SafeArrayGetDim (*safearray);
5074         if (dim != 1) {
5075                 return 1;
5076         }
5077
5078         SafeArrayGetLBound (*safearray, 1, &lbound);
5079         SafeArrayGetUBound (*safearray, 1, &ubound);
5080                 
5081         if ((lbound > 0) || (ubound > 0)) {
5082                 return 1;
5083         }
5084
5085         /* Re-dimension the array and return a one-dimensional array of 8 variants filled with "0" to "7" */
5086
5087         dimensions [0].lLbound = 0;
5088         dimensions [0].cElements = 8;
5089
5090         hr = SafeArrayRedim (*safearray, dimensions);
5091         if (hr != S_OK)
5092                 return 1;
5093
5094         for (i= dimensions [0].lLbound; i< (dimensions [0].lLbound + dimensions [0].cElements); i++) {
5095                 VARIANT vOut;
5096                 VariantInit (&vOut);
5097                 vOut.vt = VT_BSTR;
5098                 _ltow (i,buffer,10);
5099                 vOut.bstrVal = SysAllocString (buffer);
5100                 indices [0] = i;
5101                 if ((hr = SafeArrayPutElement (*safearray, indices, &vOut)) != S_OK) {
5102                         VariantClear (&vOut);
5103                         SafeArrayDestroy (*safearray);
5104                         return hr;
5105                 }
5106                 VariantClear (&vOut);
5107         }
5108         return hr;
5109 }
5110
5111 LIBTEST_API int STDCALL 
5112 mono_test_marshal_safearray_in_out_byref_3dim_vt_bstr (SAFEARRAY** safearray)
5113 {
5114         /* Check that the input array is what is expected and change it so the caller can check */
5115         /* correct marshalling back to managed code                                             */
5116
5117         UINT dim;
5118         long lbound1, ubound1, lbound2, ubound2, lbound3, ubound3;
5119         SAFEARRAYBOUND dimensions [1];
5120         long i, j, k, failed;
5121         wchar_t buffer [20];
5122         HRESULT hr = S_OK;
5123         long indices [3];
5124         VARIANT element;
5125
5126         VariantInit (&element);
5127
5128         /* Check that in array is three dimensional and contains the expected values */
5129
5130         dim = SafeArrayGetDim (*safearray);
5131         if (dim != 3)
5132                 return 1;
5133
5134         SafeArrayGetLBound (*safearray, 1, &lbound1);
5135         SafeArrayGetUBound (*safearray, 1, &ubound1);
5136
5137         if ((lbound1 != 0) || (ubound1 != 1))
5138                 return 1;
5139
5140         SafeArrayGetLBound (*safearray, 2, &lbound2);
5141         SafeArrayGetUBound (*safearray, 2, &ubound2);
5142
5143         if ((lbound2 != 0) || (ubound2 != 1))
5144                 return 1;
5145
5146         SafeArrayGetLBound (*safearray, 3, &lbound3);
5147         SafeArrayGetUBound (*safearray, 3, &ubound3);
5148
5149         if ((lbound3 != 0) || (ubound3 != 2))
5150                 return 1;
5151
5152         for (i= lbound1; i <= ubound1; i++) {
5153                 indices [0] = i;
5154                 for (j= lbound2; j <= ubound2; j++) {
5155                         indices [1] = j;
5156                         for (k= lbound3; k <= ubound3; k++) {
5157                                 indices [2] = k;
5158                                 if (SafeArrayGetElement (*safearray, indices, &element) != S_OK)
5159                                         return 1;
5160                                 failed = ((element.vt != VT_BSTR) 
5161                                         || (VariantChangeType (&element, &element, VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK) 
5162                                         || (element.lVal != 100*(i+1)+10*(j+1)+(k+1)));
5163                                 VariantClear (&element);
5164                                 if (failed)
5165                                         return 1;
5166                         }
5167                 }
5168         }
5169
5170         hr = SafeArrayDestroy (*safearray);
5171         if (hr != S_OK)
5172                 return 1;
5173
5174         /* Return a new one-dimensional array of 8 variants filled with "0" to "7" */
5175
5176         dimensions [0].lLbound = 0;
5177         dimensions [0].cElements = 8;
5178
5179         *safearray = SafeArrayCreate (VT_VARIANT, 1, dimensions);
5180
5181         for (i= dimensions [0].lLbound; i< (dimensions [0].lLbound + dimensions [0].cElements); i++) {
5182                 VARIANT vOut;
5183                 VariantInit (&vOut);
5184                 vOut.vt = VT_BSTR;
5185                 _ltow (i,buffer,10);
5186                 vOut.bstrVal = SysAllocString (buffer);
5187                 indices [0] = i;
5188                 if ((hr = SafeArrayPutElement (*safearray, indices, &vOut)) != S_OK) {
5189                         VariantClear (&vOut);
5190                         SafeArrayDestroy (*safearray);
5191                         return hr;
5192                 }
5193                 VariantClear (&vOut);
5194         }
5195         return hr;
5196 }
5197
5198 LIBTEST_API int STDCALL 
5199 mono_test_marshal_safearray_in_out_byref_1dim_vt_i4 (SAFEARRAY** safearray)
5200 {
5201         /* Check that the input array is what is expected and change it so the caller can check */
5202         /* correct marshalling back to managed code                                             */
5203
5204         UINT dim;
5205         long lbound1, ubound1;
5206         long i, failed;
5207         HRESULT hr = S_OK;
5208         long indices [1];
5209         VARIANT element;
5210         
5211         VariantInit (&element);
5212
5213         /* Check that in array is one dimensional and contains the expected value */
5214
5215         dim = SafeArrayGetDim (*safearray);
5216         if (dim != 1)
5217                 return 1;
5218
5219         SafeArrayGetLBound (*safearray, 1, &lbound1);
5220         SafeArrayGetUBound (*safearray, 1, &ubound1);
5221
5222         ubound1 = 1;
5223         if ((lbound1 != 0) || (ubound1 != 1))
5224                 return 1;
5225         ubound1 = 0;
5226
5227         for (i= lbound1; i <= ubound1; i++) {
5228                 indices [0] = i;
5229                 if (SafeArrayGetElement (*safearray, indices, &element) != S_OK)
5230                         return 1;
5231                 failed = (element.vt != VT_I4) || (element.lVal != i+1);
5232                 VariantClear (&element);
5233                 if (failed)
5234                         return 1;
5235         }
5236
5237         /* Change one of the elements of the array to verify that [out] parameter is marshalled back to the managed side */
5238
5239         indices [0] = 0;
5240         element.vt = VT_I4;
5241         element.lVal = -1;
5242         SafeArrayPutElement (*safearray, indices, &element);
5243         VariantClear (&element);
5244
5245         return hr;
5246 }
5247
5248 LIBTEST_API int STDCALL 
5249 mono_test_marshal_safearray_in_out_byval_1dim_vt_i4 (SAFEARRAY* safearray)
5250 {
5251         /* Check that the input array is what is expected and change it so the caller can check */
5252         /* correct marshalling back to managed code                                             */
5253
5254         UINT dim;
5255         long lbound1, ubound1;
5256         SAFEARRAYBOUND dimensions [1];
5257         long i, failed;
5258         HRESULT hr = S_OK;
5259         long indices [1];
5260         VARIANT element;
5261
5262         VariantInit (&element);
5263
5264         /* Check that in array is one dimensional and contains the expected value */
5265
5266         dim = SafeArrayGetDim (safearray);
5267         if (dim != 1)
5268                 return 1;
5269
5270         SafeArrayGetLBound (safearray, 1, &lbound1);
5271         SafeArrayGetUBound (safearray, 1, &ubound1);
5272                 
5273         if ((lbound1 != 0) || (ubound1 != 0))
5274                 return 1;
5275
5276         for (i= lbound1; i <= ubound1; i++) {
5277                 indices [0] = i;
5278                 if (SafeArrayGetElement (safearray, indices, &element) != S_OK)
5279                         return 1;
5280                 failed = (element.vt != VT_I4) || (element.lVal != i+1);
5281                 VariantClear (&element);
5282                 if (failed)
5283                         return 1;
5284         }
5285
5286         /* Change the array to verify how [out] parameter is marshalled back to the managed side */
5287
5288         /* Redimension the array */
5289         dimensions [0].lLbound = lbound1;
5290         dimensions [0].cElements = 2;
5291         hr = SafeArrayRedim(safearray, dimensions);
5292
5293         indices [0] = 0;
5294         element.vt = VT_I4;
5295         element.lVal = 12345;
5296         SafeArrayPutElement (safearray, indices, &element);
5297         VariantClear (&element);
5298
5299         indices [0] = 1;
5300         element.vt = VT_I4;
5301         element.lVal = -12345;
5302         SafeArrayPutElement (safearray, indices, &element);
5303         VariantClear (&element);
5304
5305         return hr;
5306 }
5307
5308 LIBTEST_API int STDCALL 
5309 mono_test_marshal_safearray_in_out_byval_3dim_vt_bstr (SAFEARRAY* safearray)
5310 {
5311         /* Check that the input array is what is expected and change it so the caller can check */
5312         /* correct marshalling back to managed code                                             */
5313
5314         UINT dim;
5315         long lbound1, ubound1, lbound2, ubound2, lbound3, ubound3;
5316         long i, j, k, failed;
5317         HRESULT hr = S_OK;
5318         long indices [3];
5319         VARIANT element;
5320
5321         VariantInit (&element);
5322
5323         /* Check that in array is three dimensional and contains the expected values */
5324
5325         dim = SafeArrayGetDim (safearray);
5326         if (dim != 3)
5327                 return 1;
5328
5329         SafeArrayGetLBound (safearray, 1, &lbound1);
5330         SafeArrayGetUBound (safearray, 1, &ubound1);
5331
5332         if ((lbound1 != 0) || (ubound1 != 1))
5333                 return 1;
5334
5335         SafeArrayGetLBound (safearray, 2, &lbound2);
5336         SafeArrayGetUBound (safearray, 2, &ubound2);
5337
5338         if ((lbound2 != 0) || (ubound2 != 1))
5339                 return 1;
5340
5341         SafeArrayGetLBound (safearray, 3, &lbound3);
5342         SafeArrayGetUBound (safearray, 3, &ubound3);
5343
5344         if ((lbound3 != 0) || (ubound3 != 2))
5345                 return 1;
5346
5347         for (i= lbound1; i <= ubound1; i++) {
5348                 indices [0] = i;
5349                 for (j= lbound2; j <= ubound2; j++) {
5350                         indices [1] = j;
5351                         for (k= lbound3; k <= ubound3; k++) {
5352                                 indices [2] = k;
5353                                 if (SafeArrayGetElement (safearray, indices, &element) != S_OK)
5354                                         return 1;
5355                                 failed = ((element.vt != VT_BSTR) 
5356                                         || (VariantChangeType (&element, &element, VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK) 
5357                                         || (element.lVal != 100*(i+1)+10*(j+1)+(k+1)));
5358                                 VariantClear (&element);
5359                                 if (failed)
5360                                         return 1;
5361                         }
5362                 }
5363         }
5364
5365         /* Change the elements of the array to verify that [out] parameter is marshalled back to the managed side */
5366
5367         indices [0] = 1;
5368         indices [1] = 1;
5369         indices [2] = 2;
5370         element.vt = VT_I4;
5371         element.lVal = 333;
5372         SafeArrayPutElement (safearray, indices, &element);
5373         VariantClear (&element);
5374
5375         indices [0] = 1;
5376         indices [1] = 1;
5377         indices [2] = 1;
5378         element.vt = VT_I4;
5379         element.lVal = 111;
5380         SafeArrayPutElement (safearray, indices, &element);
5381         VariantClear (&element);
5382
5383         indices [0] = 0;
5384         indices [1] = 1;
5385         indices [2] = 0;
5386         element.vt = VT_BSTR;
5387         element.bstrVal = marshal_bstr_alloc("ABCDEFG");
5388         SafeArrayPutElement (safearray, indices, &element);
5389         VariantClear (&element);
5390
5391         return hr;
5392 }
5393
5394 LIBTEST_API int STDCALL 
5395 mono_test_marshal_safearray_mixed(
5396                 SAFEARRAY  *safearray1,
5397                 SAFEARRAY **safearray2,
5398                 SAFEARRAY  *safearray3,
5399                 SAFEARRAY **safearray4
5400                 )
5401 {
5402         HRESULT hr = S_OK;
5403
5404         /* Initialize out parameters */
5405         *safearray2 = NULL;
5406
5407         /* array1: Check that in array is one dimensional and contains the expected value */
5408         hr = mono_test_marshal_safearray_in_out_byval_1dim_vt_i4 (safearray1);
5409
5410         /* array2: Fill in with some values to check on the managed side */
5411         if (hr == S_OK)
5412                 hr = mono_test_marshal_safearray_out_1dim_vt_bstr (safearray2);
5413
5414         /* array3: Check that in array is one dimensional and contains the expected value */
5415         if (hr == S_OK)
5416                 hr = mono_test_marshal_safearray_in_byval_1dim_vt_mixed(safearray3);
5417
5418         /* array4: Check input values and fill in with some values to check on the managed side */
5419         if (hr == S_OK)
5420                 hr = mono_test_marshal_safearray_in_out_byref_3dim_vt_bstr(safearray4);
5421
5422         return hr;
5423 }
5424
5425 #endif
5426
5427 static int call_managed_res;
5428
5429 static void
5430 call_managed (gpointer arg)
5431 {
5432         SimpleDelegate del = (SimpleDelegate)arg;
5433
5434         call_managed_res = del (42);
5435 }
5436
5437 LIBTEST_API int STDCALL 
5438 mono_test_marshal_thread_attach (SimpleDelegate del)
5439 {
5440 #ifdef WIN32
5441         return 43;
5442 #else
5443         int res;
5444         pthread_t t;
5445
5446         res = pthread_create (&t, NULL, (gpointer (*)(gpointer))call_managed, del);
5447         g_assert (res == 0);
5448         pthread_join (t, NULL);
5449
5450         return call_managed_res;
5451 #endif
5452 }
5453
5454 typedef int (STDCALL *Callback) (void);
5455
5456 static Callback callback;
5457
5458 LIBTEST_API void STDCALL 
5459 mono_test_marshal_set_callback (Callback cb)
5460 {
5461         callback = cb;
5462 }
5463
5464 LIBTEST_API int STDCALL 
5465 mono_test_marshal_call_callback (void)
5466 {
5467         return callback ();
5468 }
5469
5470 LIBTEST_API int STDCALL
5471 mono_test_marshal_lpstr (char *str)
5472 {
5473         return strcmp ("ABC", str);
5474 }
5475
5476 LIBTEST_API int STDCALL
5477 mono_test_marshal_lpwstr (gunichar2 *str)
5478 {
5479         char *s;
5480         int res;
5481
5482         s = g_utf16_to_utf8 (str, -1, NULL, NULL, NULL);
5483         res = strcmp ("ABC", s);
5484         g_free (s);
5485
5486         return res;
5487 }
5488
5489 LIBTEST_API char* STDCALL
5490 mono_test_marshal_return_lpstr (void)
5491 {
5492         char *res = (char *)marshal_alloc (4);
5493         strcpy (res, "XYZ");
5494         return res;
5495 }
5496
5497
5498 LIBTEST_API gunichar2* STDCALL
5499 mono_test_marshal_return_lpwstr (void)
5500 {
5501         gunichar2 *res = (gunichar2 *)marshal_alloc (8);
5502         gunichar2* tmp = g_utf8_to_utf16 ("XYZ", -1, NULL, NULL, NULL);
5503
5504         memcpy (res, tmp, 8);
5505         g_free (tmp);
5506
5507         return res;
5508 }
5509
5510 typedef struct {
5511         double d;
5512 } SingleDoubleStruct;
5513
5514 LIBTEST_API SingleDoubleStruct STDCALL
5515 mono_test_marshal_return_single_double_struct (void)
5516 {
5517         SingleDoubleStruct res;
5518
5519         res.d = 3.0;
5520
5521         return res;
5522 }
5523
5524
5525 #ifndef TARGET_X86
5526
5527 LIBTEST_API int STDCALL
5528 mono_test_has_thiscall (void)
5529 {
5530         return 1;
5531 }
5532
5533 LIBTEST_API int
5534 _mono_test_native_thiscall1 (int arg)
5535 {
5536         return arg;
5537 }
5538
5539 LIBTEST_API int
5540 _mono_test_native_thiscall2 (int arg, int arg2)
5541 {
5542         return arg + (arg2^1);
5543 }
5544
5545 LIBTEST_API int
5546 _mono_test_native_thiscall3 (int arg, int arg2, int arg3)
5547 {
5548         return arg + (arg2^1) + (arg3^2);
5549 }
5550
5551 #elif defined(__GNUC__)
5552
5553 LIBTEST_API int STDCALL
5554 mono_test_has_thiscall (void)
5555 {
5556         return 1;
5557 }
5558
5559 #define def_asm_fn(name) \
5560         "\t.align 4\n" \
5561         "\t.globl _" #name "\n" \
5562         "_" #name ":\n" \
5563         "\t.globl __" #name "\n" \
5564         "__" #name ":\n"
5565
5566 asm(".text\n"
5567
5568 def_asm_fn(mono_test_native_thiscall1)
5569 "\tmovl %ecx,%eax\n"
5570 "\tret\n"
5571
5572 def_asm_fn(mono_test_native_thiscall2)
5573 "\tmovl %ecx,%eax\n"
5574 "\tmovl 4(%esp),%ecx\n"
5575 "\txorl $1,%ecx\n"
5576 "\taddl %ecx,%eax\n"
5577 "\tret $4\n"
5578
5579 def_asm_fn(mono_test_native_thiscall3)
5580 "\tmovl %ecx,%eax\n"
5581 "\tmovl 4(%esp),%ecx\n"
5582 "\txorl $1,%ecx\n"
5583 "\taddl %ecx,%eax\n"
5584 "\tmovl 8(%esp),%ecx\n"
5585 "\txorl $2,%ecx\n"
5586 "\taddl %ecx,%eax\n"
5587 "\tret $8\n"
5588
5589 );
5590
5591 #else
5592
5593 LIBTEST_API int STDCALL
5594 mono_test_has_thiscall (void)
5595 {
5596         return 0;
5597 }
5598
5599 #endif
5600
5601
5602 typedef struct {
5603         char f1;
5604 } sbyte1;
5605
5606 LIBTEST_API sbyte1 STDCALL
5607 mono_return_sbyte1 (sbyte1 s1, int addend) {
5608         if (s1.f1 != 1) {
5609                 fprintf(stderr, "mono_return_sbyte1 s1.f1: got %d but expected %d\n", s1.f1, 1);
5610         }
5611         s1.f1+=addend; 
5612         return s1;
5613 }
5614
5615 typedef struct {
5616         char f1,f2;
5617 } sbyte2;
5618
5619 LIBTEST_API sbyte2 STDCALL
5620 mono_return_sbyte2 (sbyte2 s2, int addend) {
5621         if (s2.f1 != 1) {
5622                 fprintf(stderr, "mono_return_sbyte2 s2.f1: got %d but expected %d\n", s2.f1, 1);
5623         }
5624         if (s2.f2 != 2) {
5625                 fprintf(stderr, "mono_return_sbyte2 s2.f2: got %d but expected %d\n", s2.f2, 2);
5626         }
5627         s2.f1+=addend; s2.f2+=addend; 
5628         return s2;
5629 }
5630
5631 typedef struct {
5632         char f1,f2,f3;
5633 } sbyte3;
5634
5635 LIBTEST_API sbyte3 STDCALL
5636 mono_return_sbyte3 (sbyte3 s3, int addend) {
5637         if (s3.f1 != 1) {
5638                 fprintf(stderr, "mono_return_sbyte3 s3.f1: got %d but expected %d\n", s3.f1, 1);
5639         }
5640         if (s3.f2 != 2) {
5641                 fprintf(stderr, "mono_return_sbyte3 s3.f2: got %d but expected %d\n", s3.f2, 2);
5642         }
5643         if (s3.f3 != 3) {
5644                 fprintf(stderr, "mono_return_sbyte3 s3.f3: got %d but expected %d\n", s3.f3, 3);
5645         }
5646         s3.f1+=addend; s3.f2+=addend; s3.f3+=addend; 
5647         return s3;
5648 }
5649
5650 typedef struct {
5651         char f1,f2,f3,f4;
5652 } sbyte4;
5653
5654 LIBTEST_API sbyte4 STDCALL
5655 mono_return_sbyte4 (sbyte4 s4, int addend) {
5656         if (s4.f1 != 1) {
5657                 fprintf(stderr, "mono_return_sbyte4 s4.f1: got %d but expected %d\n", s4.f1, 1);
5658         }
5659         if (s4.f2 != 2) {
5660                 fprintf(stderr, "mono_return_sbyte4 s4.f2: got %d but expected %d\n", s4.f2, 2);
5661         }
5662         if (s4.f3 != 3) {
5663                 fprintf(stderr, "mono_return_sbyte4 s4.f3: got %d but expected %d\n", s4.f3, 3);
5664         }
5665         if (s4.f4 != 4) {
5666                 fprintf(stderr, "mono_return_sbyte4 s4.f4: got %d but expected %d\n", s4.f4, 4);
5667         }
5668         s4.f1+=addend; s4.f2+=addend; s4.f3+=addend; s4.f4+=addend; 
5669         return s4;
5670 }
5671
5672 typedef struct {
5673         char f1,f2,f3,f4,f5;
5674 } sbyte5;
5675
5676 LIBTEST_API sbyte5 STDCALL
5677 mono_return_sbyte5 (sbyte5 s5, int addend) {
5678         if (s5.f1 != 1) {
5679                 fprintf(stderr, "mono_return_sbyte5 s5.f1: got %d but expected %d\n", s5.f1, 1);
5680         }
5681         if (s5.f2 != 2) {
5682                 fprintf(stderr, "mono_return_sbyte5 s5.f2: got %d but expected %d\n", s5.f2, 2);
5683         }
5684         if (s5.f3 != 3) {
5685                 fprintf(stderr, "mono_return_sbyte5 s5.f3: got %d but expected %d\n", s5.f3, 3);
5686         }
5687         if (s5.f4 != 4) {
5688                 fprintf(stderr, "mono_return_sbyte5 s5.f4: got %d but expected %d\n", s5.f4, 4);
5689         }
5690         if (s5.f5 != 5) {
5691                 fprintf(stderr, "mono_return_sbyte5 s5.f5: got %d but expected %d\n", s5.f5, 5);
5692         }
5693         s5.f1+=addend; s5.f2+=addend; s5.f3+=addend; s5.f4+=addend; s5.f5+=addend; 
5694         return s5;
5695 }
5696
5697 typedef struct {
5698         char f1,f2,f3,f4,f5,f6;
5699 } sbyte6;
5700
5701 LIBTEST_API sbyte6 STDCALL
5702 mono_return_sbyte6 (sbyte6 s6, int addend) {
5703         if (s6.f1 != 1) {
5704                 fprintf(stderr, "mono_return_sbyte6 s6.f1: got %d but expected %d\n", s6.f1, 1);
5705         }
5706         if (s6.f2 != 2) {
5707                 fprintf(stderr, "mono_return_sbyte6 s6.f2: got %d but expected %d\n", s6.f2, 2);
5708         }
5709         if (s6.f3 != 3) {
5710                 fprintf(stderr, "mono_return_sbyte6 s6.f3: got %d but expected %d\n", s6.f3, 3);
5711         }
5712         if (s6.f4 != 4) {
5713                 fprintf(stderr, "mono_return_sbyte6 s6.f4: got %d but expected %d\n", s6.f4, 4);
5714         }
5715         if (s6.f5 != 5) {
5716                 fprintf(stderr, "mono_return_sbyte6 s6.f5: got %d but expected %d\n", s6.f5, 5);
5717         }
5718         if (s6.f6 != 6) {
5719                 fprintf(stderr, "mono_return_sbyte6 s6.f6: got %d but expected %d\n", s6.f6, 6);
5720         }
5721         s6.f1+=addend; s6.f2+=addend; s6.f3+=addend; s6.f4+=addend; s6.f5+=addend; s6.f6+=addend; 
5722         return s6;
5723 }
5724
5725 typedef struct {
5726         char f1,f2,f3,f4,f5,f6,f7;
5727 } sbyte7;
5728
5729 LIBTEST_API sbyte7 STDCALL
5730 mono_return_sbyte7 (sbyte7 s7, int addend) {
5731         if (s7.f1 != 1) {
5732                 fprintf(stderr, "mono_return_sbyte7 s7.f1: got %d but expected %d\n", s7.f1, 1);
5733         }
5734         if (s7.f2 != 2) {
5735                 fprintf(stderr, "mono_return_sbyte7 s7.f2: got %d but expected %d\n", s7.f2, 2);
5736         }
5737         if (s7.f3 != 3) {
5738                 fprintf(stderr, "mono_return_sbyte7 s7.f3: got %d but expected %d\n", s7.f3, 3);
5739         }
5740         if (s7.f4 != 4) {
5741                 fprintf(stderr, "mono_return_sbyte7 s7.f4: got %d but expected %d\n", s7.f4, 4);
5742         }
5743         if (s7.f5 != 5) {
5744                 fprintf(stderr, "mono_return_sbyte7 s7.f5: got %d but expected %d\n", s7.f5, 5);
5745         }
5746         if (s7.f6 != 6) {
5747                 fprintf(stderr, "mono_return_sbyte7 s7.f6: got %d but expected %d\n", s7.f6, 6);
5748         }
5749         if (s7.f7 != 7) {
5750                 fprintf(stderr, "mono_return_sbyte7 s7.f7: got %d but expected %d\n", s7.f7, 7);
5751         }
5752         s7.f1+=addend; s7.f2+=addend; s7.f3+=addend; s7.f4+=addend; s7.f5+=addend; s7.f6+=addend; s7.f7+=addend; 
5753         return s7;
5754 }
5755
5756 typedef struct {
5757         char f1,f2,f3,f4,f5,f6,f7,f8;
5758 } sbyte8;
5759
5760 LIBTEST_API sbyte8 STDCALL
5761 mono_return_sbyte8 (sbyte8 s8, int addend) {
5762         if (s8.f1 != 1) {
5763                 fprintf(stderr, "mono_return_sbyte8 s8.f1: got %d but expected %d\n", s8.f1, 1);
5764         }
5765         if (s8.f2 != 2) {
5766                 fprintf(stderr, "mono_return_sbyte8 s8.f2: got %d but expected %d\n", s8.f2, 2);
5767         }
5768         if (s8.f3 != 3) {
5769                 fprintf(stderr, "mono_return_sbyte8 s8.f3: got %d but expected %d\n", s8.f3, 3);
5770         }
5771         if (s8.f4 != 4) {
5772                 fprintf(stderr, "mono_return_sbyte8 s8.f4: got %d but expected %d\n", s8.f4, 4);
5773         }
5774         if (s8.f5 != 5) {
5775                 fprintf(stderr, "mono_return_sbyte8 s8.f5: got %d but expected %d\n", s8.f5, 5);
5776         }
5777         if (s8.f6 != 6) {
5778                 fprintf(stderr, "mono_return_sbyte8 s8.f6: got %d but expected %d\n", s8.f6, 6);
5779         }
5780         if (s8.f7 != 7) {
5781                 fprintf(stderr, "mono_return_sbyte8 s8.f7: got %d but expected %d\n", s8.f7, 7);
5782         }
5783         if (s8.f8 != 8) {
5784                 fprintf(stderr, "mono_return_sbyte8 s8.f8: got %d but expected %d\n", s8.f8, 8);
5785         }
5786         s8.f1+=addend; s8.f2+=addend; s8.f3+=addend; s8.f4+=addend; s8.f5+=addend; s8.f6+=addend; s8.f7+=addend; s8.f8+=addend; 
5787         return s8;
5788 }
5789
5790 typedef struct {
5791         char f1,f2,f3,f4,f5,f6,f7,f8,f9;
5792 } sbyte9;
5793
5794 LIBTEST_API sbyte9 STDCALL
5795 mono_return_sbyte9 (sbyte9 s9, int addend) {
5796         if (s9.f1 != 1) {
5797                 fprintf(stderr, "mono_return_sbyte9 s9.f1: got %d but expected %d\n", s9.f1, 1);
5798         }
5799         if (s9.f2 != 2) {
5800                 fprintf(stderr, "mono_return_sbyte9 s9.f2: got %d but expected %d\n", s9.f2, 2);
5801         }
5802         if (s9.f3 != 3) {
5803                 fprintf(stderr, "mono_return_sbyte9 s9.f3: got %d but expected %d\n", s9.f3, 3);
5804         }
5805         if (s9.f4 != 4) {
5806                 fprintf(stderr, "mono_return_sbyte9 s9.f4: got %d but expected %d\n", s9.f4, 4);
5807         }
5808         if (s9.f5 != 5) {
5809                 fprintf(stderr, "mono_return_sbyte9 s9.f5: got %d but expected %d\n", s9.f5, 5);
5810         }
5811         if (s9.f6 != 6) {
5812                 fprintf(stderr, "mono_return_sbyte9 s9.f6: got %d but expected %d\n", s9.f6, 6);
5813         }
5814         if (s9.f7 != 7) {
5815                 fprintf(stderr, "mono_return_sbyte9 s9.f7: got %d but expected %d\n", s9.f7, 7);
5816         }
5817         if (s9.f8 != 8) {
5818                 fprintf(stderr, "mono_return_sbyte9 s9.f8: got %d but expected %d\n", s9.f8, 8);
5819         }
5820         if (s9.f9 != 9) {
5821                 fprintf(stderr, "mono_return_sbyte9 s9.f9: got %d but expected %d\n", s9.f9, 9);
5822         }
5823         s9.f1+=addend; s9.f2+=addend; s9.f3+=addend; s9.f4+=addend; s9.f5+=addend; s9.f6+=addend; s9.f7+=addend; s9.f8+=addend; s9.f9+=addend; 
5824         return s9;
5825 }
5826
5827 typedef struct {
5828         char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10;
5829 } sbyte10;
5830
5831 LIBTEST_API sbyte10 STDCALL
5832 mono_return_sbyte10 (sbyte10 s10, int addend) {
5833         if (s10.f1 != 1) {
5834                 fprintf(stderr, "mono_return_sbyte10 s10.f1: got %d but expected %d\n", s10.f1, 1);
5835         }
5836         if (s10.f2 != 2) {
5837                 fprintf(stderr, "mono_return_sbyte10 s10.f2: got %d but expected %d\n", s10.f2, 2);
5838         }
5839         if (s10.f3 != 3) {
5840                 fprintf(stderr, "mono_return_sbyte10 s10.f3: got %d but expected %d\n", s10.f3, 3);
5841         }
5842         if (s10.f4 != 4) {
5843                 fprintf(stderr, "mono_return_sbyte10 s10.f4: got %d but expected %d\n", s10.f4, 4);
5844         }
5845         if (s10.f5 != 5) {
5846                 fprintf(stderr, "mono_return_sbyte10 s10.f5: got %d but expected %d\n", s10.f5, 5);
5847         }
5848         if (s10.f6 != 6) {
5849                 fprintf(stderr, "mono_return_sbyte10 s10.f6: got %d but expected %d\n", s10.f6, 6);
5850         }
5851         if (s10.f7 != 7) {
5852                 fprintf(stderr, "mono_return_sbyte10 s10.f7: got %d but expected %d\n", s10.f7, 7);
5853         }
5854         if (s10.f8 != 8) {
5855                 fprintf(stderr, "mono_return_sbyte10 s10.f8: got %d but expected %d\n", s10.f8, 8);
5856         }
5857         if (s10.f9 != 9) {
5858                 fprintf(stderr, "mono_return_sbyte10 s10.f9: got %d but expected %d\n", s10.f9, 9);
5859         }
5860         if (s10.f10 != 10) {
5861                 fprintf(stderr, "mono_return_sbyte10 s10.f10: got %d but expected %d\n", s10.f10, 10);
5862         }
5863         s10.f1+=addend; s10.f2+=addend; s10.f3+=addend; s10.f4+=addend; s10.f5+=addend; s10.f6+=addend; s10.f7+=addend; s10.f8+=addend; s10.f9+=addend; s10.f10+=addend; 
5864         return s10;
5865 }
5866
5867 typedef struct {
5868         char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11;
5869 } sbyte11;
5870
5871 LIBTEST_API sbyte11 STDCALL
5872 mono_return_sbyte11 (sbyte11 s11, int addend) {
5873         if (s11.f1 != 1) {
5874                 fprintf(stderr, "mono_return_sbyte11 s11.f1: got %d but expected %d\n", s11.f1, 1);
5875         }
5876         if (s11.f2 != 2) {
5877                 fprintf(stderr, "mono_return_sbyte11 s11.f2: got %d but expected %d\n", s11.f2, 2);
5878         }
5879         if (s11.f3 != 3) {
5880                 fprintf(stderr, "mono_return_sbyte11 s11.f3: got %d but expected %d\n", s11.f3, 3);
5881         }
5882         if (s11.f4 != 4) {
5883                 fprintf(stderr, "mono_return_sbyte11 s11.f4: got %d but expected %d\n", s11.f4, 4);
5884         }
5885         if (s11.f5 != 5) {
5886                 fprintf(stderr, "mono_return_sbyte11 s11.f5: got %d but expected %d\n", s11.f5, 5);
5887         }
5888         if (s11.f6 != 6) {
5889                 fprintf(stderr, "mono_return_sbyte11 s11.f6: got %d but expected %d\n", s11.f6, 6);
5890         }
5891         if (s11.f7 != 7) {
5892                 fprintf(stderr, "mono_return_sbyte11 s11.f7: got %d but expected %d\n", s11.f7, 7);
5893         }
5894         if (s11.f8 != 8) {
5895                 fprintf(stderr, "mono_return_sbyte11 s11.f8: got %d but expected %d\n", s11.f8, 8);
5896         }
5897         if (s11.f9 != 9) {
5898                 fprintf(stderr, "mono_return_sbyte11 s11.f9: got %d but expected %d\n", s11.f9, 9);
5899         }
5900         if (s11.f10 != 10) {
5901                 fprintf(stderr, "mono_return_sbyte11 s11.f10: got %d but expected %d\n", s11.f10, 10);
5902         }
5903         if (s11.f11 != 11) {
5904                 fprintf(stderr, "mono_return_sbyte11 s11.f11: got %d but expected %d\n", s11.f11, 11);
5905         }
5906         s11.f1+=addend; s11.f2+=addend; s11.f3+=addend; s11.f4+=addend; s11.f5+=addend; s11.f6+=addend; s11.f7+=addend; s11.f8+=addend; s11.f9+=addend; s11.f10+=addend; s11.f11+=addend; 
5907         return s11;
5908 }
5909
5910 typedef struct {
5911         char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12;
5912 } sbyte12;
5913
5914 LIBTEST_API sbyte12 STDCALL
5915 mono_return_sbyte12 (sbyte12 s12, int addend) {
5916         if (s12.f1 != 1) {
5917                 fprintf(stderr, "mono_return_sbyte12 s12.f1: got %d but expected %d\n", s12.f1, 1);
5918         }
5919         if (s12.f2 != 2) {
5920                 fprintf(stderr, "mono_return_sbyte12 s12.f2: got %d but expected %d\n", s12.f2, 2);
5921         }
5922         if (s12.f3 != 3) {
5923                 fprintf(stderr, "mono_return_sbyte12 s12.f3: got %d but expected %d\n", s12.f3, 3);
5924         }
5925         if (s12.f4 != 4) {
5926                 fprintf(stderr, "mono_return_sbyte12 s12.f4: got %d but expected %d\n", s12.f4, 4);
5927         }
5928         if (s12.f5 != 5) {
5929                 fprintf(stderr, "mono_return_sbyte12 s12.f5: got %d but expected %d\n", s12.f5, 5);
5930         }
5931         if (s12.f6 != 6) {
5932                 fprintf(stderr, "mono_return_sbyte12 s12.f6: got %d but expected %d\n", s12.f6, 6);
5933         }
5934         if (s12.f7 != 7) {
5935                 fprintf(stderr, "mono_return_sbyte12 s12.f7: got %d but expected %d\n", s12.f7, 7);
5936         }
5937         if (s12.f8 != 8) {
5938                 fprintf(stderr, "mono_return_sbyte12 s12.f8: got %d but expected %d\n", s12.f8, 8);
5939         }
5940         if (s12.f9 != 9) {
5941                 fprintf(stderr, "mono_return_sbyte12 s12.f9: got %d but expected %d\n", s12.f9, 9);
5942         }
5943         if (s12.f10 != 10) {
5944                 fprintf(stderr, "mono_return_sbyte12 s12.f10: got %d but expected %d\n", s12.f10, 10);
5945         }
5946         if (s12.f11 != 11) {
5947                 fprintf(stderr, "mono_return_sbyte12 s12.f11: got %d but expected %d\n", s12.f11, 11);
5948         }
5949         if (s12.f12 != 12) {
5950                 fprintf(stderr, "mono_return_sbyte12 s12.f12: got %d but expected %d\n", s12.f12, 12);
5951         }
5952         s12.f1+=addend; s12.f2+=addend; s12.f3+=addend; s12.f4+=addend; s12.f5+=addend; s12.f6+=addend; s12.f7+=addend; s12.f8+=addend; s12.f9+=addend; s12.f10+=addend; s12.f11+=addend; s12.f12+=addend; 
5953         return s12;
5954 }
5955
5956 typedef struct {
5957         char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13;
5958 } sbyte13;
5959
5960 LIBTEST_API sbyte13 STDCALL
5961 mono_return_sbyte13 (sbyte13 s13, int addend) {
5962         if (s13.f1 != 1) {
5963                 fprintf(stderr, "mono_return_sbyte13 s13.f1: got %d but expected %d\n", s13.f1, 1);
5964         }
5965         if (s13.f2 != 2) {
5966                 fprintf(stderr, "mono_return_sbyte13 s13.f2: got %d but expected %d\n", s13.f2, 2);
5967         }
5968         if (s13.f3 != 3) {
5969                 fprintf(stderr, "mono_return_sbyte13 s13.f3: got %d but expected %d\n", s13.f3, 3);
5970         }
5971         if (s13.f4 != 4) {
5972                 fprintf(stderr, "mono_return_sbyte13 s13.f4: got %d but expected %d\n", s13.f4, 4);
5973         }
5974         if (s13.f5 != 5) {
5975                 fprintf(stderr, "mono_return_sbyte13 s13.f5: got %d but expected %d\n", s13.f5, 5);
5976         }
5977         if (s13.f6 != 6) {
5978                 fprintf(stderr, "mono_return_sbyte13 s13.f6: got %d but expected %d\n", s13.f6, 6);
5979         }
5980         if (s13.f7 != 7) {
5981                 fprintf(stderr, "mono_return_sbyte13 s13.f7: got %d but expected %d\n", s13.f7, 7);
5982         }
5983         if (s13.f8 != 8) {
5984                 fprintf(stderr, "mono_return_sbyte13 s13.f8: got %d but expected %d\n", s13.f8, 8);
5985         }
5986         if (s13.f9 != 9) {
5987                 fprintf(stderr, "mono_return_sbyte13 s13.f9: got %d but expected %d\n", s13.f9, 9);
5988         }
5989         if (s13.f10 != 10) {
5990                 fprintf(stderr, "mono_return_sbyte13 s13.f10: got %d but expected %d\n", s13.f10, 10);
5991         }
5992         if (s13.f11 != 11) {
5993                 fprintf(stderr, "mono_return_sbyte13 s13.f11: got %d but expected %d\n", s13.f11, 11);
5994         }
5995         if (s13.f12 != 12) {
5996                 fprintf(stderr, "mono_return_sbyte13 s13.f12: got %d but expected %d\n", s13.f12, 12);
5997         }
5998         if (s13.f13 != 13) {
5999                 fprintf(stderr, "mono_return_sbyte13 s13.f13: got %d but expected %d\n", s13.f13, 13);
6000         }
6001         s13.f1+=addend; s13.f2+=addend; s13.f3+=addend; s13.f4+=addend; s13.f5+=addend; s13.f6+=addend; s13.f7+=addend; s13.f8+=addend; s13.f9+=addend; s13.f10+=addend; s13.f11+=addend; s13.f12+=addend; s13.f13+=addend; 
6002         return s13;
6003 }
6004
6005 typedef struct {
6006         char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14;
6007 } sbyte14;
6008
6009 LIBTEST_API sbyte14 STDCALL
6010 mono_return_sbyte14 (sbyte14 s14, int addend) {
6011         if (s14.f1 != 1) {
6012                 fprintf(stderr, "mono_return_sbyte14 s14.f1: got %d but expected %d\n", s14.f1, 1);
6013         }
6014         if (s14.f2 != 2) {
6015                 fprintf(stderr, "mono_return_sbyte14 s14.f2: got %d but expected %d\n", s14.f2, 2);
6016         }
6017         if (s14.f3 != 3) {
6018                 fprintf(stderr, "mono_return_sbyte14 s14.f3: got %d but expected %d\n", s14.f3, 3);
6019         }
6020         if (s14.f4 != 4) {
6021                 fprintf(stderr, "mono_return_sbyte14 s14.f4: got %d but expected %d\n", s14.f4, 4);
6022         }
6023         if (s14.f5 != 5) {
6024                 fprintf(stderr, "mono_return_sbyte14 s14.f5: got %d but expected %d\n", s14.f5, 5);
6025         }
6026         if (s14.f6 != 6) {
6027                 fprintf(stderr, "mono_return_sbyte14 s14.f6: got %d but expected %d\n", s14.f6, 6);
6028         }
6029         if (s14.f7 != 7) {
6030                 fprintf(stderr, "mono_return_sbyte14 s14.f7: got %d but expected %d\n", s14.f7, 7);
6031         }
6032         if (s14.f8 != 8) {
6033                 fprintf(stderr, "mono_return_sbyte14 s14.f8: got %d but expected %d\n", s14.f8, 8);
6034         }
6035         if (s14.f9 != 9) {
6036                 fprintf(stderr, "mono_return_sbyte14 s14.f9: got %d but expected %d\n", s14.f9, 9);
6037         }
6038         if (s14.f10 != 10) {
6039                 fprintf(stderr, "mono_return_sbyte14 s14.f10: got %d but expected %d\n", s14.f10, 10);
6040         }
6041         if (s14.f11 != 11) {
6042                 fprintf(stderr, "mono_return_sbyte14 s14.f11: got %d but expected %d\n", s14.f11, 11);
6043         }
6044         if (s14.f12 != 12) {
6045                 fprintf(stderr, "mono_return_sbyte14 s14.f12: got %d but expected %d\n", s14.f12, 12);
6046         }
6047         if (s14.f13 != 13) {
6048                 fprintf(stderr, "mono_return_sbyte14 s14.f13: got %d but expected %d\n", s14.f13, 13);
6049         }
6050         if (s14.f14 != 14) {
6051                 fprintf(stderr, "mono_return_sbyte14 s14.f14: got %d but expected %d\n", s14.f14, 14);
6052         }
6053         s14.f1+=addend; s14.f2+=addend; s14.f3+=addend; s14.f4+=addend; s14.f5+=addend; s14.f6+=addend; s14.f7+=addend; s14.f8+=addend; s14.f9+=addend; s14.f10+=addend; s14.f11+=addend; s14.f12+=addend; s14.f13+=addend; s14.f14+=addend; 
6054         return s14;
6055 }
6056
6057 typedef struct {
6058         char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15;
6059 } sbyte15;
6060
6061 LIBTEST_API sbyte15 STDCALL
6062 mono_return_sbyte15 (sbyte15 s15, int addend) {
6063         if (s15.f1 != 1) {
6064                 fprintf(stderr, "mono_return_sbyte15 s15.f1: got %d but expected %d\n", s15.f1, 1);
6065         }
6066         if (s15.f2 != 2) {
6067                 fprintf(stderr, "mono_return_sbyte15 s15.f2: got %d but expected %d\n", s15.f2, 2);
6068         }
6069         if (s15.f3 != 3) {
6070                 fprintf(stderr, "mono_return_sbyte15 s15.f3: got %d but expected %d\n", s15.f3, 3);
6071         }
6072         if (s15.f4 != 4) {
6073                 fprintf(stderr, "mono_return_sbyte15 s15.f4: got %d but expected %d\n", s15.f4, 4);
6074         }
6075         if (s15.f5 != 5) {
6076                 fprintf(stderr, "mono_return_sbyte15 s15.f5: got %d but expected %d\n", s15.f5, 5);
6077         }
6078         if (s15.f6 != 6) {
6079                 fprintf(stderr, "mono_return_sbyte15 s15.f6: got %d but expected %d\n", s15.f6, 6);
6080         }
6081         if (s15.f7 != 7) {
6082                 fprintf(stderr, "mono_return_sbyte15 s15.f7: got %d but expected %d\n", s15.f7, 7);
6083         }
6084         if (s15.f8 != 8) {
6085                 fprintf(stderr, "mono_return_sbyte15 s15.f8: got %d but expected %d\n", s15.f8, 8);
6086         }
6087         if (s15.f9 != 9) {
6088                 fprintf(stderr, "mono_return_sbyte15 s15.f9: got %d but expected %d\n", s15.f9, 9);
6089         }
6090         if (s15.f10 != 10) {
6091                 fprintf(stderr, "mono_return_sbyte15 s15.f10: got %d but expected %d\n", s15.f10, 10);
6092         }
6093         if (s15.f11 != 11) {
6094                 fprintf(stderr, "mono_return_sbyte15 s15.f11: got %d but expected %d\n", s15.f11, 11);
6095         }
6096         if (s15.f12 != 12) {
6097                 fprintf(stderr, "mono_return_sbyte15 s15.f12: got %d but expected %d\n", s15.f12, 12);
6098         }
6099         if (s15.f13 != 13) {
6100                 fprintf(stderr, "mono_return_sbyte15 s15.f13: got %d but expected %d\n", s15.f13, 13);
6101         }
6102         if (s15.f14 != 14) {
6103                 fprintf(stderr, "mono_return_sbyte15 s15.f14: got %d but expected %d\n", s15.f14, 14);
6104         }
6105         if (s15.f15 != 15) {
6106                 fprintf(stderr, "mono_return_sbyte15 s15.f15: got %d but expected %d\n", s15.f15, 15);
6107         }
6108         s15.f1+=addend; s15.f2+=addend; s15.f3+=addend; s15.f4+=addend; s15.f5+=addend; s15.f6+=addend; s15.f7+=addend; s15.f8+=addend; s15.f9+=addend; s15.f10+=addend; s15.f11+=addend; s15.f12+=addend; s15.f13+=addend; s15.f14+=addend; s15.f15+=addend; 
6109         return s15;
6110 }
6111
6112 typedef struct {
6113         char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16;
6114 } sbyte16;
6115
6116 LIBTEST_API sbyte16 STDCALL
6117 mono_return_sbyte16 (sbyte16 s16, int addend) {
6118         if (s16.f1 != 1) {
6119                 fprintf(stderr, "mono_return_sbyte16 s16.f1: got %d but expected %d\n", s16.f1, 1);
6120         }
6121         if (s16.f2 != 2) {
6122                 fprintf(stderr, "mono_return_sbyte16 s16.f2: got %d but expected %d\n", s16.f2, 2);
6123         }
6124         if (s16.f3 != 3) {
6125                 fprintf(stderr, "mono_return_sbyte16 s16.f3: got %d but expected %d\n", s16.f3, 3);
6126         }
6127         if (s16.f4 != 4) {
6128                 fprintf(stderr, "mono_return_sbyte16 s16.f4: got %d but expected %d\n", s16.f4, 4);
6129         }
6130         if (s16.f5 != 5) {
6131                 fprintf(stderr, "mono_return_sbyte16 s16.f5: got %d but expected %d\n", s16.f5, 5);
6132         }
6133         if (s16.f6 != 6) {
6134                 fprintf(stderr, "mono_return_sbyte16 s16.f6: got %d but expected %d\n", s16.f6, 6);
6135         }
6136         if (s16.f7 != 7) {
6137                 fprintf(stderr, "mono_return_sbyte16 s16.f7: got %d but expected %d\n", s16.f7, 7);
6138         }
6139         if (s16.f8 != 8) {
6140                 fprintf(stderr, "mono_return_sbyte16 s16.f8: got %d but expected %d\n", s16.f8, 8);
6141         }
6142         if (s16.f9 != 9) {
6143                 fprintf(stderr, "mono_return_sbyte16 s16.f9: got %d but expected %d\n", s16.f9, 9);
6144         }
6145         if (s16.f10 != 10) {
6146                 fprintf(stderr, "mono_return_sbyte16 s16.f10: got %d but expected %d\n", s16.f10, 10);
6147         }
6148         if (s16.f11 != 11) {
6149                 fprintf(stderr, "mono_return_sbyte16 s16.f11: got %d but expected %d\n", s16.f11, 11);
6150         }
6151         if (s16.f12 != 12) {
6152                 fprintf(stderr, "mono_return_sbyte16 s16.f12: got %d but expected %d\n", s16.f12, 12);
6153         }
6154         if (s16.f13 != 13) {
6155                 fprintf(stderr, "mono_return_sbyte16 s16.f13: got %d but expected %d\n", s16.f13, 13);
6156         }
6157         if (s16.f14 != 14) {
6158                 fprintf(stderr, "mono_return_sbyte16 s16.f14: got %d but expected %d\n", s16.f14, 14);
6159         }
6160         if (s16.f15 != 15) {
6161                 fprintf(stderr, "mono_return_sbyte16 s16.f15: got %d but expected %d\n", s16.f15, 15);
6162         }
6163         if (s16.f16 != 16) {
6164                 fprintf(stderr, "mono_return_sbyte16 s16.f16: got %d but expected %d\n", s16.f16, 16);
6165         }
6166         s16.f1+=addend; s16.f2+=addend; s16.f3+=addend; s16.f4+=addend; s16.f5+=addend; s16.f6+=addend; s16.f7+=addend; s16.f8+=addend; s16.f9+=addend; s16.f10+=addend; s16.f11+=addend; s16.f12+=addend; s16.f13+=addend; s16.f14+=addend; s16.f15+=addend; s16.f16+=addend; 
6167         return s16;
6168 }
6169
6170 typedef struct {
6171         char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17;
6172 } sbyte17;
6173
6174 LIBTEST_API sbyte17 STDCALL
6175 mono_return_sbyte17 (sbyte17 s17, int addend) {
6176         if (s17.f1 != 1) {
6177                 fprintf(stderr, "mono_return_sbyte17 s17.f1: got %d but expected %d\n", s17.f1, 1);
6178         }
6179         if (s17.f2 != 2) {
6180                 fprintf(stderr, "mono_return_sbyte17 s17.f2: got %d but expected %d\n", s17.f2, 2);
6181         }
6182         if (s17.f3 != 3) {
6183                 fprintf(stderr, "mono_return_sbyte17 s17.f3: got %d but expected %d\n", s17.f3, 3);
6184         }
6185         if (s17.f4 != 4) {
6186                 fprintf(stderr, "mono_return_sbyte17 s17.f4: got %d but expected %d\n", s17.f4, 4);
6187         }
6188         if (s17.f5 != 5) {
6189                 fprintf(stderr, "mono_return_sbyte17 s17.f5: got %d but expected %d\n", s17.f5, 5);
6190         }
6191         if (s17.f6 != 6) {
6192                 fprintf(stderr, "mono_return_sbyte17 s17.f6: got %d but expected %d\n", s17.f6, 6);
6193         }
6194         if (s17.f7 != 7) {
6195                 fprintf(stderr, "mono_return_sbyte17 s17.f7: got %d but expected %d\n", s17.f7, 7);
6196         }
6197         if (s17.f8 != 8) {
6198                 fprintf(stderr, "mono_return_sbyte17 s17.f8: got %d but expected %d\n", s17.f8, 8);
6199         }
6200         if (s17.f9 != 9) {
6201                 fprintf(stderr, "mono_return_sbyte17 s17.f9: got %d but expected %d\n", s17.f9, 9);
6202         }
6203         if (s17.f10 != 10) {
6204                 fprintf(stderr, "mono_return_sbyte17 s17.f10: got %d but expected %d\n", s17.f10, 10);
6205         }
6206         if (s17.f11 != 11) {
6207                 fprintf(stderr, "mono_return_sbyte17 s17.f11: got %d but expected %d\n", s17.f11, 11);
6208         }
6209         if (s17.f12 != 12) {
6210                 fprintf(stderr, "mono_return_sbyte17 s17.f12: got %d but expected %d\n", s17.f12, 12);
6211         }
6212         if (s17.f13 != 13) {
6213                 fprintf(stderr, "mono_return_sbyte17 s17.f13: got %d but expected %d\n", s17.f13, 13);
6214         }
6215         if (s17.f14 != 14) {
6216                 fprintf(stderr, "mono_return_sbyte17 s17.f14: got %d but expected %d\n", s17.f14, 14);
6217         }
6218         if (s17.f15 != 15) {
6219                 fprintf(stderr, "mono_return_sbyte17 s17.f15: got %d but expected %d\n", s17.f15, 15);
6220         }
6221         if (s17.f16 != 16) {
6222                 fprintf(stderr, "mono_return_sbyte17 s17.f16: got %d but expected %d\n", s17.f16, 16);
6223         }
6224         if (s17.f17 != 17) {
6225                 fprintf(stderr, "mono_return_sbyte17 s17.f17: got %d but expected %d\n", s17.f17, 17);
6226         }
6227         s17.f1+=addend; s17.f2+=addend; s17.f3+=addend; s17.f4+=addend; s17.f5+=addend; s17.f6+=addend; s17.f7+=addend; s17.f8+=addend; s17.f9+=addend; s17.f10+=addend; s17.f11+=addend; s17.f12+=addend; s17.f13+=addend; s17.f14+=addend; s17.f15+=addend; s17.f16+=addend; s17.f17+=addend; 
6228         return s17;
6229 }
6230
6231 typedef struct {
6232         struct {
6233                 char f1;
6234         } nested1;
6235         char f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15;
6236         struct {
6237                 char f16;
6238         } nested2;
6239 } sbyte16_nested;
6240
6241 LIBTEST_API sbyte16_nested STDCALL
6242 mono_return_sbyte16_nested (sbyte16_nested sn16, int addend) {
6243         if (sn16.nested1.f1 != 1) {
6244                 fprintf(stderr, "mono_return_sbyte16_nested sn16.nested1.f1: got %d but expected %d\n", sn16.nested1.f1, 1);
6245         }
6246         if (sn16.f2 != 2) {
6247                 fprintf(stderr, "mono_return_sbyte16_nested sn16.f2: got %d but expected %d\n", sn16.f2, 2);
6248         }
6249         if (sn16.f3 != 3) {
6250                 fprintf(stderr, "mono_return_sbyte16_nested sn16.f3: got %d but expected %d\n", sn16.f3, 3);
6251         }
6252         if (sn16.f4 != 4) {
6253                 fprintf(stderr, "mono_return_sbyte16_nested sn16.f4: got %d but expected %d\n", sn16.f4, 4);
6254         }
6255         if (sn16.f5 != 5) {
6256                 fprintf(stderr, "mono_return_sbyte16_nested sn16.f5: got %d but expected %d\n", sn16.f5, 5);
6257         }
6258         if (sn16.f6 != 6) {
6259                 fprintf(stderr, "mono_return_sbyte16_nested sn16.f6: got %d but expected %d\n", sn16.f6, 6);
6260         }
6261         if (sn16.f7 != 7) {
6262                 fprintf(stderr, "mono_return_sbyte16_nested sn16.f7: got %d but expected %d\n", sn16.f7, 7);
6263         }
6264         if (sn16.f8 != 8) {
6265                 fprintf(stderr, "mono_return_sbyte16_nested sn16.f8: got %d but expected %d\n", sn16.f8, 8);
6266         }
6267         if (sn16.f9 != 9) {
6268                 fprintf(stderr, "mono_return_sbyte16_nested sn16.f9: got %d but expected %d\n", sn16.f9, 9);
6269         }
6270         if (sn16.f10 != 10) {
6271                 fprintf(stderr, "mono_return_sbyte16_nested sn16.f10: got %d but expected %d\n", sn16.f10, 10);
6272         }
6273         if (sn16.f11 != 11) {
6274                 fprintf(stderr, "mono_return_sbyte16_nested sn16.f11: got %d but expected %d\n", sn16.f11, 11);
6275         }
6276         if (sn16.f12 != 12) {
6277                 fprintf(stderr, "mono_return_sbyte16_nested sn16.f12: got %d but expected %d\n", sn16.f12, 12);
6278         }
6279         if (sn16.f13 != 13) {
6280                 fprintf(stderr, "mono_return_sbyte16_nested sn16.f13: got %d but expected %d\n", sn16.f13, 13);
6281         }
6282         if (sn16.f14 != 14) {
6283                 fprintf(stderr, "mono_return_sbyte16_nested sn16.f14: got %d but expected %d\n", sn16.f14, 14);
6284         }
6285         if (sn16.f15 != 15) {
6286                 fprintf(stderr, "mono_return_sbyte16_nested sn16.f15: got %d but expected %d\n", sn16.f15, 15);
6287         }
6288         if (sn16.nested2.f16 != 16) {
6289                 fprintf(stderr, "mono_return_sbyte16_nested sn16.nested2.f16: got %d but expected %d\n", sn16.nested2.f16, 16);
6290         }
6291         sn16.nested1.f1+=addend; sn16.f2+=addend; sn16.f3+=addend; sn16.f4+=addend; sn16.f5+=addend; sn16.f6+=addend; sn16.f7+=addend; sn16.f8+=addend; sn16.f9+=addend; sn16.f10+=addend; sn16.f11+=addend; sn16.f12+=addend; sn16.f13+=addend; sn16.f14+=addend; sn16.f15+=addend; sn16.nested2.f16+=addend; 
6292         return sn16;
6293 }
6294
6295
6296 typedef struct {
6297         short f1;
6298 } short1;
6299
6300 LIBTEST_API short1 STDCALL
6301 mono_return_short1 (short1 s1, int addend) {
6302         if (s1.f1 != 1) {
6303                 fprintf(stderr, "mono_return_short1 s1.f1: got %d but expected %d\n", s1.f1, 1);
6304         }
6305         s1.f1+=addend; 
6306         return s1;
6307 }
6308
6309 typedef struct {
6310         short f1,f2;
6311 } short2;
6312
6313 LIBTEST_API short2 STDCALL
6314 mono_return_short2 (short2 s2, int addend) {
6315         if (s2.f1 != 1) {
6316                 fprintf(stderr, "mono_return_short2 s2.f1: got %d but expected %d\n", s2.f1, 1);
6317         }
6318         if (s2.f2 != 2) {
6319                 fprintf(stderr, "mono_return_short2 s2.f2: got %d but expected %d\n", s2.f2, 2);
6320         }
6321         s2.f1+=addend; s2.f2+=addend; 
6322         return s2;
6323 }
6324
6325 typedef struct {
6326         short f1,f2,f3;
6327 } short3;
6328
6329 LIBTEST_API short3 STDCALL
6330 mono_return_short3 (short3 s3, int addend) {
6331         if (s3.f1 != 1) {
6332                 fprintf(stderr, "mono_return_short3 s3.f1: got %d but expected %d\n", s3.f1, 1);
6333         }
6334         if (s3.f2 != 2) {
6335                 fprintf(stderr, "mono_return_short3 s3.f2: got %d but expected %d\n", s3.f2, 2);
6336         }
6337         if (s3.f3 != 3) {
6338                 fprintf(stderr, "mono_return_short3 s3.f3: got %d but expected %d\n", s3.f3, 3);
6339         }
6340         s3.f1+=addend; s3.f2+=addend; s3.f3+=addend; 
6341         return s3;
6342 }
6343
6344 typedef struct {
6345         short f1,f2,f3,f4;
6346 } short4;
6347
6348 LIBTEST_API short4 STDCALL
6349 mono_return_short4 (short4 s4, int addend) {
6350         if (s4.f1 != 1) {
6351                 fprintf(stderr, "mono_return_short4 s4.f1: got %d but expected %d\n", s4.f1, 1);
6352         }
6353         if (s4.f2 != 2) {
6354                 fprintf(stderr, "mono_return_short4 s4.f2: got %d but expected %d\n", s4.f2, 2);
6355         }
6356         if (s4.f3 != 3) {
6357                 fprintf(stderr, "mono_return_short4 s4.f3: got %d but expected %d\n", s4.f3, 3);
6358         }
6359         if (s4.f4 != 4) {
6360                 fprintf(stderr, "mono_return_short4 s4.f4: got %d but expected %d\n", s4.f4, 4);
6361         }
6362         s4.f1+=addend; s4.f2+=addend; s4.f3+=addend; s4.f4+=addend; 
6363         return s4;
6364 }
6365
6366 typedef struct {
6367         short f1,f2,f3,f4,f5;
6368 } short5;
6369
6370 LIBTEST_API short5 STDCALL
6371 mono_return_short5 (short5 s5, int addend) {
6372         if (s5.f1 != 1) {
6373                 fprintf(stderr, "mono_return_short5 s5.f1: got %d but expected %d\n", s5.f1, 1);
6374         }
6375         if (s5.f2 != 2) {
6376                 fprintf(stderr, "mono_return_short5 s5.f2: got %d but expected %d\n", s5.f2, 2);
6377         }
6378         if (s5.f3 != 3) {
6379                 fprintf(stderr, "mono_return_short5 s5.f3: got %d but expected %d\n", s5.f3, 3);
6380         }
6381         if (s5.f4 != 4) {
6382                 fprintf(stderr, "mono_return_short5 s5.f4: got %d but expected %d\n", s5.f4, 4);
6383         }
6384         if (s5.f5 != 5) {
6385                 fprintf(stderr, "mono_return_short5 s5.f5: got %d but expected %d\n", s5.f5, 5);
6386         }
6387         s5.f1+=addend; s5.f2+=addend; s5.f3+=addend; s5.f4+=addend; s5.f5+=addend; 
6388         return s5;
6389 }
6390
6391 typedef struct {
6392         short f1,f2,f3,f4,f5,f6;
6393 } short6;
6394
6395 LIBTEST_API short6 STDCALL
6396 mono_return_short6 (short6 s6, int addend) {
6397         if (s6.f1 != 1) {
6398                 fprintf(stderr, "mono_return_short6 s6.f1: got %d but expected %d\n", s6.f1, 1);
6399         }
6400         if (s6.f2 != 2) {
6401                 fprintf(stderr, "mono_return_short6 s6.f2: got %d but expected %d\n", s6.f2, 2);
6402         }
6403         if (s6.f3 != 3) {
6404                 fprintf(stderr, "mono_return_short6 s6.f3: got %d but expected %d\n", s6.f3, 3);
6405         }
6406         if (s6.f4 != 4) {
6407                 fprintf(stderr, "mono_return_short6 s6.f4: got %d but expected %d\n", s6.f4, 4);
6408         }
6409         if (s6.f5 != 5) {
6410                 fprintf(stderr, "mono_return_short6 s6.f5: got %d but expected %d\n", s6.f5, 5);
6411         }
6412         if (s6.f6 != 6) {
6413                 fprintf(stderr, "mono_return_short6 s6.f6: got %d but expected %d\n", s6.f6, 6);
6414         }
6415         s6.f1+=addend; s6.f2+=addend; s6.f3+=addend; s6.f4+=addend; s6.f5+=addend; s6.f6+=addend; 
6416         return s6;
6417 }
6418
6419 typedef struct {
6420         short f1,f2,f3,f4,f5,f6,f7;
6421 } short7;
6422
6423 LIBTEST_API short7 STDCALL
6424 mono_return_short7 (short7 s7, int addend) {
6425         if (s7.f1 != 1) {
6426                 fprintf(stderr, "mono_return_short7 s7.f1: got %d but expected %d\n", s7.f1, 1);
6427         }
6428         if (s7.f2 != 2) {
6429                 fprintf(stderr, "mono_return_short7 s7.f2: got %d but expected %d\n", s7.f2, 2);
6430         }
6431         if (s7.f3 != 3) {
6432                 fprintf(stderr, "mono_return_short7 s7.f3: got %d but expected %d\n", s7.f3, 3);
6433         }
6434         if (s7.f4 != 4) {
6435                 fprintf(stderr, "mono_return_short7 s7.f4: got %d but expected %d\n", s7.f4, 4);
6436         }
6437         if (s7.f5 != 5) {
6438                 fprintf(stderr, "mono_return_short7 s7.f5: got %d but expected %d\n", s7.f5, 5);
6439         }
6440         if (s7.f6 != 6) {
6441                 fprintf(stderr, "mono_return_short7 s7.f6: got %d but expected %d\n", s7.f6, 6);
6442         }
6443         if (s7.f7 != 7) {
6444                 fprintf(stderr, "mono_return_short7 s7.f7: got %d but expected %d\n", s7.f7, 7);
6445         }
6446         s7.f1+=addend; s7.f2+=addend; s7.f3+=addend; s7.f4+=addend; s7.f5+=addend; s7.f6+=addend; s7.f7+=addend; 
6447         return s7;
6448 }
6449
6450 typedef struct {
6451         short f1,f2,f3,f4,f5,f6,f7,f8;
6452 } short8;
6453
6454 LIBTEST_API short8 STDCALL
6455 mono_return_short8 (short8 s8, int addend) {
6456         if (s8.f1 != 1) {
6457                 fprintf(stderr, "mono_return_short8 s8.f1: got %d but expected %d\n", s8.f1, 1);
6458         }
6459         if (s8.f2 != 2) {
6460                 fprintf(stderr, "mono_return_short8 s8.f2: got %d but expected %d\n", s8.f2, 2);
6461         }
6462         if (s8.f3 != 3) {
6463                 fprintf(stderr, "mono_return_short8 s8.f3: got %d but expected %d\n", s8.f3, 3);
6464         }
6465         if (s8.f4 != 4) {
6466                 fprintf(stderr, "mono_return_short8 s8.f4: got %d but expected %d\n", s8.f4, 4);
6467         }
6468         if (s8.f5 != 5) {
6469                 fprintf(stderr, "mono_return_short8 s8.f5: got %d but expected %d\n", s8.f5, 5);
6470         }
6471         if (s8.f6 != 6) {
6472                 fprintf(stderr, "mono_return_short8 s8.f6: got %d but expected %d\n", s8.f6, 6);
6473         }
6474         if (s8.f7 != 7) {
6475                 fprintf(stderr, "mono_return_short8 s8.f7: got %d but expected %d\n", s8.f7, 7);
6476         }
6477         if (s8.f8 != 8) {
6478                 fprintf(stderr, "mono_return_short8 s8.f8: got %d but expected %d\n", s8.f8, 8);
6479         }
6480         s8.f1+=addend; s8.f2+=addend; s8.f3+=addend; s8.f4+=addend; s8.f5+=addend; s8.f6+=addend; s8.f7+=addend; s8.f8+=addend; 
6481         return s8;
6482 }
6483
6484 typedef struct {
6485         short f1,f2,f3,f4,f5,f6,f7,f8,f9;
6486 } short9;
6487
6488 LIBTEST_API short9 STDCALL
6489 mono_return_short9 (short9 s9, int addend) {
6490         if (s9.f1 != 1) {
6491                 fprintf(stderr, "mono_return_short9 s9.f1: got %d but expected %d\n", s9.f1, 1);
6492         }
6493         if (s9.f2 != 2) {
6494                 fprintf(stderr, "mono_return_short9 s9.f2: got %d but expected %d\n", s9.f2, 2);
6495         }
6496         if (s9.f3 != 3) {
6497                 fprintf(stderr, "mono_return_short9 s9.f3: got %d but expected %d\n", s9.f3, 3);
6498         }
6499         if (s9.f4 != 4) {
6500                 fprintf(stderr, "mono_return_short9 s9.f4: got %d but expected %d\n", s9.f4, 4);
6501         }
6502         if (s9.f5 != 5) {
6503                 fprintf(stderr, "mono_return_short9 s9.f5: got %d but expected %d\n", s9.f5, 5);
6504         }
6505         if (s9.f6 != 6) {
6506                 fprintf(stderr, "mono_return_short9 s9.f6: got %d but expected %d\n", s9.f6, 6);
6507         }
6508         if (s9.f7 != 7) {
6509                 fprintf(stderr, "mono_return_short9 s9.f7: got %d but expected %d\n", s9.f7, 7);
6510         }
6511         if (s9.f8 != 8) {
6512                 fprintf(stderr, "mono_return_short9 s9.f8: got %d but expected %d\n", s9.f8, 8);
6513         }
6514         if (s9.f9 != 9) {
6515                 fprintf(stderr, "mono_return_short9 s9.f9: got %d but expected %d\n", s9.f9, 9);
6516         }
6517         s9.f1+=addend; s9.f2+=addend; s9.f3+=addend; s9.f4+=addend; s9.f5+=addend; s9.f6+=addend; s9.f7+=addend; s9.f8+=addend; s9.f9+=addend; 
6518         return s9;
6519 }
6520
6521 typedef struct {
6522         struct {
6523                 short f1;
6524         } nested1;
6525         short f2,f3,f4,f5,f6,f7;
6526         struct {
6527                 short f8;
6528         } nested2;
6529 } short8_nested;
6530
6531 LIBTEST_API short8_nested STDCALL
6532 mono_return_short8_nested (short8_nested sn8, int addend) {
6533         if (sn8.nested1.f1 != 1) {
6534                 fprintf(stderr, "mono_return_short8_nested sn8.nested1.f1: got %d but expected %d\n", sn8.nested1.f1, 1);
6535         }
6536         if (sn8.f2 != 2) {
6537                 fprintf(stderr, "mono_return_short8_nested sn8.f2: got %d but expected %d\n", sn8.f2, 2);
6538         }
6539         if (sn8.f3 != 3) {
6540                 fprintf(stderr, "mono_return_short8_nested sn8.f3: got %d but expected %d\n", sn8.f3, 3);
6541         }
6542         if (sn8.f4 != 4) {
6543                 fprintf(stderr, "mono_return_short8_nested sn8.f4: got %d but expected %d\n", sn8.f4, 4);
6544         }
6545         if (sn8.f5 != 5) {
6546                 fprintf(stderr, "mono_return_short8_nested sn8.f5: got %d but expected %d\n", sn8.f5, 5);
6547         }
6548         if (sn8.f6 != 6) {
6549                 fprintf(stderr, "mono_return_short8_nested sn8.f6: got %d but expected %d\n", sn8.f6, 6);
6550         }
6551         if (sn8.f7 != 7) {
6552                 fprintf(stderr, "mono_return_short8_nested sn8.f7: got %d but expected %d\n", sn8.f7, 7);
6553         }
6554         if (sn8.nested2.f8 != 8) {
6555                 fprintf(stderr, "mono_return_short8_nested sn8.nested2.f8: got %d but expected %d\n", sn8.nested2.f8, 8);
6556         }
6557         sn8.nested1.f1+=addend; sn8.f2+=addend; sn8.f3+=addend; sn8.f4+=addend; sn8.f5+=addend; sn8.f6+=addend; sn8.f7+=addend; sn8.nested2.f8+=addend; 
6558         return sn8;
6559 }
6560
6561
6562 typedef struct {
6563         int f1;
6564 } int1;
6565
6566 LIBTEST_API int1 STDCALL
6567 mono_return_int1 (int1 s1, int addend) {
6568         if (s1.f1 != 1) {
6569                 fprintf(stderr, "mono_return_int1 s1.f1: got %d but expected %d\n", s1.f1, 1);
6570         }
6571         s1.f1+=addend; 
6572         return s1;
6573 }
6574
6575 typedef struct {
6576         int f1,f2;
6577 } int2;
6578
6579 LIBTEST_API int2 STDCALL
6580 mono_return_int2 (int2 s2, int addend) {
6581         if (s2.f1 != 1) {
6582                 fprintf(stderr, "mono_return_int2 s2.f1: got %d but expected %d\n", s2.f1, 1);
6583         }
6584         if (s2.f2 != 2) {
6585                 fprintf(stderr, "mono_return_int2 s2.f2: got %d but expected %d\n", s2.f2, 2);
6586         }
6587         s2.f1+=addend; s2.f2+=addend; 
6588         return s2;
6589 }
6590
6591 typedef struct {
6592         int f1,f2,f3;
6593 } int3;
6594
6595 LIBTEST_API int3 STDCALL
6596 mono_return_int3 (int3 s3, int addend) {
6597         if (s3.f1 != 1) {
6598                 fprintf(stderr, "mono_return_int3 s3.f1: got %d but expected %d\n", s3.f1, 1);
6599         }
6600         if (s3.f2 != 2) {
6601                 fprintf(stderr, "mono_return_int3 s3.f2: got %d but expected %d\n", s3.f2, 2);
6602         }
6603         if (s3.f3 != 3) {
6604                 fprintf(stderr, "mono_return_int3 s3.f3: got %d but expected %d\n", s3.f3, 3);
6605         }
6606         s3.f1+=addend; s3.f2+=addend; s3.f3+=addend; 
6607         return s3;
6608 }
6609
6610 typedef struct {
6611         int f1,f2,f3,f4;
6612 } int4;
6613
6614 LIBTEST_API int4 STDCALL
6615 mono_return_int4 (int4 s4, int addend) {
6616         if (s4.f1 != 1) {
6617                 fprintf(stderr, "mono_return_int4 s4.f1: got %d but expected %d\n", s4.f1, 1);
6618         }
6619         if (s4.f2 != 2) {
6620                 fprintf(stderr, "mono_return_int4 s4.f2: got %d but expected %d\n", s4.f2, 2);
6621         }
6622         if (s4.f3 != 3) {
6623                 fprintf(stderr, "mono_return_int4 s4.f3: got %d but expected %d\n", s4.f3, 3);
6624         }
6625         if (s4.f4 != 4) {
6626                 fprintf(stderr, "mono_return_int4 s4.f4: got %d but expected %d\n", s4.f4, 4);
6627         }
6628         s4.f1+=addend; s4.f2+=addend; s4.f3+=addend; s4.f4+=addend; 
6629         return s4;
6630 }
6631
6632 typedef struct {
6633         int f1,f2,f3,f4,f5;
6634 } int5;
6635
6636 LIBTEST_API int5 STDCALL
6637 mono_return_int5 (int5 s5, int addend) {
6638         if (s5.f1 != 1) {
6639                 fprintf(stderr, "mono_return_int5 s5.f1: got %d but expected %d\n", s5.f1, 1);
6640         }
6641         if (s5.f2 != 2) {
6642                 fprintf(stderr, "mono_return_int5 s5.f2: got %d but expected %d\n", s5.f2, 2);
6643         }
6644         if (s5.f3 != 3) {
6645                 fprintf(stderr, "mono_return_int5 s5.f3: got %d but expected %d\n", s5.f3, 3);
6646         }
6647         if (s5.f4 != 4) {
6648                 fprintf(stderr, "mono_return_int5 s5.f4: got %d but expected %d\n", s5.f4, 4);
6649         }
6650         if (s5.f5 != 5) {
6651                 fprintf(stderr, "mono_return_int5 s5.f5: got %d but expected %d\n", s5.f5, 5);
6652         }
6653         s5.f1+=addend; s5.f2+=addend; s5.f3+=addend; s5.f4+=addend; s5.f5+=addend; 
6654         return s5;
6655 }
6656
6657 typedef struct {
6658         struct {
6659                 int f1;
6660         } nested1;
6661         int f2,f3;
6662         struct {
6663                 int f4;
6664         } nested2;
6665 } int4_nested;
6666
6667 LIBTEST_API int4_nested STDCALL
6668 mono_return_int4_nested (int4_nested sn4, int addend) {
6669         if (sn4.nested1.f1 != 1) {
6670                 fprintf(stderr, "mono_return_int4_nested sn4.nested1.f1: got %d but expected %d\n", sn4.nested1.f1, 1);
6671         }
6672         if (sn4.f2 != 2) {
6673                 fprintf(stderr, "mono_return_int4_nested sn4.f2: got %d but expected %d\n", sn4.f2, 2);
6674         }
6675         if (sn4.f3 != 3) {
6676                 fprintf(stderr, "mono_return_int4_nested sn4.f3: got %d but expected %d\n", sn4.f3, 3);
6677         }
6678         if (sn4.nested2.f4 != 4) {
6679                 fprintf(stderr, "mono_return_int4_nested sn4.nested2.f4: got %d but expected %d\n", sn4.nested2.f4, 4);
6680         }
6681         sn4.nested1.f1+=addend; sn4.f2+=addend; sn4.f3+=addend; sn4.nested2.f4+=addend; 
6682         return sn4;
6683 }
6684
6685 typedef struct {
6686         float f1;
6687 } float1;
6688
6689 LIBTEST_API float1 STDCALL
6690 mono_return_float1 (float1 s1, int addend) {
6691         if (s1.f1 != 1) {
6692                 fprintf(stderr, "mono_return_float1 s1.f1: got %f but expected %d\n", s1.f1, 1);
6693         }
6694         s1.f1+=addend; 
6695         return s1;
6696 }
6697
6698 typedef struct {
6699         float f1,f2;
6700 } float2;
6701
6702 LIBTEST_API float2 STDCALL
6703 mono_return_float2 (float2 s2, int addend) {
6704         if (s2.f1 != 1) {
6705                 fprintf(stderr, "mono_return_float2 s2.f1: got %f but expected %d\n", s2.f1, 1);
6706         }
6707         if (s2.f2 != 2) {
6708                 fprintf(stderr, "mono_return_float2 s2.f2: got %f but expected %d\n", s2.f2, 2);
6709         }
6710         s2.f1+=addend; s2.f2+=addend; 
6711         return s2;
6712 }
6713
6714 typedef struct {
6715         float f1,f2,f3;
6716 } float3;
6717
6718 LIBTEST_API float3 STDCALL
6719 mono_return_float3 (float3 s3, int addend) {
6720         if (s3.f1 != 1) {
6721                 fprintf(stderr, "mono_return_float3 s3.f1: got %f but expected %d\n", s3.f1, 1);
6722         }
6723         if (s3.f2 != 2) {
6724                 fprintf(stderr, "mono_return_float3 s3.f2: got %f but expected %d\n", s3.f2, 2);
6725         }
6726         if (s3.f3 != 3) {
6727                 fprintf(stderr, "mono_return_float3 s3.f3: got %f but expected %d\n", s3.f3, 3);
6728         }
6729         s3.f1+=addend; s3.f2+=addend; s3.f3+=addend; 
6730         return s3;
6731 }
6732
6733 typedef struct {
6734         float f1,f2,f3,f4;
6735 } float4;
6736
6737 LIBTEST_API float4 STDCALL
6738 mono_return_float4 (float4 s4, int addend) {
6739         if (s4.f1 != 1) {
6740                 fprintf(stderr, "mono_return_float4 s4.f1: got %f but expected %d\n", s4.f1, 1);
6741         }
6742         if (s4.f2 != 2) {
6743                 fprintf(stderr, "mono_return_float4 s4.f2: got %f but expected %d\n", s4.f2, 2);
6744         }
6745         if (s4.f3 != 3) {
6746                 fprintf(stderr, "mono_return_float4 s4.f3: got %f but expected %d\n", s4.f3, 3);
6747         }
6748         if (s4.f4 != 4) {
6749                 fprintf(stderr, "mono_return_float4 s4.f4: got %f but expected %d\n", s4.f4, 4);
6750         }
6751         s4.f1+=addend; s4.f2+=addend; s4.f3+=addend; s4.f4+=addend; 
6752         return s4;
6753 }
6754
6755 typedef struct {
6756         float f1,f2,f3,f4,f5;
6757 } float5;
6758
6759 LIBTEST_API float5 STDCALL
6760 mono_return_float5 (float5 s5, int addend) {
6761         if (s5.f1 != 1) {
6762                 fprintf(stderr, "mono_return_float5 s5.f1: got %f but expected %d\n", s5.f1, 1);
6763         }
6764         if (s5.f2 != 2) {
6765                 fprintf(stderr, "mono_return_float5 s5.f2: got %f but expected %d\n", s5.f2, 2);
6766         }
6767         if (s5.f3 != 3) {
6768                 fprintf(stderr, "mono_return_float5 s5.f3: got %f but expected %d\n", s5.f3, 3);
6769         }
6770         if (s5.f4 != 4) {
6771                 fprintf(stderr, "mono_return_float5 s5.f4: got %f but expected %d\n", s5.f4, 4);
6772         }
6773         if (s5.f5 != 5) {
6774                 fprintf(stderr, "mono_return_float5 s5.f5: got %f but expected %d\n", s5.f5, 5);
6775         }
6776         s5.f1+=addend; s5.f2+=addend; s5.f3+=addend; s5.f4+=addend; s5.f5+=addend; 
6777         return s5;
6778 }
6779
6780 typedef struct {
6781         float f1,f2,f3,f4,f5,f6;
6782 } float6;
6783
6784 LIBTEST_API float6 STDCALL
6785 mono_return_float6 (float6 s6, int addend) {
6786         if (s6.f1 != 1) {
6787                 fprintf(stderr, "mono_return_float6 s6.f1: got %f but expected %d\n", s6.f1, 1);
6788         }
6789         if (s6.f2 != 2) {
6790                 fprintf(stderr, "mono_return_float6 s6.f2: got %f but expected %d\n", s6.f2, 2);
6791         }
6792         if (s6.f3 != 3) {
6793                 fprintf(stderr, "mono_return_float6 s6.f3: got %f but expected %d\n", s6.f3, 3);
6794         }
6795         if (s6.f4 != 4) {
6796                 fprintf(stderr, "mono_return_float6 s6.f4: got %f but expected %d\n", s6.f4, 4);
6797         }
6798         if (s6.f5 != 5) {
6799                 fprintf(stderr, "mono_return_float6 s6.f5: got %f but expected %d\n", s6.f5, 5);
6800         }
6801         if (s6.f6 != 6) {
6802                 fprintf(stderr, "mono_return_float6 s6.f6: got %f but expected %d\n", s6.f6, 6);
6803         }
6804         s6.f1+=addend; s6.f2+=addend; s6.f3+=addend; s6.f4+=addend; s6.f5+=addend; s6.f6+=addend; 
6805         return s6;
6806 }
6807
6808 typedef struct {
6809         float f1,f2,f3,f4,f5,f6,f7;
6810 } float7;
6811
6812 LIBTEST_API float7 STDCALL
6813 mono_return_float7 (float7 s7, int addend) {
6814         if (s7.f1 != 1) {
6815                 fprintf(stderr, "mono_return_float7 s7.f1: got %f but expected %d\n", s7.f1, 1);
6816         }
6817         if (s7.f2 != 2) {
6818                 fprintf(stderr, "mono_return_float7 s7.f2: got %f but expected %d\n", s7.f2, 2);
6819         }
6820         if (s7.f3 != 3) {
6821                 fprintf(stderr, "mono_return_float7 s7.f3: got %f but expected %d\n", s7.f3, 3);
6822         }
6823         if (s7.f4 != 4) {
6824                 fprintf(stderr, "mono_return_float7 s7.f4: got %f but expected %d\n", s7.f4, 4);
6825         }
6826         if (s7.f5 != 5) {
6827                 fprintf(stderr, "mono_return_float7 s7.f5: got %f but expected %d\n", s7.f5, 5);
6828         }
6829         if (s7.f6 != 6) {
6830                 fprintf(stderr, "mono_return_float7 s7.f6: got %f but expected %d\n", s7.f6, 6);
6831         }
6832         if (s7.f7 != 7) {
6833                 fprintf(stderr, "mono_return_float7 s7.f7: got %f but expected %d\n", s7.f7, 7);
6834         }
6835         s7.f1+=addend; s7.f2+=addend; s7.f3+=addend; s7.f4+=addend; s7.f5+=addend; s7.f6+=addend; s7.f7+=addend; 
6836         return s7;
6837 }
6838
6839 typedef struct {
6840         float f1,f2,f3,f4,f5,f6,f7,f8;
6841 } float8;
6842
6843 LIBTEST_API float8 STDCALL
6844 mono_return_float8 (float8 s8, int addend) {
6845         if (s8.f1 != 1) {
6846                 fprintf(stderr, "mono_return_float8 s8.f1: got %f but expected %d\n", s8.f1, 1);
6847         }
6848         if (s8.f2 != 2) {
6849                 fprintf(stderr, "mono_return_float8 s8.f2: got %f but expected %d\n", s8.f2, 2);
6850         }
6851         if (s8.f3 != 3) {
6852                 fprintf(stderr, "mono_return_float8 s8.f3: got %f but expected %d\n", s8.f3, 3);
6853         }
6854         if (s8.f4 != 4) {
6855                 fprintf(stderr, "mono_return_float8 s8.f4: got %f but expected %d\n", s8.f4, 4);
6856         }
6857         if (s8.f5 != 5) {
6858                 fprintf(stderr, "mono_return_float8 s8.f5: got %f but expected %d\n", s8.f5, 5);
6859         }
6860         if (s8.f6 != 6) {
6861                 fprintf(stderr, "mono_return_float8 s8.f6: got %f but expected %d\n", s8.f6, 6);
6862         }
6863         if (s8.f7 != 7) {
6864                 fprintf(stderr, "mono_return_float8 s8.f7: got %f but expected %d\n", s8.f7, 7);
6865         }
6866         if (s8.f8 != 8) {
6867                 fprintf(stderr, "mono_return_float8 s8.f8: got %f but expected %d\n", s8.f8, 8);
6868         }
6869         s8.f1+=addend; s8.f2+=addend; s8.f3+=addend; s8.f4+=addend; s8.f5+=addend; s8.f6+=addend; s8.f7+=addend; s8.f8+=addend; 
6870         return s8;
6871 }
6872
6873 typedef struct {
6874         float f1,f2,f3,f4,f5,f6,f7,f8,f9;
6875 } float9;
6876
6877 LIBTEST_API float9 STDCALL
6878 mono_return_float9 (float9 s9, int addend) {
6879         if (s9.f1 != 1) {
6880                 fprintf(stderr, "mono_return_float9 s9.f1: got %f but expected %d\n", s9.f1, 1);
6881         }
6882         if (s9.f2 != 2) {
6883                 fprintf(stderr, "mono_return_float9 s9.f2: got %f but expected %d\n", s9.f2, 2);
6884         }
6885         if (s9.f3 != 3) {
6886                 fprintf(stderr, "mono_return_float9 s9.f3: got %f but expected %d\n", s9.f3, 3);
6887         }
6888         if (s9.f4 != 4) {
6889                 fprintf(stderr, "mono_return_float9 s9.f4: got %f but expected %d\n", s9.f4, 4);
6890         }
6891         if (s9.f5 != 5) {
6892                 fprintf(stderr, "mono_return_float9 s9.f5: got %f but expected %d\n", s9.f5, 5);
6893         }
6894         if (s9.f6 != 6) {
6895                 fprintf(stderr, "mono_return_float9 s9.f6: got %f but expected %d\n", s9.f6, 6);
6896         }
6897         if (s9.f7 != 7) {
6898                 fprintf(stderr, "mono_return_float9 s9.f7: got %f but expected %d\n", s9.f7, 7);
6899         }
6900         if (s9.f8 != 8) {
6901                 fprintf(stderr, "mono_return_float9 s9.f8: got %f but expected %d\n", s9.f8, 8);
6902         }
6903         if (s9.f9 != 9) {
6904                 fprintf(stderr, "mono_return_float9 s9.f9: got %f but expected %d\n", s9.f9, 9);
6905         }
6906         s9.f1+=addend; s9.f2+=addend; s9.f3+=addend; s9.f4+=addend; s9.f5+=addend; s9.f6+=addend; s9.f7+=addend; s9.f8+=addend; s9.f9+=addend; 
6907         return s9;
6908 }
6909
6910 typedef struct {
6911         struct {
6912                 float f1;
6913         } nested1;
6914         float f2,f3;
6915         struct {
6916                 float f4;
6917         } nested2;
6918 } float4_nested;
6919
6920 LIBTEST_API float4_nested STDCALL
6921 mono_return_float4_nested (float4_nested sn4, int addend) {
6922         if (sn4.nested1.f1 != 1) {
6923                 fprintf(stderr, "mono_return_float4_nested sn4.nested1.f1: got %f but expected %d\n", sn4.nested1.f1, 1);
6924         }
6925         if (sn4.f2 != 2) {
6926                 fprintf(stderr, "mono_return_float4_nested sn4.f2: got %f but expected %d\n", sn4.f2, 2);
6927         }
6928         if (sn4.f3 != 3) {
6929                 fprintf(stderr, "mono_return_float4_nested sn4.f3: got %f but expected %d\n", sn4.f3, 3);
6930         }
6931         if (sn4.nested2.f4 != 4) {
6932                 fprintf(stderr, "mono_return_float4_nested sn4.nested2.f4: got %f but expected %d\n", sn4.nested2.f4, 4);
6933         }
6934         sn4.nested1.f1+=addend; sn4.f2+=addend; sn4.f3+=addend; sn4.nested2.f4+=addend; 
6935         return sn4;
6936 }
6937
6938 typedef struct {
6939         double f1;
6940 } double1;
6941
6942 LIBTEST_API double1 STDCALL
6943 mono_return_double1 (double1 s1, int addend) {
6944         if (s1.f1 != 1) {
6945                 fprintf(stderr, "mono_return_double1 s1.f1: got %f but expected %d\n", s1.f1, 1);
6946         }
6947         s1.f1+=addend; 
6948         return s1;
6949 }
6950
6951 typedef struct {
6952         double f1,f2;
6953 } double2;
6954
6955 LIBTEST_API double2 STDCALL
6956 mono_return_double2 (double2 s2, int addend) {
6957         if (s2.f1 != 1) {
6958                 fprintf(stderr, "mono_return_double2 s2.f1: got %f but expected %d\n", s2.f1, 1);
6959         }
6960         if (s2.f2 != 2) {
6961                 fprintf(stderr, "mono_return_double2 s2.f2: got %f but expected %d\n", s2.f2, 2);
6962         }
6963         s2.f1+=addend; s2.f2+=addend; 
6964         return s2;
6965 }
6966
6967 typedef struct {
6968         double f1,f2,f3;
6969 } double3;
6970
6971 LIBTEST_API double3 STDCALL
6972 mono_return_double3 (double3 s3, int addend) {
6973         if (s3.f1 != 1) {
6974                 fprintf(stderr, "mono_return_double3 s3.f1: got %f but expected %d\n", s3.f1, 1);
6975         }
6976         if (s3.f2 != 2) {
6977                 fprintf(stderr, "mono_return_double3 s3.f2: got %f but expected %d\n", s3.f2, 2);
6978         }
6979         if (s3.f3 != 3) {
6980                 fprintf(stderr, "mono_return_double3 s3.f3: got %f but expected %d\n", s3.f3, 3);
6981         }
6982         s3.f1+=addend; s3.f2+=addend; s3.f3+=addend; 
6983         return s3;
6984 }
6985
6986 typedef struct {
6987         double f1,f2,f3,f4;
6988 } double4;
6989
6990 LIBTEST_API double4 STDCALL
6991 mono_return_double4 (double4 s4, int addend) {
6992         if (s4.f1 != 1) {
6993                 fprintf(stderr, "mono_return_double4 s4.f1: got %f but expected %d\n", s4.f1, 1);
6994         }
6995         if (s4.f2 != 2) {
6996                 fprintf(stderr, "mono_return_double4 s4.f2: got %f but expected %d\n", s4.f2, 2);
6997         }
6998         if (s4.f3 != 3) {
6999                 fprintf(stderr, "mono_return_double4 s4.f3: got %f but expected %d\n", s4.f3, 3);
7000         }
7001         if (s4.f4 != 4) {
7002                 fprintf(stderr, "mono_return_double4 s4.f4: got %f but expected %d\n", s4.f4, 4);
7003         }
7004         s4.f1+=addend; s4.f2+=addend; s4.f3+=addend; s4.f4+=addend; 
7005         return s4;
7006 }
7007
7008 typedef struct {
7009         double f1,f2,f3,f4,f5;
7010 } double5;
7011
7012 LIBTEST_API double5 STDCALL
7013 mono_return_double5 (double5 s5, int addend) {
7014         if (s5.f1 != 1) {
7015                 fprintf(stderr, "mono_return_double5 s5.f1: got %f but expected %d\n", s5.f1, 1);
7016         }
7017         if (s5.f2 != 2) {
7018                 fprintf(stderr, "mono_return_double5 s5.f2: got %f but expected %d\n", s5.f2, 2);
7019         }
7020         if (s5.f3 != 3) {
7021                 fprintf(stderr, "mono_return_double5 s5.f3: got %f but expected %d\n", s5.f3, 3);
7022         }
7023         if (s5.f4 != 4) {
7024                 fprintf(stderr, "mono_return_double5 s5.f4: got %f but expected %d\n", s5.f4, 4);
7025         }
7026         if (s5.f5 != 5) {
7027                 fprintf(stderr, "mono_return_double5 s5.f5: got %f but expected %d\n", s5.f5, 5);
7028         }
7029         s5.f1+=addend; s5.f2+=addend; s5.f3+=addend; s5.f4+=addend; s5.f5+=addend; 
7030         return s5;
7031 }
7032
7033 typedef struct {
7034         double f1,f2,f3,f4,f5,f6;
7035 } double6;
7036
7037 LIBTEST_API double6 STDCALL
7038 mono_return_double6 (double6 s6, int addend) {
7039         if (s6.f1 != 1) {
7040                 fprintf(stderr, "mono_return_double6 s6.f1: got %f but expected %d\n", s6.f1, 1);
7041         }
7042         if (s6.f2 != 2) {
7043                 fprintf(stderr, "mono_return_double6 s6.f2: got %f but expected %d\n", s6.f2, 2);
7044         }
7045         if (s6.f3 != 3) {
7046                 fprintf(stderr, "mono_return_double6 s6.f3: got %f but expected %d\n", s6.f3, 3);
7047         }
7048         if (s6.f4 != 4) {
7049                 fprintf(stderr, "mono_return_double6 s6.f4: got %f but expected %d\n", s6.f4, 4);
7050         }
7051         if (s6.f5 != 5) {
7052                 fprintf(stderr, "mono_return_double6 s6.f5: got %f but expected %d\n", s6.f5, 5);
7053         }
7054         if (s6.f6 != 6) {
7055                 fprintf(stderr, "mono_return_double6 s6.f6: got %f but expected %d\n", s6.f6, 6);
7056         }
7057         s6.f1+=addend; s6.f2+=addend; s6.f3+=addend; s6.f4+=addend; s6.f5+=addend; s6.f6+=addend; 
7058         return s6;
7059 }
7060
7061 typedef struct {
7062         double f1,f2,f3,f4,f5,f6,f7;
7063 } double7;
7064
7065 LIBTEST_API double7 STDCALL
7066 mono_return_double7 (double7 s7, int addend) {
7067         if (s7.f1 != 1) {
7068                 fprintf(stderr, "mono_return_double7 s7.f1: got %f but expected %d\n", s7.f1, 1);
7069         }
7070         if (s7.f2 != 2) {
7071                 fprintf(stderr, "mono_return_double7 s7.f2: got %f but expected %d\n", s7.f2, 2);
7072         }
7073         if (s7.f3 != 3) {
7074                 fprintf(stderr, "mono_return_double7 s7.f3: got %f but expected %d\n", s7.f3, 3);
7075         }
7076         if (s7.f4 != 4) {
7077                 fprintf(stderr, "mono_return_double7 s7.f4: got %f but expected %d\n", s7.f4, 4);
7078         }
7079         if (s7.f5 != 5) {
7080                 fprintf(stderr, "mono_return_double7 s7.f5: got %f but expected %d\n", s7.f5, 5);
7081         }
7082         if (s7.f6 != 6) {
7083                 fprintf(stderr, "mono_return_double7 s7.f6: got %f but expected %d\n", s7.f6, 6);
7084         }
7085         if (s7.f7 != 7) {
7086                 fprintf(stderr, "mono_return_double7 s7.f7: got %f but expected %d\n", s7.f7, 7);
7087         }
7088         s7.f1+=addend; s7.f2+=addend; s7.f3+=addend; s7.f4+=addend; s7.f5+=addend; s7.f6+=addend; s7.f7+=addend; 
7089         return s7;
7090 }
7091
7092 typedef struct {
7093         double f1,f2,f3,f4,f5,f6,f7,f8;
7094 } double8;
7095
7096 LIBTEST_API double8 STDCALL
7097 mono_return_double8 (double8 s8, int addend) {
7098         if (s8.f1 != 1) {
7099                 fprintf(stderr, "mono_return_double8 s8.f1: got %f but expected %d\n", s8.f1, 1);
7100         }
7101         if (s8.f2 != 2) {
7102                 fprintf(stderr, "mono_return_double8 s8.f2: got %f but expected %d\n", s8.f2, 2);
7103         }
7104         if (s8.f3 != 3) {
7105                 fprintf(stderr, "mono_return_double8 s8.f3: got %f but expected %d\n", s8.f3, 3);
7106         }
7107         if (s8.f4 != 4) {
7108                 fprintf(stderr, "mono_return_double8 s8.f4: got %f but expected %d\n", s8.f4, 4);
7109         }
7110         if (s8.f5 != 5) {
7111                 fprintf(stderr, "mono_return_double8 s8.f5: got %f but expected %d\n", s8.f5, 5);
7112         }
7113         if (s8.f6 != 6) {
7114                 fprintf(stderr, "mono_return_double8 s8.f6: got %f but expected %d\n", s8.f6, 6);
7115         }
7116         if (s8.f7 != 7) {
7117                 fprintf(stderr, "mono_return_double8 s8.f7: got %f but expected %d\n", s8.f7, 7);
7118         }
7119         if (s8.f8 != 8) {
7120                 fprintf(stderr, "mono_return_double8 s8.f8: got %f but expected %d\n", s8.f8, 8);
7121         }
7122         s8.f1+=addend; s8.f2+=addend; s8.f3+=addend; s8.f4+=addend; s8.f5+=addend; s8.f6+=addend; s8.f7+=addend; s8.f8+=addend; 
7123         return s8;
7124 }
7125
7126 typedef struct {
7127         double f1,f2,f3,f4,f5,f6,f7,f8,f9;
7128 } double9;
7129
7130 LIBTEST_API double9 STDCALL
7131 mono_return_double9 (double9 s9, int addend) {
7132         if (s9.f1 != 1) {
7133                 fprintf(stderr, "mono_return_double9 s9.f1: got %f but expected %d\n", s9.f1, 1);
7134         }
7135         if (s9.f2 != 2) {
7136                 fprintf(stderr, "mono_return_double9 s9.f2: got %f but expected %d\n", s9.f2, 2);
7137         }
7138         if (s9.f3 != 3) {
7139                 fprintf(stderr, "mono_return_double9 s9.f3: got %f but expected %d\n", s9.f3, 3);
7140         }
7141         if (s9.f4 != 4) {
7142                 fprintf(stderr, "mono_return_double9 s9.f4: got %f but expected %d\n", s9.f4, 4);
7143         }
7144         if (s9.f5 != 5) {
7145                 fprintf(stderr, "mono_return_double9 s9.f5: got %f but expected %d\n", s9.f5, 5);
7146         }
7147         if (s9.f6 != 6) {
7148                 fprintf(stderr, "mono_return_double9 s9.f6: got %f but expected %d\n", s9.f6, 6);
7149         }
7150         if (s9.f7 != 7) {
7151                 fprintf(stderr, "mono_return_double9 s9.f7: got %f but expected %d\n", s9.f7, 7);
7152         }
7153         if (s9.f8 != 8) {
7154                 fprintf(stderr, "mono_return_double9 s9.f8: got %f but expected %d\n", s9.f8, 8);
7155         }
7156         if (s9.f9 != 9) {
7157                 fprintf(stderr, "mono_return_double9 s9.f9: got %f but expected %d\n", s9.f9, 9);
7158         }
7159         s9.f1+=addend; s9.f2+=addend; s9.f3+=addend; s9.f4+=addend; s9.f5+=addend; s9.f6+=addend; s9.f7+=addend; s9.f8+=addend; s9.f9+=addend; 
7160         return s9;
7161 }
7162
7163 typedef struct {
7164         struct {
7165                 double f1;
7166         } nested1;
7167         struct {
7168                 double f2;
7169         } nested2;
7170 } double2_nested;
7171
7172 LIBTEST_API double2_nested STDCALL
7173 mono_return_double2_nested (double2_nested sn2, int addend) {
7174         if (sn2.nested1.f1 != 1) {
7175                 fprintf(stderr, "mono_return_double2_nested sn2.nested1.f1: got %f but expected %d\n", sn2.nested1.f1, 1);
7176         }
7177         if (sn2.nested2.f2 != 2) {
7178                 fprintf(stderr, "mono_return_double2_nested sn2.nested2.f2: got %f but expected %d\n", sn2.nested2.f2, 2);
7179         }
7180         sn2.nested1.f1+=addend; sn2.nested2.f2+=addend; 
7181         return sn2;
7182 }
7183
7184
7185
7186 typedef struct {
7187         double f1[4];
7188 } double_array4;
7189
7190 LIBTEST_API double_array4 STDCALL
7191 mono_return_double_array4 (double_array4 sa4, int addend) {
7192         if (sa4.f1[0] != 1) {
7193                 fprintf(stderr, "mono_return_double_array4 sa4.f1[0]: got %f but expected %d\n", sa4.f1[0], 1);
7194         }
7195         if (sa4.f1[1] != 2) {
7196                 fprintf(stderr, "mono_return_double_array4 sa4.f1[1]: got %f but expected %d\n", sa4.f1[1], 2);
7197         }
7198         if (sa4.f1[2] != 3) {
7199                 fprintf(stderr, "mono_return_double_array4 sa4.f1[2]: got %f but expected %d\n", sa4.f1[2], 3);
7200         }
7201         if (sa4.f1[3] != 4) {
7202                 fprintf(stderr, "mono_return_double_array4 sa4.f1[3]: got %f but expected %d\n", sa4.f1[3], 4);
7203         }
7204         sa4.f1[0]+=addend; sa4.f1[1]+=addend; sa4.f1[2]+=addend; sa4.f1[3]+=addend; 
7205         return sa4;
7206 }
7207