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