Apply changes from https://github.com/dotnet/runtime/commit/eb1756e97d23df13bc6fe798e...
[mono-project.git] / mono / tests / libtest.c
blobc2e3639f1418e77a18cef9575b00be37f943e025
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 #include <setjmp.h>
11 #include <signal.h>
12 #include "../utils/mono-errno.h"
13 #include "../utils/mono-compiler.h"
15 #ifndef HOST_WIN32
16 #include <dlfcn.h>
17 #endif
19 #ifdef WIN32
20 #include <windows.h>
21 #include "initguid.h"
22 #else
23 #include <pthread.h>
24 #endif
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
30 #ifdef WIN32
31 #define STDCALL __stdcall
32 #else
33 #define STDCALL
34 #define __thiscall /* nothing */
35 #endif
37 #ifdef __GNUC__
38 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
39 #endif
41 #ifdef WIN32
42 extern __declspec(dllimport) void __stdcall CoTaskMemFree(void *ptr);
43 #endif
45 typedef int (STDCALL *SimpleDelegate) (int a);
47 #if defined(WIN32) && defined (_MSC_VER)
48 #define LIBTEST_API __declspec(dllexport)
49 #elif defined(__GNUC__)
50 #define LIBTEST_API __attribute__ ((__visibility__ ("default")))
51 #else
52 #define LIBTEST_API
53 #endif
55 static void marshal_free (void *ptr)
57 #ifdef WIN32
58 CoTaskMemFree (ptr);
59 #else
60 g_free (ptr);
61 #endif
64 static void* marshal_alloc (gsize size)
66 #ifdef WIN32
67 return CoTaskMemAlloc (size);
68 #else
69 return g_malloc (size);
70 #endif
73 static void* marshal_alloc0 (gsize size)
75 #ifdef WIN32
76 void* ptr = CoTaskMemAlloc (size);
77 memset(ptr, 0, size);
78 return ptr;
79 #else
80 return g_malloc0 (size);
81 #endif
84 static char* marshal_strdup (const char *str)
86 #ifdef WIN32
87 if (!str)
88 return NULL;
90 char *buf = (char *) CoTaskMemAlloc (strlen (str) + 1);
91 return strcpy (buf, str);
92 #else
93 return g_strdup (str);
94 #endif
97 static gunichar2* marshal_bstr_alloc(const gchar* str)
99 #ifdef WIN32
100 gunichar2* temp = g_utf8_to_utf16 (str, -1, NULL, NULL, NULL);
101 gunichar2* ret = SysAllocString (temp);
102 g_free (temp);
103 return ret;
104 #else
105 gchar* ret = NULL;
106 int slen = strlen (str);
107 gunichar2* temp;
108 /* allocate len + 1 utf16 characters plus 4 byte integer for length*/
109 ret = (gchar *)g_malloc ((slen + 1) * sizeof(gunichar2) + sizeof(guint32));
110 if (ret == NULL)
111 return NULL;
112 temp = g_utf8_to_utf16 (str, -1, NULL, NULL, NULL);
113 memcpy (ret + sizeof(guint32), temp, slen * sizeof(gunichar2));
114 * ((guint32 *) ret) = slen * sizeof(gunichar2);
115 ret [4 + slen * sizeof(gunichar2)] = 0;
116 ret [5 + slen * sizeof(gunichar2)] = 0;
118 return (gunichar2*)(ret + 4);
119 #endif
122 #define marshal_new0(type,size) ((type *) marshal_alloc0 (sizeof (type)* (size)))
124 LIBTEST_API int STDCALL
125 mono_cominterop_is_supported (void)
127 #if defined(TARGET_X86) || defined(TARGET_AMD64)
128 return 1;
129 #endif
130 return 0;
133 LIBTEST_API unsigned short* STDCALL
134 test_lpwstr_marshal (unsigned short* chars, int length)
136 int i = 0;
137 unsigned short *res;
139 res = (unsigned short *)marshal_alloc (2 * (length + 1));
141 // printf("test_lpwstr_marshal()\n");
143 while ( i < length ) {
144 // printf("X|%u|\n", chars[i]);
145 res [i] = chars[i];
146 i++;
149 res [i] = 0;
151 return res;
155 LIBTEST_API void STDCALL
156 test_lpwstr_marshal_out (unsigned short** chars)
158 int i = 0;
159 const char abc[] = "ABC";
160 glong len = strlen(abc);
162 *chars = (unsigned short *)marshal_alloc (2 * (len + 1));
164 while ( i < len ) {
165 (*chars) [i] = abc[i];
166 i++;
169 (*chars) [i] = 0;
172 typedef struct {
173 int b;
174 int a;
175 int c;
176 } union_test_1_type;
178 LIBTEST_API int STDCALL
179 mono_union_test_1 (union_test_1_type u1) {
180 // printf ("Got values %d %d %d\n", u1.b, u1.a, u1.c);
181 return u1.a + u1.b + u1.c;
184 LIBTEST_API int STDCALL
185 mono_return_int (int a) {
186 // printf ("Got value %d\n", a);
187 return a;
190 LIBTEST_API float STDCALL
191 mono_test_marshal_pass_return_float (float f) {
192 return f + 1.0;
195 struct ss
197 int i;
200 LIBTEST_API int STDCALL
201 mono_return_int_ss (struct ss a) {
202 // printf ("Got value %d\n", a.i);
203 return a.i;
206 LIBTEST_API struct ss STDCALL
207 mono_return_ss (struct ss a) {
208 // printf ("Got value %d\n", a.i);
209 a.i++;
210 return a;
213 struct sc1
215 char c[1];
218 LIBTEST_API struct sc1 STDCALL
219 mono_return_sc1 (struct sc1 a) {
220 // printf ("Got value %d\n", a.c[0]);
221 a.c[0]++;
222 return a;
226 struct sc3
228 char c[3];
231 LIBTEST_API struct sc3 STDCALL
232 mono_return_sc3 (struct sc3 a) {
233 // printf ("Got values %d %d %d\n", a.c[0], a.c[1], a.c[2]);
234 a.c[0]++;
235 a.c[1] += 2;
236 a.c[2] += 3;
237 return a;
240 struct sc5
242 char c[5];
245 LIBTEST_API struct sc5 STDCALL
246 mono_return_sc5 (struct sc5 a) {
247 // printf ("Got values %d %d %d %d %d\n", a.c[0], a.c[1], a.c[2], a.c[3], a.c[4]);
248 a.c[0]++;
249 a.c[1] += 2;
250 a.c[2] += 3;
251 a.c[3] += 4;
252 a.c[4] += 5;
253 return a;
256 union su
258 int i1;
259 int i2;
262 LIBTEST_API int STDCALL
263 mono_return_int_su (union su a) {
264 // printf ("Got value %d\n", a.i1);
265 return a.i1;
268 struct FI {
269 float f1;
270 float f2;
271 float f3;
274 struct NestedFloat {
275 struct FI fi;
276 float f4;
279 LIBTEST_API struct NestedFloat STDCALL
280 mono_return_nested_float (void)
282 struct NestedFloat f;
283 f.fi.f1 = 1.0;
284 f.fi.f2 = 2.0;
285 f.fi.f3 = 3.0;
286 f.f4 = 4.0;
287 return f;
290 struct Scalar4 {
291 double val[4];
294 struct Rect {
295 int x;
296 int y;
297 int width;
298 int height;
301 LIBTEST_API char * STDCALL
302 mono_return_struct_4_double (void *ptr, struct Rect rect, struct Scalar4 sc4, int a, int b, int c)
304 char *buffer = (char *)marshal_alloc (1024 * sizeof (char));
305 sprintf (buffer, "sc4 = {%.1f, %.1f, %.1f, %.1f }, a=%x, b=%x, c=%x\n", (float) sc4.val [0], (float) sc4.val [1], (float) sc4.val [2], (float) sc4.val [3], a, b, c);
306 return buffer;
309 LIBTEST_API int STDCALL
310 mono_test_many_int_arguments (int a, int b, int c, int d, int e,
311 int f, int g, int h, int i, int j);
312 LIBTEST_API short STDCALL
313 mono_test_many_short_arguments (short a, short b, short c, short d, short e,
314 short f, short g, short h, short i, short j);
315 LIBTEST_API char STDCALL
316 mono_test_many_char_arguments (char a, char b, char c, char d, char e,
317 char f, char g, char h, char i, char j);
319 LIBTEST_API int STDCALL
320 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)
322 return a + b + c + d + e + f + g + h + i + j;
325 LIBTEST_API short STDCALL
326 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)
328 return a + b + c + d + e + f + g + h + i + j;
331 LIBTEST_API char STDCALL
332 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)
334 return a + b + c + d + e + f + g + h + i + j;
337 LIBTEST_API float STDCALL
338 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)
340 return a + b + c + d + e + f + g + h + i + j;
343 LIBTEST_API double STDCALL
344 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)
346 return a + b + c + d + e + f + g + h + i + j;
349 LIBTEST_API double STDCALL
350 mono_test_split_double_arguments (double a, double b, float c, double d, double e)
352 return a + b + c + d + e;
355 LIBTEST_API int STDCALL
356 mono_test_puts_static (char *s)
358 // printf ("TEST %s\n", s);
359 return 1;
362 typedef int (STDCALL *SimpleDelegate3) (int a, int b);
364 LIBTEST_API int STDCALL
365 mono_invoke_delegate (SimpleDelegate3 delegate)
367 int res;
369 // printf ("start invoke %p\n", delegate);
371 res = delegate (2, 3);
373 // printf ("end invoke\n");
375 return res;
378 LIBTEST_API int STDCALL
379 mono_invoke_simple_delegate (SimpleDelegate d)
381 return d (4);
384 LIBTEST_API int STDCALL
385 mono_test_marshal_char (short a1)
387 if (a1 == 'a')
388 return 0;
390 return 1;
393 LIBTEST_API void STDCALL
394 mono_test_marshal_char_array (gunichar2 *s)
396 const char m[] = "abcdef";
397 gunichar2* s2;
398 glong len;
400 s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
402 len = (len * 2) + 2;
403 memcpy (s, s2, len);
405 g_free (s2);
408 LIBTEST_API int STDCALL
409 mono_test_marshal_ansi_char_array (char *s)
411 const char m[] = "abcdef";
413 if (strncmp ("qwer", s, 4))
414 return 1;
416 memcpy (s, m, sizeof (m));
417 return 0;
420 LIBTEST_API int STDCALL
421 mono_test_marshal_unicode_char_array (gunichar2 *s)
423 const char m[] = "abcdef";
424 const char expected[] = "qwer";
425 gunichar2 *s1, *s2;
426 glong len1, len2;
428 s1 = g_utf8_to_utf16 (m, -1, NULL, &len1, NULL);
429 s2 = g_utf8_to_utf16 (expected, -1, NULL, &len2, NULL);
430 len1 = (len1 * 2);
431 len2 = (len2 * 2);
433 if (memcmp (s, s2, len2))
434 return 1;
436 memcpy (s, s1, len1);
437 return 0;
440 LIBTEST_API int STDCALL
441 mono_test_empty_pinvoke (int i)
443 return i;
446 LIBTEST_API int STDCALL
447 mono_test_marshal_bool_byref (int a, int *b, int c)
449 int res = *b;
451 *b = 1;
453 return res;
456 LIBTEST_API int STDCALL
457 mono_test_marshal_bool_in_as_I1_U1 (char bTrue, char bFalse)
459 if (!bTrue)
460 return 1;
461 if (bFalse)
462 return 2;
463 return 0;
466 LIBTEST_API int STDCALL
467 mono_test_marshal_bool_out_as_I1_U1 (char* bTrue, char* bFalse)
469 if (!bTrue || !bFalse)
470 return 3;
472 *bTrue = 1;
473 *bFalse = 0;
475 return 0;
478 LIBTEST_API int STDCALL
479 mono_test_marshal_bool_ref_as_I1_U1 (char* bTrue, char* bFalse)
481 if (!bTrue || !bFalse)
482 return 4;
484 if (!(*bTrue))
485 return 5;
486 if (*bFalse)
487 return 6;
489 *bFalse = 1;
490 *bTrue = 0;
492 return 0;
495 LIBTEST_API int STDCALL
496 mono_test_marshal_array (int *a1)
498 int i, sum = 0;
500 for (i = 0; i < 50; i++)
501 sum += a1 [i];
503 return sum;
506 LIBTEST_API int STDCALL
507 mono_test_marshal_inout_array (int *a1)
509 int i, sum = 0;
511 for (i = 0; i < 50; i++) {
512 sum += a1 [i];
513 a1 [i] = 50 - a1 [i];
516 return sum;
519 LIBTEST_API int /* cdecl */
520 mono_test_marshal_inout_array_cdecl (int *a1)
522 return mono_test_marshal_inout_array (a1);
525 LIBTEST_API int STDCALL
526 mono_test_marshal_out_array (int *a1)
528 int i;
530 for (i = 0; i < 50; i++) {
531 a1 [i] = i;
534 return 0;
537 LIBTEST_API int STDCALL
538 mono_test_marshal_out_byref_array_out_size_param (int **out_arr, int *out_len)
540 int *arr;
541 int i, len;
543 len = 4;
544 arr = (gint32 *)marshal_alloc (sizeof (gint32) * len);
545 for (i = 0; i < len; ++i)
546 arr [i] = i;
547 *out_arr = arr;
548 *out_len = len;
550 return 0;
553 LIBTEST_API int STDCALL
554 mono_test_marshal_out_lparray_out_size_param (int *arr, int *out_len)
556 int i, len;
558 len = 4;
559 for (i = 0; i < len; ++i)
560 arr [i] = i;
561 *out_len = len;
563 return 0;
566 LIBTEST_API int STDCALL
567 mono_test_marshal_inout_nonblittable_array (gunichar2 *a1)
569 int i, sum = 0;
571 for (i = 0; i < 10; i++) {
572 a1 [i] = 'F';
575 return sum;
578 typedef struct {
579 int a;
580 int b;
581 int c;
582 const char *d;
583 gunichar2 *d2;
584 } simplestruct;
586 typedef struct {
587 double x;
588 double y;
589 } point;
591 LIBTEST_API simplestruct STDCALL
592 mono_test_return_vtype (int i)
594 simplestruct res;
595 static gunichar2 test2 [] = { 'T', 'E', 'S', 'T', '2', 0 };
597 res.a = 0;
598 res.b = 1;
599 res.c = 0;
600 res.d = "TEST";
601 res.d2 = test2;
603 return res;
606 LIBTEST_API void STDCALL
607 mono_test_delegate_struct (void)
609 // printf ("TEST\n");
612 typedef char* (STDCALL *ReturnStringDelegate) (const char *s);
614 LIBTEST_API char * STDCALL
615 mono_test_return_string (ReturnStringDelegate func)
617 char *res;
619 // printf ("mono_test_return_string\n");
621 res = func ("TEST");
622 marshal_free (res);
624 // printf ("got string: %s\n", res);
625 return marshal_strdup ("12345");
628 typedef int (STDCALL *RefVTypeDelegate) (int a, simplestruct *ss, int b);
630 LIBTEST_API int STDCALL
631 mono_test_ref_vtype (int a, simplestruct *ss, int b, RefVTypeDelegate func)
633 if (a == 1 && b == 2 && ss->a == 0 && ss->b == 1 && ss->c == 0 &&
634 !strcmp (ss->d, "TEST1")) {
635 ss->a = 1;
636 ss->b = 0;
637 ss->c = 1;
638 ss->d = "TEST2";
640 return func (a, ss, b);
643 return 1;
646 typedef int (STDCALL *OutVTypeDelegate) (int a, simplestruct *ss, int b);
648 LIBTEST_API int STDCALL
649 mono_test_marshal_out_struct (int a, simplestruct *ss, int b, OutVTypeDelegate func)
651 /* Check that the input pointer is ignored */
652 ss->d = (const char *)0x12345678;
654 func (a, ss, b);
656 if (ss->a && ss->b && ss->c && !strcmp (ss->d, "TEST3"))
657 return 0;
658 else
659 return 1;
662 typedef int (STDCALL *InVTypeDelegate) (int a, simplestruct *ss, int b);
664 LIBTEST_API int STDCALL
665 mono_test_marshal_in_struct (int a, simplestruct *ss, int b, InVTypeDelegate func)
667 simplestruct ss2;
668 int res;
670 memcpy (&ss2, ss, sizeof (simplestruct));
672 res = func (a, ss, b);
673 if (res) {
674 printf ("mono_test_marshal_in_struct () failed: %d\n", res);
675 return 1;
678 /* Check that no modifications is made to the struct */
679 if (ss2.a == ss->a && ss2.b == ss->b && ss2.c == ss->c && ss2.d == ss->d)
680 return 0;
681 else
682 return 1;
685 typedef struct {
686 int a;
687 SimpleDelegate func, func2, func3;
688 } DelegateStruct;
690 LIBTEST_API DelegateStruct STDCALL
691 mono_test_marshal_delegate_struct (DelegateStruct ds)
693 DelegateStruct res;
695 res.a = ds.func (ds.a) + ds.func2 (ds.a) + (ds.func3 == NULL ? 0 : 1);
696 res.func = ds.func;
697 res.func2 = ds.func2;
698 res.func3 = NULL;
700 return res;
703 LIBTEST_API int STDCALL
704 mono_test_marshal_byref_struct (simplestruct *ss, int a, int b, int c, char *d)
706 gboolean res = (ss->a == a && ss->b == b && ss->c == c && strcmp (ss->d, d) == 0);
708 marshal_free ((char*)ss->d);
710 ss->a = !ss->a;
711 ss->b = !ss->b;
712 ss->c = !ss->c;
713 ss->d = marshal_strdup ("DEF");
715 return res ? 0 : 1;
718 typedef struct {
719 int a;
720 int b;
721 int c;
722 char *d;
723 unsigned char e;
724 double f;
725 unsigned char g;
726 guint64 h;
727 } simplestruct2;
729 LIBTEST_API int STDCALL
730 mono_test_marshal_struct2 (simplestruct2 ss)
732 if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
733 !strcmp (ss.d, "TEST") &&
734 ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
735 return 0;
737 return 1;
740 /* on HP some of the struct should be on the stack and not in registers */
741 LIBTEST_API int STDCALL
742 mono_test_marshal_struct2_2 (int i, int j, int k, simplestruct2 ss)
744 if (i != 10 || j != 11 || k != 12)
745 return 1;
746 if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
747 !strcmp (ss.d, "TEST") &&
748 ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
749 return 0;
751 return 1;
754 LIBTEST_API int STDCALL
755 mono_test_marshal_lpstruct (simplestruct *ss)
757 if (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
758 !strcmp (ss->d, "TEST"))
759 return 0;
761 return 1;
764 LIBTEST_API int STDCALL
765 mono_test_marshal_lpstruct_blittable (point *p)
767 if (p->x == 1.0 && p->y == 2.0)
768 return 0;
769 else
770 return 1;
773 LIBTEST_API int STDCALL
774 mono_test_marshal_struct_array (simplestruct2 *ss)
776 if (! (ss[0].a == 0 && ss[0].b == 1 && ss[0].c == 0 &&
777 !strcmp (ss[0].d, "TEST") &&
778 ss[0].e == 99 && ss[0].f == 1.5 && ss[0].g == 42 && ss[0].h == (guint64)123))
779 return 1;
781 if (! (ss[1].a == 0 && ss[1].b == 0 && ss[1].c == 0 &&
782 !strcmp (ss[1].d, "TEST2") &&
783 ss[1].e == 100 && ss[1].f == 2.5 && ss[1].g == 43 && ss[1].h == (guint64)124))
784 return 1;
786 return 0;
789 typedef struct long_align_struct {
790 gint32 a;
791 gint64 b;
792 gint64 c;
793 } long_align_struct;
795 LIBTEST_API int STDCALL
796 mono_test_marshal_long_align_struct_array (long_align_struct *ss)
798 return ss[0].a + ss[0].b + ss[0].c + ss[1].a + ss[1].b + ss[1].c;
801 LIBTEST_API simplestruct2 * STDCALL
802 mono_test_marshal_class (int i, int j, int k, simplestruct2 *ss, int l)
804 simplestruct2 *res;
806 if (!ss)
807 return NULL;
809 if (i != 10 || j != 11 || k != 12 || l != 14)
810 return NULL;
811 if (! (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
812 !strcmp (ss->d, "TEST") &&
813 ss->e == 99 && ss->f == 1.5 && ss->g == 42 && ss->h == (guint64)123))
814 return NULL;
816 res = marshal_new0 (simplestruct2, 1);
817 memcpy (res, ss, sizeof (simplestruct2));
818 res->d = marshal_strdup ("TEST");
819 return res;
822 LIBTEST_API int STDCALL
823 mono_test_marshal_byref_class (simplestruct2 **ssp)
825 simplestruct2 *ss = *ssp;
826 simplestruct2 *res;
828 if (! (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
829 !strcmp (ss->d, "TEST") &&
830 ss->e == 99 && ss->f == 1.5 && ss->g == 42 && ss->h == (guint64)123))
831 return 1;
833 res = marshal_new0 (simplestruct2, 1);
834 memcpy (res, ss, sizeof (simplestruct2));
835 res->d = marshal_strdup ("TEST-RES");
837 *ssp = res;
838 return 0;
841 MONO_DISABLE_WARNING (4172) // returning address of local
843 static void *
844 get_sp (void)
846 int i;
847 void *p;
849 /* Yes, this is correct, we are only trying to determine the value of the stack here */
850 p = &i;
851 return p;
854 MONO_RESTORE_WARNING
856 LIBTEST_API int STDCALL
857 reliable_delegate (int a)
859 return a;
863 * Checks whether get_sp() works as expected. It doesn't work with gcc-2.95.3 on linux.
865 static gboolean
866 is_get_sp_reliable (void)
868 void *sp1, *sp2;
870 reliable_delegate(1);
871 sp1 = get_sp();
872 reliable_delegate(1);
873 sp2 = get_sp();
874 return sp1 == sp2;
877 LIBTEST_API int STDCALL
878 mono_test_marshal_delegate (SimpleDelegate delegate)
880 void *sp1, *sp2;
882 /* Check that the delegate wrapper is stdcall */
883 delegate (2);
884 sp1 = get_sp ();
885 delegate (2);
886 sp2 = get_sp ();
887 if (is_get_sp_reliable())
888 g_assert (sp1 == sp2);
890 return delegate (2);
893 static int STDCALL inc_cb (int i)
895 return i + 1;
898 LIBTEST_API int STDCALL
899 mono_test_marshal_out_delegate (SimpleDelegate *delegate)
901 *delegate = inc_cb;
903 return 0;
906 LIBTEST_API SimpleDelegate STDCALL
907 mono_test_marshal_return_delegate (SimpleDelegate delegate)
909 return delegate;
912 typedef int (STDCALL *DelegateByrefDelegate) (void *);
914 LIBTEST_API int STDCALL
915 mono_test_marshal_delegate_ref_delegate (DelegateByrefDelegate del)
917 int (STDCALL *ptr) (int i);
919 del (&ptr);
921 return ptr (54);
924 static int STDCALL
925 return_plus_one (int i)
927 return i + 1;
930 LIBTEST_API SimpleDelegate STDCALL
931 mono_test_marshal_return_delegate_2 (void)
933 return return_plus_one;
936 typedef simplestruct (STDCALL *SimpleDelegate2) (simplestruct ss);
938 static gboolean
939 is_utf16_equals (gunichar2 *s1, const char *s2)
941 char *s;
942 int res;
944 s = g_utf16_to_utf8 (s1, -1, NULL, NULL, NULL);
945 res = strcmp (s, s2);
946 g_free (s);
948 return res == 0;
951 LIBTEST_API int STDCALL
952 mono_test_marshal_struct (simplestruct ss)
954 if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
955 !strcmp (ss.d, "TEST") && is_utf16_equals (ss.d2, "OK"))
956 return 0;
958 return 1;
961 LIBTEST_API int STDCALL
962 mono_test_marshal_delegate2 (SimpleDelegate2 delegate)
964 simplestruct ss, res;
966 ss.a = 0;
967 ss.b = 1;
968 ss.c = 0;
969 ss.d = "TEST";
970 ss.d2 = g_utf8_to_utf16 ("TEST2", -1, NULL, NULL, NULL);
972 res = delegate (ss);
973 if (! (res.a && !res.b && res.c && !strcmp (res.d, "TEST-RES") && is_utf16_equals (res.d2, "TEST2-RES")))
974 return 1;
976 return 0;
979 typedef simplestruct* (STDCALL *SimpleDelegate4) (simplestruct *ss);
981 LIBTEST_API int STDCALL
982 mono_test_marshal_delegate4 (SimpleDelegate4 delegate)
984 simplestruct ss;
985 simplestruct *res;
987 ss.a = 0;
988 ss.b = 1;
989 ss.c = 0;
990 ss.d = "TEST";
992 /* Check argument */
993 res = delegate (&ss);
994 if (!res)
995 return 1;
997 /* Check return value */
998 if (! (!res->a && res->b && !res->c && !strcmp (res->d, "TEST")))
999 return 2;
1001 /* Check NULL argument and NULL result */
1002 res = delegate (NULL);
1003 if (res)
1004 return 3;
1006 return 0;
1009 typedef int (STDCALL *SimpleDelegate5) (simplestruct **ss);
1011 LIBTEST_API int STDCALL
1012 mono_test_marshal_delegate5 (SimpleDelegate5 delegate)
1014 simplestruct ss;
1015 int res;
1016 simplestruct *ptr;
1018 ss.a = 0;
1019 ss.b = 1;
1020 ss.c = 0;
1021 ss.d = "TEST";
1023 ptr = &ss;
1025 res = delegate (&ptr);
1026 if (res != 0)
1027 return 1;
1029 if (!(ptr->a && !ptr->b && ptr->c && !strcmp (ptr->d, "RES")))
1030 return 2;
1032 return 0;
1035 LIBTEST_API int STDCALL
1036 mono_test_marshal_delegate6 (SimpleDelegate5 delegate)
1038 delegate (NULL);
1039 return 0;
1042 typedef int (STDCALL *SimpleDelegate7) (simplestruct **ss);
1044 LIBTEST_API int STDCALL
1045 mono_test_marshal_delegate7 (SimpleDelegate7 delegate)
1047 int res;
1048 simplestruct *ptr;
1050 /* Check that the input pointer is ignored */
1051 ptr = (simplestruct *)0x12345678;
1053 res = delegate (&ptr);
1054 if (res != 0)
1055 return 1;
1057 if (!(ptr->a && !ptr->b && ptr->c && !strcmp (ptr->d, "RES")))
1058 return 2;
1060 return 0;
1063 typedef int (STDCALL *InOutByvalClassDelegate) (simplestruct *ss);
1065 LIBTEST_API int STDCALL
1066 mono_test_marshal_inout_byval_class_delegate (InOutByvalClassDelegate delegate)
1068 int res;
1069 simplestruct ss;
1071 ss.a = FALSE;
1072 ss.b = TRUE;
1073 ss.c = FALSE;
1074 ss.d = g_strdup_printf ("%s", "FOO");
1076 res = delegate (&ss);
1077 if (res != 0)
1078 return 1;
1080 if (!(ss.a && !ss.b && ss.c && !strcmp (ss.d, "RES")))
1081 return 2;
1083 return 0;
1086 typedef int (STDCALL *SimpleDelegate8) (gunichar2 *s);
1088 LIBTEST_API int STDCALL
1089 mono_test_marshal_delegate8 (SimpleDelegate8 delegate, gunichar2 *s)
1091 return delegate (s);
1094 typedef int (STDCALL *return_int_fnt) (int i);
1095 typedef int (STDCALL *SimpleDelegate9) (return_int_fnt d);
1097 LIBTEST_API int STDCALL
1098 mono_test_marshal_delegate9 (SimpleDelegate9 delegate, gpointer ftn)
1100 return delegate ((return_int_fnt)ftn);
1103 static int STDCALL
1104 return_self (int i)
1106 return i;
1109 LIBTEST_API int STDCALL
1110 mono_test_marshal_delegate10 (SimpleDelegate9 delegate)
1112 return delegate (return_self);
1115 typedef int (STDCALL *PrimitiveByrefDelegate) (int *i);
1117 LIBTEST_API int STDCALL
1118 mono_test_marshal_primitive_byref_delegate (PrimitiveByrefDelegate delegate)
1120 int i = 1;
1122 int res = delegate (&i);
1123 if (res != 0)
1124 return res;
1126 if (i != 2)
1127 return 2;
1129 return 0;
1132 typedef int (STDCALL *return_int_delegate) (int i);
1134 typedef return_int_delegate (STDCALL *ReturnDelegateDelegate) (void);
1136 LIBTEST_API int STDCALL
1137 mono_test_marshal_return_delegate_delegate (ReturnDelegateDelegate d)
1139 return (d ()) (55);
1142 typedef int (STDCALL *VirtualDelegate) (int);
1144 LIBTEST_API int STDCALL
1145 mono_test_marshal_virtual_delegate (VirtualDelegate del)
1147 return del (42);
1150 typedef char* (STDCALL *IcallDelegate) (const char *);
1151 LIBTEST_API int STDCALL
1152 mono_test_marshal_icall_delegate (IcallDelegate del)
1154 char *res = del ("ABC");
1155 return strcmp (res, "ABC") == 0 ? 0 : 1;
1158 LIBTEST_API int STDCALL
1159 mono_test_marshal_stringbuilder (char *s, int n)
1161 const char m[] = "This is my message. Isn't it nice?";
1163 if (strcmp (s, "ABCD") != 0)
1164 return 1;
1165 memcpy(s, m, n);
1166 s [n] = '\0';
1167 return 0;
1170 LIBTEST_API int STDCALL
1171 mono_test_marshal_stringbuilder_append (char *s, int length)
1173 const char out_sentinel[] = "CSHARP_";
1174 const char out_len = strlen (out_sentinel);
1176 for (int i=0; i < length; i++) {
1177 s [i] = out_sentinel [i % out_len];
1180 s [length] = '\0';
1183 return 0;
1186 LIBTEST_API int STDCALL
1187 mono_test_marshal_stringbuilder_default (char *s, int n)
1189 const char m[] = "This is my message. Isn't it nice?";
1191 memcpy(s, m, n);
1192 s [n] = '\0';
1193 return 0;
1196 LIBTEST_API int STDCALL
1197 mono_test_marshal_stringbuilder_unicode (gunichar2 *s, int n)
1199 const char m[] = "This is my message. Isn't it nice?";
1200 gunichar2* s2;
1201 glong len;
1203 s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
1205 len = (len * 2) + 2;
1206 if (len > (n * 2))
1207 len = n * 2;
1208 memcpy (s, s2, len);
1210 g_free (s2);
1212 return 0;
1215 LIBTEST_API void STDCALL
1216 mono_test_marshal_stringbuilder_out (char **s)
1218 const char m[] = "This is my message. Isn't it nice?";
1219 char *str;
1221 str = (char *)marshal_alloc (strlen (m) + 1);
1222 memcpy (str, m, strlen (m) + 1);
1224 *s = str;
1227 LIBTEST_API int STDCALL
1228 mono_test_marshal_stringbuilder_out_unicode (gunichar2 **s)
1230 const char m[] = "This is my message. Isn't it nice?";
1231 gunichar2 *s2;
1232 glong len;
1234 s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
1236 len = (len * 2) + 2;
1237 *s = (gunichar2 *)marshal_alloc (len);
1238 memcpy (*s, s2, len);
1240 g_free (s2);
1242 return 0;
1245 LIBTEST_API int STDCALL
1246 mono_test_marshal_stringbuilder_ref (char **s)
1248 const char m[] = "This is my message. Isn't it nice?";
1249 char *str;
1251 if (strcmp (*s, "ABC"))
1252 return 1;
1254 str = (char *)marshal_alloc (strlen (m) + 1);
1255 memcpy (str, m, strlen (m) + 1);
1257 *s = str;
1258 return 0;
1261 LIBTEST_API void STDCALL
1262 mono_test_marshal_stringbuilder_utf16_tolower (short *s, int n)
1264 for (int i = 0; i < n; i++)
1265 s[i] = tolower(s[i]);
1269 #ifdef __GNUC__
1270 #pragma GCC diagnostic push
1271 #pragma GCC diagnostic ignored "-Wc++-compat"
1272 #endif
1275 * Standard C and C++ doesn't allow empty structs, empty structs will always have a size of 1 byte.
1276 * GCC have an extension to allow empty structs, https://gcc.gnu.org/onlinedocs/gcc/Empty-Structures.html.
1277 * This cause a little dilemma since runtime build using none GCC compiler will not be compatible with
1278 * GCC build C libraries and the other way around. On platforms where empty structs has size of 1 byte
1279 * it must be represented in call and cannot be dropped. On Windows x64 structs will always be represented in the call
1280 * meaning that an empty struct must have a representation in the callee in order to correctly follow the ABI used by the
1281 * C/C++ standard and the runtime.
1283 typedef struct {
1284 #if !defined(__GNUC__) || defined(TARGET_WIN32)
1285 char a;
1286 #endif
1287 } EmptyStruct;
1289 #ifdef __GNUC__
1290 #pragma GCC diagnostic pop
1291 #endif
1293 LIBTEST_API int STDCALL
1294 mono_test_marshal_empty_string_array (char **array)
1296 return (array == NULL) ? 0 : 1;
1299 LIBTEST_API int STDCALL
1300 mono_test_marshal_string_array (char **array)
1302 if (strcmp (array [0], "ABC"))
1303 return 1;
1304 if (strcmp (array [1], "DEF"))
1305 return 2;
1307 if (array [2] != NULL)
1308 return 3;
1310 return 0;
1313 LIBTEST_API int STDCALL
1314 mono_test_marshal_byref_string_array (char ***array)
1316 if (*array == NULL)
1317 return 0;
1319 if (strcmp ((*array) [0], "Alpha"))
1320 return 2;
1321 if (strcmp ((*array) [1], "Beta"))
1322 return 2;
1323 if (strcmp ((*array) [2], "Gamma"))
1324 return 2;
1326 return 1;
1329 LIBTEST_API int STDCALL
1330 mono_test_marshal_stringbuilder_array (char **array)
1332 if (strcmp (array [0], "ABC"))
1333 return 1;
1334 if (strcmp (array [1], "DEF"))
1335 return 2;
1337 strcpy (array [0], "DEF");
1338 strcpy (array [1], "ABC");
1340 return 0;
1343 LIBTEST_API int STDCALL
1344 mono_test_marshal_unicode_string_array (gunichar2 **array, char **array2)
1346 GError *gerror = NULL;
1347 char *s;
1349 s = g_utf16_to_utf8 (array [0], -1, NULL, NULL, &gerror);
1350 if (strcmp (s, "ABC")) {
1351 g_free (s);
1352 return 1;
1354 else
1355 g_free (s);
1357 s = g_utf16_to_utf8 (array [1], -1, NULL, NULL, &gerror);
1358 if (strcmp (s, "DEF")) {
1359 g_free (s);
1360 return 2;
1362 else
1363 g_free (s);
1365 if (strcmp (array2 [0], "ABC"))
1366 return 3;
1368 if (strcmp (array2 [1], "DEF"))
1369 return 4;
1371 return 0;
1374 /* this does not work on Redhat gcc 2.96 */
1375 LIBTEST_API int STDCALL
1376 mono_test_empty_struct (int a, EmptyStruct es, int b)
1378 // printf ("mono_test_empty_struct %d %d\n", a, b);
1380 // Intel icc on ia64 passes 'es' in 2 registers
1381 #if defined(__ia64) && defined(__INTEL_COMPILER)
1382 return 0;
1383 #else
1384 if (a == 1 && b == 2)
1385 return 0;
1386 return 1;
1387 #endif
1390 LIBTEST_API EmptyStruct STDCALL
1391 mono_test_return_empty_struct (int a)
1393 EmptyStruct s;
1395 memset (&s, 0, sizeof (s));
1397 #if !(defined(__i386__) && defined(__clang__))
1398 /* https://bugzilla.xamarin.com/show_bug.cgi?id=58901 */
1399 g_assert (a == 42);
1400 #endif
1402 return s;
1405 typedef struct {
1406 char a[100];
1407 } ByValStrStruct;
1409 LIBTEST_API ByValStrStruct * STDCALL
1410 mono_test_byvalstr_gen (void)
1412 ByValStrStruct *ret;
1414 ret = (ByValStrStruct *)malloc (sizeof (ByValStrStruct));
1415 memset(ret, 'a', sizeof(ByValStrStruct)-1);
1416 ret->a[sizeof(ByValStrStruct)-1] = 0;
1418 return ret;
1421 LIBTEST_API int STDCALL
1422 mono_test_byvalstr_check (ByValStrStruct* data, char* correctString)
1424 int ret;
1426 ret = strcmp(data->a, correctString);
1427 // printf ("T1: %s\n", data->a);
1428 // printf ("T2: %s\n", correctString);
1430 /* we need g_free because the allocation was performed by mono_test_byvalstr_gen */
1431 g_free (data);
1432 return (ret != 0);
1435 typedef struct {
1436 guint16 a[4];
1437 int flag;
1438 } ByValStrStruct_Unicode;
1440 LIBTEST_API int STDCALL
1441 mono_test_byvalstr_check_unicode (ByValStrStruct_Unicode *ref, int test)
1443 if (ref->flag != 0x1234abcd){
1444 printf ("overwritten data");
1445 return 1;
1448 if (test == 1 || test == 3){
1449 if (ref->a [0] != '1' ||
1450 ref->a [1] != '2' ||
1451 ref->a [2] != '3')
1452 return 1;
1453 return 0;
1455 if (test == 2){
1456 if (ref->a [0] != '1' ||
1457 ref->a [1] != '2')
1458 return 1;
1459 return 0;
1461 return 10;
1464 LIBTEST_API int STDCALL
1465 NameManglingAnsi (char *data)
1467 return data [0] + data [1] + data [2];
1470 LIBTEST_API int STDCALL
1471 NameManglingAnsiA (char *data)
1473 g_assert_not_reached ();
1476 LIBTEST_API int STDCALL
1477 NameManglingAnsiW (char *data)
1479 g_assert_not_reached ();
1482 LIBTEST_API int STDCALL
1483 NameManglingAnsi2A (char *data)
1485 return data [0] + data [1] + data [2];
1488 LIBTEST_API int STDCALL
1489 NameManglingAnsi2W (char *data)
1491 g_assert_not_reached ();
1494 LIBTEST_API int STDCALL
1495 NameManglingUnicode (char *data)
1497 g_assert_not_reached ();
1500 LIBTEST_API int STDCALL
1501 NameManglingUnicodeW (gunichar2 *data)
1503 return data [0] + data [1] + data [2];
1506 LIBTEST_API int STDCALL
1507 NameManglingUnicode2 (gunichar2 *data)
1509 return data [0] + data [1] + data [2];
1512 LIBTEST_API int STDCALL
1513 NameManglingAutoW (char *data)
1515 #ifdef WIN32
1516 return (data [0] + data [1] + data [2]) == 131 ? 0 : 1;
1517 #else
1518 g_assert_not_reached ();
1519 #endif
1522 LIBTEST_API int STDCALL
1523 NameManglingAuto (char *data)
1525 #ifndef WIN32
1526 return (data [0] + data [1] + data [2]) == 198 ? 0 : 1;
1527 #else
1528 g_assert_not_reached ();
1529 #endif
1532 typedef int (STDCALL *intcharFunc)(const char*);
1534 LIBTEST_API void STDCALL
1535 callFunction (intcharFunc f)
1537 f ("ABC");
1540 typedef struct {
1541 const char* str;
1542 int i;
1543 } SimpleObj;
1545 LIBTEST_API int STDCALL
1546 class_marshal_test0 (SimpleObj *obj1)
1548 // printf ("class_marshal_test0 %s %d\n", obj1->str, obj1->i);
1550 if (strcmp(obj1->str, "T1"))
1551 return -1;
1552 if (obj1->i != 4)
1553 return -2;
1555 return 0;
1558 LIBTEST_API int STDCALL
1559 class_marshal_test4 (SimpleObj *obj1)
1561 if (obj1)
1562 return -1;
1564 return 0;
1567 LIBTEST_API void STDCALL
1568 class_marshal_test1 (SimpleObj **obj1)
1570 SimpleObj *res = (SimpleObj *)malloc (sizeof (SimpleObj));
1572 res->str = marshal_strdup ("ABC");
1573 res->i = 5;
1575 *obj1 = res;
1578 LIBTEST_API int STDCALL
1579 class_marshal_test2 (SimpleObj **obj1)
1581 // printf ("class_marshal_test2 %s %d\n", (*obj1)->str, (*obj1)->i);
1583 if (strcmp((*obj1)->str, "ABC"))
1584 return -1;
1585 if ((*obj1)->i != 5)
1586 return -2;
1588 return 0;
1591 LIBTEST_API int STDCALL
1592 string_marshal_test0 (char *str)
1594 if (strcmp (str, "TEST0"))
1595 return -1;
1597 return 0;
1600 LIBTEST_API void STDCALL
1601 string_marshal_test1 (const char **str)
1603 *str = marshal_strdup ("TEST1");
1606 LIBTEST_API int STDCALL
1607 string_marshal_test2 (char **str)
1609 // printf ("string_marshal_test2 %s\n", *str);
1611 if (strcmp (*str, "TEST1"))
1612 return -1;
1614 *str = marshal_strdup ("TEST2");
1616 return 0;
1619 LIBTEST_API int STDCALL
1620 string_marshal_test3 (char *str)
1622 if (str)
1623 return -1;
1625 return 0;
1628 typedef struct {
1629 int a;
1630 int b;
1631 } BlittableClass;
1633 LIBTEST_API BlittableClass* STDCALL
1634 TestBlittableClass (BlittableClass *vl)
1636 BlittableClass *res;
1638 // printf ("TestBlittableClass %d %d\n", vl->a, vl->b);
1640 if (vl) {
1641 vl->a++;
1642 vl->b++;
1644 res = marshal_new0 (BlittableClass, 1);
1645 memcpy (res, vl, sizeof (BlittableClass));
1646 } else {
1647 res = marshal_new0 (BlittableClass, 1);
1648 res->a = 42;
1649 res->b = 43;
1652 return res;
1655 typedef struct OSVERSIONINFO_STRUCT
1657 int a;
1658 int b;
1659 } OSVERSIONINFO_STRUCT;
1661 LIBTEST_API int STDCALL
1662 MyGetVersionEx (OSVERSIONINFO_STRUCT *osvi)
1665 // printf ("GOT %d %d\n", osvi->a, osvi->b);
1667 osvi->a += 1;
1668 osvi->b += 1;
1670 return osvi->a + osvi->b;
1673 LIBTEST_API int STDCALL
1674 BugGetVersionEx (int a, int b, int c, int d, int e, int f, int g, int h, OSVERSIONINFO_STRUCT *osvi)
1677 // printf ("GOT %d %d\n", osvi->a, osvi->b);
1679 osvi->a += 1;
1680 osvi->b += 1;
1682 return osvi->a + osvi->b;
1685 LIBTEST_API int STDCALL
1686 mono_test_marshal_point (point pt)
1688 // printf("point %g %g\n", pt.x, pt.y);
1689 if (pt.x == 1.25 && pt.y == 3.5)
1690 return 0;
1692 return 1;
1695 typedef struct {
1696 int x;
1697 double y;
1698 } mixed_point;
1700 LIBTEST_API int STDCALL
1701 mono_test_marshal_mixed_point (mixed_point pt)
1703 // printf("mixed point %d %g\n", pt.x, pt.y);
1704 if (pt.x == 5 && pt.y == 6.75)
1705 return 0;
1707 return 1;
1710 LIBTEST_API int STDCALL
1711 mono_test_marshal_mixed_point_2 (mixed_point *pt)
1713 if (pt->x != 5 || pt->y != 6.75)
1714 return 1;
1716 pt->x = 10;
1717 pt->y = 12.35;
1719 return 0;
1722 LIBTEST_API int STDCALL
1723 marshal_test_ref_bool(int i, char *b1, short *b2, int *b3)
1725 int res = 1;
1726 if (*b1 != 0 && *b1 != 1)
1727 return 1;
1728 if (*b2 != 0 && *b2 != -1) /* variant_bool */
1729 return 1;
1730 if (*b3 != 0 && *b3 != 1)
1731 return 1;
1732 if (i == ((*b1 << 2) | (-*b2 << 1) | *b3))
1733 res = 0;
1734 *b1 = !*b1;
1735 *b2 = ~*b2;
1736 *b3 = !*b3;
1737 return res;
1740 struct BoolStruct
1742 int i;
1743 char b1;
1744 short b2; /* variant_bool */
1745 int b3;
1748 LIBTEST_API int STDCALL
1749 marshal_test_bool_struct(struct BoolStruct *s)
1751 int res = 1;
1752 if (s->b1 != 0 && s->b1 != 1)
1753 return 1;
1754 if (s->b2 != 0 && s->b2 != -1)
1755 return 1;
1756 if (s->b3 != 0 && s->b3 != 1)
1757 return 1;
1758 if (s->i == ((s->b1 << 2) | (-s->b2 << 1) | s->b3))
1759 res = 0;
1760 s->b1 = !s->b1;
1761 s->b2 = ~s->b2;
1762 s->b3 = !s->b3;
1763 return res;
1766 typedef struct {
1767 gint64 l;
1768 } LongStruct2;
1770 typedef struct {
1771 int i;
1772 LongStruct2 l;
1773 } LongStruct;
1775 LIBTEST_API int STDCALL
1776 mono_test_marshal_long_struct (LongStruct *s)
1778 return s->i + s->l.l;
1781 LIBTEST_API void STDCALL
1782 mono_test_last_error (int err)
1784 #ifdef WIN32
1785 SetLastError (err);
1788 * Make sure argument register used calling SetLastError
1789 * get's cleaned before returning back to caller. This is done to ensure
1790 * we don't get a undetected failure if error is preserved in register
1791 * on return since we read back value directly when doing p/invoke with SetLastError = true
1792 * into first argument register and then pass it to Mono function setting value in TLS.
1793 * If there is a codegen bug reading last error or the code has been incorrectly eliminated
1794 * this test could still succeed since expected error code could be left in argument register.
1795 * Below code just do something that shouldn't touch last error and won't be optimized away
1796 * but will change the argument registers to something different than err.
1798 char buffer[256] = { 0 };
1799 char value[] = "Dummy";
1800 strncpy (buffer, value, G_N_ELEMENTS (value) - 1);
1801 #else
1802 mono_set_errno (err);
1803 #endif
1806 LIBTEST_API int STDCALL
1807 mono_test_asany (void *ptr, int what)
1809 switch (what) {
1810 case 1:
1811 return (*(int*)ptr == 5) ? 0 : 1;
1812 case 2:
1813 return strcmp ((const char*)ptr, "ABC") == 0 ? 0 : 1;
1814 case 3: {
1815 simplestruct2 ss = *(simplestruct2*)ptr;
1817 if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
1818 !strcmp (ss.d, "TEST") &&
1819 ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
1820 return 0;
1821 else
1822 return 1;
1824 case 4: {
1825 GError *gerror = NULL;
1826 char *s;
1828 s = g_utf16_to_utf8 ((const gunichar2 *)ptr, -1, NULL, NULL, &gerror);
1830 if (!s)
1831 return 1;
1833 if (!strcmp (s, "ABC")) {
1834 g_free (s);
1835 return 0;
1837 else {
1838 g_free (s);
1839 return 1;
1842 case 5: {
1843 return (*(intptr_t*)ptr == 5) ? 0 : 1;
1845 default:
1846 g_assert_not_reached ();
1849 return 1;
1852 typedef struct
1854 int i;
1855 int j;
1856 int k;
1857 char *s;
1858 } AsAnyStruct;
1860 LIBTEST_API int STDCALL
1861 mono_test_marshal_asany_in (void* ptr)
1863 AsAnyStruct *asAny = (AsAnyStruct *)ptr;
1864 int res = asAny->i + asAny->j + asAny->k;
1866 return res;
1869 LIBTEST_API int STDCALL
1870 mono_test_marshal_asany_inout (void* ptr)
1872 AsAnyStruct *asAny = (AsAnyStruct *)ptr;
1873 int res = asAny->i + asAny->j + asAny->k;
1875 marshal_free (asAny->s);
1877 asAny->i = 10;
1878 asAny->j = 20;
1879 asAny->k = 30;
1880 asAny->s = 0;
1882 return res;
1885 LIBTEST_API int STDCALL
1886 mono_test_marshal_asany_out (void* ptr)
1888 AsAnyStruct *asAny = (AsAnyStruct *)ptr;
1889 int res = asAny->i + asAny->j + asAny->k;
1891 asAny->i = 10;
1892 asAny->j = 20;
1893 asAny->k = 30;
1894 asAny->s = 0;
1896 return res;
1900 * AMD64 marshalling tests.
1903 typedef struct amd64_struct1 {
1904 int i;
1905 int j;
1906 int k;
1907 int l;
1908 } amd64_struct1;
1910 LIBTEST_API amd64_struct1 STDCALL
1911 mono_test_marshal_amd64_pass_return_struct1 (amd64_struct1 s)
1913 s.i ++;
1914 s.j ++;
1915 s.k ++;
1916 s.l ++;
1918 return s;
1921 LIBTEST_API amd64_struct1 STDCALL
1922 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)
1924 s.i ++;
1925 s.j ++;
1926 s.k ++;
1927 s.l += 1 + i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8;
1929 return s;
1932 typedef struct amd64_struct2 {
1933 int i;
1934 int j;
1935 } amd64_struct2;
1937 LIBTEST_API amd64_struct2 STDCALL
1938 mono_test_marshal_amd64_pass_return_struct2 (amd64_struct2 s)
1940 s.i ++;
1941 s.j ++;
1943 return s;
1946 typedef struct amd64_struct3 {
1947 int i;
1948 } amd64_struct3;
1950 LIBTEST_API amd64_struct3 STDCALL
1951 mono_test_marshal_amd64_pass_return_struct3 (amd64_struct3 s)
1953 s.i ++;
1955 return s;
1958 typedef struct amd64_struct4 {
1959 double d1, d2;
1960 } amd64_struct4;
1962 LIBTEST_API amd64_struct4 STDCALL
1963 mono_test_marshal_amd64_pass_return_struct4 (amd64_struct4 s)
1965 s.d1 ++;
1966 s.d2 ++;
1968 return s;
1972 * IA64 marshalling tests.
1974 typedef struct test_struct5 {
1975 float d1, d2;
1976 } test_struct5;
1978 LIBTEST_API test_struct5 STDCALL
1979 mono_test_marshal_ia64_pass_return_struct5 (double d1, double d2, test_struct5 s, int i, double d3, double d4)
1981 s.d1 += d1 + d2 + i;
1982 s.d2 += d3 + d4 + i;
1984 return s;
1987 typedef struct test_struct6 {
1988 double d1, d2;
1989 } test_struct6;
1991 LIBTEST_API test_struct6 STDCALL
1992 mono_test_marshal_ia64_pass_return_struct6 (double d1, double d2, test_struct6 s, int i, double d3, double d4)
1994 s.d1 += d1 + d2 + i;
1995 s.d2 += d3 + d4;
1997 return s;
2000 static guint32 custom_res [2];
2002 LIBTEST_API void* STDCALL
2003 mono_test_marshal_pass_return_custom (int i, guint32 *ptr, int j)
2005 /* ptr will be freed by CleanupNative, so make a copy */
2006 custom_res [0] = 0; /* not allocated by AllocHGlobal */
2007 custom_res [1] = ptr [1];
2009 return &custom_res;
2012 LIBTEST_API int STDCALL
2013 mono_test_marshal_pass_out_custom (int i, guint32 **ptr, int j)
2015 custom_res [0] = 0;
2016 custom_res [1] = i + j + 10;
2018 *ptr = custom_res;
2020 return 0;
2023 LIBTEST_API int STDCALL
2024 mono_test_marshal_pass_inout_custom (int i, guint32 *ptr, int j)
2026 ptr [0] = 0;
2027 ptr [1] = i + ptr [1] + j;
2029 return 0;
2032 LIBTEST_API int STDCALL
2033 mono_test_marshal_pass_out_byval_custom (int i, guint32 *ptr, int j)
2035 return ptr == NULL ? 0 : 1;
2038 LIBTEST_API int STDCALL
2039 mono_test_marshal_pass_byref_custom (int i, guint32 **ptr, int j)
2041 (*ptr)[1] += i + j;
2043 return 0;
2046 LIBTEST_API void* STDCALL
2047 mono_test_marshal_pass_return_custom2 (int i, guint32 *ptr, int j)
2049 g_assert_not_reached ();
2051 return NULL;
2054 LIBTEST_API void* STDCALL
2055 mono_test_marshal_pass_return_custom_null (int i, guint32 *ptr, int j)
2057 g_assert (ptr == NULL);
2059 return NULL;
2062 typedef void *(STDCALL *PassReturnPtrDelegate) (void *ptr);
2064 LIBTEST_API int STDCALL
2065 mono_test_marshal_pass_return_custom_in_delegate (PassReturnPtrDelegate del)
2067 guint32 buf [2];
2068 guint32 res;
2069 guint32 *ptr;
2071 buf [0] = 0;
2072 buf [1] = 10;
2074 ptr = (guint32 *)del (&buf);
2076 res = ptr [1];
2078 #ifdef WIN32
2079 /* FIXME: Freed with FreeHGlobal */
2080 #else
2081 g_free (ptr);
2082 #endif
2084 return res;
2087 LIBTEST_API int STDCALL
2088 mono_test_marshal_pass_return_custom_null_in_delegate (PassReturnPtrDelegate del)
2090 void *ptr = del (NULL);
2092 return (ptr == NULL) ? 15 : 0;
2095 typedef void (STDCALL *CustomOutParamDelegate) (void **pptr);
2097 LIBTEST_API int STDCALL
2098 mono_test_marshal_custom_out_param_delegate (CustomOutParamDelegate del)
2100 void* pptr = (void*)del;
2102 del (&pptr);
2104 if(pptr != NULL)
2105 return 1;
2107 return 0;
2110 typedef int (STDCALL *ReturnEnumDelegate) (int e);
2112 LIBTEST_API int STDCALL
2113 mono_test_marshal_return_enum_delegate (ReturnEnumDelegate func)
2115 return func (1);
2118 typedef struct {
2119 int a, b, c;
2120 gint64 d;
2121 } BlittableStruct;
2123 typedef BlittableStruct (STDCALL *SimpleDelegate10) (BlittableStruct ss);
2125 LIBTEST_API int STDCALL
2126 mono_test_marshal_blittable_struct_delegate (SimpleDelegate10 delegate)
2128 BlittableStruct ss, res;
2130 ss.a = 1;
2131 ss.b = 2;
2132 ss.c = 3;
2133 ss.d = 55;
2135 res = delegate (ss);
2136 if (! ((res.a == -1) && (res.b == -2) && (res.c == -3) && (res.d == -55)))
2137 return 1;
2139 return 0;
2142 LIBTEST_API int STDCALL
2143 mono_test_stdcall_name_mangling (int a, int b, int c)
2145 return a + b + c;
2148 LIBTEST_API int
2149 mono_test_stdcall_mismatch_1 (int a, int b, int c)
2151 return a + b + c;
2154 LIBTEST_API int STDCALL
2155 mono_test_stdcall_mismatch_2 (int a, int b, int c)
2157 return a + b + c;
2161 * PASSING AND RETURNING SMALL STRUCTURES FROM DELEGATES TESTS
2164 typedef struct {
2165 int i;
2166 } SmallStruct1;
2168 typedef SmallStruct1 (STDCALL *SmallStructDelegate1) (SmallStruct1 ss);
2170 LIBTEST_API int STDCALL
2171 mono_test_marshal_small_struct_delegate1 (SmallStructDelegate1 delegate)
2173 SmallStruct1 ss, res;
2175 ss.i = 1;
2177 res = delegate (ss);
2178 if (! (res.i == -1))
2179 return 1;
2181 return 0;
2184 typedef struct {
2185 gint16 i, j;
2186 } SmallStruct2;
2188 typedef SmallStruct2 (STDCALL *SmallStructDelegate2) (SmallStruct2 ss);
2190 LIBTEST_API int STDCALL
2191 mono_test_marshal_small_struct_delegate2 (SmallStructDelegate2 delegate)
2193 SmallStruct2 ss, res;
2195 ss.i = 2;
2196 ss.j = 3;
2198 res = delegate (ss);
2199 if (! ((res.i == -2) && (res.j == -3)))
2200 return 1;
2202 return 0;
2205 typedef struct {
2206 gint16 i;
2207 gint8 j;
2208 } SmallStruct3;
2210 typedef SmallStruct3 (STDCALL *SmallStructDelegate3) (SmallStruct3 ss);
2212 LIBTEST_API int STDCALL
2213 mono_test_marshal_small_struct_delegate3 (SmallStructDelegate3 delegate)
2215 SmallStruct3 ss, res;
2217 ss.i = 1;
2218 ss.j = 2;
2220 res = delegate (ss);
2221 if (! ((res.i == -1) && (res.j == -2)))
2222 return 1;
2224 return 0;
2227 typedef struct {
2228 gint16 i;
2229 } SmallStruct4;
2231 typedef SmallStruct4 (STDCALL *SmallStructDelegate4) (SmallStruct4 ss);
2233 LIBTEST_API int STDCALL
2234 mono_test_marshal_small_struct_delegate4 (SmallStructDelegate4 delegate)
2236 SmallStruct4 ss, res;
2238 ss.i = 1;
2240 res = delegate (ss);
2241 if (! (res.i == -1))
2242 return 1;
2244 return 0;
2247 typedef struct {
2248 gint64 i;
2249 } SmallStruct5;
2251 typedef SmallStruct5 (STDCALL *SmallStructDelegate5) (SmallStruct5 ss);
2253 LIBTEST_API int STDCALL
2254 mono_test_marshal_small_struct_delegate5 (SmallStructDelegate5 delegate)
2256 SmallStruct5 ss, res;
2258 ss.i = 5;
2260 res = delegate (ss);
2261 if (! (res.i == -5))
2262 return 1;
2264 return 0;
2267 typedef struct {
2268 int i, j;
2269 } SmallStruct6;
2271 typedef SmallStruct6 (STDCALL *SmallStructDelegate6) (SmallStruct6 ss);
2273 LIBTEST_API int STDCALL
2274 mono_test_marshal_small_struct_delegate6 (SmallStructDelegate6 delegate)
2276 SmallStruct6 ss, res;
2278 ss.i = 1;
2279 ss.j = 2;
2281 res = delegate (ss);
2282 if (! ((res.i == -1) && (res.j == -2)))
2283 return 1;
2285 return 0;
2288 typedef struct {
2289 int i;
2290 gint16 j;
2291 } SmallStruct7;
2293 typedef SmallStruct7 (STDCALL *SmallStructDelegate7) (SmallStruct7 ss);
2295 LIBTEST_API int STDCALL
2296 mono_test_marshal_small_struct_delegate7 (SmallStructDelegate7 delegate)
2298 SmallStruct7 ss, res;
2300 ss.i = 1;
2301 ss.j = 2;
2303 res = delegate (ss);
2304 if (! ((res.i == -1) && (res.j == -2)))
2305 return 1;
2307 return 0;
2310 typedef struct {
2311 float i;
2312 } SmallStruct8;
2314 typedef SmallStruct8 (STDCALL *SmallStructDelegate8) (SmallStruct8 ss);
2316 LIBTEST_API int STDCALL
2317 mono_test_marshal_small_struct_delegate8 (SmallStructDelegate8 delegate)
2319 SmallStruct8 ss, res;
2321 ss.i = 1.0;
2323 res = delegate (ss);
2324 if (! ((res.i == -1.0)))
2325 return 1;
2327 return 0;
2330 typedef struct {
2331 double i;
2332 } SmallStruct9;
2334 typedef SmallStruct9 (STDCALL *SmallStructDelegate9) (SmallStruct9 ss);
2336 LIBTEST_API int STDCALL
2337 mono_test_marshal_small_struct_delegate9 (SmallStructDelegate9 delegate)
2339 SmallStruct9 ss, res;
2341 ss.i = 1.0;
2343 res = delegate (ss);
2344 if (! ((res.i == -1.0)))
2345 return 1;
2347 return 0;
2350 typedef struct {
2351 float i, j;
2352 } SmallStruct10;
2354 typedef SmallStruct10 (STDCALL *SmallStructDelegate10) (SmallStruct10 ss);
2356 LIBTEST_API int STDCALL
2357 mono_test_marshal_small_struct_delegate10 (SmallStructDelegate10 delegate)
2359 SmallStruct10 ss, res;
2361 ss.i = 1.0;
2362 ss.j = 2.0;
2364 res = delegate (ss);
2365 if (! ((res.i == -1.0) && (res.j == -2.0)))
2366 return 1;
2368 return 0;
2371 typedef struct {
2372 float i;
2373 int j;
2374 } SmallStruct11;
2376 typedef SmallStruct11 (STDCALL *SmallStructDelegate11) (SmallStruct11 ss);
2378 LIBTEST_API int STDCALL
2379 mono_test_marshal_small_struct_delegate11 (SmallStructDelegate11 delegate)
2381 SmallStruct11 ss, res;
2383 ss.i = 1.0;
2384 ss.j = 2;
2386 res = delegate (ss);
2387 if (! ((res.i == -1.0) && (res.j == -2)))
2388 return 1;
2390 return 0;
2393 typedef int (STDCALL *ArrayDelegate) (int i, char *j, void *arr);
2395 LIBTEST_API int STDCALL
2396 mono_test_marshal_array_delegate (void *arr, int len, ArrayDelegate del)
2398 return del (len, NULL, arr);
2401 typedef int (STDCALL *ArrayDelegateLong) (gint64 i, char *j, void *arr);
2403 LIBTEST_API int STDCALL
2404 mono_test_marshal_array_delegate_long (void *arr, gint64 len, ArrayDelegateLong del)
2406 return del (len, NULL, arr);
2409 LIBTEST_API int STDCALL
2410 mono_test_marshal_out_array_delegate (int *arr, int len, ArrayDelegate del)
2412 del (len, NULL, arr);
2414 if ((arr [0] != 1) || (arr [1] != 2))
2415 return 1;
2416 else
2417 return 0;
2420 typedef gunichar2* (STDCALL *UnicodeStringDelegate) (gunichar2 *message);
2422 LIBTEST_API int STDCALL
2423 mono_test_marshal_return_unicode_string_delegate (UnicodeStringDelegate del)
2425 const char m[] = "abcdef";
2426 gunichar2 *s2, *res;
2427 glong len;
2429 s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
2431 res = del (s2);
2433 marshal_free (res);
2435 return 0;
2438 LIBTEST_API int STDCALL
2439 mono_test_marshal_out_string_array_delegate (char **arr, int len, ArrayDelegate del)
2441 del (len, NULL, arr);
2443 if (!strcmp (arr [0], "ABC") && !strcmp (arr [1], "DEF"))
2444 return 0;
2445 else
2446 return 1;
2449 typedef int (*CdeclDelegate) (int i, int j);
2451 LIBTEST_API int STDCALL
2452 mono_test_marshal_cdecl_delegate (CdeclDelegate del)
2454 int i;
2456 for (i = 0; i < 1000; ++i)
2457 del (1, 2);
2459 return 0;
2462 typedef char** (STDCALL *ReturnStringArrayDelegate) (int i);
2464 LIBTEST_API int STDCALL
2465 mono_test_marshal_return_string_array_delegate (ReturnStringArrayDelegate d)
2467 char **arr = d (2);
2468 int res;
2470 if (arr == NULL)
2471 return 3;
2473 if (strcmp (arr [0], "ABC") || strcmp (arr [1], "DEF"))
2474 res = 1;
2475 else
2476 res = 0;
2478 marshal_free (arr);
2480 return res;
2483 typedef int (STDCALL *ByrefStringDelegate) (char **s);
2485 LIBTEST_API int STDCALL
2486 mono_test_marshal_byref_string_delegate (ByrefStringDelegate d)
2488 char *s = (char*)"ABC";
2489 int res;
2491 res = d (&s);
2492 if (res != 0)
2493 return res;
2495 if (!strcmp (s, "DEF"))
2496 res = 0;
2497 else
2498 res = 2;
2500 marshal_free (s);
2502 return res;
2505 LIBTEST_API int STDCALL
2506 add_delegate (int i, int j)
2508 return i + j;
2511 LIBTEST_API gpointer STDCALL
2512 mono_test_marshal_return_fnptr (void)
2514 return (gpointer)&add_delegate;
2517 LIBTEST_API int STDCALL
2518 mono_xr (int code)
2520 printf ("codigo %x\n", code);
2521 return code + 1234;
2524 typedef struct {
2525 int handle;
2526 } HandleRef;
2528 LIBTEST_API HandleRef STDCALL
2529 mono_xr_as_handle (int code)
2531 HandleRef ref;
2533 memset (&ref, 0, sizeof (ref));
2535 return ref;
2538 typedef struct {
2539 int a;
2540 void *handle1;
2541 void *handle2;
2542 int b;
2543 } HandleStructs;
2545 LIBTEST_API int STDCALL
2546 mono_safe_handle_struct_ref (HandleStructs *x)
2548 printf ("Dingus Ref! \n");
2549 printf ("Values: %d %d %p %p\n", x->a, x->b, x->handle1, x->handle2);
2550 if (x->a != 1234)
2551 return 1;
2552 if (x->b != 8743)
2553 return 2;
2555 if (x->handle1 != (void*) 0x7080feed)
2556 return 3;
2558 if (x->handle2 != (void*) 0x1234abcd)
2559 return 4;
2561 return 0xf00d;
2564 LIBTEST_API int STDCALL
2565 mono_safe_handle_struct (HandleStructs x)
2567 printf ("Dingus Standard! \n");
2568 printf ("Values: %d %d %p %p\n", x.a, x.b, x.handle1, x.handle2);
2569 if (x.a != 1234)
2570 return 1;
2571 if (x.b != 8743)
2572 return 2;
2574 if (x.handle1 != (void*) 0x7080feed)
2575 return 3;
2577 if (x.handle2 != (void*) 0x1234abcd)
2578 return 4;
2580 return 0xf00f;
2583 typedef struct {
2584 void *a;
2585 } TrivialHandle;
2587 LIBTEST_API int STDCALL
2588 mono_safe_handle_struct_simple (TrivialHandle x)
2590 printf ("The value is %p\n", x.a);
2591 return ((int)(gsize)x.a) * 2;
2594 LIBTEST_API int STDCALL
2595 mono_safe_handle_return (void)
2597 return 0x1000f00d;
2600 LIBTEST_API void STDCALL
2601 mono_safe_handle_ref (void **handle)
2603 if (*handle != 0){
2604 *handle = (void *) 0x800d;
2605 return;
2608 *handle = (void *) 0xbad;
2611 LIBTEST_API void* STDCALL
2612 mono_safe_handle_ref_nomod (void **handle)
2614 return *handle;
2617 LIBTEST_API double STDCALL
2618 mono_test_marshal_date_time (double d, double *d2)
2620 *d2 = d;
2621 return d;
2625 * COM INTEROP TESTS
2628 #ifndef WIN32
2630 typedef struct
2632 guint32 a;
2633 guint16 b;
2634 guint16 c;
2635 guint8 d[8];
2636 } GUID;
2638 typedef const GUID *REFIID;
2640 typedef struct IDispatch IDispatch;
2642 typedef struct
2644 int (STDCALL *QueryInterface)(IDispatch *iface, REFIID iid, gpointer *out);
2645 int (STDCALL *AddRef)(IDispatch *iface);
2646 int (STDCALL *Release)(IDispatch *iface);
2647 int (STDCALL *GetTypeInfoCount)(IDispatch *iface, unsigned int *count);
2648 int (STDCALL *GetTypeInfo)(IDispatch *iface, unsigned int index, unsigned int lcid, gpointer *out);
2649 int (STDCALL *GetIDsOfNames)(IDispatch *iface, REFIID iid, gpointer names, unsigned int count, unsigned int lcid, gpointer ids);
2650 int (STDCALL *Invoke)(IDispatch *iface, unsigned int dispid, REFIID iid, unsigned int lcid, unsigned short flags, gpointer params, gpointer result, gpointer excepinfo, gpointer err_arg);
2651 } IDispatchVtbl;
2653 struct IDispatch
2655 const IDispatchVtbl *lpVtbl;
2658 typedef struct {
2659 guint16 vt;
2660 guint16 wReserved1;
2661 guint16 wReserved2;
2662 guint16 wReserved3;
2663 union {
2664 gint64 llVal;
2665 gint32 lVal;
2666 guint8 bVal;
2667 gint16 iVal;
2668 float fltVal;
2669 double dblVal;
2670 gint16 boolVal;
2671 gunichar2* bstrVal;
2672 gint8 cVal;
2673 guint16 uiVal;
2674 guint32 ulVal;
2675 guint64 ullVal;
2676 gpointer byref;
2677 struct {
2678 gpointer pvRecord;
2679 gpointer pRecInfo;
2682 } VARIANT;
2684 typedef enum {
2685 VARIANT_TRUE = -1,
2686 VARIANT_FALSE = 0
2687 } VariantBool;
2689 typedef enum {
2690 VT_EMPTY = 0,
2691 VT_NULL = 1,
2692 VT_I2 = 2,
2693 VT_I4 = 3,
2694 VT_R4 = 4,
2695 VT_R8 = 5,
2696 VT_CY = 6,
2697 VT_DATE = 7,
2698 VT_BSTR = 8,
2699 VT_DISPATCH = 9,
2700 VT_ERROR = 10,
2701 VT_BOOL = 11,
2702 VT_VARIANT = 12,
2703 VT_UNKNOWN = 13,
2704 VT_DECIMAL = 14,
2705 VT_I1 = 16,
2706 VT_UI1 = 17,
2707 VT_UI2 = 18,
2708 VT_UI4 = 19,
2709 VT_I8 = 20,
2710 VT_UI8 = 21,
2711 VT_INT = 22,
2712 VT_UINT = 23,
2713 VT_VOID = 24,
2714 VT_HRESULT = 25,
2715 VT_PTR = 26,
2716 VT_SAFEARRAY = 27,
2717 VT_CARRAY = 28,
2718 VT_USERDEFINED = 29,
2719 VT_LPSTR = 30,
2720 VT_LPWSTR = 31,
2721 VT_RECORD = 36,
2722 VT_FILETIME = 64,
2723 VT_BLOB = 65,
2724 VT_STREAM = 66,
2725 VT_STORAGE = 67,
2726 VT_STREAMED_OBJECT = 68,
2727 VT_STORED_OBJECT = 69,
2728 VT_BLOB_OBJECT = 70,
2729 VT_CF = 71,
2730 VT_CLSID = 72,
2731 VT_VECTOR = 4096,
2732 VT_ARRAY = 8192,
2733 VT_BYREF = 16384
2734 } VarEnum;
2736 void VariantInit(VARIANT* vt)
2738 vt->vt = VT_EMPTY;
2741 #define S_OK 0
2743 #endif
2745 LIBTEST_API int STDCALL
2746 mono_test_marshal_bstr_in(gunichar2* bstr)
2748 gint32 result = 0;
2749 gchar* bstr_utf8 = g_utf16_to_utf8 (bstr, -1, NULL, NULL, NULL);
2750 result = strcmp("mono_test_marshal_bstr_in", bstr_utf8);
2751 g_free(bstr_utf8);
2752 if (result == 0)
2753 return 0;
2754 return 1;
2757 LIBTEST_API int STDCALL
2758 mono_test_marshal_bstr_out(gunichar2** bstr)
2760 *bstr = marshal_bstr_alloc ("mono_test_marshal_bstr_out");
2761 return 0;
2764 LIBTEST_API int STDCALL
2765 mono_test_marshal_bstr_in_null(gunichar2* bstr)
2767 if (!bstr)
2768 return 0;
2769 return 1;
2772 LIBTEST_API int STDCALL
2773 mono_test_marshal_bstr_out_null(gunichar2** bstr)
2775 *bstr = NULL;
2776 return 0;
2779 LIBTEST_API int STDCALL
2780 mono_test_marshal_variant_in_sbyte(VARIANT variant)
2782 if (variant.vt == VT_I1 && variant.cVal == 100)
2783 return 0;
2784 return 1;
2787 LIBTEST_API int STDCALL
2788 mono_test_marshal_variant_in_byte(VARIANT variant)
2790 if (variant.vt == VT_UI1 && variant.bVal == 100)
2791 return 0;
2792 return 1;
2795 LIBTEST_API int STDCALL
2796 mono_test_marshal_variant_in_short(VARIANT variant)
2798 if (variant.vt == VT_I2 && variant.iVal == 314)
2799 return 0;
2800 return 1;
2803 LIBTEST_API int STDCALL
2804 mono_test_marshal_variant_in_ushort(VARIANT variant)
2806 if (variant.vt == VT_UI2 && variant.uiVal == 314)
2807 return 0;
2808 return 1;
2811 LIBTEST_API int STDCALL
2812 mono_test_marshal_variant_in_int(VARIANT variant)
2814 if (variant.vt == VT_I4 && variant.lVal == 314)
2815 return 0;
2816 return 1;
2819 LIBTEST_API int STDCALL
2820 mono_test_marshal_variant_in_uint(VARIANT variant)
2822 if (variant.vt == VT_UI4 && variant.ulVal == 314)
2823 return 0;
2824 return 1;
2827 LIBTEST_API int STDCALL
2828 mono_test_marshal_variant_in_long(VARIANT variant)
2830 if (variant.vt == VT_I8 && variant.llVal == 314)
2831 return 0;
2832 return 1;
2835 LIBTEST_API int STDCALL
2836 mono_test_marshal_variant_in_ulong(VARIANT variant)
2838 if (variant.vt == VT_UI8 && variant.ullVal == 314)
2839 return 0;
2840 return 1;
2843 LIBTEST_API int STDCALL
2844 mono_test_marshal_variant_in_float(VARIANT variant)
2846 if (variant.vt == VT_R4 && (variant.fltVal - 3.14)/3.14 < .001)
2847 return 0;
2848 return 1;
2851 LIBTEST_API int STDCALL
2852 mono_test_marshal_variant_in_double(VARIANT variant)
2854 if (variant.vt == VT_R8 && (variant.dblVal - 3.14)/3.14 < .001)
2855 return 0;
2856 return 1;
2859 LIBTEST_API int STDCALL
2860 mono_test_marshal_variant_in_bstr(VARIANT variant)
2862 gint32 result = 0;
2863 gchar* bstr_utf8 = g_utf16_to_utf8 (variant.bstrVal, -1, NULL, NULL, NULL);
2864 result = strcmp("PI", bstr_utf8);
2865 g_free(bstr_utf8);
2867 if (variant.vt == VT_BSTR && !result)
2868 return 0;
2869 return 1;
2872 LIBTEST_API int STDCALL
2873 mono_test_marshal_variant_in_bool_true (VARIANT variant)
2875 if (variant.vt == VT_BOOL && variant.boolVal == VARIANT_TRUE)
2876 return 0;
2877 return 1;
2880 LIBTEST_API int STDCALL
2881 mono_test_marshal_variant_in_bool_false (VARIANT variant)
2883 if (variant.vt == VT_BOOL && variant.boolVal == VARIANT_FALSE)
2884 return 0;
2885 return 1;
2888 LIBTEST_API int STDCALL
2889 mono_test_marshal_variant_out_sbyte(VARIANT* variant)
2891 variant->vt = VT_I1;
2892 variant->cVal = 100;
2894 return 0;
2897 LIBTEST_API int STDCALL
2898 mono_test_marshal_variant_out_sbyte_byref(VARIANT* variant)
2900 variant->vt = VT_I1|VT_BYREF;
2901 variant->byref = marshal_alloc(1);
2902 *((gint8*)variant->byref) = 100;
2904 return 0;
2907 LIBTEST_API int STDCALL
2908 mono_test_marshal_variant_out_byte(VARIANT* variant)
2910 variant->vt = VT_UI1;
2911 variant->bVal = 100;
2913 return 0;
2916 LIBTEST_API int STDCALL
2917 mono_test_marshal_variant_out_byte_byref(VARIANT* variant)
2919 variant->vt = VT_UI1|VT_BYREF;
2920 variant->byref = marshal_alloc(1);
2921 *((gint8*)variant->byref) = 100;
2923 return 0;
2926 LIBTEST_API int STDCALL
2927 mono_test_marshal_variant_out_short(VARIANT* variant)
2929 variant->vt = VT_I2;
2930 variant->iVal = 314;
2932 return 0;
2935 LIBTEST_API int STDCALL
2936 mono_test_marshal_variant_out_short_byref(VARIANT* variant)
2938 variant->vt = VT_I2|VT_BYREF;
2939 variant->byref = marshal_alloc(2);
2940 *((gint16*)variant->byref) = 314;
2942 return 0;
2945 LIBTEST_API int STDCALL
2946 mono_test_marshal_variant_out_ushort(VARIANT* variant)
2948 variant->vt = VT_UI2;
2949 variant->uiVal = 314;
2951 return 0;
2954 LIBTEST_API int STDCALL
2955 mono_test_marshal_variant_out_ushort_byref(VARIANT* variant)
2957 variant->vt = VT_UI2|VT_BYREF;
2958 variant->byref = marshal_alloc(2);
2959 *((guint16*)variant->byref) = 314;
2961 return 0;
2964 LIBTEST_API int STDCALL
2965 mono_test_marshal_variant_out_int(VARIANT* variant)
2967 variant->vt = VT_I4;
2968 variant->lVal = 314;
2970 return 0;
2973 LIBTEST_API int STDCALL
2974 mono_test_marshal_variant_out_int_byref(VARIANT* variant)
2976 variant->vt = VT_I4|VT_BYREF;
2977 variant->byref = marshal_alloc(4);
2978 *((gint32*)variant->byref) = 314;
2980 return 0;
2983 LIBTEST_API int STDCALL
2984 mono_test_marshal_variant_out_uint(VARIANT* variant)
2986 variant->vt = VT_UI4;
2987 variant->ulVal = 314;
2989 return 0;
2992 LIBTEST_API int STDCALL
2993 mono_test_marshal_variant_out_uint_byref(VARIANT* variant)
2995 variant->vt = VT_UI4|VT_BYREF;
2996 variant->byref = marshal_alloc(4);
2997 *((guint32*)variant->byref) = 314;
2999 return 0;
3002 LIBTEST_API int STDCALL
3003 mono_test_marshal_variant_out_long(VARIANT* variant)
3005 variant->vt = VT_I8;
3006 variant->llVal = 314;
3008 return 0;
3011 LIBTEST_API int STDCALL
3012 mono_test_marshal_variant_out_long_byref(VARIANT* variant)
3014 variant->vt = VT_I8|VT_BYREF;
3015 variant->byref = marshal_alloc(8);
3016 *((gint64*)variant->byref) = 314;
3018 return 0;
3021 LIBTEST_API int STDCALL
3022 mono_test_marshal_variant_out_ulong(VARIANT* variant)
3024 variant->vt = VT_UI8;
3025 variant->ullVal = 314;
3027 return 0;
3030 LIBTEST_API int STDCALL
3031 mono_test_marshal_variant_out_ulong_byref(VARIANT* variant)
3033 variant->vt = VT_UI8|VT_BYREF;
3034 variant->byref = marshal_alloc(8);
3035 *((guint64*)variant->byref) = 314;
3037 return 0;
3040 LIBTEST_API int STDCALL
3041 mono_test_marshal_variant_out_float(VARIANT* variant)
3043 variant->vt = VT_R4;
3044 variant->fltVal = 3.14;
3046 return 0;
3049 LIBTEST_API int STDCALL
3050 mono_test_marshal_variant_out_float_byref(VARIANT* variant)
3052 variant->vt = VT_R4|VT_BYREF;
3053 variant->byref = marshal_alloc(4);
3054 *((float*)variant->byref) = 3.14;
3056 return 0;
3059 LIBTEST_API int STDCALL
3060 mono_test_marshal_variant_out_double(VARIANT* variant)
3062 variant->vt = VT_R8;
3063 variant->dblVal = 3.14;
3065 return 0;
3068 LIBTEST_API int STDCALL
3069 mono_test_marshal_variant_out_double_byref(VARIANT* variant)
3071 variant->vt = VT_R8|VT_BYREF;
3072 variant->byref = marshal_alloc(8);
3073 *((double*)variant->byref) = 3.14;
3075 return 0;
3078 LIBTEST_API int STDCALL
3079 mono_test_marshal_variant_out_bstr(VARIANT* variant)
3081 variant->vt = VT_BSTR;
3082 variant->bstrVal = marshal_bstr_alloc("PI");
3084 return 0;
3087 LIBTEST_API int STDCALL
3088 mono_test_marshal_variant_out_bstr_byref(VARIANT* variant)
3090 variant->vt = VT_BSTR|VT_BYREF;
3091 variant->byref = marshal_alloc(sizeof(gpointer));
3092 *((gunichar**)variant->byref) = (gunichar*)marshal_bstr_alloc("PI");
3094 return 0;
3097 LIBTEST_API int STDCALL
3098 mono_test_marshal_variant_out_bool_true (VARIANT* variant)
3100 variant->vt = VT_BOOL;
3101 variant->boolVal = VARIANT_TRUE;
3103 return 0;
3106 LIBTEST_API int STDCALL
3107 mono_test_marshal_variant_out_bool_true_byref (VARIANT* variant)
3109 variant->vt = VT_BOOL|VT_BYREF;
3110 variant->byref = marshal_alloc(2);
3111 *((gint16*)variant->byref) = VARIANT_TRUE;
3113 return 0;
3116 LIBTEST_API int STDCALL
3117 mono_test_marshal_variant_out_bool_false (VARIANT* variant)
3119 variant->vt = VT_BOOL;
3120 variant->boolVal = VARIANT_FALSE;
3122 return 0;
3125 LIBTEST_API int STDCALL
3126 mono_test_marshal_variant_out_bool_false_byref (VARIANT* variant)
3128 variant->vt = VT_BOOL|VT_BYREF;
3129 variant->byref = marshal_alloc(2);
3130 *((gint16*)variant->byref) = VARIANT_FALSE;
3132 return 0;
3135 typedef int (STDCALL *VarFunc) (int vt, VARIANT variant);
3136 typedef int (STDCALL *VarRefFunc) (int vt, VARIANT* variant);
3138 LIBTEST_API int STDCALL
3139 mono_test_marshal_variant_in_sbyte_unmanaged(VarFunc func)
3141 VARIANT vt;
3142 vt.vt = VT_I1;
3143 vt.cVal = -100;
3144 return func (VT_I1, vt);
3147 LIBTEST_API int STDCALL
3148 mono_test_marshal_variant_in_byte_unmanaged(VarFunc func)
3150 VARIANT vt;
3151 vt.vt = VT_UI1;
3152 vt.bVal = 100;
3153 return func (VT_UI1, vt);
3156 LIBTEST_API int STDCALL
3157 mono_test_marshal_variant_in_short_unmanaged(VarFunc func)
3159 VARIANT vt;
3160 vt.vt = VT_I2;
3161 vt.iVal = -100;
3162 return func (VT_I2, vt);
3165 LIBTEST_API int STDCALL
3166 mono_test_marshal_variant_in_ushort_unmanaged(VarFunc func)
3168 VARIANT vt;
3169 vt.vt = VT_UI2;
3170 vt.uiVal = 100;
3171 return func (VT_UI2, vt);
3174 LIBTEST_API int STDCALL
3175 mono_test_marshal_variant_in_int_unmanaged(VarFunc func)
3177 VARIANT vt;
3178 vt.vt = VT_I4;
3179 vt.lVal = -100;
3180 return func (VT_I4, vt);
3183 LIBTEST_API int STDCALL
3184 mono_test_marshal_variant_in_uint_unmanaged(VarFunc func)
3186 VARIANT vt;
3187 vt.vt = VT_UI4;
3188 vt.ulVal = 100;
3189 return func (VT_UI4, vt);
3192 LIBTEST_API int STDCALL
3193 mono_test_marshal_variant_in_long_unmanaged(VarFunc func)
3195 VARIANT vt;
3196 vt.vt = VT_I8;
3197 vt.llVal = -100;
3198 return func (VT_I8, vt);
3201 LIBTEST_API int STDCALL
3202 mono_test_marshal_variant_in_ulong_unmanaged(VarFunc func)
3204 VARIANT vt;
3205 vt.vt = VT_UI8;
3206 vt.ullVal = 100;
3207 return func (VT_UI8, vt);
3210 LIBTEST_API int STDCALL
3211 mono_test_marshal_variant_in_float_unmanaged(VarFunc func)
3213 VARIANT vt;
3214 vt.vt = VT_R4;
3215 vt.fltVal = 3.14;
3216 return func (VT_R4, vt);
3219 LIBTEST_API int STDCALL
3220 mono_test_marshal_variant_in_double_unmanaged(VarFunc func)
3222 VARIANT vt;
3223 vt.vt = VT_R8;
3224 vt.dblVal = 3.14;
3225 return func (VT_R8, vt);
3228 LIBTEST_API int STDCALL
3229 mono_test_marshal_variant_in_bstr_unmanaged(VarFunc func)
3231 VARIANT vt;
3232 vt.vt = VT_BSTR;
3233 vt.bstrVal = marshal_bstr_alloc("PI");
3234 return func (VT_BSTR, vt);
3237 LIBTEST_API int STDCALL
3238 mono_test_marshal_variant_in_bool_true_unmanaged(VarFunc func)
3240 VARIANT vt;
3241 vt.vt = VT_BOOL;
3242 vt.boolVal = VARIANT_TRUE;
3243 return func (VT_BOOL, vt);
3246 LIBTEST_API int STDCALL
3247 mono_test_marshal_variant_in_bool_false_unmanaged(VarFunc func)
3249 VARIANT vt;
3250 vt.vt = VT_BOOL;
3251 vt.boolVal = VARIANT_FALSE;
3252 return func (VT_BOOL, vt);
3255 LIBTEST_API int STDCALL
3256 mono_test_marshal_variant_out_sbyte_unmanaged(VarRefFunc func)
3258 VARIANT vt;
3259 VariantInit (&vt);
3260 func (VT_I1, &vt);
3261 if (vt.vt == VT_I1 && vt.cVal == -100)
3262 return 0;
3263 return 1;
3266 LIBTEST_API int STDCALL
3267 mono_test_marshal_variant_out_byte_unmanaged(VarRefFunc func)
3269 VARIANT vt;
3270 VariantInit (&vt);
3271 func (VT_UI1, &vt);
3272 if (vt.vt == VT_UI1 && vt.bVal == 100)
3273 return 0;
3274 return 1;
3277 LIBTEST_API int STDCALL
3278 mono_test_marshal_variant_out_short_unmanaged(VarRefFunc func)
3280 VARIANT vt;
3281 VariantInit (&vt);
3282 func (VT_I2, &vt);
3283 if (vt.vt == VT_I2 && vt.iVal == -100)
3284 return 0;
3285 return 1;
3288 LIBTEST_API int STDCALL
3289 mono_test_marshal_variant_out_ushort_unmanaged(VarRefFunc func)
3291 VARIANT vt;
3292 VariantInit (&vt);
3293 func (VT_UI2, &vt);
3294 if (vt.vt == VT_UI2 && vt.uiVal == 100)
3295 return 0;
3296 return 1;
3299 LIBTEST_API int STDCALL
3300 mono_test_marshal_variant_out_int_unmanaged(VarRefFunc func)
3302 VARIANT vt;
3303 VariantInit (&vt);
3304 func (VT_I4, &vt);
3305 if (vt.vt == VT_I4 && vt.lVal == -100)
3306 return 0;
3307 return 1;
3310 LIBTEST_API int STDCALL
3311 mono_test_marshal_variant_out_uint_unmanaged(VarRefFunc func)
3313 VARIANT vt;
3314 VariantInit (&vt);
3315 func (VT_UI4, &vt);
3316 if (vt.vt == VT_UI4 && vt.ulVal == 100)
3317 return 0;
3318 return 1;
3321 LIBTEST_API int STDCALL
3322 mono_test_marshal_variant_out_long_unmanaged(VarRefFunc func)
3324 VARIANT vt;
3325 VariantInit (&vt);
3326 func (VT_I8, &vt);
3327 if (vt.vt == VT_I8 && vt.llVal == -100)
3328 return 0;
3329 return 1;
3332 LIBTEST_API int STDCALL
3333 mono_test_marshal_variant_out_ulong_unmanaged(VarRefFunc func)
3335 VARIANT vt;
3336 VariantInit (&vt);
3337 func (VT_UI8, &vt);
3338 if (vt.vt == VT_UI8 && vt.ullVal == 100)
3339 return 0;
3340 return 1;
3343 LIBTEST_API int STDCALL
3344 mono_test_marshal_variant_out_float_unmanaged(VarRefFunc func)
3346 VARIANT vt;
3347 VariantInit (&vt);
3348 func (VT_R4, &vt);
3349 if (vt.vt == VT_R4 && fabs (vt.fltVal - 3.14f) < 1e-10)
3350 return 0;
3351 return 1;
3354 LIBTEST_API int STDCALL
3355 mono_test_marshal_variant_out_double_unmanaged(VarRefFunc func)
3357 VARIANT vt;
3358 VariantInit (&vt);
3359 func (VT_R8, &vt);
3360 if (vt.vt == VT_R8 && fabs (vt.dblVal - 3.14) < 1e-10)
3361 return 0;
3362 return 1;
3365 LIBTEST_API int STDCALL
3366 mono_test_marshal_variant_out_bstr_unmanaged(VarRefFunc func)
3368 VARIANT vt;
3369 gchar* bstr_utf8;
3370 gint32 result = 0;
3373 VariantInit (&vt);
3374 func (VT_BSTR, &vt);
3375 bstr_utf8 = g_utf16_to_utf8 (vt.bstrVal, -1, NULL, NULL, NULL);
3376 result = strcmp("PI", bstr_utf8);
3377 g_free(bstr_utf8);
3378 if (vt.vt == VT_BSTR && !result)
3379 return 0;
3380 return 1;
3383 LIBTEST_API int STDCALL
3384 mono_test_marshal_variant_out_bool_true_unmanaged(VarRefFunc func)
3386 VARIANT vt;
3387 VariantInit (&vt);
3388 func (VT_BOOL, &vt);
3389 if (vt.vt == VT_BOOL && vt.boolVal == VARIANT_TRUE)
3390 return 0;
3391 return 1;
3394 LIBTEST_API int STDCALL
3395 mono_test_marshal_variant_out_bool_false_unmanaged(VarRefFunc func)
3397 VARIANT vt;
3398 VariantInit (&vt);
3399 func (VT_BOOL, &vt);
3400 if (vt.vt == VT_BOOL && vt.boolVal == VARIANT_TRUE)
3401 return 0;
3402 return 1;
3405 typedef struct MonoComObject MonoComObject;
3406 typedef struct MonoDefItfObject MonoDefItfObject;
3408 typedef struct
3410 int (STDCALL *QueryInterface)(MonoDefItfObject* pUnk, gpointer riid, gpointer* ppv);
3411 int (STDCALL *AddRef)(MonoDefItfObject* pUnk);
3412 int (STDCALL *Release)(MonoDefItfObject* pUnk);
3413 int (STDCALL *Method)(MonoDefItfObject* pUnk, int *value);
3414 } MonoDefItf;
3416 typedef struct
3418 int (STDCALL *QueryInterface)(MonoComObject* pUnk, gpointer riid, gpointer* ppv);
3419 int (STDCALL *AddRef)(MonoComObject* pUnk);
3420 int (STDCALL *Release)(MonoComObject* pUnk);
3421 int (STDCALL *get_ITest)(MonoComObject* pUnk, MonoComObject* *ppUnk);
3422 int (STDCALL *SByteIn)(MonoComObject* pUnk, char a);
3423 int (STDCALL *ByteIn)(MonoComObject* pUnk, unsigned char a);
3424 int (STDCALL *ShortIn)(MonoComObject* pUnk, short a);
3425 int (STDCALL *UShortIn)(MonoComObject* pUnk, unsigned short a);
3426 int (STDCALL *IntIn)(MonoComObject* pUnk, int a);
3427 int (STDCALL *UIntIn)(MonoComObject* pUnk, unsigned int a);
3428 int (STDCALL *LongIn)(MonoComObject* pUnk, gint64 a);
3429 int (STDCALL *ULongIn)(MonoComObject* pUnk, guint64 a);
3430 int (STDCALL *FloatIn)(MonoComObject* pUnk, float a);
3431 int (STDCALL *DoubleIn)(MonoComObject* pUnk, double a);
3432 int (STDCALL *ITestIn)(MonoComObject* pUnk, MonoComObject* pUnk2);
3433 int (STDCALL *ITestOut)(MonoComObject* pUnk, MonoComObject* *ppUnk);
3434 int (STDCALL *Return22NoICall)(MonoComObject* pUnk);
3435 int (STDCALL *IntOut)(MonoComObject* pUnk, int *a);
3436 int (STDCALL *ArrayIn)(MonoComObject* pUnk, void *array);
3437 int (STDCALL *ArrayIn2)(MonoComObject* pUnk, void *array);
3438 int (STDCALL *ArrayIn3)(MonoComObject* pUnk, void *array);
3439 int (STDCALL *GetDefInterface1)(MonoComObject* pUnk, MonoDefItfObject **iface);
3440 int (STDCALL *GetDefInterface2)(MonoComObject* pUnk, MonoDefItfObject **iface);
3441 } MonoIUnknown;
3443 struct MonoComObject
3445 MonoIUnknown* vtbl;
3446 int m_ref;
3449 struct MonoDefItfObject
3451 MonoDefItf* vtbl;
3454 static GUID IID_ITest = {0, 0, 0, {0,0,0,0,0,0,0,1}};
3455 static GUID IID_IMonoUnknown = {0, 0, 0, {0xc0,0,0,0,0,0,0,0x46}};
3456 static GUID IID_IMonoDispatch = {0x00020400, 0, 0, {0xc0,0,0,0,0,0,0,0x46}};
3457 static GUID IID_INotImplemented = {0x12345678, 0, 0, {0x9a, 0xbc, 0xde, 0xf0, 0, 0, 0, 0}};
3459 LIBTEST_API int STDCALL
3460 MonoQueryInterface(MonoComObject* pUnk, gpointer riid, gpointer* ppv)
3463 *ppv = NULL;
3464 if (!memcmp(riid, &IID_IMonoUnknown, sizeof(GUID))) {
3465 *ppv = pUnk;
3466 return S_OK;
3468 else if (!memcmp(riid, &IID_ITest, sizeof(GUID))) {
3469 *ppv = pUnk;
3470 return S_OK;
3472 else if (!memcmp(riid, &IID_IMonoDispatch, sizeof(GUID))) {
3473 *ppv = pUnk;
3474 return S_OK;
3476 return 0x80004002; //E_NOINTERFACE;
3479 LIBTEST_API int STDCALL
3480 MonoAddRef(MonoComObject* pUnk)
3482 return ++(pUnk->m_ref);
3485 LIBTEST_API int STDCALL
3486 MonoRelease(MonoComObject* pUnk)
3488 return --(pUnk->m_ref);
3491 LIBTEST_API int STDCALL
3492 SByteIn(MonoComObject* pUnk, char a)
3494 return S_OK;
3497 LIBTEST_API int STDCALL
3498 ByteIn(MonoComObject* pUnk, unsigned char a)
3500 return S_OK;
3503 LIBTEST_API int STDCALL
3504 ShortIn(MonoComObject* pUnk, short a)
3506 return S_OK;
3509 LIBTEST_API int STDCALL
3510 UShortIn(MonoComObject* pUnk, unsigned short a)
3512 return S_OK;
3515 LIBTEST_API int STDCALL
3516 IntIn(MonoComObject* pUnk, int a)
3518 return S_OK;
3521 LIBTEST_API int STDCALL
3522 UIntIn(MonoComObject* pUnk, unsigned int a)
3524 return S_OK;
3527 LIBTEST_API int STDCALL
3528 LongIn(MonoComObject* pUnk, gint64 a)
3530 return S_OK;
3533 LIBTEST_API int STDCALL
3534 ULongIn(MonoComObject* pUnk, guint64 a)
3536 return S_OK;
3539 LIBTEST_API int STDCALL
3540 FloatIn(MonoComObject* pUnk, float a)
3542 return S_OK;
3545 LIBTEST_API int STDCALL
3546 DoubleIn(MonoComObject* pUnk, double a)
3548 return S_OK;
3551 LIBTEST_API int STDCALL
3552 ITestIn(MonoComObject* pUnk, MonoComObject *pUnk2)
3554 return S_OK;
3557 LIBTEST_API int STDCALL
3558 ITestOut(MonoComObject* pUnk, MonoComObject* *ppUnk)
3560 return S_OK;
3563 LIBTEST_API int STDCALL
3564 Return22NoICall(MonoComObject* pUnk)
3566 return 22;
3569 LIBTEST_API int STDCALL
3570 IntOut(MonoComObject* pUnk, int *a)
3572 return S_OK;
3575 LIBTEST_API int STDCALL
3576 ArrayIn(MonoComObject* pUnk, void *array)
3578 return S_OK;
3581 LIBTEST_API int STDCALL
3582 ArrayIn2(MonoComObject* pUnk, void *array)
3584 return S_OK;
3587 LIBTEST_API int STDCALL
3588 ArrayIn3(MonoComObject* pUnk, void *array)
3590 return S_OK;
3593 LIBTEST_API int STDCALL
3594 GetDefInterface1(MonoComObject* pUnk, MonoDefItfObject **obj)
3596 return S_OK;
3599 LIBTEST_API int STDCALL
3600 GetDefInterface2(MonoComObject* pUnk, MonoDefItfObject **obj)
3602 return S_OK;
3605 static void create_com_object (MonoComObject** pOut);
3607 LIBTEST_API int STDCALL
3608 get_ITest(MonoComObject* pUnk, MonoComObject* *ppUnk)
3610 create_com_object (ppUnk);
3611 return S_OK;
3614 static void create_com_object (MonoComObject** pOut)
3616 *pOut = marshal_new0 (MonoComObject, 1);
3617 (*pOut)->vtbl = marshal_new0 (MonoIUnknown, 1);
3619 (*pOut)->m_ref = 1;
3620 (*pOut)->vtbl->QueryInterface = MonoQueryInterface;
3621 (*pOut)->vtbl->AddRef = MonoAddRef;
3622 (*pOut)->vtbl->Release = MonoRelease;
3623 (*pOut)->vtbl->SByteIn = SByteIn;
3624 (*pOut)->vtbl->ByteIn = ByteIn;
3625 (*pOut)->vtbl->ShortIn = ShortIn;
3626 (*pOut)->vtbl->UShortIn = UShortIn;
3627 (*pOut)->vtbl->IntIn = IntIn;
3628 (*pOut)->vtbl->UIntIn = UIntIn;
3629 (*pOut)->vtbl->LongIn = LongIn;
3630 (*pOut)->vtbl->ULongIn = ULongIn;
3631 (*pOut)->vtbl->FloatIn = FloatIn;
3632 (*pOut)->vtbl->DoubleIn = DoubleIn;
3633 (*pOut)->vtbl->ITestIn = ITestIn;
3634 (*pOut)->vtbl->ITestOut = ITestOut;
3635 (*pOut)->vtbl->get_ITest = get_ITest;
3636 (*pOut)->vtbl->Return22NoICall = Return22NoICall;
3637 (*pOut)->vtbl->IntOut = IntOut;
3638 (*pOut)->vtbl->ArrayIn = ArrayIn;
3639 (*pOut)->vtbl->ArrayIn2 = ArrayIn2;
3640 (*pOut)->vtbl->ArrayIn3 = ArrayIn3;
3641 (*pOut)->vtbl->GetDefInterface1 = GetDefInterface1;
3642 (*pOut)->vtbl->GetDefInterface2 = GetDefInterface2;
3645 static MonoComObject* same_object = NULL;
3647 LIBTEST_API int STDCALL
3648 mono_test_marshal_com_object_create(MonoComObject* *pUnk)
3650 create_com_object (pUnk);
3652 if (!same_object)
3653 same_object = *pUnk;
3655 return 0;
3658 LIBTEST_API int STDCALL
3659 mono_test_marshal_com_object_same(MonoComObject* *pUnk)
3661 *pUnk = same_object;
3663 return 0;
3666 LIBTEST_API int STDCALL
3667 mono_test_marshal_com_object_destroy(MonoComObject *pUnk)
3669 int ref = --(pUnk->m_ref);
3670 g_free(pUnk->vtbl);
3671 g_free(pUnk);
3673 return ref;
3676 LIBTEST_API int STDCALL
3677 mono_test_marshal_com_object_ref_count(MonoComObject *pUnk)
3679 return pUnk->m_ref;
3682 LIBTEST_API int STDCALL
3683 mono_test_marshal_ccw_itest (MonoComObject *pUnk)
3685 int hr = 0;
3686 MonoComObject* pTest;
3688 if (!pUnk)
3689 return 1;
3691 hr = pUnk->vtbl->SByteIn (pUnk, -100);
3692 if (hr != 0)
3693 return 2;
3694 hr = pUnk->vtbl->ByteIn (pUnk, 100);
3695 if (hr != 0)
3696 return 3;
3697 hr = pUnk->vtbl->ShortIn (pUnk, -100);
3698 if (hr != 0)
3699 return 4;
3700 hr = pUnk->vtbl->UShortIn (pUnk, 100);
3701 if (hr != 0)
3702 return 5;
3703 hr = pUnk->vtbl->IntIn (pUnk, -100);
3704 if (hr != 0)
3705 return 6;
3706 hr = pUnk->vtbl->UIntIn (pUnk, 100);
3707 if (hr != 0)
3708 return 7;
3709 hr = pUnk->vtbl->LongIn (pUnk, -100);
3710 if (hr != 0)
3711 return 8;
3712 hr = pUnk->vtbl->ULongIn (pUnk, 100);
3713 if (hr != 0)
3714 return 9;
3715 hr = pUnk->vtbl->FloatIn (pUnk, 3.14f);
3716 if (hr != 0)
3717 return 10;
3718 hr = pUnk->vtbl->DoubleIn (pUnk, 3.14);
3719 if (hr != 0)
3720 return 11;
3721 hr = pUnk->vtbl->ITestIn (pUnk, pUnk);
3722 if (hr != 0)
3723 return 12;
3724 hr = pUnk->vtbl->ITestOut (pUnk, &pTest);
3725 if (hr != 0)
3726 return 13;
3728 return 0;
3731 // Xamarin-47560
3732 LIBTEST_API int STDCALL
3733 mono_test_marshal_array_ccw_itest (int count, MonoComObject ** ppUnk)
3735 int hr = 0;
3737 if (!ppUnk)
3738 return 1;
3740 if (count < 1)
3741 return 2;
3743 if (!ppUnk[0])
3744 return 3;
3746 hr = ppUnk[0]->vtbl->SByteIn (ppUnk[0], -100);
3747 if (hr != 0)
3748 return 4;
3750 return 0;
3753 LIBTEST_API int STDCALL
3754 mono_test_marshal_retval_ccw_itest (MonoComObject *pUnk, int test_null)
3756 int hr = 0, i = 0;
3758 if (!pUnk)
3759 return 1;
3761 hr = pUnk->vtbl->IntOut (pUnk, &i);
3762 if (hr != 0)
3763 return 2;
3764 if (i != 33)
3765 return 3;
3766 if (test_null)
3768 hr = pUnk->vtbl->IntOut (pUnk, NULL);
3769 if (hr != 0)
3770 return 4;
3773 return 0;
3776 LIBTEST_API int STDCALL
3777 mono_test_default_interface_ccw (MonoComObject *pUnk)
3779 MonoDefItfObject *obj;
3780 int ret, value;
3782 ret = pUnk->vtbl->GetDefInterface1(pUnk, &obj);
3783 if (ret)
3784 return 1;
3785 value = 0;
3787 ret = obj->vtbl->Method(obj, &value);
3788 obj->vtbl->Release(obj);
3789 if (ret)
3790 return 2;
3791 if (value != 1)
3792 return 3;
3794 ret = pUnk->vtbl->GetDefInterface2(pUnk, &obj);
3795 if (ret)
3796 return 4;
3797 ret = obj->vtbl->Method(obj, &value);
3798 obj->vtbl->Release(obj);
3799 if (ret)
3800 return 5;
3801 if (value != 2)
3802 return 6;
3804 return 0;
3808 * mono_method_get_unmanaged_thunk tests
3811 #if defined(__GNUC__) && ((defined(__i386__) && (defined(__linux__) || defined (__APPLE__)) || defined (__FreeBSD__) || defined(__OpenBSD__)) || (defined(__ppc__) && defined(__APPLE__)))
3812 #define ALIGN(size) __attribute__ ((__aligned__(size)))
3813 #else
3814 #define ALIGN(size)
3815 #endif
3818 /* thunks.cs:TestStruct */
3819 typedef struct _TestStruct {
3820 int A;
3821 double B;
3822 } TestStruct;
3824 /* Searches for mono symbols in all loaded modules */
3825 static gpointer
3826 lookup_mono_symbol (const char *symbol_name)
3828 gpointer symbol = NULL;
3829 GModule *mod = g_module_open (NULL, G_MODULE_BIND_LAZY);
3830 g_assert (mod != NULL);
3831 const gboolean success = g_module_symbol (mod, symbol_name, &symbol);
3832 g_assertf (success, "%s", symbol_name);
3833 return success ? symbol : NULL;
3836 LIBTEST_API gpointer STDCALL
3837 mono_test_marshal_lookup_symbol (const char *symbol_name)
3839 #ifndef HOST_WIN32
3840 return dlsym (RTLD_DEFAULT, symbol_name);
3841 #else
3842 // This isn't really proper, but it should work
3843 return lookup_mono_symbol (symbol_name);
3844 #endif
3848 // FIXME use runtime headers
3849 #define MONO_BEGIN_EFRAME { void *__dummy; void *__region_cookie = mono_threads_enter_gc_unsafe_region ? mono_threads_enter_gc_unsafe_region (&__dummy) : NULL;
3850 #define MONO_END_EFRAME if (mono_threads_exit_gc_unsafe_region) mono_threads_exit_gc_unsafe_region (__region_cookie, &__dummy); }
3853 * test_method_thunk:
3855 * @test_id: the test number
3856 * @test_method_handle: MonoMethod* of the C# test method
3857 * @create_object_method_handle: MonoMethod* of thunks.cs:Test.CreateObject
3859 LIBTEST_API int STDCALL
3860 test_method_thunk (int test_id, gpointer test_method_handle, gpointer create_object_method_handle)
3862 int ret = 0;
3864 // FIXME use runtime headers
3865 gpointer (*mono_method_get_unmanaged_thunk)(gpointer)
3866 = (gpointer (*)(gpointer))lookup_mono_symbol ("mono_method_get_unmanaged_thunk");
3868 // FIXME use runtime headers
3869 gpointer (*mono_string_new_wrapper)(const char *)
3870 = (gpointer (*)(const char *))lookup_mono_symbol ("mono_string_new_wrapper");
3872 // FIXME use runtime headers
3873 char *(*mono_string_to_utf8)(gpointer)
3874 = (char *(*)(gpointer))lookup_mono_symbol ("mono_string_to_utf8");
3876 // FIXME use runtime headers
3877 gpointer (*mono_object_unbox)(gpointer)
3878 = (gpointer (*)(gpointer))lookup_mono_symbol ("mono_object_unbox");
3880 // FIXME use runtime headers
3881 gpointer (*mono_threads_enter_gc_unsafe_region) (gpointer)
3882 = (gpointer (*)(gpointer))lookup_mono_symbol ("mono_threads_enter_gc_unsafe_region");
3884 // FIXME use runtime headers
3885 void (*mono_threads_exit_gc_unsafe_region) (gpointer, gpointer)
3886 = (void (*)(gpointer, gpointer))lookup_mono_symbol ("mono_threads_exit_gc_unsafe_region");
3890 gpointer test_method, ex = NULL;
3891 gpointer (STDCALL *CreateObject)(gpointer*);
3893 MONO_BEGIN_EFRAME;
3895 if (!mono_method_get_unmanaged_thunk) {
3896 ret = 1;
3897 goto done;
3900 test_method = mono_method_get_unmanaged_thunk (test_method_handle);
3901 if (!test_method) {
3902 ret = 2;
3903 goto done;
3906 CreateObject = (gpointer (STDCALL *)(gpointer *))mono_method_get_unmanaged_thunk (create_object_method_handle);
3907 if (!CreateObject) {
3908 ret = 3;
3909 goto done;
3913 switch (test_id) {
3915 case 0: {
3916 /* thunks.cs:Test.Test0 */
3917 void (STDCALL *F)(gpointer *) = (void (STDCALL *)(gpointer *))test_method;
3918 F (&ex);
3919 break;
3922 case 1: {
3923 /* thunks.cs:Test.Test1 */
3924 int (STDCALL *F)(gpointer *) = (int (STDCALL *)(gpointer *))test_method;
3925 if (F (&ex) != 42) {
3926 ret = 4;
3927 goto done;
3929 break;
3932 case 2: {
3933 /* thunks.cs:Test.Test2 */
3934 gpointer (STDCALL *F)(gpointer, gpointer*) = (gpointer (STDCALL *)(gpointer, gpointer *))test_method;
3935 gpointer str = mono_string_new_wrapper ("foo");
3936 if (str != F (str, &ex)) {
3937 ret = 4;
3938 goto done;
3940 break;
3943 case 3: {
3944 /* thunks.cs:Test.Test3 */
3945 gpointer (STDCALL *F)(gpointer, gpointer, gpointer*);
3946 gpointer obj;
3947 gpointer str;
3949 F = (gpointer (STDCALL *)(gpointer, gpointer, gpointer *))test_method;
3950 obj = CreateObject (&ex);
3951 str = mono_string_new_wrapper ("bar");
3953 if (str != F (obj, str, &ex)) {
3954 ret = 4;
3955 goto done;
3957 break;
3960 case 4: {
3961 /* thunks.cs:Test.Test4 */
3962 int (STDCALL *F)(gpointer, gpointer, int, gpointer*);
3963 gpointer obj;
3964 gpointer str;
3966 F = (int (STDCALL *)(gpointer, gpointer, int, gpointer *))test_method;
3967 obj = CreateObject (&ex);
3968 str = mono_string_new_wrapper ("bar");
3970 if (42 != F (obj, str, 42, &ex)) {
3971 ret = 4;
3972 goto done;
3975 break;
3978 case 5: {
3979 /* thunks.cs:Test.Test5 */
3980 int (STDCALL *F)(gpointer, gpointer, int, gpointer*);
3981 gpointer obj;
3982 gpointer str;
3984 F = (int (STDCALL *)(gpointer, gpointer, int, gpointer *))test_method;
3985 obj = CreateObject (&ex);
3986 str = mono_string_new_wrapper ("bar");
3988 F (obj, str, 42, &ex);
3989 if (!ex) {
3990 ret = 4;
3991 goto done;
3994 break;
3997 case 6: {
3998 /* thunks.cs:Test.Test6 */
3999 int (STDCALL *F)(gpointer, guint8, gint16, gint32, gint64, float, double,
4000 gpointer, gpointer*);
4001 gpointer obj;
4002 gpointer str = mono_string_new_wrapper ("Test6");
4003 int res;
4005 F = (int (STDCALL *)(gpointer, guint8, gint16, gint32, gint64, float, double, gpointer, gpointer *))test_method;
4006 obj = CreateObject (&ex);
4008 res = F (obj, 254, 32700, -245378, 6789600, 3.1415, 3.1415, str, &ex);
4009 if (ex) {
4010 ret = 4;
4011 goto done;
4014 if (!res) {
4015 ret = 5;
4016 goto done;
4019 break;
4022 case 7: {
4023 /* thunks.cs:Test.Test7 */
4024 gint64 (STDCALL *F)(gpointer*) = (gint64 (STDCALL *)(gpointer *))test_method;
4025 if (F (&ex) != G_MAXINT64) {
4026 ret = 4;
4027 goto done;
4029 break;
4032 case 8: {
4033 /* thunks.cs:Test.Test8 */
4034 void (STDCALL *F)(guint8*, gint16*, gint32*, gint64*, float*, double*,
4035 gpointer*, gpointer*);
4037 guint8 a1;
4038 gint16 a2;
4039 gint32 a3;
4040 gint64 a4;
4041 float a5;
4042 double a6;
4043 gpointer a7;
4045 F = (void (STDCALL *)(guint8 *, gint16 *, gint32 *, gint64 *, float *, double *,
4046 gpointer *, gpointer *))test_method;
4048 F (&a1, &a2, &a3, &a4, &a5, &a6, &a7, &ex);
4049 if (ex) {
4050 ret = 4;
4051 goto done;
4054 if (!(a1 == 254 &&
4055 a2 == 32700 &&
4056 a3 == -245378 &&
4057 a4 == 6789600 &&
4058 (fabs (a5 - 3.1415) < 0.001) &&
4059 (fabs (a6 - 3.1415) < 0.001) &&
4060 strcmp (mono_string_to_utf8 (a7), "Test8") == 0)){
4061 ret = 5;
4062 goto done;
4065 break;
4068 case 9: {
4069 /* thunks.cs:Test.Test9 */
4070 void (STDCALL *F)(guint8*, gint16*, gint32*, gint64*, float*, double*,
4071 gpointer*, gpointer*);
4073 guint8 a1;
4074 gint16 a2;
4075 gint32 a3;
4076 gint64 a4;
4077 float a5;
4078 double a6;
4079 gpointer a7;
4081 F = (void (STDCALL *)(guint8 *, gint16 *, gint32 *, gint64 *, float *, double *,
4082 gpointer *, gpointer *))test_method;
4084 F (&a1, &a2, &a3, &a4, &a5, &a6, &a7, &ex);
4085 if (!ex) {
4086 ret = 4;
4087 goto done;
4090 break;
4093 case 10: {
4094 /* thunks.cs:Test.Test10 */
4095 void (STDCALL *F)(gpointer*, gpointer*);
4097 gpointer obj1, obj2;
4099 obj1 = obj2 = CreateObject (&ex);
4100 if (ex) {
4101 ret = 4;
4102 goto done;
4105 F = (void (STDCALL *)(gpointer *, gpointer *))test_method;
4107 F (&obj1, &ex);
4108 if (ex) {
4109 ret = 5;
4110 goto done;
4113 if (obj1 == obj2) {
4114 ret = 6;
4115 goto done;
4118 break;
4121 case 100: {
4122 /* thunks.cs:TestStruct.Test0 */
4123 int (STDCALL *F)(gpointer*, gpointer*);
4125 gpointer obj;
4126 TestStruct *a1;
4127 int res;
4129 obj = CreateObject (&ex);
4130 if (ex) {
4131 ret = 4;
4132 goto done;
4135 if (!obj) {
4136 ret = 5;
4137 goto done;
4140 a1 = (TestStruct *)mono_object_unbox (obj);
4141 if (!a1) {
4142 ret = 6;
4143 goto done;
4146 a1->A = 42;
4147 a1->B = 3.1415;
4149 F = (int (STDCALL *)(gpointer *, gpointer *))test_method;
4151 res = F ((gpointer *)obj, &ex);
4152 if (ex) {
4153 ret = 7;
4154 goto done;
4157 if (!res) {
4158 ret = 8;
4159 goto done;
4162 /* check whether the call was really by value */
4163 if (a1->A != 42 || a1->B != 3.1415) {
4164 ret = 9;
4165 goto done;
4168 break;
4171 case 101: {
4172 /* thunks.cs:TestStruct.Test1 */
4173 void (STDCALL *F)(gpointer, gpointer*);
4175 TestStruct *a1;
4176 gpointer obj;
4178 obj = CreateObject (&ex);
4179 if (ex) {
4180 ret = 4;
4181 goto done;
4184 if (!obj) {
4185 ret = 5;
4186 goto done;
4189 a1 = (TestStruct *)mono_object_unbox (obj);
4190 if (!a1) {
4191 ret = 6;
4192 goto done;
4195 F = (void (STDCALL *)(gpointer, gpointer *))test_method;
4197 F (obj, &ex);
4198 if (ex) {
4199 ret = 7;
4200 goto done;
4203 if (a1->A != 42) {
4204 ret = 8;
4205 goto done;
4208 if (!(fabs (a1->B - 3.1415) < 0.001)) {
4209 ret = 9;
4210 goto done;
4213 break;
4216 case 102: {
4217 /* thunks.cs:TestStruct.Test2 */
4218 gpointer (STDCALL *F)(gpointer*);
4220 TestStruct *a1;
4221 gpointer obj;
4223 F = (gpointer (STDCALL *)(gpointer *))test_method;
4225 obj = F (&ex);
4226 if (ex) {
4227 ret = 4;
4228 goto done;
4231 if (!obj) {
4232 ret = 5;
4233 goto done;
4236 a1 = (TestStruct *)mono_object_unbox (obj);
4238 if (a1->A != 42) {
4239 ret = 5;
4240 goto done;
4243 if (!(fabs (a1->B - 3.1415) < 0.001)) {
4244 ret = 6;
4245 goto done;
4248 break;
4251 case 103: {
4252 /* thunks.cs:TestStruct.Test3 */
4253 void (STDCALL *F)(gpointer, gpointer*);
4255 TestStruct *a1;
4256 gpointer obj;
4258 obj = CreateObject (&ex);
4259 if (ex) {
4260 ret = 4;
4261 goto done;
4264 if (!obj) {
4265 ret = 5;
4266 goto done;
4269 a1 = (TestStruct *)mono_object_unbox (obj);
4271 if (!a1) {
4272 ret = 6;
4273 goto done;
4276 a1->A = 42;
4277 a1->B = 3.1415;
4279 F = (void (STDCALL *)(gpointer, gpointer *))test_method;
4281 F (obj, &ex);
4282 if (ex) {
4283 ret = 4;
4284 goto done;
4287 if (a1->A != 1) {
4288 ret = 5;
4289 goto done;
4292 if (a1->B != 17) {
4293 ret = 6;
4294 goto done;
4297 break;
4300 default:
4301 ret = 9;
4304 done:
4305 MONO_END_EFRAME;
4307 return ret;
4310 typedef struct
4312 char a;
4313 } winx64_struct1;
4315 LIBTEST_API int STDCALL
4316 mono_test_Winx64_struct1_in (winx64_struct1 var)
4318 if (var.a != 123)
4319 return 1;
4320 return 0;
4323 typedef struct
4325 char a;
4326 char b;
4327 } winx64_struct2;
4329 LIBTEST_API int STDCALL
4330 mono_test_Winx64_struct2_in (winx64_struct2 var)
4332 if (var.a != 4)
4333 return 1;
4334 if (var.b != 5)
4335 return 2;
4336 return 0;
4340 typedef struct
4342 char a;
4343 char b;
4344 short c;
4345 } winx64_struct3;
4347 LIBTEST_API int STDCALL
4348 mono_test_Winx64_struct3_in (winx64_struct3 var)
4350 if (var.a != 4)
4351 return 1;
4352 if (var.b != 5)
4353 return 2;
4354 if (var.c != 0x1234)
4355 return 3;
4356 return 0;
4359 typedef struct
4361 char a;
4362 char b;
4363 short c;
4364 unsigned int d;
4365 } winx64_struct4;
4367 LIBTEST_API int STDCALL
4368 mono_test_Winx64_struct4_in (winx64_struct4 var)
4370 if (var.a != 4)
4371 return 1;
4372 if (var.b != 5)
4373 return 2;
4374 if (var.c != 0x1234)
4375 return 3;
4376 if (var.d != 0x87654321)
4377 return 4;
4378 return 0;
4381 typedef struct
4383 char a;
4384 char b;
4385 char c;
4386 } winx64_struct5;
4388 LIBTEST_API int STDCALL
4389 mono_test_Winx64_struct5_in (winx64_struct5 var)
4391 if (var.a != 4)
4392 return 1;
4393 if (var.b != 5)
4394 return 2;
4395 if (var.c != 6)
4396 return 3;
4397 return 0;
4400 typedef struct
4402 winx64_struct1 a;
4403 short b;
4404 char c;
4405 } winx64_struct6;
4407 LIBTEST_API int STDCALL
4408 mono_test_Winx64_struct6_in (winx64_struct6 var)
4410 if (var.a.a != 4)
4411 return 1;
4412 if (var.b != 5)
4413 return 2;
4414 if (var.c != 6)
4415 return 3;
4416 return 0;
4419 LIBTEST_API int STDCALL
4420 mono_test_Winx64_structs_in1 (winx64_struct1 var1,
4421 winx64_struct2 var2,
4422 winx64_struct3 var3,
4423 winx64_struct4 var4)
4425 if (var1.a != 123)
4426 return 1;
4428 if (var2.a != 4)
4429 return 2;
4430 if (var2.b != 5)
4431 return 3;
4433 if (var3.a != 4)
4434 return 4;
4435 if (var3.b != 5)
4436 return 2;
4437 if (var3.c != 0x1234)
4438 return 5;
4440 if (var4.a != 4)
4441 return 6;
4442 if (var4.b != 5)
4443 return 7;
4444 if (var4.c != 0x1234)
4445 return 8;
4446 if (var4.d != 0x87654321)
4447 return 9;
4448 return 0;
4451 LIBTEST_API int STDCALL
4452 mono_test_Winx64_structs_in2 (winx64_struct1 var1,
4453 winx64_struct1 var2,
4454 winx64_struct1 var3,
4455 winx64_struct1 var4,
4456 winx64_struct1 var5)
4458 if (var1.a != 1)
4459 return 1;
4460 if (var2.a != 2)
4461 return 2;
4462 if (var3.a != 3)
4463 return 3;
4464 if (var4.a != 4)
4465 return 4;
4466 if (var5.a != 5)
4467 return 5;
4469 return 0;
4472 LIBTEST_API int STDCALL
4473 mono_test_Winx64_structs_in3 (winx64_struct1 var1,
4474 winx64_struct5 var2,
4475 winx64_struct1 var3,
4476 winx64_struct5 var4,
4477 winx64_struct1 var5,
4478 winx64_struct5 var6)
4480 if (var1.a != 1)
4481 return 1;
4483 if (var2.a != 2)
4484 return 2;
4485 if (var2.b != 3)
4486 return 2;
4487 if (var2.c != 4)
4488 return 4;
4490 if (var3.a != 5)
4491 return 5;
4493 if (var4.a != 6)
4494 return 6;
4495 if (var4.b != 7)
4496 return 7;
4497 if (var4.c != 8)
4498 return 8;
4500 if (var5.a != 9)
4501 return 9;
4503 if (var6.a != 10)
4504 return 10;
4505 if (var6.b != 11)
4506 return 11;
4507 if (var6.c != 12)
4508 return 12;
4510 return 0;
4513 LIBTEST_API winx64_struct1 STDCALL
4514 mono_test_Winx64_struct1_ret (void)
4516 winx64_struct1 ret;
4517 ret.a = 123;
4518 return ret;
4521 LIBTEST_API winx64_struct2 STDCALL
4522 mono_test_Winx64_struct2_ret (void)
4524 winx64_struct2 ret;
4525 ret.a = 4;
4526 ret.b = 5;
4527 return ret;
4530 LIBTEST_API winx64_struct3 STDCALL
4531 mono_test_Winx64_struct3_ret (void)
4533 winx64_struct3 ret;
4534 ret.a = 4;
4535 ret.b = 5;
4536 ret.c = 0x1234;
4537 return ret;
4540 LIBTEST_API winx64_struct4 STDCALL
4541 mono_test_Winx64_struct4_ret (void)
4543 winx64_struct4 ret;
4544 ret.a = 4;
4545 ret.b = 5;
4546 ret.c = 0x1234;
4547 ret.d = 0x87654321;
4548 return ret;
4551 LIBTEST_API winx64_struct5 STDCALL
4552 mono_test_Winx64_struct5_ret (void)
4554 winx64_struct5 ret;
4555 ret.a = 4;
4556 ret.b = 5;
4557 ret.c = 6;
4558 return ret;
4561 LIBTEST_API winx64_struct1 STDCALL
4562 mono_test_Winx64_struct1_ret_5_args (char a, char b, char c, char d, char e)
4564 winx64_struct1 ret;
4565 ret.a = a + b + c + d + e;
4566 return ret;
4569 LIBTEST_API winx64_struct5 STDCALL
4570 mono_test_Winx64_struct5_ret6_args (char a, char b, char c, char d, char e)
4572 winx64_struct5 ret;
4573 ret.a = a + b;
4574 ret.b = c + d;
4575 ret.c = e;
4576 return ret;
4579 typedef struct
4581 float a;
4582 float b;
4583 } winx64_floatStruct;
4585 LIBTEST_API int STDCALL
4586 mono_test_Winx64_floatStruct (winx64_floatStruct a)
4588 if (a.a > 5.6 || a.a < 5.4)
4589 return 1;
4591 if (a.b > 9.6 || a.b < 9.4)
4592 return 2;
4594 return 0;
4597 typedef struct
4599 double a;
4600 } winx64_doubleStruct;
4602 LIBTEST_API int STDCALL
4603 mono_test_Winx64_doubleStruct (winx64_doubleStruct a)
4605 if (a.a > 5.6 || a.a < 5.4)
4606 return 1;
4608 return 0;
4611 typedef int (STDCALL *managed_struct1_delegate) (winx64_struct1 a);
4613 LIBTEST_API int STDCALL
4614 mono_test_managed_Winx64_struct1_in(managed_struct1_delegate func)
4616 winx64_struct1 val;
4617 val.a = 5;
4618 return func (val);
4621 typedef int (STDCALL *managed_struct5_delegate) (winx64_struct5 a);
4623 LIBTEST_API int STDCALL
4624 mono_test_managed_Winx64_struct5_in(managed_struct5_delegate func)
4626 winx64_struct5 val;
4627 val.a = 5;
4628 val.b = 0x10;
4629 val.c = (char)0x99;
4630 return func (val);
4633 typedef int (STDCALL *managed_struct1_struct5_delegate) (winx64_struct1 a, winx64_struct5 b,
4634 winx64_struct1 c, winx64_struct5 d,
4635 winx64_struct1 e, winx64_struct5 f);
4637 LIBTEST_API int STDCALL
4638 mono_test_managed_Winx64_struct1_struct5_in(managed_struct1_struct5_delegate func)
4640 winx64_struct1 a, c, e;
4641 winx64_struct5 b, d, f;
4642 a.a = 1;
4643 b.a = 2; b.b = 3; b.c = 4;
4644 c.a = 5;
4645 d.a = 6; d.b = 7; d.c = 8;
4646 e.a = 9;
4647 f.a = 10; f.b = 11; f.c = 12;
4649 return func (a, b, c, d, e, f);
4652 typedef winx64_struct1 (STDCALL *managed_struct1_ret_delegate) (void);
4654 LIBTEST_API int STDCALL
4655 mono_test_Winx64_struct1_ret_managed (managed_struct1_ret_delegate func)
4657 winx64_struct1 ret;
4659 ret = func ();
4661 if (ret.a != 0x45)
4662 return 1;
4664 return 0;
4667 typedef winx64_struct5 (STDCALL *managed_struct5_ret_delegate) (void);
4669 LIBTEST_API int STDCALL
4670 mono_test_Winx64_struct5_ret_managed (managed_struct5_ret_delegate func)
4672 winx64_struct5 ret;
4674 ret = func ();
4676 if (ret.a != 0x12)
4677 return 1;
4678 if (ret.b != 0x34)
4679 return 2;
4680 if (ret.c != 0x56)
4681 return 3;
4683 return 0;
4686 LIBTEST_API int STDCALL
4687 mono_test_marshal_bool_in (int arg, unsigned int expected, unsigned int bDefaultMarsh, unsigned int bBoolCustMarsh,
4688 char bI1CustMarsh, unsigned char bU1CustMarsh, short bVBCustMarsh)
4690 switch (arg) {
4691 case 1:
4692 if (bDefaultMarsh != expected)
4693 return 1;
4694 break;
4695 case 2:
4696 if (bBoolCustMarsh != expected)
4697 return 2;
4698 break;
4699 case 3:
4700 if (bI1CustMarsh != expected)
4701 return 3;
4702 break;
4703 case 4:
4704 if (bU1CustMarsh != expected)
4705 return 4;
4706 break;
4707 case 5:
4708 if (bVBCustMarsh != expected)
4709 return 5;
4710 break;
4711 default:
4712 return 999;
4714 return 0;
4717 LIBTEST_API int STDCALL
4718 mono_test_marshal_bool_out (int arg, unsigned int testVal, unsigned int* bDefaultMarsh, unsigned int* bBoolCustMarsh,
4719 char* bI1CustMarsh, unsigned char* bU1CustMarsh, unsigned short* bVBCustMarsh)
4721 switch (arg) {
4722 case 1:
4723 if (!bDefaultMarsh)
4724 return 1;
4725 *bDefaultMarsh = testVal;
4726 break;
4727 case 2:
4728 if (!bBoolCustMarsh)
4729 return 2;
4730 *bBoolCustMarsh = testVal;
4731 break;
4732 case 3:
4733 if (!bI1CustMarsh)
4734 return 3;
4735 *bI1CustMarsh = (char)testVal;
4736 break;
4737 case 4:
4738 if (!bU1CustMarsh)
4739 return 4;
4740 *bU1CustMarsh = (unsigned char)testVal;
4741 break;
4742 case 5:
4743 if (!bVBCustMarsh)
4744 return 5;
4745 *bVBCustMarsh = (unsigned short)testVal;
4746 break;
4747 default:
4748 return 999;
4750 return 0;
4753 LIBTEST_API int STDCALL
4754 mono_test_marshal_bool_ref (int arg, unsigned int expected, unsigned int testVal, unsigned int* bDefaultMarsh,
4755 unsigned int* bBoolCustMarsh, char* bI1CustMarsh, unsigned char* bU1CustMarsh,
4756 unsigned short* bVBCustMarsh)
4758 switch (arg) {
4759 case 1:
4760 if (!bDefaultMarsh)
4761 return 1;
4762 if (*bDefaultMarsh != expected)
4763 return 2;
4764 *bDefaultMarsh = testVal;
4765 break;
4766 case 2:
4767 if (!bBoolCustMarsh)
4768 return 3;
4769 if (*bBoolCustMarsh != expected)
4770 return 4;
4771 *bBoolCustMarsh = testVal;
4772 break;
4773 case 3:
4774 if (!bI1CustMarsh)
4775 return 5;
4776 if (*bI1CustMarsh != expected)
4777 return 6;
4778 *bI1CustMarsh = (char)testVal;
4779 break;
4780 case 4:
4781 if (!bU1CustMarsh)
4782 return 7;
4783 if (*bU1CustMarsh != expected)
4784 return 8;
4785 *bU1CustMarsh = (unsigned char)testVal;
4786 break;
4787 case 5:
4788 if (!bVBCustMarsh)
4789 return 9;
4790 if (*bVBCustMarsh != expected)
4791 return 10;
4792 *bVBCustMarsh = (unsigned short)testVal;
4793 break;
4794 default:
4795 return 999;
4797 return 0;
4801 typedef int (STDCALL *MarshalBoolInDelegate) (int arg, unsigned int expected, unsigned int bDefaultMarsh,
4802 unsigned int bBoolCustMarsh, char bI1CustMarsh, unsigned char bU1CustMarsh, unsigned short bVBCustMarsh);
4804 LIBTEST_API int STDCALL
4805 mono_test_managed_marshal_bool_in (int arg, unsigned int expected, unsigned int testVal, MarshalBoolInDelegate pfcn)
4807 if (!pfcn)
4808 return 0x9900;
4810 switch (arg) {
4811 case 1:
4812 return pfcn (arg, expected, testVal, 0, 0, 0, 0);
4813 case 2:
4814 return pfcn (arg, expected, 0, testVal, 0, 0, 0);
4815 case 3:
4816 return pfcn (arg, expected, 0, 0, testVal, 0, 0);
4817 case 4:
4818 return pfcn (arg, expected, 0, 0, 0, testVal, 0);
4819 case 5:
4820 return pfcn (arg, expected, 0, 0, 0, 0, testVal);
4821 default:
4822 return 0x9800;
4825 return 0;
4828 typedef int (STDCALL *MarshalBoolOutDelegate) (int arg, unsigned int expected, unsigned int* bDefaultMarsh,
4829 unsigned int* bBoolCustMarsh, char* bI1CustMarsh, unsigned char* bU1CustMarsh, unsigned short* bVBCustMarsh);
4831 LIBTEST_API int STDCALL
4832 mono_test_managed_marshal_bool_out (int arg, unsigned int expected, unsigned int testVal, MarshalBoolOutDelegate pfcn)
4834 int ret;
4835 unsigned int lDefaultMarsh, lBoolCustMarsh;
4836 char lI1CustMarsh = 0;
4837 unsigned char lU1CustMarsh = 0;
4838 unsigned short lVBCustMarsh = 0;
4839 lDefaultMarsh = lBoolCustMarsh = 0;
4841 if (!pfcn)
4842 return 0x9900;
4844 switch (arg) {
4845 case 1: {
4846 unsigned int ltVal = 0;
4847 ret = pfcn (arg, testVal, &ltVal, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4848 if (ret)
4849 return 0x0100 + ret;
4850 if (expected != ltVal)
4851 return 0x0200;
4852 break;
4854 case 2: {
4855 unsigned int ltVal = 0;
4856 ret = pfcn (arg, testVal, &lDefaultMarsh, &ltVal, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4857 if (ret)
4858 return 0x0300 + ret;
4859 if (expected != ltVal)
4860 return 0x0400;
4861 break;
4863 case 3: {
4864 char ltVal = 0;
4865 ret = pfcn (arg, testVal, &lDefaultMarsh, &lBoolCustMarsh, &ltVal, &lU1CustMarsh, &lVBCustMarsh);
4866 if (ret)
4867 return 0x0500 + ret;
4868 if (expected != ltVal)
4869 return 0x0600;
4870 break;
4872 case 4: {
4873 unsigned char ltVal = 0;
4874 ret = pfcn (arg, testVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &ltVal, &lVBCustMarsh);
4875 if (ret)
4876 return 0x0700 + ret;
4877 if (expected != ltVal)
4878 return 0x0800;
4879 break;
4881 case 5: {
4882 unsigned short ltVal = 0;
4883 ret = pfcn (arg, testVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &ltVal);
4884 if (ret)
4885 return 0x0900 + ret;
4886 if (expected != ltVal)
4887 return 0x1000;
4888 break;
4890 default:
4891 return 0x9800;
4894 return 0;
4897 typedef int (STDCALL *MarshalBoolRefDelegate) (int arg, unsigned int expected, unsigned int testVal, unsigned int* bDefaultMarsh,
4898 unsigned int* bBoolCustMarsh, char* bI1CustMarsh, unsigned char* bU1CustMarsh, unsigned short* bVBCustMarsh);
4900 LIBTEST_API int STDCALL
4901 mono_test_managed_marshal_bool_ref (int arg, unsigned int expected, unsigned int testVal, unsigned int outExpected,
4902 unsigned int outTestVal, MarshalBoolRefDelegate pfcn)
4904 int ret;
4905 unsigned int lDefaultMarsh, lBoolCustMarsh;
4906 char lI1CustMarsh = 0;
4907 unsigned char lU1CustMarsh = 0;
4908 unsigned short lVBCustMarsh = 0;
4909 lDefaultMarsh = lBoolCustMarsh = 0;
4911 if (!pfcn)
4912 return 0x9900;
4914 switch (arg) {
4915 case 1:
4917 unsigned int ltestVal = testVal;
4918 ret = pfcn (arg, expected, outTestVal, &ltestVal, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4919 if (ret)
4920 return 0x0100 + ret;
4921 if (outExpected != ltestVal)
4922 return 0x0200;
4923 break;
4925 case 2:
4927 unsigned int ltestVal = testVal;
4928 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &ltestVal, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4929 if (ret)
4930 return 0x0300 + ret;
4931 if (outExpected != ltestVal)
4932 return 0x0400;
4933 break;
4935 case 3:
4937 char ltestVal = testVal;
4938 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &lBoolCustMarsh, &ltestVal, &lU1CustMarsh, &lVBCustMarsh);
4939 if (ret)
4940 return 0x0500 + ret;
4941 if (outExpected != ltestVal)
4942 return 0x0600;
4943 break;
4945 case 4:
4947 unsigned char ltestVal = testVal;
4948 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &ltestVal, &lVBCustMarsh);
4949 if (ret)
4950 return 0x0700 + ret;
4951 if (outExpected != ltestVal)
4952 return 0x0800;
4953 break;
4955 case 5:
4957 unsigned short ltestVal = testVal;
4958 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &ltestVal);
4959 if (ret)
4960 return 0x0900 + ret;
4961 if (outExpected != ltestVal)
4962 return 0x1000;
4963 break;
4965 default:
4966 return 0x9800;
4969 return 0;
4972 #ifdef WIN32
4974 LIBTEST_API int STDCALL
4975 mono_test_marshal_safearray_out_1dim_vt_bstr_empty (SAFEARRAY** safearray)
4977 /* Create an empty one-dimensional array of variants */
4978 SAFEARRAY *pSA;
4979 SAFEARRAYBOUND dimensions [1];
4981 dimensions [0].lLbound = 0;
4982 dimensions [0].cElements = 0;
4984 pSA = SafeArrayCreate (VT_VARIANT, 1, dimensions);
4985 *safearray = pSA;
4986 return S_OK;
4989 LIBTEST_API int STDCALL
4990 mono_test_marshal_safearray_out_1dim_vt_bstr (SAFEARRAY** safearray)
4992 /* Create a one-dimensional array of 10 variants filled with "0" to "9" */
4993 SAFEARRAY *pSA;
4994 SAFEARRAYBOUND dimensions [1];
4995 long i;
4996 gchar buffer [20];
4997 HRESULT hr = S_OK;
4998 long indices [1];
5000 dimensions [0].lLbound = 0;
5001 dimensions [0].cElements = 10;
5003 pSA= SafeArrayCreate (VT_VARIANT, 1, dimensions);
5004 for (i= dimensions [0].lLbound; i< (dimensions [0].cElements + dimensions [0].lLbound); i++) {
5005 VARIANT vOut;
5006 VariantInit (&vOut);
5007 vOut.vt = VT_BSTR;
5008 _ltoa (i,buffer,10);
5009 vOut.bstrVal= marshal_bstr_alloc (buffer);
5010 indices [0] = i;
5011 if ((hr = SafeArrayPutElement (pSA, indices, &vOut)) != S_OK) {
5012 VariantClear (&vOut);
5013 SafeArrayDestroy (pSA);
5014 return hr;
5016 VariantClear (&vOut);
5018 *safearray = pSA;
5019 return hr;
5022 LIBTEST_API int STDCALL
5023 mono_test_marshal_safearray_out_2dim_vt_i4 (SAFEARRAY** safearray)
5025 /* Create a two-dimensional array of 4x3 variants filled with 11, 12, 13, etc. */
5026 SAFEARRAY *pSA;
5027 SAFEARRAYBOUND dimensions [2];
5028 long i, j;
5029 HRESULT hr = S_OK;
5030 long indices [2];
5032 dimensions [0].lLbound = 0;
5033 dimensions [0].cElements = 4;
5034 dimensions [1].lLbound = 0;
5035 dimensions [1].cElements = 3;
5037 pSA= SafeArrayCreate(VT_VARIANT, 2, dimensions);
5038 for (i= dimensions [0].lLbound; i< (dimensions [0].cElements + dimensions [0].lLbound); i++) {
5039 for (j= dimensions [1].lLbound; j< (dimensions [1].cElements + dimensions [1].lLbound); j++) {
5040 VARIANT vOut;
5041 VariantInit (&vOut);
5042 vOut.vt = VT_I4;
5043 vOut.lVal = (i+1)*10+(j+1);
5044 indices [0] = i;
5045 indices [1] = j;
5046 if ((hr = SafeArrayPutElement (pSA, indices, &vOut)) != S_OK) {
5047 VariantClear (&vOut);
5048 SafeArrayDestroy (pSA);
5049 return hr;
5051 VariantClear (&vOut); // does a deep destroy of source VARIANT
5054 *safearray = pSA;
5055 return hr;
5058 LIBTEST_API int STDCALL
5059 mono_test_marshal_safearray_out_4dim_vt_i4 (SAFEARRAY** safearray)
5061 /* Create a four-dimensional array of 10x3x6x7 variants filled with their indices */
5062 /* Also use non zero lower bounds */
5063 SAFEARRAY *pSA;
5064 SAFEARRAYBOUND dimensions [4];
5065 long i;
5066 HRESULT hr = S_OK;
5067 VARIANT *pData;
5069 dimensions [0].lLbound = 15;
5070 dimensions [0].cElements = 10;
5071 dimensions [1].lLbound = 20;
5072 dimensions [1].cElements = 3;
5073 dimensions [2].lLbound = 5;
5074 dimensions [2].cElements = 6;
5075 dimensions [3].lLbound = 12;
5076 dimensions [3].cElements = 7;
5078 pSA= SafeArrayCreate (VT_VARIANT, 4, dimensions);
5080 SafeArrayAccessData (pSA, (void **)&pData);
5082 for (i= 0; i< 10*3*6*7; i++) {
5083 VariantInit(&pData [i]);
5084 pData [i].vt = VT_I4;
5085 pData [i].lVal = i;
5087 SafeArrayUnaccessData (pSA);
5088 *safearray = pSA;
5089 return hr;
5092 LIBTEST_API int STDCALL
5093 mono_test_marshal_safearray_in_byval_1dim_empty (SAFEARRAY* safearray)
5095 /* Check that array is one dimensional and empty */
5097 UINT dim;
5098 long lbound, ubound;
5100 dim = SafeArrayGetDim (safearray);
5101 if (dim != 1)
5102 return 1;
5104 SafeArrayGetLBound (safearray, 1, &lbound);
5105 SafeArrayGetUBound (safearray, 1, &ubound);
5107 if ((lbound > 0) || (ubound > 0))
5108 return 1;
5110 return 0;
5113 LIBTEST_API int STDCALL
5114 mono_test_marshal_safearray_in_byval_1dim_vt_i4 (SAFEARRAY* safearray)
5116 /* Check that array is one dimensional containing integers from 1 to 10 */
5118 UINT dim;
5119 long lbound, ubound;
5120 VARIANT *pData;
5121 long i;
5122 int result=0;
5124 dim = SafeArrayGetDim (safearray);
5125 if (dim != 1)
5126 return 1;
5128 SafeArrayGetLBound (safearray, 1, &lbound);
5129 SafeArrayGetUBound (safearray, 1, &ubound);
5131 if ((lbound != 0) || (ubound != 9))
5132 return 1;
5134 SafeArrayAccessData (safearray, (void **)&pData);
5135 for (i= lbound; i <= ubound; i++) {
5136 if ((VariantChangeType (&pData [i], &pData [i], VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK) || (pData [i].lVal != i + 1))
5137 result = 1;
5139 SafeArrayUnaccessData (safearray);
5141 return result;
5144 LIBTEST_API int STDCALL
5145 mono_test_marshal_safearray_in_byval_1dim_vt_mixed (SAFEARRAY* safearray)
5147 /* Check that array is one dimensional containing integers mixed with strings from 0 to 12 */
5149 UINT dim;
5150 long lbound, ubound;
5151 VARIANT *pData;
5152 long i;
5153 long indices [1];
5154 VARIANT element;
5155 int result=0;
5157 VariantInit (&element);
5159 dim = SafeArrayGetDim (safearray);
5160 if (dim != 1)
5161 return 1;
5163 SafeArrayGetLBound (safearray, 1, &lbound);
5164 SafeArrayGetUBound (safearray, 1, &ubound);
5166 if ((lbound != 0) || (ubound != 12))
5167 return 1;
5169 SafeArrayAccessData (safearray, (void **)&pData);
5170 for (i= lbound; i <= ubound; i++) {
5171 if ((i%2 == 0) && (pData [i].vt != VT_I4))
5172 result = 1;
5173 if ((i%2 == 1) && (pData [i].vt != VT_BSTR))
5174 result = 1;
5175 if ((VariantChangeType (&pData [i], &pData [i], VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK) || (pData [i].lVal != i))
5176 result = 1;
5178 SafeArrayUnaccessData (safearray);
5180 /* Change the first element of the array to verify that [in] parameters are not marshalled back to the managed side */
5182 indices [0] = 0;
5183 element.vt = VT_I4;
5184 element.lVal = 333;
5185 SafeArrayPutElement (safearray, indices, &element);
5186 VariantClear (&element);
5188 return result;
5191 LIBTEST_API int STDCALL
5192 mono_test_marshal_safearray_in_byval_2dim_vt_i4 (SAFEARRAY* safearray)
5194 /* Check that array is one dimensional containing integers mixed with strings from 0 to 12 */
5196 UINT dim;
5197 long lbound1, ubound1, lbound2, ubound2;
5198 long i, j, failed;
5199 long indices [2];
5200 VARIANT element;
5202 VariantInit (&element);
5204 dim = SafeArrayGetDim (safearray);
5205 if (dim != 2)
5206 return 1;
5208 SafeArrayGetLBound (safearray, 1, &lbound1);
5209 SafeArrayGetUBound (safearray, 1, &ubound1);
5211 if ((lbound1 != 0) || (ubound1 != 1))
5212 return 1;
5214 SafeArrayGetLBound (safearray, 2, &lbound2);
5215 SafeArrayGetUBound (safearray, 2, &ubound2);
5217 if ((lbound2 != 0) || (ubound2 != 3)) {
5218 return 1;
5221 for (i= lbound1; i <= ubound1; i++) {
5222 indices [0] = i;
5223 for (j= lbound2; j <= ubound2; j++) {
5224 indices [1] = j;
5225 if (SafeArrayGetElement (safearray, indices, &element) != S_OK)
5226 return 1;
5227 failed = ((element.vt != VT_I4) || (element.lVal != 10*(i+1)+(j+1)));
5228 VariantClear (&element);
5229 if (failed)
5230 return 1;
5234 /* Change the first element of the array to verify that [in] parameters are not marshalled back to the managed side */
5236 indices [0] = 0;
5237 indices [1] = 0;
5238 element.vt = VT_I4;
5239 element.lVal = 333;
5240 SafeArrayPutElement (safearray, indices, &element);
5241 VariantClear (&element);
5243 return 0;
5246 LIBTEST_API int STDCALL
5247 mono_test_marshal_safearray_in_byval_3dim_vt_bstr (SAFEARRAY* safearray)
5249 /* Check that array is one dimensional containing integers mixed with strings from 0 to 12 */
5251 UINT dim;
5252 long lbound1, ubound1, lbound2, ubound2, lbound3, ubound3;
5253 long i, j, k, failed;
5254 long indices [3];
5255 VARIANT element;
5257 VariantInit (&element);
5259 dim = SafeArrayGetDim (safearray);
5260 if (dim != 3)
5261 return 1;
5263 SafeArrayGetLBound (safearray, 1, &lbound1);
5264 SafeArrayGetUBound (safearray, 1, &ubound1);
5266 if ((lbound1 != 0) || (ubound1 != 1))
5267 return 1;
5269 SafeArrayGetLBound (safearray, 2, &lbound2);
5270 SafeArrayGetUBound (safearray, 2, &ubound2);
5272 if ((lbound2 != 0) || (ubound2 != 1))
5273 return 1;
5275 SafeArrayGetLBound (safearray, 3, &lbound3);
5276 SafeArrayGetUBound (safearray, 3, &ubound3);
5278 if ((lbound3 != 0) || (ubound3 != 2))
5279 return 1;
5281 for (i= lbound1; i <= ubound1; i++) {
5282 indices [0] = i;
5283 for (j= lbound2; j <= ubound2; j++) {
5284 indices [1] = j;
5285 for (k= lbound3; k <= ubound3; k++) {
5286 indices [2] = k;
5287 if (SafeArrayGetElement (safearray, indices, &element) != S_OK)
5288 return 1;
5289 failed = ((element.vt != VT_BSTR)
5290 || (VariantChangeType (&element, &element, VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK)
5291 || (element.lVal != 100*(i+1)+10*(j+1)+(k+1)));
5292 VariantClear (&element);
5293 if (failed)
5294 return 1;
5299 /* Change the first element of the array to verify that [in] parameters are not marshalled back to the managed side */
5301 indices [0] = 0;
5302 indices [1] = 0;
5303 indices [2] = 0;
5304 element.vt = VT_BSTR;
5305 element.bstrVal = SysAllocString(L"Should not be copied");
5306 SafeArrayPutElement (safearray, indices, &element);
5307 VariantClear (&element);
5309 return 0;
5312 LIBTEST_API int STDCALL
5313 mono_test_marshal_safearray_in_byref_3dim_vt_bstr (SAFEARRAY** safearray)
5315 return mono_test_marshal_safearray_in_byval_3dim_vt_bstr (*safearray);
5318 LIBTEST_API int STDCALL
5319 mono_test_marshal_safearray_in_out_byref_1dim_empty (SAFEARRAY** safearray)
5321 /* Check that the input array is what is expected and change it so the caller can check */
5322 /* correct marshalling back to managed code */
5324 UINT dim;
5325 long lbound, ubound;
5326 SAFEARRAYBOUND dimensions [1];
5327 long i;
5328 wchar_t buffer [20];
5329 HRESULT hr = S_OK;
5330 long indices [1];
5332 /* Check that in array is one dimensional and empty */
5334 dim = SafeArrayGetDim (*safearray);
5335 if (dim != 1) {
5336 return 1;
5339 SafeArrayGetLBound (*safearray, 1, &lbound);
5340 SafeArrayGetUBound (*safearray, 1, &ubound);
5342 if ((lbound > 0) || (ubound > 0)) {
5343 return 1;
5346 /* Re-dimension the array and return a one-dimensional array of 8 variants filled with "0" to "7" */
5348 dimensions [0].lLbound = 0;
5349 dimensions [0].cElements = 8;
5351 hr = SafeArrayRedim (*safearray, dimensions);
5352 if (hr != S_OK)
5353 return 1;
5355 for (i= dimensions [0].lLbound; i< (dimensions [0].lLbound + dimensions [0].cElements); i++) {
5356 VARIANT vOut;
5357 VariantInit (&vOut);
5358 vOut.vt = VT_BSTR;
5359 _ltow (i,buffer,10);
5360 vOut.bstrVal = SysAllocString (buffer);
5361 indices [0] = i;
5362 if ((hr = SafeArrayPutElement (*safearray, indices, &vOut)) != S_OK) {
5363 VariantClear (&vOut);
5364 SafeArrayDestroy (*safearray);
5365 return hr;
5367 VariantClear (&vOut);
5369 return hr;
5372 LIBTEST_API int STDCALL
5373 mono_test_marshal_safearray_in_out_byref_3dim_vt_bstr (SAFEARRAY** safearray)
5375 /* Check that the input array is what is expected and change it so the caller can check */
5376 /* correct marshalling back to managed code */
5378 UINT dim;
5379 long lbound1, ubound1, lbound2, ubound2, lbound3, ubound3;
5380 SAFEARRAYBOUND dimensions [1];
5381 long i, j, k, failed;
5382 wchar_t buffer [20];
5383 HRESULT hr = S_OK;
5384 long indices [3];
5385 VARIANT element;
5387 VariantInit (&element);
5389 /* Check that in array is three dimensional and contains the expected values */
5391 dim = SafeArrayGetDim (*safearray);
5392 if (dim != 3)
5393 return 1;
5395 SafeArrayGetLBound (*safearray, 1, &lbound1);
5396 SafeArrayGetUBound (*safearray, 1, &ubound1);
5398 if ((lbound1 != 0) || (ubound1 != 1))
5399 return 1;
5401 SafeArrayGetLBound (*safearray, 2, &lbound2);
5402 SafeArrayGetUBound (*safearray, 2, &ubound2);
5404 if ((lbound2 != 0) || (ubound2 != 1))
5405 return 1;
5407 SafeArrayGetLBound (*safearray, 3, &lbound3);
5408 SafeArrayGetUBound (*safearray, 3, &ubound3);
5410 if ((lbound3 != 0) || (ubound3 != 2))
5411 return 1;
5413 for (i= lbound1; i <= ubound1; i++) {
5414 indices [0] = i;
5415 for (j= lbound2; j <= ubound2; j++) {
5416 indices [1] = j;
5417 for (k= lbound3; k <= ubound3; k++) {
5418 indices [2] = k;
5419 if (SafeArrayGetElement (*safearray, indices, &element) != S_OK)
5420 return 1;
5421 failed = ((element.vt != VT_BSTR)
5422 || (VariantChangeType (&element, &element, VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK)
5423 || (element.lVal != 100*(i+1)+10*(j+1)+(k+1)));
5424 VariantClear (&element);
5425 if (failed)
5426 return 1;
5431 hr = SafeArrayDestroy (*safearray);
5432 if (hr != S_OK)
5433 return 1;
5435 /* Return a new one-dimensional array of 8 variants filled with "0" to "7" */
5437 dimensions [0].lLbound = 0;
5438 dimensions [0].cElements = 8;
5440 *safearray = SafeArrayCreate (VT_VARIANT, 1, dimensions);
5442 for (i= dimensions [0].lLbound; i< (dimensions [0].lLbound + dimensions [0].cElements); i++) {
5443 VARIANT vOut;
5444 VariantInit (&vOut);
5445 vOut.vt = VT_BSTR;
5446 _ltow (i,buffer,10);
5447 vOut.bstrVal = SysAllocString (buffer);
5448 indices [0] = i;
5449 if ((hr = SafeArrayPutElement (*safearray, indices, &vOut)) != S_OK) {
5450 VariantClear (&vOut);
5451 SafeArrayDestroy (*safearray);
5452 return hr;
5454 VariantClear (&vOut);
5456 return hr;
5459 LIBTEST_API int STDCALL
5460 mono_test_marshal_safearray_in_out_byref_1dim_vt_i4 (SAFEARRAY** safearray)
5462 /* Check that the input array is what is expected and change it so the caller can check */
5463 /* correct marshalling back to managed code */
5465 UINT dim;
5466 long lbound1, ubound1;
5467 long i, failed;
5468 HRESULT hr = S_OK;
5469 long indices [1];
5470 VARIANT element;
5472 VariantInit (&element);
5474 /* Check that in array is one dimensional and contains the expected value */
5476 dim = SafeArrayGetDim (*safearray);
5477 if (dim != 1)
5478 return 1;
5480 SafeArrayGetLBound (*safearray, 1, &lbound1);
5481 SafeArrayGetUBound (*safearray, 1, &ubound1);
5483 ubound1 = 1;
5484 if ((lbound1 != 0) || (ubound1 != 1))
5485 return 1;
5486 ubound1 = 0;
5488 for (i= lbound1; i <= ubound1; i++) {
5489 indices [0] = i;
5490 if (SafeArrayGetElement (*safearray, indices, &element) != S_OK)
5491 return 1;
5492 failed = (element.vt != VT_I4) || (element.lVal != i+1);
5493 VariantClear (&element);
5494 if (failed)
5495 return 1;
5498 /* Change one of the elements of the array to verify that [out] parameter is marshalled back to the managed side */
5500 indices [0] = 0;
5501 element.vt = VT_I4;
5502 element.lVal = -1;
5503 SafeArrayPutElement (*safearray, indices, &element);
5504 VariantClear (&element);
5506 return hr;
5509 LIBTEST_API int STDCALL
5510 mono_test_marshal_safearray_in_out_byval_1dim_vt_i4 (SAFEARRAY* safearray)
5512 /* Check that the input array is what is expected and change it so the caller can check */
5513 /* correct marshalling back to managed code */
5515 UINT dim;
5516 long lbound1, ubound1;
5517 SAFEARRAYBOUND dimensions [1];
5518 long i, failed;
5519 HRESULT hr = S_OK;
5520 long indices [1];
5521 VARIANT element;
5523 VariantInit (&element);
5525 /* Check that in array is one dimensional and contains the expected value */
5527 dim = SafeArrayGetDim (safearray);
5528 if (dim != 1)
5529 return 1;
5531 SafeArrayGetLBound (safearray, 1, &lbound1);
5532 SafeArrayGetUBound (safearray, 1, &ubound1);
5534 if ((lbound1 != 0) || (ubound1 != 0))
5535 return 1;
5537 for (i= lbound1; i <= ubound1; i++) {
5538 indices [0] = i;
5539 if (SafeArrayGetElement (safearray, indices, &element) != S_OK)
5540 return 1;
5541 failed = (element.vt != VT_I4) || (element.lVal != i+1);
5542 VariantClear (&element);
5543 if (failed)
5544 return 1;
5547 /* Change the array to verify how [out] parameter is marshalled back to the managed side */
5549 /* Redimension the array */
5550 dimensions [0].lLbound = lbound1;
5551 dimensions [0].cElements = 2;
5552 hr = SafeArrayRedim(safearray, dimensions);
5554 indices [0] = 0;
5555 element.vt = VT_I4;
5556 element.lVal = 12345;
5557 SafeArrayPutElement (safearray, indices, &element);
5558 VariantClear (&element);
5560 indices [0] = 1;
5561 element.vt = VT_I4;
5562 element.lVal = -12345;
5563 SafeArrayPutElement (safearray, indices, &element);
5564 VariantClear (&element);
5566 return hr;
5569 LIBTEST_API int STDCALL
5570 mono_test_marshal_safearray_in_out_byval_3dim_vt_bstr (SAFEARRAY* safearray)
5572 /* Check that the input array is what is expected and change it so the caller can check */
5573 /* correct marshalling back to managed code */
5575 UINT dim;
5576 long lbound1, ubound1, lbound2, ubound2, lbound3, ubound3;
5577 long i, j, k, failed;
5578 HRESULT hr = S_OK;
5579 long indices [3];
5580 VARIANT element;
5582 VariantInit (&element);
5584 /* Check that in array is three dimensional and contains the expected values */
5586 dim = SafeArrayGetDim (safearray);
5587 if (dim != 3)
5588 return 1;
5590 SafeArrayGetLBound (safearray, 1, &lbound1);
5591 SafeArrayGetUBound (safearray, 1, &ubound1);
5593 if ((lbound1 != 0) || (ubound1 != 1))
5594 return 1;
5596 SafeArrayGetLBound (safearray, 2, &lbound2);
5597 SafeArrayGetUBound (safearray, 2, &ubound2);
5599 if ((lbound2 != 0) || (ubound2 != 1))
5600 return 1;
5602 SafeArrayGetLBound (safearray, 3, &lbound3);
5603 SafeArrayGetUBound (safearray, 3, &ubound3);
5605 if ((lbound3 != 0) || (ubound3 != 2))
5606 return 1;
5608 for (i= lbound1; i <= ubound1; i++) {
5609 indices [0] = i;
5610 for (j= lbound2; j <= ubound2; j++) {
5611 indices [1] = j;
5612 for (k= lbound3; k <= ubound3; k++) {
5613 indices [2] = k;
5614 if (SafeArrayGetElement (safearray, indices, &element) != S_OK)
5615 return 1;
5616 failed = ((element.vt != VT_BSTR)
5617 || (VariantChangeType (&element, &element, VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK)
5618 || (element.lVal != 100*(i+1)+10*(j+1)+(k+1)));
5619 VariantClear (&element);
5620 if (failed)
5621 return 1;
5626 /* Change the elements of the array to verify that [out] parameter is marshalled back to the managed side */
5628 indices [0] = 1;
5629 indices [1] = 1;
5630 indices [2] = 2;
5631 element.vt = VT_I4;
5632 element.lVal = 333;
5633 SafeArrayPutElement (safearray, indices, &element);
5634 VariantClear (&element);
5636 indices [0] = 1;
5637 indices [1] = 1;
5638 indices [2] = 1;
5639 element.vt = VT_I4;
5640 element.lVal = 111;
5641 SafeArrayPutElement (safearray, indices, &element);
5642 VariantClear (&element);
5644 indices [0] = 0;
5645 indices [1] = 1;
5646 indices [2] = 0;
5647 element.vt = VT_BSTR;
5648 element.bstrVal = marshal_bstr_alloc("ABCDEFG");
5649 SafeArrayPutElement (safearray, indices, &element);
5650 VariantClear (&element);
5652 return hr;
5655 LIBTEST_API int STDCALL
5656 mono_test_marshal_safearray_mixed(
5657 SAFEARRAY *safearray1,
5658 SAFEARRAY **safearray2,
5659 SAFEARRAY *safearray3,
5660 SAFEARRAY **safearray4
5663 HRESULT hr = S_OK;
5665 /* Initialize out parameters */
5666 *safearray2 = NULL;
5668 /* array1: Check that in array is one dimensional and contains the expected value */
5669 hr = mono_test_marshal_safearray_in_out_byval_1dim_vt_i4 (safearray1);
5671 /* array2: Fill in with some values to check on the managed side */
5672 if (hr == S_OK)
5673 hr = mono_test_marshal_safearray_out_1dim_vt_bstr (safearray2);
5675 /* array3: Check that in array is one dimensional and contains the expected value */
5676 if (hr == S_OK)
5677 hr = mono_test_marshal_safearray_in_byval_1dim_vt_mixed(safearray3);
5679 /* array4: Check input values and fill in with some values to check on the managed side */
5680 if (hr == S_OK)
5681 hr = mono_test_marshal_safearray_in_out_byref_3dim_vt_bstr(safearray4);
5683 return hr;
5686 LIBTEST_API int STDCALL
5687 mono_test_marshal_safearray_in_ccw(MonoComObject *pUnk)
5689 SAFEARRAY *array;
5690 VARIANT var;
5691 long index;
5692 int ret;
5694 array = SafeArrayCreateVector(VT_VARIANT, 0, 2);
5696 var.vt = VT_BSTR;
5697 var.bstrVal = marshal_bstr_alloc("Test");
5698 index = 0;
5699 SafeArrayPutElement(array, &index, &var);
5701 var.vt = VT_I4;
5702 var.intVal = 2345;
5703 index = 1;
5704 SafeArrayPutElement(array, &index, &var);
5706 ret = pUnk->vtbl->ArrayIn (pUnk, (void *)array);
5707 if (!ret)
5708 ret = pUnk->vtbl->ArrayIn2 (pUnk, (void *)array);
5709 if (!ret)
5710 ret = pUnk->vtbl->ArrayIn3 (pUnk, (void *)array);
5712 SafeArrayDestroy(array);
5714 return ret;
5717 #endif
5719 static int call_managed_res;
5721 static void
5722 call_managed (gpointer arg)
5724 SimpleDelegate del = (SimpleDelegate)arg;
5726 call_managed_res = del (42);
5729 LIBTEST_API int STDCALL
5730 mono_test_marshal_thread_attach (SimpleDelegate del)
5732 #ifdef WIN32
5733 return 43;
5734 #else
5735 int res;
5736 pthread_t t;
5738 res = pthread_create (&t, NULL, (gpointer (*)(gpointer))call_managed, (gpointer)del);
5739 g_assert (res == 0);
5740 pthread_join (t, NULL);
5742 return call_managed_res;
5743 #endif
5746 typedef struct {
5747 char arr [4 * 1024];
5748 } LargeStruct;
5750 typedef int (STDCALL *LargeStructDelegate) (LargeStruct *s);
5752 static void
5753 call_managed_large_vt (gpointer arg)
5755 LargeStructDelegate del = (LargeStructDelegate)arg;
5756 LargeStruct s;
5758 call_managed_res = del (&s);
5761 LIBTEST_API int STDCALL
5762 mono_test_marshal_thread_attach_large_vt (SimpleDelegate del)
5764 #ifdef WIN32
5765 return 43;
5766 #else
5767 int res;
5768 pthread_t t;
5770 res = pthread_create (&t, NULL, (gpointer (*)(gpointer))call_managed_large_vt, (gpointer)del);
5771 g_assert (res == 0);
5772 pthread_join (t, NULL);
5774 return call_managed_res;
5775 #endif
5778 typedef int (STDCALL *Callback) (void);
5780 static Callback callback;
5782 LIBTEST_API void STDCALL
5783 mono_test_marshal_set_callback (Callback cb)
5785 callback = cb;
5788 LIBTEST_API int STDCALL
5789 mono_test_marshal_call_callback (void)
5791 return callback ();
5794 LIBTEST_API int STDCALL
5795 mono_test_marshal_lpstr (char *str)
5797 return strcmp ("ABC", str);
5800 LIBTEST_API int STDCALL
5801 mono_test_marshal_lpwstr (gunichar2 *str)
5803 char *s;
5804 int res;
5806 s = g_utf16_to_utf8 (str, -1, NULL, NULL, NULL);
5807 res = strcmp ("ABC", s);
5808 g_free (s);
5810 return res;
5813 LIBTEST_API char* STDCALL
5814 mono_test_marshal_return_lpstr (void)
5816 char *res = (char *)marshal_alloc (4);
5817 strcpy (res, "XYZ");
5818 return res;
5821 LIBTEST_API gunichar2* STDCALL
5822 mono_test_marshal_return_lpwstr (void)
5824 gunichar2 *res = (gunichar2 *)marshal_alloc (8);
5825 gunichar2* tmp = g_utf8_to_utf16 ("XYZ", -1, NULL, NULL, NULL);
5827 memcpy (res, tmp, 8);
5828 g_free (tmp);
5830 return res;
5833 typedef
5834 #if defined (HOST_WIN32) && defined (HOST_X86) && defined (__GNUC__)
5835 // Workaround gcc ABI bug. It returns the struct in ST0 instead of edx:eax.
5836 // Mono and Visual C++ agree.
5837 union
5838 #else
5839 struct
5840 #endif
5842 double d;
5843 } SingleDoubleStruct;
5845 LIBTEST_API SingleDoubleStruct STDCALL
5846 mono_test_marshal_return_single_double_struct (void)
5848 SingleDoubleStruct res = {3.0};
5849 return res;
5852 LIBTEST_API int STDCALL
5853 mono_test_has_thiscall_globals (void)
5855 // Visual C++ does not accept __thiscall on global functions, only
5856 // member function and function pointers. Gcc accepts it also on global functions.
5857 #if defined (HOST_X86) && defined (HOST_WIN32) && !defined (_MSC_VER)
5858 return 1;
5859 #else
5860 return 0;
5861 #endif
5864 LIBTEST_API int STDCALL
5865 mono_test_has_thiscall_pointers (void)
5867 #if defined (HOST_X86) && defined (HOST_WIN32)
5868 return 1;
5869 #else
5870 return 0;
5871 #endif
5874 LIBTEST_API int
5875 #ifndef _MSC_VER
5876 __thiscall
5877 #endif
5878 _mono_test_native_thiscall1 (int arg)
5880 return arg;
5883 LIBTEST_API int
5884 #ifndef _MSC_VER
5885 __thiscall
5886 #endif
5887 _mono_test_native_thiscall2 (int arg, int arg2)
5889 return arg + (arg2^1);
5892 LIBTEST_API int
5893 #ifndef _MSC_VER
5894 __thiscall
5895 #endif
5896 _mono_test_native_thiscall3 (int arg, int arg2, int arg3)
5898 return arg + (arg2^1) + (arg3^2);
5901 typedef int (
5902 #ifndef _MSC_VER
5903 __thiscall
5904 #endif
5905 *ThiscallFunction)(int arg, int arg2);
5907 LIBTEST_API ThiscallFunction STDCALL
5908 mono_test_get_native_thiscall2 (void)
5910 return _mono_test_native_thiscall2;
5913 LIBTEST_API int STDCALL
5914 _mono_test_managed_thiscall1 (int (__thiscall*fn)(int), int arg)
5916 return fn(arg);
5919 LIBTEST_API int STDCALL
5920 _mono_test_managed_thiscall2 (int (__thiscall*fn)(int,int), int arg, int arg2)
5922 return fn(arg, arg2);
5925 LIBTEST_API int STDCALL
5926 _mono_test_managed_thiscall3 (int (__thiscall*fn)(int,int,int), int arg, int arg2, int arg3)
5928 return fn(arg, arg2, arg3);
5931 typedef struct {
5932 char f1;
5933 } sbyte1;
5935 LIBTEST_API sbyte1 STDCALL
5936 mono_return_sbyte1 (sbyte1 s1, int addend) {
5937 if (s1.f1 != 1) {
5938 fprintf(stderr, "mono_return_sbyte1 s1.f1: got %d but expected %d\n", s1.f1, 1);
5940 s1.f1+=addend;
5941 return s1;
5944 typedef struct {
5945 char f1,f2;
5946 } sbyte2;
5948 LIBTEST_API sbyte2 STDCALL
5949 mono_return_sbyte2 (sbyte2 s2, int addend) {
5950 if (s2.f1 != 1) {
5951 fprintf(stderr, "mono_return_sbyte2 s2.f1: got %d but expected %d\n", s2.f1, 1);
5953 if (s2.f2 != 2) {
5954 fprintf(stderr, "mono_return_sbyte2 s2.f2: got %d but expected %d\n", s2.f2, 2);
5956 s2.f1+=addend; s2.f2+=addend;
5957 return s2;
5960 typedef struct {
5961 char f1,f2,f3;
5962 } sbyte3;
5964 LIBTEST_API sbyte3 STDCALL
5965 mono_return_sbyte3 (sbyte3 s3, int addend) {
5966 if (s3.f1 != 1) {
5967 fprintf(stderr, "mono_return_sbyte3 s3.f1: got %d but expected %d\n", s3.f1, 1);
5969 if (s3.f2 != 2) {
5970 fprintf(stderr, "mono_return_sbyte3 s3.f2: got %d but expected %d\n", s3.f2, 2);
5972 if (s3.f3 != 3) {
5973 fprintf(stderr, "mono_return_sbyte3 s3.f3: got %d but expected %d\n", s3.f3, 3);
5975 s3.f1+=addend; s3.f2+=addend; s3.f3+=addend;
5976 return s3;
5979 typedef struct {
5980 char f1,f2,f3,f4;
5981 } sbyte4;
5983 LIBTEST_API sbyte4 STDCALL
5984 mono_return_sbyte4 (sbyte4 s4, int addend) {
5985 if (s4.f1 != 1) {
5986 fprintf(stderr, "mono_return_sbyte4 s4.f1: got %d but expected %d\n", s4.f1, 1);
5988 if (s4.f2 != 2) {
5989 fprintf(stderr, "mono_return_sbyte4 s4.f2: got %d but expected %d\n", s4.f2, 2);
5991 if (s4.f3 != 3) {
5992 fprintf(stderr, "mono_return_sbyte4 s4.f3: got %d but expected %d\n", s4.f3, 3);
5994 if (s4.f4 != 4) {
5995 fprintf(stderr, "mono_return_sbyte4 s4.f4: got %d but expected %d\n", s4.f4, 4);
5997 s4.f1+=addend; s4.f2+=addend; s4.f3+=addend; s4.f4+=addend;
5998 return s4;
6001 typedef struct {
6002 char f1,f2,f3,f4,f5;
6003 } sbyte5;
6005 LIBTEST_API sbyte5 STDCALL
6006 mono_return_sbyte5 (sbyte5 s5, int addend) {
6007 if (s5.f1 != 1) {
6008 fprintf(stderr, "mono_return_sbyte5 s5.f1: got %d but expected %d\n", s5.f1, 1);
6010 if (s5.f2 != 2) {
6011 fprintf(stderr, "mono_return_sbyte5 s5.f2: got %d but expected %d\n", s5.f2, 2);
6013 if (s5.f3 != 3) {
6014 fprintf(stderr, "mono_return_sbyte5 s5.f3: got %d but expected %d\n", s5.f3, 3);
6016 if (s5.f4 != 4) {
6017 fprintf(stderr, "mono_return_sbyte5 s5.f4: got %d but expected %d\n", s5.f4, 4);
6019 if (s5.f5 != 5) {
6020 fprintf(stderr, "mono_return_sbyte5 s5.f5: got %d but expected %d\n", s5.f5, 5);
6022 s5.f1+=addend; s5.f2+=addend; s5.f3+=addend; s5.f4+=addend; s5.f5+=addend;
6023 return s5;
6026 typedef struct {
6027 char f1,f2,f3,f4,f5,f6;
6028 } sbyte6;
6030 LIBTEST_API sbyte6 STDCALL
6031 mono_return_sbyte6 (sbyte6 s6, int addend) {
6032 if (s6.f1 != 1) {
6033 fprintf(stderr, "mono_return_sbyte6 s6.f1: got %d but expected %d\n", s6.f1, 1);
6035 if (s6.f2 != 2) {
6036 fprintf(stderr, "mono_return_sbyte6 s6.f2: got %d but expected %d\n", s6.f2, 2);
6038 if (s6.f3 != 3) {
6039 fprintf(stderr, "mono_return_sbyte6 s6.f3: got %d but expected %d\n", s6.f3, 3);
6041 if (s6.f4 != 4) {
6042 fprintf(stderr, "mono_return_sbyte6 s6.f4: got %d but expected %d\n", s6.f4, 4);
6044 if (s6.f5 != 5) {
6045 fprintf(stderr, "mono_return_sbyte6 s6.f5: got %d but expected %d\n", s6.f5, 5);
6047 if (s6.f6 != 6) {
6048 fprintf(stderr, "mono_return_sbyte6 s6.f6: got %d but expected %d\n", s6.f6, 6);
6050 s6.f1+=addend; s6.f2+=addend; s6.f3+=addend; s6.f4+=addend; s6.f5+=addend; s6.f6+=addend;
6051 return s6;
6054 typedef struct {
6055 char f1,f2,f3,f4,f5,f6,f7;
6056 } sbyte7;
6058 LIBTEST_API sbyte7 STDCALL
6059 mono_return_sbyte7 (sbyte7 s7, int addend) {
6060 if (s7.f1 != 1) {
6061 fprintf(stderr, "mono_return_sbyte7 s7.f1: got %d but expected %d\n", s7.f1, 1);
6063 if (s7.f2 != 2) {
6064 fprintf(stderr, "mono_return_sbyte7 s7.f2: got %d but expected %d\n", s7.f2, 2);
6066 if (s7.f3 != 3) {
6067 fprintf(stderr, "mono_return_sbyte7 s7.f3: got %d but expected %d\n", s7.f3, 3);
6069 if (s7.f4 != 4) {
6070 fprintf(stderr, "mono_return_sbyte7 s7.f4: got %d but expected %d\n", s7.f4, 4);
6072 if (s7.f5 != 5) {
6073 fprintf(stderr, "mono_return_sbyte7 s7.f5: got %d but expected %d\n", s7.f5, 5);
6075 if (s7.f6 != 6) {
6076 fprintf(stderr, "mono_return_sbyte7 s7.f6: got %d but expected %d\n", s7.f6, 6);
6078 if (s7.f7 != 7) {
6079 fprintf(stderr, "mono_return_sbyte7 s7.f7: got %d but expected %d\n", s7.f7, 7);
6081 s7.f1+=addend; s7.f2+=addend; s7.f3+=addend; s7.f4+=addend; s7.f5+=addend; s7.f6+=addend; s7.f7+=addend;
6082 return s7;
6085 typedef struct {
6086 char f1,f2,f3,f4,f5,f6,f7,f8;
6087 } sbyte8;
6089 LIBTEST_API sbyte8 STDCALL
6090 mono_return_sbyte8 (sbyte8 s8, int addend) {
6091 if (s8.f1 != 1) {
6092 fprintf(stderr, "mono_return_sbyte8 s8.f1: got %d but expected %d\n", s8.f1, 1);
6094 if (s8.f2 != 2) {
6095 fprintf(stderr, "mono_return_sbyte8 s8.f2: got %d but expected %d\n", s8.f2, 2);
6097 if (s8.f3 != 3) {
6098 fprintf(stderr, "mono_return_sbyte8 s8.f3: got %d but expected %d\n", s8.f3, 3);
6100 if (s8.f4 != 4) {
6101 fprintf(stderr, "mono_return_sbyte8 s8.f4: got %d but expected %d\n", s8.f4, 4);
6103 if (s8.f5 != 5) {
6104 fprintf(stderr, "mono_return_sbyte8 s8.f5: got %d but expected %d\n", s8.f5, 5);
6106 if (s8.f6 != 6) {
6107 fprintf(stderr, "mono_return_sbyte8 s8.f6: got %d but expected %d\n", s8.f6, 6);
6109 if (s8.f7 != 7) {
6110 fprintf(stderr, "mono_return_sbyte8 s8.f7: got %d but expected %d\n", s8.f7, 7);
6112 if (s8.f8 != 8) {
6113 fprintf(stderr, "mono_return_sbyte8 s8.f8: got %d but expected %d\n", s8.f8, 8);
6115 s8.f1+=addend; s8.f2+=addend; s8.f3+=addend; s8.f4+=addend; s8.f5+=addend; s8.f6+=addend; s8.f7+=addend; s8.f8+=addend;
6116 return s8;
6119 typedef struct {
6120 char f1,f2,f3,f4,f5,f6,f7,f8,f9;
6121 } sbyte9;
6123 LIBTEST_API sbyte9 STDCALL
6124 mono_return_sbyte9 (sbyte9 s9, int addend) {
6125 if (s9.f1 != 1) {
6126 fprintf(stderr, "mono_return_sbyte9 s9.f1: got %d but expected %d\n", s9.f1, 1);
6128 if (s9.f2 != 2) {
6129 fprintf(stderr, "mono_return_sbyte9 s9.f2: got %d but expected %d\n", s9.f2, 2);
6131 if (s9.f3 != 3) {
6132 fprintf(stderr, "mono_return_sbyte9 s9.f3: got %d but expected %d\n", s9.f3, 3);
6134 if (s9.f4 != 4) {
6135 fprintf(stderr, "mono_return_sbyte9 s9.f4: got %d but expected %d\n", s9.f4, 4);
6137 if (s9.f5 != 5) {
6138 fprintf(stderr, "mono_return_sbyte9 s9.f5: got %d but expected %d\n", s9.f5, 5);
6140 if (s9.f6 != 6) {
6141 fprintf(stderr, "mono_return_sbyte9 s9.f6: got %d but expected %d\n", s9.f6, 6);
6143 if (s9.f7 != 7) {
6144 fprintf(stderr, "mono_return_sbyte9 s9.f7: got %d but expected %d\n", s9.f7, 7);
6146 if (s9.f8 != 8) {
6147 fprintf(stderr, "mono_return_sbyte9 s9.f8: got %d but expected %d\n", s9.f8, 8);
6149 if (s9.f9 != 9) {
6150 fprintf(stderr, "mono_return_sbyte9 s9.f9: got %d but expected %d\n", s9.f9, 9);
6152 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;
6153 return s9;
6156 typedef struct {
6157 char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10;
6158 } sbyte10;
6160 LIBTEST_API sbyte10 STDCALL
6161 mono_return_sbyte10 (sbyte10 s10, int addend) {
6162 if (s10.f1 != 1) {
6163 fprintf(stderr, "mono_return_sbyte10 s10.f1: got %d but expected %d\n", s10.f1, 1);
6165 if (s10.f2 != 2) {
6166 fprintf(stderr, "mono_return_sbyte10 s10.f2: got %d but expected %d\n", s10.f2, 2);
6168 if (s10.f3 != 3) {
6169 fprintf(stderr, "mono_return_sbyte10 s10.f3: got %d but expected %d\n", s10.f3, 3);
6171 if (s10.f4 != 4) {
6172 fprintf(stderr, "mono_return_sbyte10 s10.f4: got %d but expected %d\n", s10.f4, 4);
6174 if (s10.f5 != 5) {
6175 fprintf(stderr, "mono_return_sbyte10 s10.f5: got %d but expected %d\n", s10.f5, 5);
6177 if (s10.f6 != 6) {
6178 fprintf(stderr, "mono_return_sbyte10 s10.f6: got %d but expected %d\n", s10.f6, 6);
6180 if (s10.f7 != 7) {
6181 fprintf(stderr, "mono_return_sbyte10 s10.f7: got %d but expected %d\n", s10.f7, 7);
6183 if (s10.f8 != 8) {
6184 fprintf(stderr, "mono_return_sbyte10 s10.f8: got %d but expected %d\n", s10.f8, 8);
6186 if (s10.f9 != 9) {
6187 fprintf(stderr, "mono_return_sbyte10 s10.f9: got %d but expected %d\n", s10.f9, 9);
6189 if (s10.f10 != 10) {
6190 fprintf(stderr, "mono_return_sbyte10 s10.f10: got %d but expected %d\n", s10.f10, 10);
6192 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;
6193 return s10;
6196 typedef struct {
6197 char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11;
6198 } sbyte11;
6200 LIBTEST_API sbyte11 STDCALL
6201 mono_return_sbyte11 (sbyte11 s11, int addend) {
6202 if (s11.f1 != 1) {
6203 fprintf(stderr, "mono_return_sbyte11 s11.f1: got %d but expected %d\n", s11.f1, 1);
6205 if (s11.f2 != 2) {
6206 fprintf(stderr, "mono_return_sbyte11 s11.f2: got %d but expected %d\n", s11.f2, 2);
6208 if (s11.f3 != 3) {
6209 fprintf(stderr, "mono_return_sbyte11 s11.f3: got %d but expected %d\n", s11.f3, 3);
6211 if (s11.f4 != 4) {
6212 fprintf(stderr, "mono_return_sbyte11 s11.f4: got %d but expected %d\n", s11.f4, 4);
6214 if (s11.f5 != 5) {
6215 fprintf(stderr, "mono_return_sbyte11 s11.f5: got %d but expected %d\n", s11.f5, 5);
6217 if (s11.f6 != 6) {
6218 fprintf(stderr, "mono_return_sbyte11 s11.f6: got %d but expected %d\n", s11.f6, 6);
6220 if (s11.f7 != 7) {
6221 fprintf(stderr, "mono_return_sbyte11 s11.f7: got %d but expected %d\n", s11.f7, 7);
6223 if (s11.f8 != 8) {
6224 fprintf(stderr, "mono_return_sbyte11 s11.f8: got %d but expected %d\n", s11.f8, 8);
6226 if (s11.f9 != 9) {
6227 fprintf(stderr, "mono_return_sbyte11 s11.f9: got %d but expected %d\n", s11.f9, 9);
6229 if (s11.f10 != 10) {
6230 fprintf(stderr, "mono_return_sbyte11 s11.f10: got %d but expected %d\n", s11.f10, 10);
6232 if (s11.f11 != 11) {
6233 fprintf(stderr, "mono_return_sbyte11 s11.f11: got %d but expected %d\n", s11.f11, 11);
6235 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;
6236 return s11;
6239 typedef struct {
6240 char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12;
6241 } sbyte12;
6243 LIBTEST_API sbyte12 STDCALL
6244 mono_return_sbyte12 (sbyte12 s12, int addend) {
6245 if (s12.f1 != 1) {
6246 fprintf(stderr, "mono_return_sbyte12 s12.f1: got %d but expected %d\n", s12.f1, 1);
6248 if (s12.f2 != 2) {
6249 fprintf(stderr, "mono_return_sbyte12 s12.f2: got %d but expected %d\n", s12.f2, 2);
6251 if (s12.f3 != 3) {
6252 fprintf(stderr, "mono_return_sbyte12 s12.f3: got %d but expected %d\n", s12.f3, 3);
6254 if (s12.f4 != 4) {
6255 fprintf(stderr, "mono_return_sbyte12 s12.f4: got %d but expected %d\n", s12.f4, 4);
6257 if (s12.f5 != 5) {
6258 fprintf(stderr, "mono_return_sbyte12 s12.f5: got %d but expected %d\n", s12.f5, 5);
6260 if (s12.f6 != 6) {
6261 fprintf(stderr, "mono_return_sbyte12 s12.f6: got %d but expected %d\n", s12.f6, 6);
6263 if (s12.f7 != 7) {
6264 fprintf(stderr, "mono_return_sbyte12 s12.f7: got %d but expected %d\n", s12.f7, 7);
6266 if (s12.f8 != 8) {
6267 fprintf(stderr, "mono_return_sbyte12 s12.f8: got %d but expected %d\n", s12.f8, 8);
6269 if (s12.f9 != 9) {
6270 fprintf(stderr, "mono_return_sbyte12 s12.f9: got %d but expected %d\n", s12.f9, 9);
6272 if (s12.f10 != 10) {
6273 fprintf(stderr, "mono_return_sbyte12 s12.f10: got %d but expected %d\n", s12.f10, 10);
6275 if (s12.f11 != 11) {
6276 fprintf(stderr, "mono_return_sbyte12 s12.f11: got %d but expected %d\n", s12.f11, 11);
6278 if (s12.f12 != 12) {
6279 fprintf(stderr, "mono_return_sbyte12 s12.f12: got %d but expected %d\n", s12.f12, 12);
6281 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;
6282 return s12;
6285 typedef struct {
6286 char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13;
6287 } sbyte13;
6289 LIBTEST_API sbyte13 STDCALL
6290 mono_return_sbyte13 (sbyte13 s13, int addend) {
6291 if (s13.f1 != 1) {
6292 fprintf(stderr, "mono_return_sbyte13 s13.f1: got %d but expected %d\n", s13.f1, 1);
6294 if (s13.f2 != 2) {
6295 fprintf(stderr, "mono_return_sbyte13 s13.f2: got %d but expected %d\n", s13.f2, 2);
6297 if (s13.f3 != 3) {
6298 fprintf(stderr, "mono_return_sbyte13 s13.f3: got %d but expected %d\n", s13.f3, 3);
6300 if (s13.f4 != 4) {
6301 fprintf(stderr, "mono_return_sbyte13 s13.f4: got %d but expected %d\n", s13.f4, 4);
6303 if (s13.f5 != 5) {
6304 fprintf(stderr, "mono_return_sbyte13 s13.f5: got %d but expected %d\n", s13.f5, 5);
6306 if (s13.f6 != 6) {
6307 fprintf(stderr, "mono_return_sbyte13 s13.f6: got %d but expected %d\n", s13.f6, 6);
6309 if (s13.f7 != 7) {
6310 fprintf(stderr, "mono_return_sbyte13 s13.f7: got %d but expected %d\n", s13.f7, 7);
6312 if (s13.f8 != 8) {
6313 fprintf(stderr, "mono_return_sbyte13 s13.f8: got %d but expected %d\n", s13.f8, 8);
6315 if (s13.f9 != 9) {
6316 fprintf(stderr, "mono_return_sbyte13 s13.f9: got %d but expected %d\n", s13.f9, 9);
6318 if (s13.f10 != 10) {
6319 fprintf(stderr, "mono_return_sbyte13 s13.f10: got %d but expected %d\n", s13.f10, 10);
6321 if (s13.f11 != 11) {
6322 fprintf(stderr, "mono_return_sbyte13 s13.f11: got %d but expected %d\n", s13.f11, 11);
6324 if (s13.f12 != 12) {
6325 fprintf(stderr, "mono_return_sbyte13 s13.f12: got %d but expected %d\n", s13.f12, 12);
6327 if (s13.f13 != 13) {
6328 fprintf(stderr, "mono_return_sbyte13 s13.f13: got %d but expected %d\n", s13.f13, 13);
6330 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;
6331 return s13;
6334 typedef struct {
6335 char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14;
6336 } sbyte14;
6338 LIBTEST_API sbyte14 STDCALL
6339 mono_return_sbyte14 (sbyte14 s14, int addend) {
6340 if (s14.f1 != 1) {
6341 fprintf(stderr, "mono_return_sbyte14 s14.f1: got %d but expected %d\n", s14.f1, 1);
6343 if (s14.f2 != 2) {
6344 fprintf(stderr, "mono_return_sbyte14 s14.f2: got %d but expected %d\n", s14.f2, 2);
6346 if (s14.f3 != 3) {
6347 fprintf(stderr, "mono_return_sbyte14 s14.f3: got %d but expected %d\n", s14.f3, 3);
6349 if (s14.f4 != 4) {
6350 fprintf(stderr, "mono_return_sbyte14 s14.f4: got %d but expected %d\n", s14.f4, 4);
6352 if (s14.f5 != 5) {
6353 fprintf(stderr, "mono_return_sbyte14 s14.f5: got %d but expected %d\n", s14.f5, 5);
6355 if (s14.f6 != 6) {
6356 fprintf(stderr, "mono_return_sbyte14 s14.f6: got %d but expected %d\n", s14.f6, 6);
6358 if (s14.f7 != 7) {
6359 fprintf(stderr, "mono_return_sbyte14 s14.f7: got %d but expected %d\n", s14.f7, 7);
6361 if (s14.f8 != 8) {
6362 fprintf(stderr, "mono_return_sbyte14 s14.f8: got %d but expected %d\n", s14.f8, 8);
6364 if (s14.f9 != 9) {
6365 fprintf(stderr, "mono_return_sbyte14 s14.f9: got %d but expected %d\n", s14.f9, 9);
6367 if (s14.f10 != 10) {
6368 fprintf(stderr, "mono_return_sbyte14 s14.f10: got %d but expected %d\n", s14.f10, 10);
6370 if (s14.f11 != 11) {
6371 fprintf(stderr, "mono_return_sbyte14 s14.f11: got %d but expected %d\n", s14.f11, 11);
6373 if (s14.f12 != 12) {
6374 fprintf(stderr, "mono_return_sbyte14 s14.f12: got %d but expected %d\n", s14.f12, 12);
6376 if (s14.f13 != 13) {
6377 fprintf(stderr, "mono_return_sbyte14 s14.f13: got %d but expected %d\n", s14.f13, 13);
6379 if (s14.f14 != 14) {
6380 fprintf(stderr, "mono_return_sbyte14 s14.f14: got %d but expected %d\n", s14.f14, 14);
6382 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;
6383 return s14;
6386 typedef struct {
6387 char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15;
6388 } sbyte15;
6390 LIBTEST_API sbyte15 STDCALL
6391 mono_return_sbyte15 (sbyte15 s15, int addend) {
6392 if (s15.f1 != 1) {
6393 fprintf(stderr, "mono_return_sbyte15 s15.f1: got %d but expected %d\n", s15.f1, 1);
6395 if (s15.f2 != 2) {
6396 fprintf(stderr, "mono_return_sbyte15 s15.f2: got %d but expected %d\n", s15.f2, 2);
6398 if (s15.f3 != 3) {
6399 fprintf(stderr, "mono_return_sbyte15 s15.f3: got %d but expected %d\n", s15.f3, 3);
6401 if (s15.f4 != 4) {
6402 fprintf(stderr, "mono_return_sbyte15 s15.f4: got %d but expected %d\n", s15.f4, 4);
6404 if (s15.f5 != 5) {
6405 fprintf(stderr, "mono_return_sbyte15 s15.f5: got %d but expected %d\n", s15.f5, 5);
6407 if (s15.f6 != 6) {
6408 fprintf(stderr, "mono_return_sbyte15 s15.f6: got %d but expected %d\n", s15.f6, 6);
6410 if (s15.f7 != 7) {
6411 fprintf(stderr, "mono_return_sbyte15 s15.f7: got %d but expected %d\n", s15.f7, 7);
6413 if (s15.f8 != 8) {
6414 fprintf(stderr, "mono_return_sbyte15 s15.f8: got %d but expected %d\n", s15.f8, 8);
6416 if (s15.f9 != 9) {
6417 fprintf(stderr, "mono_return_sbyte15 s15.f9: got %d but expected %d\n", s15.f9, 9);
6419 if (s15.f10 != 10) {
6420 fprintf(stderr, "mono_return_sbyte15 s15.f10: got %d but expected %d\n", s15.f10, 10);
6422 if (s15.f11 != 11) {
6423 fprintf(stderr, "mono_return_sbyte15 s15.f11: got %d but expected %d\n", s15.f11, 11);
6425 if (s15.f12 != 12) {
6426 fprintf(stderr, "mono_return_sbyte15 s15.f12: got %d but expected %d\n", s15.f12, 12);
6428 if (s15.f13 != 13) {
6429 fprintf(stderr, "mono_return_sbyte15 s15.f13: got %d but expected %d\n", s15.f13, 13);
6431 if (s15.f14 != 14) {
6432 fprintf(stderr, "mono_return_sbyte15 s15.f14: got %d but expected %d\n", s15.f14, 14);
6434 if (s15.f15 != 15) {
6435 fprintf(stderr, "mono_return_sbyte15 s15.f15: got %d but expected %d\n", s15.f15, 15);
6437 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;
6438 return s15;
6441 typedef struct {
6442 char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16;
6443 } sbyte16;
6445 LIBTEST_API sbyte16 STDCALL
6446 mono_return_sbyte16 (sbyte16 s16, int addend) {
6447 if (s16.f1 != 1) {
6448 fprintf(stderr, "mono_return_sbyte16 s16.f1: got %d but expected %d\n", s16.f1, 1);
6450 if (s16.f2 != 2) {
6451 fprintf(stderr, "mono_return_sbyte16 s16.f2: got %d but expected %d\n", s16.f2, 2);
6453 if (s16.f3 != 3) {
6454 fprintf(stderr, "mono_return_sbyte16 s16.f3: got %d but expected %d\n", s16.f3, 3);
6456 if (s16.f4 != 4) {
6457 fprintf(stderr, "mono_return_sbyte16 s16.f4: got %d but expected %d\n", s16.f4, 4);
6459 if (s16.f5 != 5) {
6460 fprintf(stderr, "mono_return_sbyte16 s16.f5: got %d but expected %d\n", s16.f5, 5);
6462 if (s16.f6 != 6) {
6463 fprintf(stderr, "mono_return_sbyte16 s16.f6: got %d but expected %d\n", s16.f6, 6);
6465 if (s16.f7 != 7) {
6466 fprintf(stderr, "mono_return_sbyte16 s16.f7: got %d but expected %d\n", s16.f7, 7);
6468 if (s16.f8 != 8) {
6469 fprintf(stderr, "mono_return_sbyte16 s16.f8: got %d but expected %d\n", s16.f8, 8);
6471 if (s16.f9 != 9) {
6472 fprintf(stderr, "mono_return_sbyte16 s16.f9: got %d but expected %d\n", s16.f9, 9);
6474 if (s16.f10 != 10) {
6475 fprintf(stderr, "mono_return_sbyte16 s16.f10: got %d but expected %d\n", s16.f10, 10);
6477 if (s16.f11 != 11) {
6478 fprintf(stderr, "mono_return_sbyte16 s16.f11: got %d but expected %d\n", s16.f11, 11);
6480 if (s16.f12 != 12) {
6481 fprintf(stderr, "mono_return_sbyte16 s16.f12: got %d but expected %d\n", s16.f12, 12);
6483 if (s16.f13 != 13) {
6484 fprintf(stderr, "mono_return_sbyte16 s16.f13: got %d but expected %d\n", s16.f13, 13);
6486 if (s16.f14 != 14) {
6487 fprintf(stderr, "mono_return_sbyte16 s16.f14: got %d but expected %d\n", s16.f14, 14);
6489 if (s16.f15 != 15) {
6490 fprintf(stderr, "mono_return_sbyte16 s16.f15: got %d but expected %d\n", s16.f15, 15);
6492 if (s16.f16 != 16) {
6493 fprintf(stderr, "mono_return_sbyte16 s16.f16: got %d but expected %d\n", s16.f16, 16);
6495 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;
6496 return s16;
6499 typedef struct {
6500 char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17;
6501 } sbyte17;
6503 LIBTEST_API sbyte17 STDCALL
6504 mono_return_sbyte17 (sbyte17 s17, int addend) {
6505 if (s17.f1 != 1) {
6506 fprintf(stderr, "mono_return_sbyte17 s17.f1: got %d but expected %d\n", s17.f1, 1);
6508 if (s17.f2 != 2) {
6509 fprintf(stderr, "mono_return_sbyte17 s17.f2: got %d but expected %d\n", s17.f2, 2);
6511 if (s17.f3 != 3) {
6512 fprintf(stderr, "mono_return_sbyte17 s17.f3: got %d but expected %d\n", s17.f3, 3);
6514 if (s17.f4 != 4) {
6515 fprintf(stderr, "mono_return_sbyte17 s17.f4: got %d but expected %d\n", s17.f4, 4);
6517 if (s17.f5 != 5) {
6518 fprintf(stderr, "mono_return_sbyte17 s17.f5: got %d but expected %d\n", s17.f5, 5);
6520 if (s17.f6 != 6) {
6521 fprintf(stderr, "mono_return_sbyte17 s17.f6: got %d but expected %d\n", s17.f6, 6);
6523 if (s17.f7 != 7) {
6524 fprintf(stderr, "mono_return_sbyte17 s17.f7: got %d but expected %d\n", s17.f7, 7);
6526 if (s17.f8 != 8) {
6527 fprintf(stderr, "mono_return_sbyte17 s17.f8: got %d but expected %d\n", s17.f8, 8);
6529 if (s17.f9 != 9) {
6530 fprintf(stderr, "mono_return_sbyte17 s17.f9: got %d but expected %d\n", s17.f9, 9);
6532 if (s17.f10 != 10) {
6533 fprintf(stderr, "mono_return_sbyte17 s17.f10: got %d but expected %d\n", s17.f10, 10);
6535 if (s17.f11 != 11) {
6536 fprintf(stderr, "mono_return_sbyte17 s17.f11: got %d but expected %d\n", s17.f11, 11);
6538 if (s17.f12 != 12) {
6539 fprintf(stderr, "mono_return_sbyte17 s17.f12: got %d but expected %d\n", s17.f12, 12);
6541 if (s17.f13 != 13) {
6542 fprintf(stderr, "mono_return_sbyte17 s17.f13: got %d but expected %d\n", s17.f13, 13);
6544 if (s17.f14 != 14) {
6545 fprintf(stderr, "mono_return_sbyte17 s17.f14: got %d but expected %d\n", s17.f14, 14);
6547 if (s17.f15 != 15) {
6548 fprintf(stderr, "mono_return_sbyte17 s17.f15: got %d but expected %d\n", s17.f15, 15);
6550 if (s17.f16 != 16) {
6551 fprintf(stderr, "mono_return_sbyte17 s17.f16: got %d but expected %d\n", s17.f16, 16);
6553 if (s17.f17 != 17) {
6554 fprintf(stderr, "mono_return_sbyte17 s17.f17: got %d but expected %d\n", s17.f17, 17);
6556 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;
6557 return s17;
6560 typedef struct {
6561 struct {
6562 char f1;
6563 } nested1;
6564 char f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15;
6565 struct {
6566 char f16;
6567 } nested2;
6568 } sbyte16_nested;
6570 LIBTEST_API sbyte16_nested STDCALL
6571 mono_return_sbyte16_nested (sbyte16_nested sn16, int addend) {
6572 if (sn16.nested1.f1 != 1) {
6573 fprintf(stderr, "mono_return_sbyte16_nested sn16.nested1.f1: got %d but expected %d\n", sn16.nested1.f1, 1);
6575 if (sn16.f2 != 2) {
6576 fprintf(stderr, "mono_return_sbyte16_nested sn16.f2: got %d but expected %d\n", sn16.f2, 2);
6578 if (sn16.f3 != 3) {
6579 fprintf(stderr, "mono_return_sbyte16_nested sn16.f3: got %d but expected %d\n", sn16.f3, 3);
6581 if (sn16.f4 != 4) {
6582 fprintf(stderr, "mono_return_sbyte16_nested sn16.f4: got %d but expected %d\n", sn16.f4, 4);
6584 if (sn16.f5 != 5) {
6585 fprintf(stderr, "mono_return_sbyte16_nested sn16.f5: got %d but expected %d\n", sn16.f5, 5);
6587 if (sn16.f6 != 6) {
6588 fprintf(stderr, "mono_return_sbyte16_nested sn16.f6: got %d but expected %d\n", sn16.f6, 6);
6590 if (sn16.f7 != 7) {
6591 fprintf(stderr, "mono_return_sbyte16_nested sn16.f7: got %d but expected %d\n", sn16.f7, 7);
6593 if (sn16.f8 != 8) {
6594 fprintf(stderr, "mono_return_sbyte16_nested sn16.f8: got %d but expected %d\n", sn16.f8, 8);
6596 if (sn16.f9 != 9) {
6597 fprintf(stderr, "mono_return_sbyte16_nested sn16.f9: got %d but expected %d\n", sn16.f9, 9);
6599 if (sn16.f10 != 10) {
6600 fprintf(stderr, "mono_return_sbyte16_nested sn16.f10: got %d but expected %d\n", sn16.f10, 10);
6602 if (sn16.f11 != 11) {
6603 fprintf(stderr, "mono_return_sbyte16_nested sn16.f11: got %d but expected %d\n", sn16.f11, 11);
6605 if (sn16.f12 != 12) {
6606 fprintf(stderr, "mono_return_sbyte16_nested sn16.f12: got %d but expected %d\n", sn16.f12, 12);
6608 if (sn16.f13 != 13) {
6609 fprintf(stderr, "mono_return_sbyte16_nested sn16.f13: got %d but expected %d\n", sn16.f13, 13);
6611 if (sn16.f14 != 14) {
6612 fprintf(stderr, "mono_return_sbyte16_nested sn16.f14: got %d but expected %d\n", sn16.f14, 14);
6614 if (sn16.f15 != 15) {
6615 fprintf(stderr, "mono_return_sbyte16_nested sn16.f15: got %d but expected %d\n", sn16.f15, 15);
6617 if (sn16.nested2.f16 != 16) {
6618 fprintf(stderr, "mono_return_sbyte16_nested sn16.nested2.f16: got %d but expected %d\n", sn16.nested2.f16, 16);
6620 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;
6621 return sn16;
6625 typedef struct {
6626 short f1;
6627 } short1;
6629 LIBTEST_API short1 STDCALL
6630 mono_return_short1 (short1 s1, int addend) {
6631 if (s1.f1 != 1) {
6632 fprintf(stderr, "mono_return_short1 s1.f1: got %d but expected %d\n", s1.f1, 1);
6634 s1.f1+=addend;
6635 return s1;
6638 typedef struct {
6639 short f1,f2;
6640 } short2;
6642 LIBTEST_API short2 STDCALL
6643 mono_return_short2 (short2 s2, int addend) {
6644 if (s2.f1 != 1) {
6645 fprintf(stderr, "mono_return_short2 s2.f1: got %d but expected %d\n", s2.f1, 1);
6647 if (s2.f2 != 2) {
6648 fprintf(stderr, "mono_return_short2 s2.f2: got %d but expected %d\n", s2.f2, 2);
6650 s2.f1+=addend; s2.f2+=addend;
6651 return s2;
6654 typedef struct {
6655 short f1,f2,f3;
6656 } short3;
6658 LIBTEST_API short3 STDCALL
6659 mono_return_short3 (short3 s3, int addend) {
6660 if (s3.f1 != 1) {
6661 fprintf(stderr, "mono_return_short3 s3.f1: got %d but expected %d\n", s3.f1, 1);
6663 if (s3.f2 != 2) {
6664 fprintf(stderr, "mono_return_short3 s3.f2: got %d but expected %d\n", s3.f2, 2);
6666 if (s3.f3 != 3) {
6667 fprintf(stderr, "mono_return_short3 s3.f3: got %d but expected %d\n", s3.f3, 3);
6669 s3.f1+=addend; s3.f2+=addend; s3.f3+=addend;
6670 return s3;
6673 typedef struct {
6674 short f1,f2,f3,f4;
6675 } short4;
6677 LIBTEST_API short4 STDCALL
6678 mono_return_short4 (short4 s4, int addend) {
6679 if (s4.f1 != 1) {
6680 fprintf(stderr, "mono_return_short4 s4.f1: got %d but expected %d\n", s4.f1, 1);
6682 if (s4.f2 != 2) {
6683 fprintf(stderr, "mono_return_short4 s4.f2: got %d but expected %d\n", s4.f2, 2);
6685 if (s4.f3 != 3) {
6686 fprintf(stderr, "mono_return_short4 s4.f3: got %d but expected %d\n", s4.f3, 3);
6688 if (s4.f4 != 4) {
6689 fprintf(stderr, "mono_return_short4 s4.f4: got %d but expected %d\n", s4.f4, 4);
6691 s4.f1+=addend; s4.f2+=addend; s4.f3+=addend; s4.f4+=addend;
6692 return s4;
6695 typedef struct {
6696 short f1,f2,f3,f4,f5;
6697 } short5;
6699 LIBTEST_API short5 STDCALL
6700 mono_return_short5 (short5 s5, int addend) {
6701 if (s5.f1 != 1) {
6702 fprintf(stderr, "mono_return_short5 s5.f1: got %d but expected %d\n", s5.f1, 1);
6704 if (s5.f2 != 2) {
6705 fprintf(stderr, "mono_return_short5 s5.f2: got %d but expected %d\n", s5.f2, 2);
6707 if (s5.f3 != 3) {
6708 fprintf(stderr, "mono_return_short5 s5.f3: got %d but expected %d\n", s5.f3, 3);
6710 if (s5.f4 != 4) {
6711 fprintf(stderr, "mono_return_short5 s5.f4: got %d but expected %d\n", s5.f4, 4);
6713 if (s5.f5 != 5) {
6714 fprintf(stderr, "mono_return_short5 s5.f5: got %d but expected %d\n", s5.f5, 5);
6716 s5.f1+=addend; s5.f2+=addend; s5.f3+=addend; s5.f4+=addend; s5.f5+=addend;
6717 return s5;
6720 typedef struct {
6721 short f1,f2,f3,f4,f5,f6;
6722 } short6;
6724 LIBTEST_API short6 STDCALL
6725 mono_return_short6 (short6 s6, int addend) {
6726 if (s6.f1 != 1) {
6727 fprintf(stderr, "mono_return_short6 s6.f1: got %d but expected %d\n", s6.f1, 1);
6729 if (s6.f2 != 2) {
6730 fprintf(stderr, "mono_return_short6 s6.f2: got %d but expected %d\n", s6.f2, 2);
6732 if (s6.f3 != 3) {
6733 fprintf(stderr, "mono_return_short6 s6.f3: got %d but expected %d\n", s6.f3, 3);
6735 if (s6.f4 != 4) {
6736 fprintf(stderr, "mono_return_short6 s6.f4: got %d but expected %d\n", s6.f4, 4);
6738 if (s6.f5 != 5) {
6739 fprintf(stderr, "mono_return_short6 s6.f5: got %d but expected %d\n", s6.f5, 5);
6741 if (s6.f6 != 6) {
6742 fprintf(stderr, "mono_return_short6 s6.f6: got %d but expected %d\n", s6.f6, 6);
6744 s6.f1+=addend; s6.f2+=addend; s6.f3+=addend; s6.f4+=addend; s6.f5+=addend; s6.f6+=addend;
6745 return s6;
6748 typedef struct {
6749 short f1,f2,f3,f4,f5,f6,f7;
6750 } short7;
6752 LIBTEST_API short7 STDCALL
6753 mono_return_short7 (short7 s7, int addend) {
6754 if (s7.f1 != 1) {
6755 fprintf(stderr, "mono_return_short7 s7.f1: got %d but expected %d\n", s7.f1, 1);
6757 if (s7.f2 != 2) {
6758 fprintf(stderr, "mono_return_short7 s7.f2: got %d but expected %d\n", s7.f2, 2);
6760 if (s7.f3 != 3) {
6761 fprintf(stderr, "mono_return_short7 s7.f3: got %d but expected %d\n", s7.f3, 3);
6763 if (s7.f4 != 4) {
6764 fprintf(stderr, "mono_return_short7 s7.f4: got %d but expected %d\n", s7.f4, 4);
6766 if (s7.f5 != 5) {
6767 fprintf(stderr, "mono_return_short7 s7.f5: got %d but expected %d\n", s7.f5, 5);
6769 if (s7.f6 != 6) {
6770 fprintf(stderr, "mono_return_short7 s7.f6: got %d but expected %d\n", s7.f6, 6);
6772 if (s7.f7 != 7) {
6773 fprintf(stderr, "mono_return_short7 s7.f7: got %d but expected %d\n", s7.f7, 7);
6775 s7.f1+=addend; s7.f2+=addend; s7.f3+=addend; s7.f4+=addend; s7.f5+=addend; s7.f6+=addend; s7.f7+=addend;
6776 return s7;
6779 typedef struct {
6780 short f1,f2,f3,f4,f5,f6,f7,f8;
6781 } short8;
6783 LIBTEST_API short8 STDCALL
6784 mono_return_short8 (short8 s8, int addend) {
6785 if (s8.f1 != 1) {
6786 fprintf(stderr, "mono_return_short8 s8.f1: got %d but expected %d\n", s8.f1, 1);
6788 if (s8.f2 != 2) {
6789 fprintf(stderr, "mono_return_short8 s8.f2: got %d but expected %d\n", s8.f2, 2);
6791 if (s8.f3 != 3) {
6792 fprintf(stderr, "mono_return_short8 s8.f3: got %d but expected %d\n", s8.f3, 3);
6794 if (s8.f4 != 4) {
6795 fprintf(stderr, "mono_return_short8 s8.f4: got %d but expected %d\n", s8.f4, 4);
6797 if (s8.f5 != 5) {
6798 fprintf(stderr, "mono_return_short8 s8.f5: got %d but expected %d\n", s8.f5, 5);
6800 if (s8.f6 != 6) {
6801 fprintf(stderr, "mono_return_short8 s8.f6: got %d but expected %d\n", s8.f6, 6);
6803 if (s8.f7 != 7) {
6804 fprintf(stderr, "mono_return_short8 s8.f7: got %d but expected %d\n", s8.f7, 7);
6806 if (s8.f8 != 8) {
6807 fprintf(stderr, "mono_return_short8 s8.f8: got %d but expected %d\n", s8.f8, 8);
6809 s8.f1+=addend; s8.f2+=addend; s8.f3+=addend; s8.f4+=addend; s8.f5+=addend; s8.f6+=addend; s8.f7+=addend; s8.f8+=addend;
6810 return s8;
6813 typedef struct {
6814 short f1,f2,f3,f4,f5,f6,f7,f8,f9;
6815 } short9;
6817 LIBTEST_API short9 STDCALL
6818 mono_return_short9 (short9 s9, int addend) {
6819 if (s9.f1 != 1) {
6820 fprintf(stderr, "mono_return_short9 s9.f1: got %d but expected %d\n", s9.f1, 1);
6822 if (s9.f2 != 2) {
6823 fprintf(stderr, "mono_return_short9 s9.f2: got %d but expected %d\n", s9.f2, 2);
6825 if (s9.f3 != 3) {
6826 fprintf(stderr, "mono_return_short9 s9.f3: got %d but expected %d\n", s9.f3, 3);
6828 if (s9.f4 != 4) {
6829 fprintf(stderr, "mono_return_short9 s9.f4: got %d but expected %d\n", s9.f4, 4);
6831 if (s9.f5 != 5) {
6832 fprintf(stderr, "mono_return_short9 s9.f5: got %d but expected %d\n", s9.f5, 5);
6834 if (s9.f6 != 6) {
6835 fprintf(stderr, "mono_return_short9 s9.f6: got %d but expected %d\n", s9.f6, 6);
6837 if (s9.f7 != 7) {
6838 fprintf(stderr, "mono_return_short9 s9.f7: got %d but expected %d\n", s9.f7, 7);
6840 if (s9.f8 != 8) {
6841 fprintf(stderr, "mono_return_short9 s9.f8: got %d but expected %d\n", s9.f8, 8);
6843 if (s9.f9 != 9) {
6844 fprintf(stderr, "mono_return_short9 s9.f9: got %d but expected %d\n", s9.f9, 9);
6846 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;
6847 return s9;
6850 typedef struct {
6851 struct {
6852 short f1;
6853 } nested1;
6854 short f2,f3,f4,f5,f6,f7;
6855 struct {
6856 short f8;
6857 } nested2;
6858 } short8_nested;
6860 LIBTEST_API short8_nested STDCALL
6861 mono_return_short8_nested (short8_nested sn8, int addend) {
6862 if (sn8.nested1.f1 != 1) {
6863 fprintf(stderr, "mono_return_short8_nested sn8.nested1.f1: got %d but expected %d\n", sn8.nested1.f1, 1);
6865 if (sn8.f2 != 2) {
6866 fprintf(stderr, "mono_return_short8_nested sn8.f2: got %d but expected %d\n", sn8.f2, 2);
6868 if (sn8.f3 != 3) {
6869 fprintf(stderr, "mono_return_short8_nested sn8.f3: got %d but expected %d\n", sn8.f3, 3);
6871 if (sn8.f4 != 4) {
6872 fprintf(stderr, "mono_return_short8_nested sn8.f4: got %d but expected %d\n", sn8.f4, 4);
6874 if (sn8.f5 != 5) {
6875 fprintf(stderr, "mono_return_short8_nested sn8.f5: got %d but expected %d\n", sn8.f5, 5);
6877 if (sn8.f6 != 6) {
6878 fprintf(stderr, "mono_return_short8_nested sn8.f6: got %d but expected %d\n", sn8.f6, 6);
6880 if (sn8.f7 != 7) {
6881 fprintf(stderr, "mono_return_short8_nested sn8.f7: got %d but expected %d\n", sn8.f7, 7);
6883 if (sn8.nested2.f8 != 8) {
6884 fprintf(stderr, "mono_return_short8_nested sn8.nested2.f8: got %d but expected %d\n", sn8.nested2.f8, 8);
6886 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;
6887 return sn8;
6891 typedef struct {
6892 int f1;
6893 } int1;
6895 LIBTEST_API int1 STDCALL
6896 mono_return_int1 (int1 s1, int addend) {
6897 if (s1.f1 != 1) {
6898 fprintf(stderr, "mono_return_int1 s1.f1: got %d but expected %d\n", s1.f1, 1);
6900 s1.f1+=addend;
6901 return s1;
6904 typedef struct {
6905 int f1,f2;
6906 } int2;
6908 LIBTEST_API int2 STDCALL
6909 mono_return_int2 (int2 s2, int addend) {
6910 if (s2.f1 != 1) {
6911 fprintf(stderr, "mono_return_int2 s2.f1: got %d but expected %d\n", s2.f1, 1);
6913 if (s2.f2 != 2) {
6914 fprintf(stderr, "mono_return_int2 s2.f2: got %d but expected %d\n", s2.f2, 2);
6916 s2.f1+=addend; s2.f2+=addend;
6917 return s2;
6920 typedef struct {
6921 int f1,f2,f3;
6922 } int3;
6924 LIBTEST_API int3 STDCALL
6925 mono_return_int3 (int3 s3, int addend) {
6926 if (s3.f1 != 1) {
6927 fprintf(stderr, "mono_return_int3 s3.f1: got %d but expected %d\n", s3.f1, 1);
6929 if (s3.f2 != 2) {
6930 fprintf(stderr, "mono_return_int3 s3.f2: got %d but expected %d\n", s3.f2, 2);
6932 if (s3.f3 != 3) {
6933 fprintf(stderr, "mono_return_int3 s3.f3: got %d but expected %d\n", s3.f3, 3);
6935 s3.f1+=addend; s3.f2+=addend; s3.f3+=addend;
6936 return s3;
6939 typedef struct {
6940 int f1,f2,f3,f4;
6941 } int4;
6943 LIBTEST_API int4 STDCALL
6944 mono_return_int4 (int4 s4, int addend) {
6945 if (s4.f1 != 1) {
6946 fprintf(stderr, "mono_return_int4 s4.f1: got %d but expected %d\n", s4.f1, 1);
6948 if (s4.f2 != 2) {
6949 fprintf(stderr, "mono_return_int4 s4.f2: got %d but expected %d\n", s4.f2, 2);
6951 if (s4.f3 != 3) {
6952 fprintf(stderr, "mono_return_int4 s4.f3: got %d but expected %d\n", s4.f3, 3);
6954 if (s4.f4 != 4) {
6955 fprintf(stderr, "mono_return_int4 s4.f4: got %d but expected %d\n", s4.f4, 4);
6957 s4.f1+=addend; s4.f2+=addend; s4.f3+=addend; s4.f4+=addend;
6958 return s4;
6961 typedef struct {
6962 int f1,f2,f3,f4,f5;
6963 } int5;
6965 LIBTEST_API int5 STDCALL
6966 mono_return_int5 (int5 s5, int addend) {
6967 if (s5.f1 != 1) {
6968 fprintf(stderr, "mono_return_int5 s5.f1: got %d but expected %d\n", s5.f1, 1);
6970 if (s5.f2 != 2) {
6971 fprintf(stderr, "mono_return_int5 s5.f2: got %d but expected %d\n", s5.f2, 2);
6973 if (s5.f3 != 3) {
6974 fprintf(stderr, "mono_return_int5 s5.f3: got %d but expected %d\n", s5.f3, 3);
6976 if (s5.f4 != 4) {
6977 fprintf(stderr, "mono_return_int5 s5.f4: got %d but expected %d\n", s5.f4, 4);
6979 if (s5.f5 != 5) {
6980 fprintf(stderr, "mono_return_int5 s5.f5: got %d but expected %d\n", s5.f5, 5);
6982 s5.f1+=addend; s5.f2+=addend; s5.f3+=addend; s5.f4+=addend; s5.f5+=addend;
6983 return s5;
6986 typedef struct {
6987 struct {
6988 int f1;
6989 } nested1;
6990 int f2,f3;
6991 struct {
6992 int f4;
6993 } nested2;
6994 } int4_nested;
6996 LIBTEST_API int4_nested STDCALL
6997 mono_return_int4_nested (int4_nested sn4, int addend) {
6998 if (sn4.nested1.f1 != 1) {
6999 fprintf(stderr, "mono_return_int4_nested sn4.nested1.f1: got %d but expected %d\n", sn4.nested1.f1, 1);
7001 if (sn4.f2 != 2) {
7002 fprintf(stderr, "mono_return_int4_nested sn4.f2: got %d but expected %d\n", sn4.f2, 2);
7004 if (sn4.f3 != 3) {
7005 fprintf(stderr, "mono_return_int4_nested sn4.f3: got %d but expected %d\n", sn4.f3, 3);
7007 if (sn4.nested2.f4 != 4) {
7008 fprintf(stderr, "mono_return_int4_nested sn4.nested2.f4: got %d but expected %d\n", sn4.nested2.f4, 4);
7010 sn4.nested1.f1+=addend; sn4.f2+=addend; sn4.f3+=addend; sn4.nested2.f4+=addend;
7011 return sn4;
7014 typedef struct {
7015 float f1;
7016 } float1;
7018 LIBTEST_API float1 STDCALL
7019 mono_return_float1 (float1 s1, int addend) {
7020 if (s1.f1 != 1) {
7021 fprintf(stderr, "mono_return_float1 s1.f1: got %f but expected %d\n", s1.f1, 1);
7023 s1.f1+=addend;
7024 return s1;
7027 typedef struct {
7028 float f1,f2;
7029 } float2;
7031 LIBTEST_API float2 STDCALL
7032 mono_return_float2 (float2 s2, int addend) {
7033 if (s2.f1 != 1) {
7034 fprintf(stderr, "mono_return_float2 s2.f1: got %f but expected %d\n", s2.f1, 1);
7036 if (s2.f2 != 2) {
7037 fprintf(stderr, "mono_return_float2 s2.f2: got %f but expected %d\n", s2.f2, 2);
7039 s2.f1+=addend; s2.f2+=addend;
7040 return s2;
7043 typedef struct {
7044 float f1,f2,f3;
7045 } float3;
7047 LIBTEST_API float3 STDCALL
7048 mono_return_float3 (float3 s3, int addend) {
7049 if (s3.f1 != 1) {
7050 fprintf(stderr, "mono_return_float3 s3.f1: got %f but expected %d\n", s3.f1, 1);
7052 if (s3.f2 != 2) {
7053 fprintf(stderr, "mono_return_float3 s3.f2: got %f but expected %d\n", s3.f2, 2);
7055 if (s3.f3 != 3) {
7056 fprintf(stderr, "mono_return_float3 s3.f3: got %f but expected %d\n", s3.f3, 3);
7058 s3.f1+=addend; s3.f2+=addend; s3.f3+=addend;
7059 return s3;
7062 typedef struct {
7063 float f1,f2,f3,f4;
7064 } float4;
7066 LIBTEST_API float4 STDCALL
7067 mono_return_float4 (float4 s4, int addend) {
7068 if (s4.f1 != 1) {
7069 fprintf(stderr, "mono_return_float4 s4.f1: got %f but expected %d\n", s4.f1, 1);
7071 if (s4.f2 != 2) {
7072 fprintf(stderr, "mono_return_float4 s4.f2: got %f but expected %d\n", s4.f2, 2);
7074 if (s4.f3 != 3) {
7075 fprintf(stderr, "mono_return_float4 s4.f3: got %f but expected %d\n", s4.f3, 3);
7077 if (s4.f4 != 4) {
7078 fprintf(stderr, "mono_return_float4 s4.f4: got %f but expected %d\n", s4.f4, 4);
7080 s4.f1+=addend; s4.f2+=addend; s4.f3+=addend; s4.f4+=addend;
7081 return s4;
7084 typedef struct {
7085 float f1,f2,f3,f4,f5;
7086 } float5;
7088 LIBTEST_API float5 STDCALL
7089 mono_return_float5 (float5 s5, int addend) {
7090 if (s5.f1 != 1) {
7091 fprintf(stderr, "mono_return_float5 s5.f1: got %f but expected %d\n", s5.f1, 1);
7093 if (s5.f2 != 2) {
7094 fprintf(stderr, "mono_return_float5 s5.f2: got %f but expected %d\n", s5.f2, 2);
7096 if (s5.f3 != 3) {
7097 fprintf(stderr, "mono_return_float5 s5.f3: got %f but expected %d\n", s5.f3, 3);
7099 if (s5.f4 != 4) {
7100 fprintf(stderr, "mono_return_float5 s5.f4: got %f but expected %d\n", s5.f4, 4);
7102 if (s5.f5 != 5) {
7103 fprintf(stderr, "mono_return_float5 s5.f5: got %f but expected %d\n", s5.f5, 5);
7105 s5.f1+=addend; s5.f2+=addend; s5.f3+=addend; s5.f4+=addend; s5.f5+=addend;
7106 return s5;
7109 typedef struct {
7110 float f1,f2,f3,f4,f5,f6;
7111 } float6;
7113 LIBTEST_API float6 STDCALL
7114 mono_return_float6 (float6 s6, int addend) {
7115 if (s6.f1 != 1) {
7116 fprintf(stderr, "mono_return_float6 s6.f1: got %f but expected %d\n", s6.f1, 1);
7118 if (s6.f2 != 2) {
7119 fprintf(stderr, "mono_return_float6 s6.f2: got %f but expected %d\n", s6.f2, 2);
7121 if (s6.f3 != 3) {
7122 fprintf(stderr, "mono_return_float6 s6.f3: got %f but expected %d\n", s6.f3, 3);
7124 if (s6.f4 != 4) {
7125 fprintf(stderr, "mono_return_float6 s6.f4: got %f but expected %d\n", s6.f4, 4);
7127 if (s6.f5 != 5) {
7128 fprintf(stderr, "mono_return_float6 s6.f5: got %f but expected %d\n", s6.f5, 5);
7130 if (s6.f6 != 6) {
7131 fprintf(stderr, "mono_return_float6 s6.f6: got %f but expected %d\n", s6.f6, 6);
7133 s6.f1+=addend; s6.f2+=addend; s6.f3+=addend; s6.f4+=addend; s6.f5+=addend; s6.f6+=addend;
7134 return s6;
7137 typedef struct {
7138 float f1,f2,f3,f4,f5,f6,f7;
7139 } float7;
7141 LIBTEST_API float7 STDCALL
7142 mono_return_float7 (float7 s7, int addend) {
7143 if (s7.f1 != 1) {
7144 fprintf(stderr, "mono_return_float7 s7.f1: got %f but expected %d\n", s7.f1, 1);
7146 if (s7.f2 != 2) {
7147 fprintf(stderr, "mono_return_float7 s7.f2: got %f but expected %d\n", s7.f2, 2);
7149 if (s7.f3 != 3) {
7150 fprintf(stderr, "mono_return_float7 s7.f3: got %f but expected %d\n", s7.f3, 3);
7152 if (s7.f4 != 4) {
7153 fprintf(stderr, "mono_return_float7 s7.f4: got %f but expected %d\n", s7.f4, 4);
7155 if (s7.f5 != 5) {
7156 fprintf(stderr, "mono_return_float7 s7.f5: got %f but expected %d\n", s7.f5, 5);
7158 if (s7.f6 != 6) {
7159 fprintf(stderr, "mono_return_float7 s7.f6: got %f but expected %d\n", s7.f6, 6);
7161 if (s7.f7 != 7) {
7162 fprintf(stderr, "mono_return_float7 s7.f7: got %f but expected %d\n", s7.f7, 7);
7164 s7.f1+=addend; s7.f2+=addend; s7.f3+=addend; s7.f4+=addend; s7.f5+=addend; s7.f6+=addend; s7.f7+=addend;
7165 return s7;
7168 typedef struct {
7169 float f1,f2,f3,f4,f5,f6,f7,f8;
7170 } float8;
7172 LIBTEST_API float8 STDCALL
7173 mono_return_float8 (float8 s8, int addend) {
7174 if (s8.f1 != 1) {
7175 fprintf(stderr, "mono_return_float8 s8.f1: got %f but expected %d\n", s8.f1, 1);
7177 if (s8.f2 != 2) {
7178 fprintf(stderr, "mono_return_float8 s8.f2: got %f but expected %d\n", s8.f2, 2);
7180 if (s8.f3 != 3) {
7181 fprintf(stderr, "mono_return_float8 s8.f3: got %f but expected %d\n", s8.f3, 3);
7183 if (s8.f4 != 4) {
7184 fprintf(stderr, "mono_return_float8 s8.f4: got %f but expected %d\n", s8.f4, 4);
7186 if (s8.f5 != 5) {
7187 fprintf(stderr, "mono_return_float8 s8.f5: got %f but expected %d\n", s8.f5, 5);
7189 if (s8.f6 != 6) {
7190 fprintf(stderr, "mono_return_float8 s8.f6: got %f but expected %d\n", s8.f6, 6);
7192 if (s8.f7 != 7) {
7193 fprintf(stderr, "mono_return_float8 s8.f7: got %f but expected %d\n", s8.f7, 7);
7195 if (s8.f8 != 8) {
7196 fprintf(stderr, "mono_return_float8 s8.f8: got %f but expected %d\n", s8.f8, 8);
7198 s8.f1+=addend; s8.f2+=addend; s8.f3+=addend; s8.f4+=addend; s8.f5+=addend; s8.f6+=addend; s8.f7+=addend; s8.f8+=addend;
7199 return s8;
7202 typedef struct {
7203 float f1,f2,f3,f4,f5,f6,f7,f8,f9;
7204 } float9;
7206 LIBTEST_API float9 STDCALL
7207 mono_return_float9 (float9 s9, int addend) {
7208 if (s9.f1 != 1) {
7209 fprintf(stderr, "mono_return_float9 s9.f1: got %f but expected %d\n", s9.f1, 1);
7211 if (s9.f2 != 2) {
7212 fprintf(stderr, "mono_return_float9 s9.f2: got %f but expected %d\n", s9.f2, 2);
7214 if (s9.f3 != 3) {
7215 fprintf(stderr, "mono_return_float9 s9.f3: got %f but expected %d\n", s9.f3, 3);
7217 if (s9.f4 != 4) {
7218 fprintf(stderr, "mono_return_float9 s9.f4: got %f but expected %d\n", s9.f4, 4);
7220 if (s9.f5 != 5) {
7221 fprintf(stderr, "mono_return_float9 s9.f5: got %f but expected %d\n", s9.f5, 5);
7223 if (s9.f6 != 6) {
7224 fprintf(stderr, "mono_return_float9 s9.f6: got %f but expected %d\n", s9.f6, 6);
7226 if (s9.f7 != 7) {
7227 fprintf(stderr, "mono_return_float9 s9.f7: got %f but expected %d\n", s9.f7, 7);
7229 if (s9.f8 != 8) {
7230 fprintf(stderr, "mono_return_float9 s9.f8: got %f but expected %d\n", s9.f8, 8);
7232 if (s9.f9 != 9) {
7233 fprintf(stderr, "mono_return_float9 s9.f9: got %f but expected %d\n", s9.f9, 9);
7235 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;
7236 return s9;
7239 typedef struct {
7240 struct {
7241 float f1;
7242 } nested1;
7243 float f2,f3;
7244 struct {
7245 float f4;
7246 } nested2;
7247 } float4_nested;
7249 LIBTEST_API float4_nested STDCALL
7250 mono_return_float4_nested (float4_nested sn4, int addend) {
7251 if (sn4.nested1.f1 != 1) {
7252 fprintf(stderr, "mono_return_float4_nested sn4.nested1.f1: got %f but expected %d\n", sn4.nested1.f1, 1);
7254 if (sn4.f2 != 2) {
7255 fprintf(stderr, "mono_return_float4_nested sn4.f2: got %f but expected %d\n", sn4.f2, 2);
7257 if (sn4.f3 != 3) {
7258 fprintf(stderr, "mono_return_float4_nested sn4.f3: got %f but expected %d\n", sn4.f3, 3);
7260 if (sn4.nested2.f4 != 4) {
7261 fprintf(stderr, "mono_return_float4_nested sn4.nested2.f4: got %f but expected %d\n", sn4.nested2.f4, 4);
7263 sn4.nested1.f1+=addend; sn4.f2+=addend; sn4.f3+=addend; sn4.nested2.f4+=addend;
7264 return sn4;
7267 typedef struct {
7268 double f1;
7269 } double1;
7271 LIBTEST_API double1 STDCALL
7272 mono_return_double1 (double1 s1, int addend) {
7273 if (s1.f1 != 1) {
7274 fprintf(stderr, "mono_return_double1 s1.f1: got %f but expected %d\n", s1.f1, 1);
7276 s1.f1+=addend;
7277 return s1;
7280 typedef struct {
7281 double f1,f2;
7282 } double2;
7284 LIBTEST_API double2 STDCALL
7285 mono_return_double2 (double2 s2, int addend) {
7286 if (s2.f1 != 1) {
7287 fprintf(stderr, "mono_return_double2 s2.f1: got %f but expected %d\n", s2.f1, 1);
7289 if (s2.f2 != 2) {
7290 fprintf(stderr, "mono_return_double2 s2.f2: got %f but expected %d\n", s2.f2, 2);
7292 s2.f1+=addend; s2.f2+=addend;
7293 return s2;
7296 typedef struct {
7297 double f1,f2,f3;
7298 } double3;
7300 LIBTEST_API double3 STDCALL
7301 mono_return_double3 (double3 s3, int addend) {
7302 if (s3.f1 != 1) {
7303 fprintf(stderr, "mono_return_double3 s3.f1: got %f but expected %d\n", s3.f1, 1);
7305 if (s3.f2 != 2) {
7306 fprintf(stderr, "mono_return_double3 s3.f2: got %f but expected %d\n", s3.f2, 2);
7308 if (s3.f3 != 3) {
7309 fprintf(stderr, "mono_return_double3 s3.f3: got %f but expected %d\n", s3.f3, 3);
7311 s3.f1+=addend; s3.f2+=addend; s3.f3+=addend;
7312 return s3;
7315 typedef struct {
7316 double f1,f2,f3,f4;
7317 } double4;
7319 LIBTEST_API double4 STDCALL
7320 mono_return_double4 (double4 s4, int addend) {
7321 if (s4.f1 != 1) {
7322 fprintf(stderr, "mono_return_double4 s4.f1: got %f but expected %d\n", s4.f1, 1);
7324 if (s4.f2 != 2) {
7325 fprintf(stderr, "mono_return_double4 s4.f2: got %f but expected %d\n", s4.f2, 2);
7327 if (s4.f3 != 3) {
7328 fprintf(stderr, "mono_return_double4 s4.f3: got %f but expected %d\n", s4.f3, 3);
7330 if (s4.f4 != 4) {
7331 fprintf(stderr, "mono_return_double4 s4.f4: got %f but expected %d\n", s4.f4, 4);
7333 s4.f1+=addend; s4.f2+=addend; s4.f3+=addend; s4.f4+=addend;
7334 return s4;
7337 typedef struct {
7338 double f1,f2,f3,f4,f5;
7339 } double5;
7341 LIBTEST_API double5 STDCALL
7342 mono_return_double5 (double5 s5, int addend) {
7343 if (s5.f1 != 1) {
7344 fprintf(stderr, "mono_return_double5 s5.f1: got %f but expected %d\n", s5.f1, 1);
7346 if (s5.f2 != 2) {
7347 fprintf(stderr, "mono_return_double5 s5.f2: got %f but expected %d\n", s5.f2, 2);
7349 if (s5.f3 != 3) {
7350 fprintf(stderr, "mono_return_double5 s5.f3: got %f but expected %d\n", s5.f3, 3);
7352 if (s5.f4 != 4) {
7353 fprintf(stderr, "mono_return_double5 s5.f4: got %f but expected %d\n", s5.f4, 4);
7355 if (s5.f5 != 5) {
7356 fprintf(stderr, "mono_return_double5 s5.f5: got %f but expected %d\n", s5.f5, 5);
7358 s5.f1+=addend; s5.f2+=addend; s5.f3+=addend; s5.f4+=addend; s5.f5+=addend;
7359 return s5;
7362 typedef struct {
7363 double f1,f2,f3,f4,f5,f6;
7364 } double6;
7366 LIBTEST_API double6 STDCALL
7367 mono_return_double6 (double6 s6, int addend) {
7368 if (s6.f1 != 1) {
7369 fprintf(stderr, "mono_return_double6 s6.f1: got %f but expected %d\n", s6.f1, 1);
7371 if (s6.f2 != 2) {
7372 fprintf(stderr, "mono_return_double6 s6.f2: got %f but expected %d\n", s6.f2, 2);
7374 if (s6.f3 != 3) {
7375 fprintf(stderr, "mono_return_double6 s6.f3: got %f but expected %d\n", s6.f3, 3);
7377 if (s6.f4 != 4) {
7378 fprintf(stderr, "mono_return_double6 s6.f4: got %f but expected %d\n", s6.f4, 4);
7380 if (s6.f5 != 5) {
7381 fprintf(stderr, "mono_return_double6 s6.f5: got %f but expected %d\n", s6.f5, 5);
7383 if (s6.f6 != 6) {
7384 fprintf(stderr, "mono_return_double6 s6.f6: got %f but expected %d\n", s6.f6, 6);
7386 s6.f1+=addend; s6.f2+=addend; s6.f3+=addend; s6.f4+=addend; s6.f5+=addend; s6.f6+=addend;
7387 return s6;
7390 typedef struct {
7391 double f1,f2,f3,f4,f5,f6,f7;
7392 } double7;
7394 LIBTEST_API double7 STDCALL
7395 mono_return_double7 (double7 s7, int addend) {
7396 if (s7.f1 != 1) {
7397 fprintf(stderr, "mono_return_double7 s7.f1: got %f but expected %d\n", s7.f1, 1);
7399 if (s7.f2 != 2) {
7400 fprintf(stderr, "mono_return_double7 s7.f2: got %f but expected %d\n", s7.f2, 2);
7402 if (s7.f3 != 3) {
7403 fprintf(stderr, "mono_return_double7 s7.f3: got %f but expected %d\n", s7.f3, 3);
7405 if (s7.f4 != 4) {
7406 fprintf(stderr, "mono_return_double7 s7.f4: got %f but expected %d\n", s7.f4, 4);
7408 if (s7.f5 != 5) {
7409 fprintf(stderr, "mono_return_double7 s7.f5: got %f but expected %d\n", s7.f5, 5);
7411 if (s7.f6 != 6) {
7412 fprintf(stderr, "mono_return_double7 s7.f6: got %f but expected %d\n", s7.f6, 6);
7414 if (s7.f7 != 7) {
7415 fprintf(stderr, "mono_return_double7 s7.f7: got %f but expected %d\n", s7.f7, 7);
7417 s7.f1+=addend; s7.f2+=addend; s7.f3+=addend; s7.f4+=addend; s7.f5+=addend; s7.f6+=addend; s7.f7+=addend;
7418 return s7;
7421 typedef struct {
7422 double f1,f2,f3,f4,f5,f6,f7,f8;
7423 } double8;
7425 LIBTEST_API double8 STDCALL
7426 mono_return_double8 (double8 s8, int addend) {
7427 if (s8.f1 != 1) {
7428 fprintf(stderr, "mono_return_double8 s8.f1: got %f but expected %d\n", s8.f1, 1);
7430 if (s8.f2 != 2) {
7431 fprintf(stderr, "mono_return_double8 s8.f2: got %f but expected %d\n", s8.f2, 2);
7433 if (s8.f3 != 3) {
7434 fprintf(stderr, "mono_return_double8 s8.f3: got %f but expected %d\n", s8.f3, 3);
7436 if (s8.f4 != 4) {
7437 fprintf(stderr, "mono_return_double8 s8.f4: got %f but expected %d\n", s8.f4, 4);
7439 if (s8.f5 != 5) {
7440 fprintf(stderr, "mono_return_double8 s8.f5: got %f but expected %d\n", s8.f5, 5);
7442 if (s8.f6 != 6) {
7443 fprintf(stderr, "mono_return_double8 s8.f6: got %f but expected %d\n", s8.f6, 6);
7445 if (s8.f7 != 7) {
7446 fprintf(stderr, "mono_return_double8 s8.f7: got %f but expected %d\n", s8.f7, 7);
7448 if (s8.f8 != 8) {
7449 fprintf(stderr, "mono_return_double8 s8.f8: got %f but expected %d\n", s8.f8, 8);
7451 s8.f1+=addend; s8.f2+=addend; s8.f3+=addend; s8.f4+=addend; s8.f5+=addend; s8.f6+=addend; s8.f7+=addend; s8.f8+=addend;
7452 return s8;
7455 typedef struct {
7456 double f1,f2,f3,f4,f5,f6,f7,f8,f9;
7457 } double9;
7459 LIBTEST_API double9 STDCALL
7460 mono_return_double9 (double9 s9, int addend) {
7461 if (s9.f1 != 1) {
7462 fprintf(stderr, "mono_return_double9 s9.f1: got %f but expected %d\n", s9.f1, 1);
7464 if (s9.f2 != 2) {
7465 fprintf(stderr, "mono_return_double9 s9.f2: got %f but expected %d\n", s9.f2, 2);
7467 if (s9.f3 != 3) {
7468 fprintf(stderr, "mono_return_double9 s9.f3: got %f but expected %d\n", s9.f3, 3);
7470 if (s9.f4 != 4) {
7471 fprintf(stderr, "mono_return_double9 s9.f4: got %f but expected %d\n", s9.f4, 4);
7473 if (s9.f5 != 5) {
7474 fprintf(stderr, "mono_return_double9 s9.f5: got %f but expected %d\n", s9.f5, 5);
7476 if (s9.f6 != 6) {
7477 fprintf(stderr, "mono_return_double9 s9.f6: got %f but expected %d\n", s9.f6, 6);
7479 if (s9.f7 != 7) {
7480 fprintf(stderr, "mono_return_double9 s9.f7: got %f but expected %d\n", s9.f7, 7);
7482 if (s9.f8 != 8) {
7483 fprintf(stderr, "mono_return_double9 s9.f8: got %f but expected %d\n", s9.f8, 8);
7485 if (s9.f9 != 9) {
7486 fprintf(stderr, "mono_return_double9 s9.f9: got %f but expected %d\n", s9.f9, 9);
7488 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;
7489 return s9;
7492 typedef struct {
7493 struct {
7494 double f1;
7495 } nested1;
7496 struct {
7497 double f2;
7498 } nested2;
7499 } double2_nested;
7501 LIBTEST_API double2_nested STDCALL
7502 mono_return_double2_nested (double2_nested sn2, int addend) {
7503 if (sn2.nested1.f1 != 1) {
7504 fprintf(stderr, "mono_return_double2_nested sn2.nested1.f1: got %f but expected %d\n", sn2.nested1.f1, 1);
7506 if (sn2.nested2.f2 != 2) {
7507 fprintf(stderr, "mono_return_double2_nested sn2.nested2.f2: got %f but expected %d\n", sn2.nested2.f2, 2);
7509 sn2.nested1.f1+=addend; sn2.nested2.f2+=addend;
7510 return sn2;
7515 typedef struct {
7516 double f1[4];
7517 } double_array4;
7519 LIBTEST_API double_array4 STDCALL
7520 mono_return_double_array4 (double_array4 sa4, int addend) {
7521 if (sa4.f1[0] != 1) {
7522 fprintf(stderr, "mono_return_double_array4 sa4.f1[0]: got %f but expected %d\n", sa4.f1[0], 1);
7524 if (sa4.f1[1] != 2) {
7525 fprintf(stderr, "mono_return_double_array4 sa4.f1[1]: got %f but expected %d\n", sa4.f1[1], 2);
7527 if (sa4.f1[2] != 3) {
7528 fprintf(stderr, "mono_return_double_array4 sa4.f1[2]: got %f but expected %d\n", sa4.f1[2], 3);
7530 if (sa4.f1[3] != 4) {
7531 fprintf(stderr, "mono_return_double_array4 sa4.f1[3]: got %f but expected %d\n", sa4.f1[3], 4);
7533 sa4.f1[0]+=addend; sa4.f1[1]+=addend; sa4.f1[2]+=addend; sa4.f1[3]+=addend;
7534 return sa4;
7537 typedef struct {
7538 int array [3];
7539 } FixedArrayStruct;
7541 LIBTEST_API int STDCALL
7542 mono_test_marshal_fixed_array (FixedArrayStruct s)
7544 return s.array [0] + s.array [1] + s.array [2];
7547 typedef struct {
7548 char array [16];
7549 char c;
7550 } FixedBufferChar;
7552 LIBTEST_API int STDCALL
7553 mono_test_marshal_fixed_buffer_char (FixedBufferChar *s)
7555 if (!(s->array [0] == 'A' && s->array [1] == 'B' && s->array [2] == 'C' && s->c == 'D'))
7556 return 1;
7557 s->array [0] = 'E';
7558 s->array [1] = 'F';
7559 s->c = 'G';
7560 return 0;
7563 typedef struct {
7564 short array [16];
7565 short c;
7566 } FixedBufferUnicode;
7568 LIBTEST_API int STDCALL
7569 mono_test_marshal_fixed_buffer_unicode (FixedBufferUnicode *s)
7571 if (!(s->array [0] == 'A' && s->array [1] == 'B' && s->array [2] == 'C' && s->c == 'D'))
7572 return 1;
7573 s->array [0] = 'E';
7574 s->array [1] = 'F';
7575 s->c = 'G';
7576 return 0;
7579 const int NSTRINGS = 6;
7580 //test strings
7581 const char *utf8Strings[] = {
7582 "Managed",
7583 "Sîne klâwen durh die wolken sint geslagen" ,
7584 "काचं शक्नोम्यत्तुम् । नोपहिनस्ति माम्",
7585 "我能吞下玻璃而不伤身体",
7586 "ღმერთსი შემვედრე,შემვედრე, ნუთუ კვლა დამხსნას შემვედრე,სოფლისა შემვედრე, შემვედრე,შემვედრე,შემვედრე,შრომასა, ცეცხლს, წყალსა და მიწასა, ჰაერთა თანა მრომასა; მომცნეს ფრთენი და აღვფრინდე, მივჰხვდე მას ჩემსა ნდომასა, დღისით და ღამით ვჰხედვიდე მზისა ელვათა კრთომაასაშემვედრე,შემვედრე,",
7587 "Τη γλώσσα μου έδωσαν ελληνική",
7588 "\0"
7591 LIBTEST_API char *
7592 build_return_string(const char* pReturn)
7594 char *ret = 0;
7595 if (pReturn == 0 || *pReturn == 0)
7596 return ret;
7598 size_t strLength = strlen(pReturn);
7599 ret = (char *)(marshal_alloc (sizeof(char)* (strLength + 1)));
7600 memcpy(ret, pReturn, strLength);
7601 ret [strLength] = '\0';
7602 return ret;
7605 LIBTEST_API char *
7606 StringParameterInOut(/*[In,Out]*/ char *s, int index)
7608 // return a copy
7609 return build_return_string(s);
7612 LIBTEST_API void
7613 StringParameterRefOut(/*out*/ char **s, int index)
7615 char *pszTextutf8 = (char*)utf8Strings[index];
7616 size_t strLength = strlen(pszTextutf8);
7617 *s = (char *)(marshal_alloc (sizeof(char)* (strLength + 1)));
7618 memcpy(*s, pszTextutf8, strLength);
7619 (*s)[strLength] = '\0';
7622 LIBTEST_API void
7623 StringParameterRef(/*ref*/ char **s, int index)
7625 char *pszTextutf8 = (char*)utf8Strings[index];
7626 size_t strLength = strlen(pszTextutf8);
7627 // do byte by byte validation of in string
7628 size_t szLen = strlen(*s);
7629 for (size_t i = 0; i < szLen; i++)
7631 if ((*s)[i] != pszTextutf8[i])
7633 printf("[in] managed string do not match native string\n");
7634 abort ();
7638 if (*s)
7640 marshal_free (*s);
7642 // overwrite the orginal
7643 *s = (char *)(marshal_alloc (sizeof(char)* (strLength + 1)));
7644 memcpy(*s, pszTextutf8, strLength);
7645 (*s)[strLength] = '\0';
7648 LIBTEST_API void
7649 StringBuilderParameterInOut(/*[In,Out] StringBuilder*/ char *s, int index)
7651 // if string.empty
7652 if (s == 0 || *s == 0)
7653 return;
7655 char *pszTextutf8 = (char*)utf8Strings[index];
7657 // do byte by byte validation of in string
7658 size_t szLen = strlen(s);
7659 for (size_t i = 0; i < szLen; i++)
7661 if (s[i] != pszTextutf8[i])
7663 printf("[in] managed string do not match native string\n");
7664 abort ();
7668 // modify the string inplace
7669 size_t outLen = strlen(pszTextutf8);
7670 for (size_t i = 0; i < outLen; i++) {
7671 s[i] = pszTextutf8[i];
7673 s[outLen] = '\0';
7676 //out string builder
7677 LIBTEST_API void
7678 StringBuilderParameterOut(/*[Out] StringBuilder*/ char *s, int index)
7680 char *pszTextutf8 = (char*)utf8Strings[index];
7682 printf ("SBPO: Receiving %s\n", s);
7683 // modify the string inplace
7684 size_t outLen = strlen(pszTextutf8);
7685 for (size_t i = 0; i < outLen; i++) {
7686 s[i] = pszTextutf8[i];
7688 s[outLen] = '\0';
7691 LIBTEST_API char *
7692 StringParameterOut(/*[Out]*/ char *s, int index)
7694 // return a copy
7695 return build_return_string(s);
7698 // Utf8 field
7699 typedef struct FieldWithUtf8
7701 char *pFirst;
7702 int index;
7703 }FieldWithUtf8;
7705 //utf8 struct field
7706 LIBTEST_API void
7707 TestStructWithUtf8Field(struct FieldWithUtf8 fieldStruct)
7709 char *pszManagedutf8 = fieldStruct.pFirst;
7710 int stringIndex = fieldStruct.index;
7711 char *pszNative = 0;
7712 size_t outLen = 0;
7714 if (pszManagedutf8 == 0 || *pszManagedutf8 == 0)
7715 return;
7717 pszNative = (char*)utf8Strings[stringIndex];
7719 outLen = strlen(pszNative);
7720 // do byte by byte comparision
7721 for (size_t i = 0; i < outLen; i++)
7723 if (pszNative[i] != pszManagedutf8[i])
7725 printf("Native and managed string do not match.\n");
7726 abort ();
7731 typedef void (* Callback2)(char *text, int index);
7733 LIBTEST_API void
7734 Utf8DelegateAsParameter(Callback2 managedCallback)
7736 for (int i = 0; i < NSTRINGS; ++i)
7738 char *pszNative = 0;
7739 pszNative = (char*)utf8Strings[i];
7740 managedCallback(pszNative, i);
7745 LIBTEST_API char*
7746 StringBuilderParameterReturn(int index)
7748 char *pszTextutf8 = (char*)utf8Strings[index];
7749 size_t strLength = strlen(pszTextutf8);
7750 char * ret = (char *)(marshal_alloc (sizeof(char)* (strLength + 1)));
7751 memcpy(ret, pszTextutf8, strLength);
7752 ret[strLength] = '\0';
7754 return ret;
7757 LIBTEST_API int STDCALL
7758 mono_test_marshal_pointer_array (int *arr[])
7760 int i;
7762 for (i = 0; i < 10; ++i) {
7763 if (*arr [i] != -1)
7764 return 1;
7766 return 0;
7769 #ifndef WIN32
7771 typedef void (*NativeToManagedExceptionRethrowFunc) (void);
7773 void *mono_test_native_to_managed_exception_rethrow_thread (void *arg)
7775 NativeToManagedExceptionRethrowFunc func = (NativeToManagedExceptionRethrowFunc) arg;
7776 func ();
7777 return NULL;
7780 LIBTEST_API void STDCALL
7781 mono_test_native_to_managed_exception_rethrow (NativeToManagedExceptionRethrowFunc func)
7783 pthread_t t;
7784 pthread_create (&t, NULL, mono_test_native_to_managed_exception_rethrow_thread, (gpointer)func);
7785 pthread_join (t, NULL);
7787 #endif
7789 typedef void (*VoidVoidCallback) (void);
7790 typedef void (*MonoFtnPtrEHCallback) (guint32 gchandle);
7792 typedef void *MonoDomain;
7793 typedef void *MonoAssembly;
7794 typedef void *MonoImage;
7795 typedef void *MonoClass;
7796 typedef void *MonoMethod;
7797 typedef void *MonoThread;
7799 typedef long long MonoObject;
7800 typedef MonoObject MonoException;
7801 typedef int32_t mono_bool;
7803 static int sym_inited = 0;
7804 static void (*sym_mono_install_ftnptr_eh_callback) (MonoFtnPtrEHCallback);
7805 static MonoObject* (*sym_mono_gchandle_get_target) (guint32 gchandle);
7806 static guint32 (*sym_mono_gchandle_new) (MonoObject *, mono_bool pinned);
7807 static void (*sym_mono_gchandle_free) (guint32 gchandle);
7808 static void (*sym_mono_raise_exception) (MonoException *ex);
7809 static void (*sym_mono_domain_unload) (gpointer);
7810 static void (*sym_mono_threads_exit_gc_safe_region_unbalanced) (gpointer, gpointer *);
7811 static void (*null_function_ptr) (void);
7813 static MonoDomain *(*sym_mono_get_root_domain) (void);
7815 static MonoDomain *(*sym_mono_domain_get)(void);
7817 static mono_bool (*sym_mono_domain_set)(MonoDomain *, mono_bool /*force */);
7819 static MonoAssembly *(*sym_mono_domain_assembly_open) (MonoDomain *, const char*);
7821 static MonoImage *(*sym_mono_assembly_get_image) (MonoAssembly *);
7823 static MonoClass *(*sym_mono_class_from_name)(MonoImage *, const char *, const char *);
7825 static MonoMethod *(*sym_mono_class_get_method_from_name)(MonoClass *, const char *, int /* arg_count */);
7827 static MonoThread *(*sym_mono_thread_attach)(MonoDomain *);
7829 static void (*sym_mono_thread_detach)(MonoThread *);
7831 static MonoObject *(*sym_mono_runtime_invoke) (MonoMethod *, void*, void**, MonoObject**);
7834 // SYM_LOOKUP(mono_runtime_invoke)
7835 // expands to
7836 // sym_mono_runtime_invoke = g_cast (lookup_mono_symbol ("mono_runtime_invoke"));
7838 // (the g_cast is necessary for C++ builds)
7839 #define SYM_LOOKUP(name) do { \
7840 sym_##name = g_cast (lookup_mono_symbol (#name)); \
7841 } while (0)
7843 static void
7844 mono_test_init_symbols (void)
7846 if (sym_inited)
7847 return;
7849 SYM_LOOKUP (mono_install_ftnptr_eh_callback);
7850 SYM_LOOKUP (mono_gchandle_get_target);
7851 SYM_LOOKUP (mono_gchandle_new);
7852 SYM_LOOKUP (mono_gchandle_free);
7853 SYM_LOOKUP (mono_raise_exception);
7854 SYM_LOOKUP (mono_domain_unload);
7855 SYM_LOOKUP (mono_threads_exit_gc_safe_region_unbalanced);
7857 SYM_LOOKUP (mono_get_root_domain);
7858 SYM_LOOKUP (mono_domain_get);
7859 SYM_LOOKUP (mono_domain_set);
7860 SYM_LOOKUP (mono_domain_assembly_open);
7861 SYM_LOOKUP (mono_assembly_get_image);
7862 SYM_LOOKUP (mono_class_from_name);
7863 SYM_LOOKUP (mono_class_get_method_from_name);
7864 SYM_LOOKUP (mono_thread_attach);
7865 SYM_LOOKUP (mono_thread_detach);
7866 SYM_LOOKUP (mono_runtime_invoke);
7868 sym_inited = 1;
7871 #ifndef TARGET_WASM
7873 static jmp_buf test_jmp_buf;
7874 static guint32 test_gchandle;
7876 static void
7877 mono_test_longjmp_callback (guint32 gchandle)
7879 test_gchandle = gchandle;
7880 longjmp (test_jmp_buf, 1);
7883 LIBTEST_API void STDCALL
7884 mono_test_setjmp_and_call (VoidVoidCallback managedCallback, intptr_t *out_handle)
7886 mono_test_init_symbols ();
7887 if (setjmp (test_jmp_buf) == 0) {
7888 *out_handle = 0;
7889 sym_mono_install_ftnptr_eh_callback (mono_test_longjmp_callback);
7890 managedCallback ();
7891 *out_handle = 0; /* Do not expect to return here */
7892 } else {
7893 sym_mono_install_ftnptr_eh_callback (NULL);
7894 *out_handle = test_gchandle;
7898 #endif
7900 LIBTEST_API void STDCALL
7901 mono_test_marshal_bstr (void *ptr)
7905 static void (*mono_test_capture_throw_callback) (guint32 gchandle, guint32 *exception_out);
7907 static void
7908 mono_test_ftnptr_eh_callback (guint32 gchandle)
7910 guint32 exception_handle = 0;
7912 g_assert (gchandle != 0);
7913 MonoObject *exc = sym_mono_gchandle_get_target (gchandle);
7914 sym_mono_gchandle_free (gchandle);
7916 guint32 handle = sym_mono_gchandle_new (exc, FALSE);
7917 mono_test_capture_throw_callback (handle, &exception_handle);
7918 sym_mono_gchandle_free (handle);
7920 g_assert (exception_handle != 0);
7921 exc = sym_mono_gchandle_get_target (exception_handle);
7922 sym_mono_gchandle_free (exception_handle);
7924 sym_mono_raise_exception (exc);
7925 g_error ("mono_raise_exception should not return");
7928 LIBTEST_API void STDCALL
7929 mono_test_setup_ftnptr_eh_callback (VoidVoidCallback managed_entry, void (*capture_throw_callback) (guint32, guint32 *))
7931 mono_test_init_symbols ();
7932 mono_test_capture_throw_callback = capture_throw_callback;
7933 sym_mono_install_ftnptr_eh_callback (mono_test_ftnptr_eh_callback);
7934 managed_entry ();
7937 LIBTEST_API void STDCALL
7938 mono_test_cleanup_ftptr_eh_callback (void)
7940 mono_test_init_symbols ();
7941 sym_mono_install_ftnptr_eh_callback (NULL);
7944 LIBTEST_API int STDCALL
7945 mono_test_cominterop_ccw_queryinterface (MonoComObject *pUnk)
7947 void *pp;
7948 int hr = pUnk->vtbl->QueryInterface (pUnk, &IID_INotImplemented, &pp);
7950 // Return true if we can't get INotImplemented
7951 return pUnk == NULL && hr == S_OK;
7954 typedef struct ccw_qi_shared_data {
7955 MonoComObject *pUnk;
7956 int i;
7957 } ccw_qi_shared_data;
7959 static void*
7960 ccw_qi_foreign_thread (void *arg)
7962 ccw_qi_shared_data *shared = (ccw_qi_shared_data *)arg;
7963 void *pp;
7964 MonoComObject *pUnk = shared->pUnk;
7965 int hr = pUnk->vtbl->QueryInterface (pUnk, &IID_ITest, &pp);
7967 shared->i = (hr == S_OK) ? 0 : 43;
7968 return NULL;
7971 LIBTEST_API int STDCALL
7972 mono_test_cominterop_ccw_queryinterface_foreign_thread (MonoComObject *pUnk)
7974 #ifdef WIN32
7975 return 0;
7976 #else
7977 pthread_t t;
7978 ccw_qi_shared_data *shared = (ccw_qi_shared_data *)malloc (sizeof (ccw_qi_shared_data));
7979 if (!shared)
7980 abort ();
7981 shared->pUnk = pUnk;
7982 shared->i = 1;
7983 int res = pthread_create (&t, NULL, ccw_qi_foreign_thread, (void*)shared);
7984 g_assert (res == 0);
7985 pthread_join (t, NULL);
7986 int result = shared->i;
7987 free (shared);
7988 return result;
7989 #endif
7992 static void*
7993 ccw_itest_foreign_thread (void *arg)
7995 ccw_qi_shared_data *shared = (ccw_qi_shared_data *)arg;
7996 MonoComObject *pUnk = shared->pUnk;
7997 int hr = pUnk->vtbl->SByteIn (pUnk, -100);
7998 shared->i = (hr == S_OK) ? 0 : 12;
7999 return NULL;
8002 LIBTEST_API int STDCALL
8003 mono_test_cominterop_ccw_itest_foreign_thread (MonoComObject *pUnk)
8005 #ifdef WIN32
8006 return 0;
8007 #else
8008 pthread_t t;
8009 ccw_qi_shared_data *shared = (ccw_qi_shared_data *)malloc (sizeof (ccw_qi_shared_data));
8010 if (!shared)
8011 abort ();
8012 shared->pUnk = pUnk;
8013 shared->i = 1;
8014 int res = pthread_create (&t, NULL, ccw_itest_foreign_thread, (void*)shared);
8015 g_assert (res == 0);
8016 pthread_join (t, NULL);
8017 int result = shared->i;
8018 free (shared);
8019 return result;
8020 #endif
8024 LIBTEST_API void STDCALL
8025 mono_test_MerpCrashSnprintf (void)
8027 fprintf (stderr, "Before overwrite\n");
8029 char buff [1] = { '\0' };
8030 char overflow [1] = { 'a' }; // Not null-terminated
8031 g_snprintf (buff, sizeof(buff) * 10, "THISSHOULDOVERRUNTERRIBLY%s", overflow);
8032 g_snprintf ((char *) GINT_TO_POINTER(-1), sizeof(buff) * 10, "THISSHOULDOVERRUNTERRIBLY%s", overflow);
8035 LIBTEST_API void STDCALL
8036 mono_test_MerpCrashDladdr (void)
8038 #ifndef HOST_WIN32
8039 dlopen (GINT_TO_POINTER(-1), -1);
8040 #endif
8043 LIBTEST_API void STDCALL
8044 mono_test_MerpCrashMalloc (void)
8046 gpointer x = g_malloc (sizeof(gpointer));
8047 g_free (x);
8049 // Double free
8050 g_free (x);
8053 LIBTEST_API void STDCALL
8054 mono_test_MerpCrashNullFp (void)
8056 null_function_ptr ();
8059 LIBTEST_API void STDCALL
8060 mono_test_MerpCrashDomainUnload (void)
8062 mono_test_init_symbols ();
8063 sym_mono_domain_unload (GINT_TO_POINTER (-1));
8066 LIBTEST_API void STDCALL
8067 mono_test_MerpCrashUnbalancedGCSafe (void)
8069 mono_test_init_symbols ();
8070 gpointer foo = GINT_TO_POINTER (-1);
8071 gpointer bar = GINT_TO_POINTER (-2);
8072 sym_mono_threads_exit_gc_safe_region_unbalanced (foo, &bar);
8075 LIBTEST_API void STDCALL
8076 mono_test_MerpCrashUnhandledExceptionHook (void)
8078 g_assert_not_reached ();
8081 LIBTEST_API void STDCALL
8082 mono_test_MerpCrashSignalTerm (void)
8084 raise (SIGTERM);
8087 // for the rest of the signal tests, we use SIGTERM as a fallback
8089 LIBTEST_API void STDCALL
8090 mono_test_MerpCrashSignalAbrt (void)
8092 #if defined (SIGABRT)
8093 raise (SIGABRT);
8094 #else
8095 raise (SIGTERM);
8096 #endif
8099 LIBTEST_API void STDCALL
8100 mono_test_MerpCrashSignalFpe (void)
8102 #if defined (SIGFPE)
8103 raise (SIGFPE);
8104 #else
8105 raise (SIGTERM);
8106 #endif
8109 LIBTEST_API void STDCALL
8110 mono_test_MerpCrashSignalBus (void)
8112 #if defined (SIGBUS)
8113 raise (SIGBUS);
8114 #else
8115 raise (SIGTERM);
8116 #endif
8119 LIBTEST_API void STDCALL
8120 mono_test_MerpCrashSignalSegv (void)
8122 #if defined (SIGSEGV)
8123 raise (SIGSEGV);
8124 #else
8125 raise (SIGTERM);
8126 #endif
8129 LIBTEST_API void STDCALL
8130 mono_test_MerpCrashSignalIll (void)
8132 #if defined (SIGILL)
8133 raise (SIGILL);
8134 #else
8135 raise (SIGTERM);
8136 #endif
8139 typedef struct _TestAutoDual _TestAutoDual;
8141 typedef struct
8143 int (STDCALL *QueryInterface)(_TestAutoDual *iface, REFIID iid, gpointer *out);
8144 int (STDCALL *AddRef)(_TestAutoDual *iface);
8145 int (STDCALL *Release)(_TestAutoDual *iface);
8146 int (STDCALL *GetTypeInfoCount)(_TestAutoDual *iface, unsigned int *count);
8147 int (STDCALL *GetTypeInfo)(_TestAutoDual *iface, unsigned int index, unsigned int lcid, gpointer *out);
8148 int (STDCALL *GetIDsOfNames)(_TestAutoDual *iface, REFIID iid, gpointer names, unsigned int count, unsigned int lcid, gpointer ids);
8149 int (STDCALL *Invoke)(_TestAutoDual *iface, unsigned int dispid, REFIID iid, unsigned int lcid, unsigned short flags, gpointer params, gpointer result, gpointer excepinfo, gpointer err_arg);
8150 int (STDCALL *ToString)(_TestAutoDual *iface, gpointer string);
8151 int (STDCALL *Equals)(_TestAutoDual *iface, VARIANT other, short *retval);
8152 int (STDCALL *GetHashCode)(_TestAutoDual *iface, int *retval);
8153 int (STDCALL *GetType)(_TestAutoDual *iface, gpointer retval);
8154 int (STDCALL *parent_method_virtual)(_TestAutoDual *iface, int *retval);
8155 int (STDCALL *get_parent_property)(_TestAutoDual *iface, int *retval);
8156 int (STDCALL *parent_method_override)(_TestAutoDual *iface, int *retval);
8157 int (STDCALL *parent_iface_method)(_TestAutoDual *iface, int *retval);
8158 int (STDCALL *parent_method)(_TestAutoDual *iface, int *retval);
8159 int (STDCALL *child_method_virtual)(_TestAutoDual *iface, int *retval);
8160 int (STDCALL *iface1_method)(_TestAutoDual *iface, int *retval);
8161 int (STDCALL *iface1_parent_method)(_TestAutoDual *iface, int *retval);
8162 int (STDCALL *iface2_method)(_TestAutoDual *iface, int *retval);
8163 int (STDCALL *child_method)(_TestAutoDual *iface, int *retval);
8164 } _TestAutoDualVtbl;
8166 struct _TestAutoDual
8168 const _TestAutoDualVtbl *lpVtbl;
8171 LIBTEST_API int STDCALL
8172 mono_test_ccw_class_type_auto_dual (_TestAutoDual *iface)
8174 int hr, retval;
8176 hr = iface->lpVtbl->parent_method_virtual(iface, &retval);
8177 if (hr != 0)
8178 return 1;
8179 if (retval != 101)
8180 return 2;
8182 hr = iface->lpVtbl->get_parent_property(iface, &retval);
8183 if (hr != 0)
8184 return 3;
8185 if (retval != 102)
8186 return 4;
8188 hr = iface->lpVtbl->parent_method_override(iface, &retval);
8189 if (hr != 0)
8190 return 5;
8191 if (retval != 203)
8192 return 6;
8194 hr = iface->lpVtbl->parent_method(iface, &retval);
8195 if (hr != 0)
8196 return 7;
8197 if (retval != 104)
8198 return 8;
8200 hr = iface->lpVtbl->child_method_virtual(iface, &retval);
8201 if (hr != 0)
8202 return 11;
8203 if (retval != 106)
8204 return 12;
8206 hr = iface->lpVtbl->iface1_method(iface, &retval);
8207 if (hr != 0)
8208 return 13;
8209 if (retval != 107)
8210 return 14;
8212 hr = iface->lpVtbl->iface1_parent_method(iface, &retval);
8213 if (hr != 0)
8214 return 15;
8215 if (retval != 108)
8216 return 16;
8218 hr = iface->lpVtbl->iface2_method(iface, &retval);
8219 if (hr != 0)
8220 return 17;
8221 if (retval != 109)
8222 return 18;
8224 hr = iface->lpVtbl->child_method(iface, &retval);
8225 if (hr != 0)
8226 return 19;
8227 if (retval != 110)
8228 return 20;
8230 hr = iface->lpVtbl->parent_iface_method(iface, &retval);
8231 if (hr != 0)
8232 return 23;
8233 if (retval != 112)
8234 return 24;
8236 return 0;
8239 static const GUID IID_IBanana = {0x12345678, 0, 0, {0, 0, 0, 0, 0, 0, 0, 2}};
8241 typedef struct IBanana IBanana;
8243 typedef struct
8245 int (STDCALL *QueryInterface)(IBanana *iface, REFIID iid, gpointer *out);
8246 int (STDCALL *AddRef)(IBanana *iface);
8247 int (STDCALL *Release)(IBanana *iface);
8248 int (STDCALL *GetTypeInfoCount)(IBanana *iface, unsigned int *count);
8249 int (STDCALL *GetTypeInfo)(IBanana *iface, unsigned int index, unsigned int lcid, gpointer *out);
8250 int (STDCALL *GetIDsOfNames)(IBanana *iface, REFIID iid, gpointer names, unsigned int count, unsigned int lcid, gpointer ids);
8251 int (STDCALL *Invoke)(IBanana *iface, unsigned int dispid, REFIID iid, unsigned int lcid, unsigned short flags, gpointer params, gpointer result, gpointer excepinfo, gpointer err_arg);
8252 int (STDCALL *iface1_method)(IBanana *iface, int *retval);
8253 } IBananaVtbl;
8255 struct IBanana
8257 const IBananaVtbl *lpVtbl;
8260 LIBTEST_API int STDCALL
8261 mono_test_ccw_class_type_none (IBanana *iface)
8263 int hr, retval;
8265 hr = iface->lpVtbl->iface1_method(iface, &retval);
8266 if (hr != 0)
8267 return 1;
8268 if (retval != 3)
8269 return 2;
8270 return 0;
8273 LIBTEST_API int STDCALL
8274 mono_test_ccw_class_type_auto_dispatch (IDispatch *disp)
8276 IBanana *banana;
8277 int hr, retval;
8279 #ifdef __cplusplus
8280 hr = disp->QueryInterface (IID_IBanana, (void **)&banana);
8281 #else
8282 hr = disp->lpVtbl->QueryInterface (disp, &IID_IBanana, (void **)&banana);
8283 #endif
8284 if (hr != 0)
8285 return 1;
8286 hr = banana->lpVtbl->iface1_method(banana, &retval);
8287 if (hr != 0)
8288 return 2;
8289 if (retval != 3)
8290 return 3;
8291 banana->lpVtbl->Release(banana);
8293 return 0;
8296 static guint8 static_arr[] = { 1, 2, 3, 4 };
8298 LIBTEST_API guint8*
8299 mono_test_marshal_return_array (void)
8301 return static_arr;
8304 struct invoke_names {
8305 char *assm_name;
8306 char *name_space;
8307 char *name;
8308 char *meth_name;
8311 static struct invoke_names *
8312 make_invoke_names (const char *assm_name, const char *name_space, const char *name, const char *meth_name)
8314 struct invoke_names *names = (struct invoke_names*) malloc (sizeof (struct invoke_names));
8315 names->assm_name = strdup (assm_name);
8316 names->name_space = strdup (name_space);
8317 names->name = strdup (name);
8318 names->meth_name = strdup (meth_name);
8319 return names;
8322 static void
8323 destroy_invoke_names (struct invoke_names *n)
8325 free (n->assm_name);
8326 free (n->name_space);
8327 free (n->name);
8328 free (n->meth_name);
8329 free (n);
8332 static void
8333 test_invoke_by_name (struct invoke_names *names)
8335 mono_test_init_symbols ();
8337 MonoDomain *domain = sym_mono_domain_get ();
8338 MonoThread *thread = NULL;
8339 if (!domain) {
8340 thread = sym_mono_thread_attach (sym_mono_get_root_domain ());
8342 domain = sym_mono_domain_get ();
8343 g_assert (domain);
8344 MonoAssembly *assm = sym_mono_domain_assembly_open (domain, names->assm_name);
8345 g_assert (assm);
8346 MonoImage *image = sym_mono_assembly_get_image (assm);
8347 MonoClass *klass = sym_mono_class_from_name (image, names->name_space, names->name);
8348 g_assert (klass);
8349 /* meth_name should be a static method that takes no arguments */
8350 MonoMethod *method = sym_mono_class_get_method_from_name (klass, names->meth_name, -1);
8351 g_assert (method);
8353 MonoObject *args[] = {NULL, };
8355 sym_mono_runtime_invoke (method, NULL, (void**)args, NULL);
8357 if (thread)
8358 sym_mono_thread_detach (thread);
8361 #ifndef HOST_WIN32
8362 static void*
8363 invoke_foreign_thread (void* user_data)
8365 struct invoke_names *names = (struct invoke_names*)user_data;
8367 * Run a couple of times to check that attach/detach multiple
8368 * times from the same thread leaves it in a reasonable coop
8369 * thread state.
8371 for (int i = 0; i < 5; ++i) {
8372 test_invoke_by_name (names);
8373 sleep (2);
8375 destroy_invoke_names (names);
8376 return NULL;
8378 #endif
8381 LIBTEST_API mono_bool STDCALL
8382 mono_test_attach_invoke_foreign_thread (const char *assm_name, const char *name_space, const char *name, const char *meth_name)
8384 #ifndef HOST_WIN32
8385 struct invoke_names *names = make_invoke_names (assm_name, name_space, name, meth_name);
8386 pthread_t t;
8387 int res = pthread_create (&t, NULL, invoke_foreign_thread, (void*)names);
8388 g_assert (res == 0);
8389 pthread_join (t, NULL);
8390 return 0;
8391 #else
8392 // TODO: Win32 version of this test
8393 return 1;
8394 #endif
8397 #ifndef HOST_WIN32
8398 struct names_and_mutex {
8399 struct invoke_names *names;
8400 /* mutex to coordinate test and foreign thread */
8401 pthread_mutex_t coord_mutex;
8402 pthread_cond_t coord_cond;
8403 /* mutex to block the foreign thread */
8404 pthread_mutex_t deadlock_mutex;
8407 static void*
8408 invoke_block_foreign_thread (void *user_data)
8410 // This thread calls into the runtime and then blocks. It should not
8411 // prevent the runtime from shutting down.
8412 struct names_and_mutex *nm = (struct names_and_mutex *)user_data;
8413 test_invoke_by_name (nm->names);
8414 pthread_mutex_lock (&nm->coord_mutex);
8415 /* signal the test thread that we called the runtime */
8416 pthread_cond_signal (&nm->coord_cond);
8417 pthread_mutex_unlock (&nm->coord_mutex);
8419 pthread_mutex_lock (&nm->deadlock_mutex); // blocks forever
8420 g_assert_not_reached ();
8422 #endif
8424 LIBTEST_API mono_bool STDCALL
8425 mono_test_attach_invoke_block_foreign_thread (const char *assm_name, const char *name_space, const char *name, const char *meth_name)
8427 #ifndef HOST_WIN32
8428 struct invoke_names *names = make_invoke_names (assm_name, name_space, name, meth_name);
8429 struct names_and_mutex *nm = malloc (sizeof (struct names_and_mutex));
8430 nm->names = names;
8431 pthread_mutex_init (&nm->coord_mutex, NULL);
8432 pthread_cond_init (&nm->coord_cond, NULL);
8433 pthread_mutex_init (&nm->deadlock_mutex, NULL);
8435 pthread_mutex_lock (&nm->deadlock_mutex); // lock the mutex and never unlock it.
8436 pthread_t t;
8437 int res = pthread_create (&t, NULL, invoke_block_foreign_thread, (void*)nm);
8438 g_assert (res == 0);
8439 /* wait for the foreign thread to finish calling the runtime before
8440 * detaching it and returning
8442 pthread_mutex_lock (&nm->coord_mutex);
8443 pthread_cond_wait (&nm->coord_cond, &nm->coord_mutex);
8444 pthread_mutex_unlock (&nm->coord_mutex);
8445 pthread_detach (t);
8446 return 0;
8447 #else
8448 // TODO: Win32 version of this test
8449 return 1;
8450 #endif
8453 #ifdef __cplusplus
8454 } // extern C
8455 #endif