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