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