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