[2019-12] [threads] Add back mono_threads_attach_tools_thread as a public API (#18074)
[mono-project.git] / mono / tests / libtest.c
blobf451b0caf0c301ac03b51e88630b479dfc8e414c
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 "../utils/mono-errno.h"
12 #include "../utils/mono-compiler.h"
14 #ifndef HOST_WIN32
15 #include <dlfcn.h>
16 #endif
18 #ifdef WIN32
19 #include <windows.h>
20 #include "initguid.h"
21 #else
22 #include <pthread.h>
23 #endif
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
29 #ifdef WIN32
30 #define STDCALL __stdcall
31 #else
32 #define STDCALL
33 #define __thiscall /* nothing */
34 #endif
36 #ifdef __GNUC__
37 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
38 #endif
40 #ifdef WIN32
41 extern __declspec(dllimport) void __stdcall CoTaskMemFree(void *ptr);
42 #endif
44 typedef int (STDCALL *SimpleDelegate) (int a);
46 #if defined(WIN32) && defined (_MSC_VER)
47 #define LIBTEST_API __declspec(dllexport)
48 #elif defined(__GNUC__)
49 #define LIBTEST_API __attribute__ ((__visibility__ ("default")))
50 #else
51 #define LIBTEST_API
52 #endif
54 static void marshal_free (void *ptr)
56 #ifdef WIN32
57 CoTaskMemFree (ptr);
58 #else
59 g_free (ptr);
60 #endif
63 static void* marshal_alloc (gsize size)
65 #ifdef WIN32
66 return CoTaskMemAlloc (size);
67 #else
68 return g_malloc (size);
69 #endif
72 static void* marshal_alloc0 (gsize size)
74 #ifdef WIN32
75 void* ptr = CoTaskMemAlloc (size);
76 memset(ptr, 0, size);
77 return ptr;
78 #else
79 return g_malloc0 (size);
80 #endif
83 static char* marshal_strdup (const char *str)
85 #ifdef WIN32
86 if (!str)
87 return NULL;
89 char *buf = (char *) CoTaskMemAlloc (strlen (str) + 1);
90 return strcpy (buf, str);
91 #else
92 return g_strdup (str);
93 #endif
96 static gunichar2* marshal_bstr_alloc(const gchar* str)
98 #ifdef WIN32
99 gunichar2* temp = g_utf8_to_utf16 (str, -1, NULL, NULL, NULL);
100 gunichar2* ret = SysAllocString (temp);
101 g_free (temp);
102 return ret;
103 #else
104 gchar* ret = NULL;
105 int slen = strlen (str);
106 gunichar2* temp;
107 /* allocate len + 1 utf16 characters plus 4 byte integer for length*/
108 ret = (gchar *)g_malloc ((slen + 1) * sizeof(gunichar2) + sizeof(guint32));
109 if (ret == NULL)
110 return NULL;
111 temp = g_utf8_to_utf16 (str, -1, NULL, NULL, NULL);
112 memcpy (ret + sizeof(guint32), temp, slen * sizeof(gunichar2));
113 * ((guint32 *) ret) = slen * sizeof(gunichar2);
114 ret [4 + slen * sizeof(gunichar2)] = 0;
115 ret [5 + slen * sizeof(gunichar2)] = 0;
117 return (gunichar2*)(ret + 4);
118 #endif
121 #define marshal_new0(type,size) ((type *) marshal_alloc0 (sizeof (type)* (size)))
123 LIBTEST_API int STDCALL
124 mono_cominterop_is_supported (void)
126 #if defined(TARGET_X86) || defined(TARGET_AMD64)
127 return 1;
128 #endif
129 return 0;
132 LIBTEST_API unsigned short* STDCALL
133 test_lpwstr_marshal (unsigned short* chars, int length)
135 int i = 0;
136 unsigned short *res;
138 res = (unsigned short *)marshal_alloc (2 * (length + 1));
140 // printf("test_lpwstr_marshal()\n");
142 while ( i < length ) {
143 // printf("X|%u|\n", chars[i]);
144 res [i] = chars[i];
145 i++;
148 res [i] = 0;
150 return res;
154 LIBTEST_API void STDCALL
155 test_lpwstr_marshal_out (unsigned short** chars)
157 int i = 0;
158 const char abc[] = "ABC";
159 glong len = strlen(abc);
161 *chars = (unsigned short *)marshal_alloc (2 * (len + 1));
163 while ( i < len ) {
164 (*chars) [i] = abc[i];
165 i++;
168 (*chars) [i] = 0;
171 typedef struct {
172 int b;
173 int a;
174 int c;
175 } union_test_1_type;
177 LIBTEST_API int STDCALL
178 mono_union_test_1 (union_test_1_type u1) {
179 // printf ("Got values %d %d %d\n", u1.b, u1.a, u1.c);
180 return u1.a + u1.b + u1.c;
183 LIBTEST_API int STDCALL
184 mono_return_int (int a) {
185 // printf ("Got value %d\n", a);
186 return a;
189 LIBTEST_API float STDCALL
190 mono_test_marshal_pass_return_float (float f) {
191 return f + 1.0;
194 struct ss
196 int i;
199 LIBTEST_API int STDCALL
200 mono_return_int_ss (struct ss a) {
201 // printf ("Got value %d\n", a.i);
202 return a.i;
205 LIBTEST_API struct ss STDCALL
206 mono_return_ss (struct ss a) {
207 // printf ("Got value %d\n", a.i);
208 a.i++;
209 return a;
212 struct sc1
214 char c[1];
217 LIBTEST_API struct sc1 STDCALL
218 mono_return_sc1 (struct sc1 a) {
219 // printf ("Got value %d\n", a.c[0]);
220 a.c[0]++;
221 return a;
225 struct sc3
227 char c[3];
230 LIBTEST_API struct sc3 STDCALL
231 mono_return_sc3 (struct sc3 a) {
232 // printf ("Got values %d %d %d\n", a.c[0], a.c[1], a.c[2]);
233 a.c[0]++;
234 a.c[1] += 2;
235 a.c[2] += 3;
236 return a;
239 struct sc5
241 char c[5];
244 LIBTEST_API struct sc5 STDCALL
245 mono_return_sc5 (struct sc5 a) {
246 // printf ("Got values %d %d %d %d %d\n", a.c[0], a.c[1], a.c[2], a.c[3], a.c[4]);
247 a.c[0]++;
248 a.c[1] += 2;
249 a.c[2] += 3;
250 a.c[3] += 4;
251 a.c[4] += 5;
252 return a;
255 union su
257 int i1;
258 int i2;
261 LIBTEST_API int STDCALL
262 mono_return_int_su (union su a) {
263 // printf ("Got value %d\n", a.i1);
264 return a.i1;
267 struct FI {
268 float f1;
269 float f2;
270 float f3;
273 struct NestedFloat {
274 struct FI fi;
275 float f4;
278 LIBTEST_API struct NestedFloat STDCALL
279 mono_return_nested_float (void)
281 struct NestedFloat f;
282 f.fi.f1 = 1.0;
283 f.fi.f2 = 2.0;
284 f.fi.f3 = 3.0;
285 f.f4 = 4.0;
286 return f;
289 struct Scalar4 {
290 double val[4];
293 struct Rect {
294 int x;
295 int y;
296 int width;
297 int height;
300 LIBTEST_API char * STDCALL
301 mono_return_struct_4_double (void *ptr, struct Rect rect, struct Scalar4 sc4, int a, int b, int c)
303 char *buffer = (char *)marshal_alloc (1024 * sizeof (char));
304 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);
305 return buffer;
308 LIBTEST_API int STDCALL
309 mono_test_many_int_arguments (int a, int b, int c, int d, int e,
310 int f, int g, int h, int i, int j);
311 LIBTEST_API short STDCALL
312 mono_test_many_short_arguments (short a, short b, short c, short d, short e,
313 short f, short g, short h, short i, short j);
314 LIBTEST_API char STDCALL
315 mono_test_many_char_arguments (char a, char b, char c, char d, char e,
316 char f, char g, char h, char i, char j);
318 LIBTEST_API int STDCALL
319 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)
321 return a + b + c + d + e + f + g + h + i + j;
324 LIBTEST_API short STDCALL
325 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)
327 return a + b + c + d + e + f + g + h + i + j;
330 LIBTEST_API char STDCALL
331 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)
333 return a + b + c + d + e + f + g + h + i + j;
336 LIBTEST_API float STDCALL
337 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)
339 return a + b + c + d + e + f + g + h + i + j;
342 LIBTEST_API double STDCALL
343 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)
345 return a + b + c + d + e + f + g + h + i + j;
348 LIBTEST_API double STDCALL
349 mono_test_split_double_arguments (double a, double b, float c, double d, double e)
351 return a + b + c + d + e;
354 LIBTEST_API int STDCALL
355 mono_test_puts_static (char *s)
357 // printf ("TEST %s\n", s);
358 return 1;
361 typedef int (STDCALL *SimpleDelegate3) (int a, int b);
363 LIBTEST_API int STDCALL
364 mono_invoke_delegate (SimpleDelegate3 delegate)
366 int res;
368 // printf ("start invoke %p\n", delegate);
370 res = delegate (2, 3);
372 // printf ("end invoke\n");
374 return res;
377 LIBTEST_API int STDCALL
378 mono_invoke_simple_delegate (SimpleDelegate d)
380 return d (4);
383 LIBTEST_API int STDCALL
384 mono_test_marshal_char (short a1)
386 if (a1 == 'a')
387 return 0;
389 return 1;
392 LIBTEST_API void STDCALL
393 mono_test_marshal_char_array (gunichar2 *s)
395 const char m[] = "abcdef";
396 gunichar2* s2;
397 glong len;
399 s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
401 len = (len * 2) + 2;
402 memcpy (s, s2, len);
404 g_free (s2);
407 LIBTEST_API int STDCALL
408 mono_test_marshal_ansi_char_array (char *s)
410 const char m[] = "abcdef";
412 if (strncmp ("qwer", s, 4))
413 return 1;
415 memcpy (s, m, sizeof (m));
416 return 0;
419 LIBTEST_API int STDCALL
420 mono_test_marshal_unicode_char_array (gunichar2 *s)
422 const char m[] = "abcdef";
423 const char expected[] = "qwer";
424 gunichar2 *s1, *s2;
425 glong len1, len2;
427 s1 = g_utf8_to_utf16 (m, -1, NULL, &len1, NULL);
428 s2 = g_utf8_to_utf16 (expected, -1, NULL, &len2, NULL);
429 len1 = (len1 * 2);
430 len2 = (len2 * 2);
432 if (memcmp (s, s2, len2))
433 return 1;
435 memcpy (s, s1, len1);
436 return 0;
439 LIBTEST_API int STDCALL
440 mono_test_empty_pinvoke (int i)
442 return i;
445 LIBTEST_API int STDCALL
446 mono_test_marshal_bool_byref (int a, int *b, int c)
448 int res = *b;
450 *b = 1;
452 return res;
455 LIBTEST_API int STDCALL
456 mono_test_marshal_bool_in_as_I1_U1 (char bTrue, char bFalse)
458 if (!bTrue)
459 return 1;
460 if (bFalse)
461 return 2;
462 return 0;
465 LIBTEST_API int STDCALL
466 mono_test_marshal_bool_out_as_I1_U1 (char* bTrue, char* bFalse)
468 if (!bTrue || !bFalse)
469 return 3;
471 *bTrue = 1;
472 *bFalse = 0;
474 return 0;
477 LIBTEST_API int STDCALL
478 mono_test_marshal_bool_ref_as_I1_U1 (char* bTrue, char* bFalse)
480 if (!bTrue || !bFalse)
481 return 4;
483 if (!(*bTrue))
484 return 5;
485 if (*bFalse)
486 return 6;
488 *bFalse = 1;
489 *bTrue = 0;
491 return 0;
494 LIBTEST_API int STDCALL
495 mono_test_marshal_array (int *a1)
497 int i, sum = 0;
499 for (i = 0; i < 50; i++)
500 sum += a1 [i];
502 return sum;
505 LIBTEST_API int STDCALL
506 mono_test_marshal_inout_array (int *a1)
508 int i, sum = 0;
510 for (i = 0; i < 50; i++) {
511 sum += a1 [i];
512 a1 [i] = 50 - a1 [i];
515 return sum;
518 LIBTEST_API int /* cdecl */
519 mono_test_marshal_inout_array_cdecl (int *a1)
521 return mono_test_marshal_inout_array (a1);
524 LIBTEST_API int STDCALL
525 mono_test_marshal_out_array (int *a1)
527 int i;
529 for (i = 0; i < 50; i++) {
530 a1 [i] = i;
533 return 0;
536 LIBTEST_API int STDCALL
537 mono_test_marshal_out_byref_array_out_size_param (int **out_arr, int *out_len)
539 int *arr;
540 int i, len;
542 len = 4;
543 arr = (gint32 *)marshal_alloc (sizeof (gint32) * len);
544 for (i = 0; i < len; ++i)
545 arr [i] = i;
546 *out_arr = arr;
547 *out_len = len;
549 return 0;
552 LIBTEST_API int STDCALL
553 mono_test_marshal_out_lparray_out_size_param (int *arr, int *out_len)
555 int i, len;
557 len = 4;
558 for (i = 0; i < len; ++i)
559 arr [i] = i;
560 *out_len = len;
562 return 0;
565 LIBTEST_API int STDCALL
566 mono_test_marshal_inout_nonblittable_array (gunichar2 *a1)
568 int i, sum = 0;
570 for (i = 0; i < 10; i++) {
571 a1 [i] = 'F';
574 return sum;
577 typedef struct {
578 int a;
579 int b;
580 int c;
581 const char *d;
582 gunichar2 *d2;
583 } simplestruct;
585 typedef struct {
586 double x;
587 double y;
588 } point;
590 LIBTEST_API simplestruct STDCALL
591 mono_test_return_vtype (int i)
593 simplestruct res;
594 static gunichar2 test2 [] = { 'T', 'E', 'S', 'T', '2', 0 };
596 res.a = 0;
597 res.b = 1;
598 res.c = 0;
599 res.d = "TEST";
600 res.d2 = test2;
602 return res;
605 LIBTEST_API void STDCALL
606 mono_test_delegate_struct (void)
608 // printf ("TEST\n");
611 typedef char* (STDCALL *ReturnStringDelegate) (const char *s);
613 LIBTEST_API char * STDCALL
614 mono_test_return_string (ReturnStringDelegate func)
616 char *res;
618 // printf ("mono_test_return_string\n");
620 res = func ("TEST");
621 marshal_free (res);
623 // printf ("got string: %s\n", res);
624 return marshal_strdup ("12345");
627 typedef int (STDCALL *RefVTypeDelegate) (int a, simplestruct *ss, int b);
629 LIBTEST_API int STDCALL
630 mono_test_ref_vtype (int a, simplestruct *ss, int b, RefVTypeDelegate func)
632 if (a == 1 && b == 2 && ss->a == 0 && ss->b == 1 && ss->c == 0 &&
633 !strcmp (ss->d, "TEST1")) {
634 ss->a = 1;
635 ss->b = 0;
636 ss->c = 1;
637 ss->d = "TEST2";
639 return func (a, ss, b);
642 return 1;
645 typedef int (STDCALL *OutVTypeDelegate) (int a, simplestruct *ss, int b);
647 LIBTEST_API int STDCALL
648 mono_test_marshal_out_struct (int a, simplestruct *ss, int b, OutVTypeDelegate func)
650 /* Check that the input pointer is ignored */
651 ss->d = (const char *)0x12345678;
653 func (a, ss, b);
655 if (ss->a && ss->b && ss->c && !strcmp (ss->d, "TEST3"))
656 return 0;
657 else
658 return 1;
661 typedef int (STDCALL *InVTypeDelegate) (int a, simplestruct *ss, int b);
663 LIBTEST_API int STDCALL
664 mono_test_marshal_in_struct (int a, simplestruct *ss, int b, InVTypeDelegate func)
666 simplestruct ss2;
667 int res;
669 memcpy (&ss2, ss, sizeof (simplestruct));
671 res = func (a, ss, b);
672 if (res) {
673 printf ("mono_test_marshal_in_struct () failed: %d\n", res);
674 return 1;
677 /* Check that no modifications is made to the struct */
678 if (ss2.a == ss->a && ss2.b == ss->b && ss2.c == ss->c && ss2.d == ss->d)
679 return 0;
680 else
681 return 1;
684 typedef struct {
685 int a;
686 SimpleDelegate func, func2, func3;
687 } DelegateStruct;
689 LIBTEST_API DelegateStruct STDCALL
690 mono_test_marshal_delegate_struct (DelegateStruct ds)
692 DelegateStruct res;
694 res.a = ds.func (ds.a) + ds.func2 (ds.a) + (ds.func3 == NULL ? 0 : 1);
695 res.func = ds.func;
696 res.func2 = ds.func2;
697 res.func3 = NULL;
699 return res;
702 LIBTEST_API int STDCALL
703 mono_test_marshal_struct (simplestruct ss)
705 if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
706 !strcmp (ss.d, "TEST"))
707 return 0;
709 return 1;
712 LIBTEST_API int STDCALL
713 mono_test_marshal_byref_struct (simplestruct *ss, int a, int b, int c, char *d)
715 gboolean res = (ss->a == a && ss->b == b && ss->c == c && strcmp (ss->d, d) == 0);
717 marshal_free ((char*)ss->d);
719 ss->a = !ss->a;
720 ss->b = !ss->b;
721 ss->c = !ss->c;
722 ss->d = marshal_strdup ("DEF");
724 return res ? 0 : 1;
727 typedef struct {
728 int a;
729 int b;
730 int c;
731 char *d;
732 unsigned char e;
733 double f;
734 unsigned char g;
735 guint64 h;
736 } simplestruct2;
738 LIBTEST_API int STDCALL
739 mono_test_marshal_struct2 (simplestruct2 ss)
741 if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
742 !strcmp (ss.d, "TEST") &&
743 ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
744 return 0;
746 return 1;
749 /* on HP some of the struct should be on the stack and not in registers */
750 LIBTEST_API int STDCALL
751 mono_test_marshal_struct2_2 (int i, int j, int k, simplestruct2 ss)
753 if (i != 10 || j != 11 || k != 12)
754 return 1;
755 if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
756 !strcmp (ss.d, "TEST") &&
757 ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
758 return 0;
760 return 1;
763 LIBTEST_API int STDCALL
764 mono_test_marshal_lpstruct (simplestruct *ss)
766 if (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
767 !strcmp (ss->d, "TEST"))
768 return 0;
770 return 1;
773 LIBTEST_API int STDCALL
774 mono_test_marshal_lpstruct_blittable (point *p)
776 if (p->x == 1.0 && p->y == 2.0)
777 return 0;
778 else
779 return 1;
782 LIBTEST_API int STDCALL
783 mono_test_marshal_struct_array (simplestruct2 *ss)
785 if (! (ss[0].a == 0 && ss[0].b == 1 && ss[0].c == 0 &&
786 !strcmp (ss[0].d, "TEST") &&
787 ss[0].e == 99 && ss[0].f == 1.5 && ss[0].g == 42 && ss[0].h == (guint64)123))
788 return 1;
790 if (! (ss[1].a == 0 && ss[1].b == 0 && ss[1].c == 0 &&
791 !strcmp (ss[1].d, "TEST2") &&
792 ss[1].e == 100 && ss[1].f == 2.5 && ss[1].g == 43 && ss[1].h == (guint64)124))
793 return 1;
795 return 0;
798 typedef struct long_align_struct {
799 gint32 a;
800 gint64 b;
801 gint64 c;
802 } long_align_struct;
804 LIBTEST_API int STDCALL
805 mono_test_marshal_long_align_struct_array (long_align_struct *ss)
807 return ss[0].a + ss[0].b + ss[0].c + ss[1].a + ss[1].b + ss[1].c;
810 LIBTEST_API simplestruct2 * STDCALL
811 mono_test_marshal_class (int i, int j, int k, simplestruct2 *ss, int l)
813 simplestruct2 *res;
815 if (!ss)
816 return NULL;
818 if (i != 10 || j != 11 || k != 12 || l != 14)
819 return NULL;
820 if (! (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
821 !strcmp (ss->d, "TEST") &&
822 ss->e == 99 && ss->f == 1.5 && ss->g == 42 && ss->h == (guint64)123))
823 return NULL;
825 res = marshal_new0 (simplestruct2, 1);
826 memcpy (res, ss, sizeof (simplestruct2));
827 res->d = marshal_strdup ("TEST");
828 return res;
831 LIBTEST_API int STDCALL
832 mono_test_marshal_byref_class (simplestruct2 **ssp)
834 simplestruct2 *ss = *ssp;
835 simplestruct2 *res;
837 if (! (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
838 !strcmp (ss->d, "TEST") &&
839 ss->e == 99 && ss->f == 1.5 && ss->g == 42 && ss->h == (guint64)123))
840 return 1;
842 res = marshal_new0 (simplestruct2, 1);
843 memcpy (res, ss, sizeof (simplestruct2));
844 res->d = marshal_strdup ("TEST-RES");
846 *ssp = res;
847 return 0;
850 static void *
851 get_sp (void)
853 int i;
854 void *p;
856 /* Yes, this is correct, we are only trying to determine the value of the stack here */
857 p = &i;
858 return p;
861 LIBTEST_API int STDCALL
862 reliable_delegate (int a)
864 return a;
868 * Checks whether get_sp() works as expected. It doesn't work with gcc-2.95.3 on linux.
870 static gboolean
871 is_get_sp_reliable (void)
873 void *sp1, *sp2;
875 reliable_delegate(1);
876 sp1 = get_sp();
877 reliable_delegate(1);
878 sp2 = get_sp();
879 return sp1 == sp2;
882 LIBTEST_API int STDCALL
883 mono_test_marshal_delegate (SimpleDelegate delegate)
885 void *sp1, *sp2;
887 /* Check that the delegate wrapper is stdcall */
888 delegate (2);
889 sp1 = get_sp ();
890 delegate (2);
891 sp2 = get_sp ();
892 if (is_get_sp_reliable())
893 g_assert (sp1 == sp2);
895 return delegate (2);
898 static int STDCALL inc_cb (int i)
900 return i + 1;
903 LIBTEST_API int STDCALL
904 mono_test_marshal_out_delegate (SimpleDelegate *delegate)
906 *delegate = inc_cb;
908 return 0;
911 LIBTEST_API SimpleDelegate STDCALL
912 mono_test_marshal_return_delegate (SimpleDelegate delegate)
914 return delegate;
917 typedef int (STDCALL *DelegateByrefDelegate) (void *);
919 LIBTEST_API int STDCALL
920 mono_test_marshal_delegate_ref_delegate (DelegateByrefDelegate del)
922 int (STDCALL *ptr) (int i);
924 del (&ptr);
926 return ptr (54);
929 static int STDCALL
930 return_plus_one (int i)
932 return i + 1;
935 LIBTEST_API SimpleDelegate STDCALL
936 mono_test_marshal_return_delegate_2 (void)
938 return return_plus_one;
941 typedef simplestruct (STDCALL *SimpleDelegate2) (simplestruct ss);
943 static gboolean
944 is_utf16_equals (gunichar2 *s1, const char *s2)
946 char *s;
947 int res;
949 s = g_utf16_to_utf8 (s1, -1, NULL, NULL, NULL);
950 res = strcmp (s, s2);
951 g_free (s);
953 return res == 0;
956 LIBTEST_API int STDCALL
957 mono_test_marshal_delegate2 (SimpleDelegate2 delegate)
959 simplestruct ss, res;
961 ss.a = 0;
962 ss.b = 1;
963 ss.c = 0;
964 ss.d = "TEST";
965 ss.d2 = g_utf8_to_utf16 ("TEST2", -1, NULL, NULL, NULL);
967 res = delegate (ss);
968 if (! (res.a && !res.b && res.c && !strcmp (res.d, "TEST-RES") && is_utf16_equals (res.d2, "TEST2-RES")))
969 return 1;
971 return 0;
974 typedef simplestruct* (STDCALL *SimpleDelegate4) (simplestruct *ss);
976 LIBTEST_API int STDCALL
977 mono_test_marshal_delegate4 (SimpleDelegate4 delegate)
979 simplestruct ss;
980 simplestruct *res;
982 ss.a = 0;
983 ss.b = 1;
984 ss.c = 0;
985 ss.d = "TEST";
987 /* Check argument */
988 res = delegate (&ss);
989 if (!res)
990 return 1;
992 /* Check return value */
993 if (! (!res->a && res->b && !res->c && !strcmp (res->d, "TEST")))
994 return 2;
996 /* Check NULL argument and NULL result */
997 res = delegate (NULL);
998 if (res)
999 return 3;
1001 return 0;
1004 typedef int (STDCALL *SimpleDelegate5) (simplestruct **ss);
1006 LIBTEST_API int STDCALL
1007 mono_test_marshal_delegate5 (SimpleDelegate5 delegate)
1009 simplestruct ss;
1010 int res;
1011 simplestruct *ptr;
1013 ss.a = 0;
1014 ss.b = 1;
1015 ss.c = 0;
1016 ss.d = "TEST";
1018 ptr = &ss;
1020 res = delegate (&ptr);
1021 if (res != 0)
1022 return 1;
1024 if (!(ptr->a && !ptr->b && ptr->c && !strcmp (ptr->d, "RES")))
1025 return 2;
1027 return 0;
1030 LIBTEST_API int STDCALL
1031 mono_test_marshal_delegate6 (SimpleDelegate5 delegate)
1033 delegate (NULL);
1034 return 0;
1037 typedef int (STDCALL *SimpleDelegate7) (simplestruct **ss);
1039 LIBTEST_API int STDCALL
1040 mono_test_marshal_delegate7 (SimpleDelegate7 delegate)
1042 int res;
1043 simplestruct *ptr;
1045 /* Check that the input pointer is ignored */
1046 ptr = (simplestruct *)0x12345678;
1048 res = delegate (&ptr);
1049 if (res != 0)
1050 return 1;
1052 if (!(ptr->a && !ptr->b && ptr->c && !strcmp (ptr->d, "RES")))
1053 return 2;
1055 return 0;
1058 typedef int (STDCALL *InOutByvalClassDelegate) (simplestruct *ss);
1060 LIBTEST_API int STDCALL
1061 mono_test_marshal_inout_byval_class_delegate (InOutByvalClassDelegate delegate)
1063 int res;
1064 simplestruct ss;
1066 ss.a = FALSE;
1067 ss.b = TRUE;
1068 ss.c = FALSE;
1069 ss.d = g_strdup_printf ("%s", "FOO");
1071 res = delegate (&ss);
1072 if (res != 0)
1073 return 1;
1075 if (!(ss.a && !ss.b && ss.c && !strcmp (ss.d, "RES")))
1076 return 2;
1078 return 0;
1081 typedef int (STDCALL *SimpleDelegate8) (gunichar2 *s);
1083 LIBTEST_API int STDCALL
1084 mono_test_marshal_delegate8 (SimpleDelegate8 delegate, gunichar2 *s)
1086 return delegate (s);
1089 typedef int (STDCALL *return_int_fnt) (int i);
1090 typedef int (STDCALL *SimpleDelegate9) (return_int_fnt d);
1092 LIBTEST_API int STDCALL
1093 mono_test_marshal_delegate9 (SimpleDelegate9 delegate, gpointer ftn)
1095 return delegate ((return_int_fnt)ftn);
1098 static int STDCALL
1099 return_self (int i)
1101 return i;
1104 LIBTEST_API int STDCALL
1105 mono_test_marshal_delegate10 (SimpleDelegate9 delegate)
1107 return delegate (return_self);
1110 typedef int (STDCALL *PrimitiveByrefDelegate) (int *i);
1112 LIBTEST_API int STDCALL
1113 mono_test_marshal_primitive_byref_delegate (PrimitiveByrefDelegate delegate)
1115 int i = 1;
1117 int res = delegate (&i);
1118 if (res != 0)
1119 return res;
1121 if (i != 2)
1122 return 2;
1124 return 0;
1127 typedef int (STDCALL *return_int_delegate) (int i);
1129 typedef return_int_delegate (STDCALL *ReturnDelegateDelegate) (void);
1131 LIBTEST_API int STDCALL
1132 mono_test_marshal_return_delegate_delegate (ReturnDelegateDelegate d)
1134 return (d ()) (55);
1137 typedef int (STDCALL *VirtualDelegate) (int);
1139 LIBTEST_API int STDCALL
1140 mono_test_marshal_virtual_delegate (VirtualDelegate del)
1142 return del (42);
1145 typedef char* (STDCALL *IcallDelegate) (const char *);
1146 LIBTEST_API int STDCALL
1147 mono_test_marshal_icall_delegate (IcallDelegate del)
1149 char *res = del ("ABC");
1150 return strcmp (res, "ABC") == 0 ? 0 : 1;
1153 LIBTEST_API int STDCALL
1154 mono_test_marshal_stringbuilder (char *s, int n)
1156 const char m[] = "This is my message. Isn't it nice?";
1158 if (strcmp (s, "ABCD") != 0)
1159 return 1;
1160 memcpy(s, m, n);
1161 s [n] = '\0';
1162 return 0;
1165 LIBTEST_API int STDCALL
1166 mono_test_marshal_stringbuilder_append (char *s, int length)
1168 const char out_sentinel[] = "CSHARP_";
1169 const char out_len = strlen (out_sentinel);
1171 for (int i=0; i < length; i++) {
1172 s [i] = out_sentinel [i % out_len];
1175 s [length] = '\0';
1178 return 0;
1181 LIBTEST_API int STDCALL
1182 mono_test_marshal_stringbuilder_default (char *s, int n)
1184 const char m[] = "This is my message. Isn't it nice?";
1186 memcpy(s, m, n);
1187 s [n] = '\0';
1188 return 0;
1191 LIBTEST_API int STDCALL
1192 mono_test_marshal_stringbuilder_unicode (gunichar2 *s, int n)
1194 const char m[] = "This is my message. Isn't it nice?";
1195 gunichar2* s2;
1196 glong len;
1198 s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
1200 len = (len * 2) + 2;
1201 if (len > (n * 2))
1202 len = n * 2;
1203 memcpy (s, s2, len);
1205 g_free (s2);
1207 return 0;
1210 LIBTEST_API void STDCALL
1211 mono_test_marshal_stringbuilder_out (char **s)
1213 const char m[] = "This is my message. Isn't it nice?";
1214 char *str;
1216 str = (char *)marshal_alloc (strlen (m) + 1);
1217 memcpy (str, m, strlen (m) + 1);
1219 *s = str;
1222 LIBTEST_API int STDCALL
1223 mono_test_marshal_stringbuilder_out_unicode (gunichar2 **s)
1225 const char m[] = "This is my message. Isn't it nice?";
1226 gunichar2 *s2;
1227 glong len;
1229 s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
1231 len = (len * 2) + 2;
1232 *s = (gunichar2 *)marshal_alloc (len);
1233 memcpy (*s, s2, len);
1235 g_free (s2);
1237 return 0;
1240 LIBTEST_API int STDCALL
1241 mono_test_marshal_stringbuilder_ref (char **s)
1243 const char m[] = "This is my message. Isn't it nice?";
1244 char *str;
1246 if (strcmp (*s, "ABC"))
1247 return 1;
1249 str = (char *)marshal_alloc (strlen (m) + 1);
1250 memcpy (str, m, strlen (m) + 1);
1252 *s = str;
1253 return 0;
1256 LIBTEST_API void STDCALL
1257 mono_test_marshal_stringbuilder_utf16_tolower (short *s, int n)
1259 for (int i = 0; i < n; i++)
1260 s[i] = tolower(s[i]);
1264 #ifdef __GNUC__
1265 #pragma GCC diagnostic push
1266 #pragma GCC diagnostic ignored "-Wc++-compat"
1267 #endif
1270 * Standard C and C++ doesn't allow empty structs, empty structs will always have a size of 1 byte.
1271 * GCC have an extension to allow empty structs, https://gcc.gnu.org/onlinedocs/gcc/Empty-Structures.html.
1272 * This cause a little dilemma since runtime build using none GCC compiler will not be compatible with
1273 * GCC build C libraries and the other way around. On platforms where empty structs has size of 1 byte
1274 * it must be represented in call and cannot be dropped. On Windows x64 structs will always be represented in the call
1275 * meaning that an empty struct must have a representation in the callee in order to correctly follow the ABI used by the
1276 * C/C++ standard and the runtime.
1278 typedef struct {
1279 #if !defined(__GNUC__) || defined(TARGET_WIN32)
1280 char a;
1281 #endif
1282 } EmptyStruct;
1284 #ifdef __GNUC__
1285 #pragma GCC diagnostic pop
1286 #endif
1288 LIBTEST_API int STDCALL
1289 mono_test_marshal_empty_string_array (char **array)
1291 return (array == NULL) ? 0 : 1;
1294 LIBTEST_API int STDCALL
1295 mono_test_marshal_string_array (char **array)
1297 if (strcmp (array [0], "ABC"))
1298 return 1;
1299 if (strcmp (array [1], "DEF"))
1300 return 2;
1302 if (array [2] != NULL)
1303 return 3;
1305 return 0;
1308 LIBTEST_API int STDCALL
1309 mono_test_marshal_byref_string_array (char ***array)
1311 if (*array == NULL)
1312 return 0;
1314 if (strcmp ((*array) [0], "Alpha"))
1315 return 2;
1316 if (strcmp ((*array) [1], "Beta"))
1317 return 2;
1318 if (strcmp ((*array) [2], "Gamma"))
1319 return 2;
1321 return 1;
1324 LIBTEST_API int STDCALL
1325 mono_test_marshal_stringbuilder_array (char **array)
1327 if (strcmp (array [0], "ABC"))
1328 return 1;
1329 if (strcmp (array [1], "DEF"))
1330 return 2;
1332 strcpy (array [0], "DEF");
1333 strcpy (array [1], "ABC");
1335 return 0;
1338 LIBTEST_API int STDCALL
1339 mono_test_marshal_unicode_string_array (gunichar2 **array, char **array2)
1341 GError *gerror = NULL;
1342 char *s;
1344 s = g_utf16_to_utf8 (array [0], -1, NULL, NULL, &gerror);
1345 if (strcmp (s, "ABC")) {
1346 g_free (s);
1347 return 1;
1349 else
1350 g_free (s);
1352 s = g_utf16_to_utf8 (array [1], -1, NULL, NULL, &gerror);
1353 if (strcmp (s, "DEF")) {
1354 g_free (s);
1355 return 2;
1357 else
1358 g_free (s);
1360 if (strcmp (array2 [0], "ABC"))
1361 return 3;
1363 if (strcmp (array2 [1], "DEF"))
1364 return 4;
1366 return 0;
1369 /* this does not work on Redhat gcc 2.96 */
1370 LIBTEST_API int STDCALL
1371 mono_test_empty_struct (int a, EmptyStruct es, int b)
1373 // printf ("mono_test_empty_struct %d %d\n", a, b);
1375 // Intel icc on ia64 passes 'es' in 2 registers
1376 #if defined(__ia64) && defined(__INTEL_COMPILER)
1377 return 0;
1378 #else
1379 if (a == 1 && b == 2)
1380 return 0;
1381 return 1;
1382 #endif
1385 LIBTEST_API EmptyStruct STDCALL
1386 mono_test_return_empty_struct (int a)
1388 EmptyStruct s;
1390 memset (&s, 0, sizeof (s));
1392 #if !(defined(__i386__) && defined(__clang__))
1393 /* https://bugzilla.xamarin.com/show_bug.cgi?id=58901 */
1394 g_assert (a == 42);
1395 #endif
1397 return s;
1400 typedef struct {
1401 char a[100];
1402 } ByValStrStruct;
1404 LIBTEST_API ByValStrStruct * STDCALL
1405 mono_test_byvalstr_gen (void)
1407 ByValStrStruct *ret;
1409 ret = (ByValStrStruct *)malloc (sizeof (ByValStrStruct));
1410 memset(ret, 'a', sizeof(ByValStrStruct)-1);
1411 ret->a[sizeof(ByValStrStruct)-1] = 0;
1413 return ret;
1416 LIBTEST_API int STDCALL
1417 mono_test_byvalstr_check (ByValStrStruct* data, char* correctString)
1419 int ret;
1421 ret = strcmp(data->a, correctString);
1422 // printf ("T1: %s\n", data->a);
1423 // printf ("T2: %s\n", correctString);
1425 /* we need g_free because the allocation was performed by mono_test_byvalstr_gen */
1426 g_free (data);
1427 return (ret != 0);
1430 typedef struct {
1431 guint16 a[4];
1432 int flag;
1433 } ByValStrStruct_Unicode;
1435 LIBTEST_API int STDCALL
1436 mono_test_byvalstr_check_unicode (ByValStrStruct_Unicode *ref, int test)
1438 if (ref->flag != 0x1234abcd){
1439 printf ("overwritten data");
1440 return 1;
1443 if (test == 1 || test == 3){
1444 if (ref->a [0] != '1' ||
1445 ref->a [1] != '2' ||
1446 ref->a [2] != '3')
1447 return 1;
1448 return 0;
1450 if (test == 2){
1451 if (ref->a [0] != '1' ||
1452 ref->a [1] != '2')
1453 return 1;
1454 return 0;
1456 return 10;
1459 LIBTEST_API int STDCALL
1460 NameManglingAnsi (char *data)
1462 return data [0] + data [1] + data [2];
1465 LIBTEST_API int STDCALL
1466 NameManglingAnsiA (char *data)
1468 g_assert_not_reached ();
1471 LIBTEST_API int STDCALL
1472 NameManglingAnsiW (char *data)
1474 g_assert_not_reached ();
1477 LIBTEST_API int STDCALL
1478 NameManglingAnsi2A (char *data)
1480 return data [0] + data [1] + data [2];
1483 LIBTEST_API int STDCALL
1484 NameManglingAnsi2W (char *data)
1486 g_assert_not_reached ();
1489 LIBTEST_API int STDCALL
1490 NameManglingUnicode (char *data)
1492 g_assert_not_reached ();
1495 LIBTEST_API int STDCALL
1496 NameManglingUnicodeW (gunichar2 *data)
1498 return data [0] + data [1] + data [2];
1501 LIBTEST_API int STDCALL
1502 NameManglingUnicode2 (gunichar2 *data)
1504 return data [0] + data [1] + data [2];
1507 LIBTEST_API int STDCALL
1508 NameManglingAutoW (char *data)
1510 #ifdef WIN32
1511 return (data [0] + data [1] + data [2]) == 131 ? 0 : 1;
1512 #else
1513 g_assert_not_reached ();
1514 #endif
1517 LIBTEST_API int STDCALL
1518 NameManglingAuto (char *data)
1520 #ifndef WIN32
1521 return (data [0] + data [1] + data [2]) == 198 ? 0 : 1;
1522 #else
1523 g_assert_not_reached ();
1524 #endif
1527 typedef int (STDCALL *intcharFunc)(const char*);
1529 LIBTEST_API void STDCALL
1530 callFunction (intcharFunc f)
1532 f ("ABC");
1535 typedef struct {
1536 const char* str;
1537 int i;
1538 } SimpleObj;
1540 LIBTEST_API int STDCALL
1541 class_marshal_test0 (SimpleObj *obj1)
1543 // printf ("class_marshal_test0 %s %d\n", obj1->str, obj1->i);
1545 if (strcmp(obj1->str, "T1"))
1546 return -1;
1547 if (obj1->i != 4)
1548 return -2;
1550 return 0;
1553 LIBTEST_API int STDCALL
1554 class_marshal_test4 (SimpleObj *obj1)
1556 if (obj1)
1557 return -1;
1559 return 0;
1562 LIBTEST_API void STDCALL
1563 class_marshal_test1 (SimpleObj **obj1)
1565 SimpleObj *res = (SimpleObj *)malloc (sizeof (SimpleObj));
1567 res->str = marshal_strdup ("ABC");
1568 res->i = 5;
1570 *obj1 = res;
1573 LIBTEST_API int STDCALL
1574 class_marshal_test2 (SimpleObj **obj1)
1576 // printf ("class_marshal_test2 %s %d\n", (*obj1)->str, (*obj1)->i);
1578 if (strcmp((*obj1)->str, "ABC"))
1579 return -1;
1580 if ((*obj1)->i != 5)
1581 return -2;
1583 return 0;
1586 LIBTEST_API int STDCALL
1587 string_marshal_test0 (char *str)
1589 if (strcmp (str, "TEST0"))
1590 return -1;
1592 return 0;
1595 LIBTEST_API void STDCALL
1596 string_marshal_test1 (const char **str)
1598 *str = marshal_strdup ("TEST1");
1601 LIBTEST_API int STDCALL
1602 string_marshal_test2 (char **str)
1604 // printf ("string_marshal_test2 %s\n", *str);
1606 if (strcmp (*str, "TEST1"))
1607 return -1;
1609 *str = marshal_strdup ("TEST2");
1611 return 0;
1614 LIBTEST_API int STDCALL
1615 string_marshal_test3 (char *str)
1617 if (str)
1618 return -1;
1620 return 0;
1623 typedef struct {
1624 int a;
1625 int b;
1626 } BlittableClass;
1628 LIBTEST_API BlittableClass* STDCALL
1629 TestBlittableClass (BlittableClass *vl)
1631 BlittableClass *res;
1633 // printf ("TestBlittableClass %d %d\n", vl->a, vl->b);
1635 if (vl) {
1636 vl->a++;
1637 vl->b++;
1639 res = marshal_new0 (BlittableClass, 1);
1640 memcpy (res, vl, sizeof (BlittableClass));
1641 } else {
1642 res = marshal_new0 (BlittableClass, 1);
1643 res->a = 42;
1644 res->b = 43;
1647 return res;
1650 typedef struct OSVERSIONINFO_STRUCT
1652 int a;
1653 int b;
1654 } OSVERSIONINFO_STRUCT;
1656 LIBTEST_API int STDCALL
1657 MyGetVersionEx (OSVERSIONINFO_STRUCT *osvi)
1660 // printf ("GOT %d %d\n", osvi->a, osvi->b);
1662 osvi->a += 1;
1663 osvi->b += 1;
1665 return osvi->a + osvi->b;
1668 LIBTEST_API int STDCALL
1669 BugGetVersionEx (int a, int b, int c, int d, int e, int f, int g, int h, OSVERSIONINFO_STRUCT *osvi)
1672 // printf ("GOT %d %d\n", osvi->a, osvi->b);
1674 osvi->a += 1;
1675 osvi->b += 1;
1677 return osvi->a + osvi->b;
1680 LIBTEST_API int STDCALL
1681 mono_test_marshal_point (point pt)
1683 // printf("point %g %g\n", pt.x, pt.y);
1684 if (pt.x == 1.25 && pt.y == 3.5)
1685 return 0;
1687 return 1;
1690 typedef struct {
1691 int x;
1692 double y;
1693 } mixed_point;
1695 LIBTEST_API int STDCALL
1696 mono_test_marshal_mixed_point (mixed_point pt)
1698 // printf("mixed point %d %g\n", pt.x, pt.y);
1699 if (pt.x == 5 && pt.y == 6.75)
1700 return 0;
1702 return 1;
1705 LIBTEST_API int STDCALL
1706 mono_test_marshal_mixed_point_2 (mixed_point *pt)
1708 if (pt->x != 5 || pt->y != 6.75)
1709 return 1;
1711 pt->x = 10;
1712 pt->y = 12.35;
1714 return 0;
1717 LIBTEST_API int STDCALL
1718 marshal_test_ref_bool(int i, char *b1, short *b2, int *b3)
1720 int res = 1;
1721 if (*b1 != 0 && *b1 != 1)
1722 return 1;
1723 if (*b2 != 0 && *b2 != -1) /* variant_bool */
1724 return 1;
1725 if (*b3 != 0 && *b3 != 1)
1726 return 1;
1727 if (i == ((*b1 << 2) | (-*b2 << 1) | *b3))
1728 res = 0;
1729 *b1 = !*b1;
1730 *b2 = ~*b2;
1731 *b3 = !*b3;
1732 return res;
1735 struct BoolStruct
1737 int i;
1738 char b1;
1739 short b2; /* variant_bool */
1740 int b3;
1743 LIBTEST_API int STDCALL
1744 marshal_test_bool_struct(struct BoolStruct *s)
1746 int res = 1;
1747 if (s->b1 != 0 && s->b1 != 1)
1748 return 1;
1749 if (s->b2 != 0 && s->b2 != -1)
1750 return 1;
1751 if (s->b3 != 0 && s->b3 != 1)
1752 return 1;
1753 if (s->i == ((s->b1 << 2) | (-s->b2 << 1) | s->b3))
1754 res = 0;
1755 s->b1 = !s->b1;
1756 s->b2 = ~s->b2;
1757 s->b3 = !s->b3;
1758 return res;
1761 typedef struct {
1762 gint64 l;
1763 } LongStruct2;
1765 typedef struct {
1766 int i;
1767 LongStruct2 l;
1768 } LongStruct;
1770 LIBTEST_API int STDCALL
1771 mono_test_marshal_long_struct (LongStruct *s)
1773 return s->i + s->l.l;
1776 LIBTEST_API void STDCALL
1777 mono_test_last_error (int err)
1779 #ifdef WIN32
1780 SetLastError (err);
1783 * Make sure argument register used calling SetLastError
1784 * get's cleaned before returning back to caller. This is done to ensure
1785 * we don't get a undetected failure if error is preserved in register
1786 * on return since we read back value directly when doing p/invoke with SetLastError = true
1787 * into first argument register and then pass it to Mono function setting value in TLS.
1788 * If there is a codegen bug reading last error or the code has been incorrectly eliminated
1789 * this test could still succeed since expected error code could be left in argument register.
1790 * Below code just do something that shouldn't touch last error and won't be optimized away
1791 * but will change the argument registers to something different than err.
1793 char buffer[256] = { 0 };
1794 char value[] = "Dummy";
1795 strncpy (buffer, value, G_N_ELEMENTS (value) - 1);
1796 #else
1797 mono_set_errno (err);
1798 #endif
1801 LIBTEST_API int STDCALL
1802 mono_test_asany (void *ptr, int what)
1804 switch (what) {
1805 case 1:
1806 return (*(int*)ptr == 5) ? 0 : 1;
1807 case 2:
1808 return strcmp ((const char*)ptr, "ABC") == 0 ? 0 : 1;
1809 case 3: {
1810 simplestruct2 ss = *(simplestruct2*)ptr;
1812 if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
1813 !strcmp (ss.d, "TEST") &&
1814 ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
1815 return 0;
1816 else
1817 return 1;
1819 case 4: {
1820 GError *gerror = NULL;
1821 char *s;
1823 s = g_utf16_to_utf8 ((const gunichar2 *)ptr, -1, NULL, NULL, &gerror);
1825 if (!s)
1826 return 1;
1828 if (!strcmp (s, "ABC")) {
1829 g_free (s);
1830 return 0;
1832 else {
1833 g_free (s);
1834 return 1;
1837 default:
1838 g_assert_not_reached ();
1841 return 1;
1844 typedef struct
1846 int i;
1847 int j;
1848 int k;
1849 char *s;
1850 } AsAnyStruct;
1852 LIBTEST_API int STDCALL
1853 mono_test_marshal_asany_in (void* ptr)
1855 AsAnyStruct *asAny = (AsAnyStruct *)ptr;
1856 int res = asAny->i + asAny->j + asAny->k;
1858 return res;
1861 LIBTEST_API int STDCALL
1862 mono_test_marshal_asany_inout (void* ptr)
1864 AsAnyStruct *asAny = (AsAnyStruct *)ptr;
1865 int res = asAny->i + asAny->j + asAny->k;
1867 marshal_free (asAny->s);
1869 asAny->i = 10;
1870 asAny->j = 20;
1871 asAny->k = 30;
1872 asAny->s = 0;
1874 return res;
1877 LIBTEST_API int STDCALL
1878 mono_test_marshal_asany_out (void* ptr)
1880 AsAnyStruct *asAny = (AsAnyStruct *)ptr;
1881 int res = asAny->i + asAny->j + asAny->k;
1883 asAny->i = 10;
1884 asAny->j = 20;
1885 asAny->k = 30;
1886 asAny->s = 0;
1888 return res;
1892 * AMD64 marshalling tests.
1895 typedef struct amd64_struct1 {
1896 int i;
1897 int j;
1898 int k;
1899 int l;
1900 } amd64_struct1;
1902 LIBTEST_API amd64_struct1 STDCALL
1903 mono_test_marshal_amd64_pass_return_struct1 (amd64_struct1 s)
1905 s.i ++;
1906 s.j ++;
1907 s.k ++;
1908 s.l ++;
1910 return s;
1913 LIBTEST_API amd64_struct1 STDCALL
1914 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)
1916 s.i ++;
1917 s.j ++;
1918 s.k ++;
1919 s.l += 1 + i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8;
1921 return s;
1924 typedef struct amd64_struct2 {
1925 int i;
1926 int j;
1927 } amd64_struct2;
1929 LIBTEST_API amd64_struct2 STDCALL
1930 mono_test_marshal_amd64_pass_return_struct2 (amd64_struct2 s)
1932 s.i ++;
1933 s.j ++;
1935 return s;
1938 typedef struct amd64_struct3 {
1939 int i;
1940 } amd64_struct3;
1942 LIBTEST_API amd64_struct3 STDCALL
1943 mono_test_marshal_amd64_pass_return_struct3 (amd64_struct3 s)
1945 s.i ++;
1947 return s;
1950 typedef struct amd64_struct4 {
1951 double d1, d2;
1952 } amd64_struct4;
1954 LIBTEST_API amd64_struct4 STDCALL
1955 mono_test_marshal_amd64_pass_return_struct4 (amd64_struct4 s)
1957 s.d1 ++;
1958 s.d2 ++;
1960 return s;
1964 * IA64 marshalling tests.
1966 typedef struct test_struct5 {
1967 float d1, d2;
1968 } test_struct5;
1970 LIBTEST_API test_struct5 STDCALL
1971 mono_test_marshal_ia64_pass_return_struct5 (double d1, double d2, test_struct5 s, int i, double d3, double d4)
1973 s.d1 += d1 + d2 + i;
1974 s.d2 += d3 + d4 + i;
1976 return s;
1979 typedef struct test_struct6 {
1980 double d1, d2;
1981 } test_struct6;
1983 LIBTEST_API test_struct6 STDCALL
1984 mono_test_marshal_ia64_pass_return_struct6 (double d1, double d2, test_struct6 s, int i, double d3, double d4)
1986 s.d1 += d1 + d2 + i;
1987 s.d2 += d3 + d4;
1989 return s;
1992 static guint32 custom_res [2];
1994 LIBTEST_API void* STDCALL
1995 mono_test_marshal_pass_return_custom (int i, guint32 *ptr, int j)
1997 /* ptr will be freed by CleanupNative, so make a copy */
1998 custom_res [0] = 0; /* not allocated by AllocHGlobal */
1999 custom_res [1] = ptr [1];
2001 return &custom_res;
2004 LIBTEST_API int STDCALL
2005 mono_test_marshal_pass_out_custom (int i, guint32 **ptr, int j)
2007 custom_res [0] = 0;
2008 custom_res [1] = i + j + 10;
2010 *ptr = custom_res;
2012 return 0;
2015 LIBTEST_API int STDCALL
2016 mono_test_marshal_pass_inout_custom (int i, guint32 *ptr, int j)
2018 ptr [0] = 0;
2019 ptr [1] = i + ptr [1] + j;
2021 return 0;
2024 LIBTEST_API int STDCALL
2025 mono_test_marshal_pass_out_byval_custom (int i, guint32 *ptr, int j)
2027 return ptr == NULL ? 0 : 1;
2030 LIBTEST_API int STDCALL
2031 mono_test_marshal_pass_byref_custom (int i, guint32 **ptr, int j)
2033 (*ptr)[1] += i + j;
2035 return 0;
2038 LIBTEST_API void* STDCALL
2039 mono_test_marshal_pass_return_custom2 (int i, guint32 *ptr, int j)
2041 g_assert_not_reached ();
2043 return NULL;
2046 LIBTEST_API void* STDCALL
2047 mono_test_marshal_pass_return_custom_null (int i, guint32 *ptr, int j)
2049 g_assert (ptr == NULL);
2051 return NULL;
2054 typedef void *(STDCALL *PassReturnPtrDelegate) (void *ptr);
2056 LIBTEST_API int STDCALL
2057 mono_test_marshal_pass_return_custom_in_delegate (PassReturnPtrDelegate del)
2059 guint32 buf [2];
2060 guint32 res;
2061 guint32 *ptr;
2063 buf [0] = 0;
2064 buf [1] = 10;
2066 ptr = (guint32 *)del (&buf);
2068 res = ptr [1];
2070 #ifdef WIN32
2071 /* FIXME: Freed with FreeHGlobal */
2072 #else
2073 g_free (ptr);
2074 #endif
2076 return res;
2079 LIBTEST_API int STDCALL
2080 mono_test_marshal_pass_return_custom_null_in_delegate (PassReturnPtrDelegate del)
2082 void *ptr = del (NULL);
2084 return (ptr == NULL) ? 15 : 0;
2087 typedef void (STDCALL *CustomOutParamDelegate) (void **pptr);
2089 LIBTEST_API int STDCALL
2090 mono_test_marshal_custom_out_param_delegate (CustomOutParamDelegate del)
2092 void* pptr = (void*)del;
2094 del (&pptr);
2096 if(pptr != NULL)
2097 return 1;
2099 return 0;
2102 typedef int (STDCALL *ReturnEnumDelegate) (int e);
2104 LIBTEST_API int STDCALL
2105 mono_test_marshal_return_enum_delegate (ReturnEnumDelegate func)
2107 return func (1);
2110 typedef struct {
2111 int a, b, c;
2112 gint64 d;
2113 } BlittableStruct;
2115 typedef BlittableStruct (STDCALL *SimpleDelegate10) (BlittableStruct ss);
2117 LIBTEST_API int STDCALL
2118 mono_test_marshal_blittable_struct_delegate (SimpleDelegate10 delegate)
2120 BlittableStruct ss, res;
2122 ss.a = 1;
2123 ss.b = 2;
2124 ss.c = 3;
2125 ss.d = 55;
2127 res = delegate (ss);
2128 if (! ((res.a == -1) && (res.b == -2) && (res.c == -3) && (res.d == -55)))
2129 return 1;
2131 return 0;
2134 LIBTEST_API int STDCALL
2135 mono_test_stdcall_name_mangling (int a, int b, int c)
2137 return a + b + c;
2140 LIBTEST_API int
2141 mono_test_stdcall_mismatch_1 (int a, int b, int c)
2143 return a + b + c;
2146 LIBTEST_API int STDCALL
2147 mono_test_stdcall_mismatch_2 (int a, int b, int c)
2149 return a + b + c;
2153 * PASSING AND RETURNING SMALL STRUCTURES FROM DELEGATES TESTS
2156 typedef struct {
2157 int i;
2158 } SmallStruct1;
2160 typedef SmallStruct1 (STDCALL *SmallStructDelegate1) (SmallStruct1 ss);
2162 LIBTEST_API int STDCALL
2163 mono_test_marshal_small_struct_delegate1 (SmallStructDelegate1 delegate)
2165 SmallStruct1 ss, res;
2167 ss.i = 1;
2169 res = delegate (ss);
2170 if (! (res.i == -1))
2171 return 1;
2173 return 0;
2176 typedef struct {
2177 gint16 i, j;
2178 } SmallStruct2;
2180 typedef SmallStruct2 (STDCALL *SmallStructDelegate2) (SmallStruct2 ss);
2182 LIBTEST_API int STDCALL
2183 mono_test_marshal_small_struct_delegate2 (SmallStructDelegate2 delegate)
2185 SmallStruct2 ss, res;
2187 ss.i = 2;
2188 ss.j = 3;
2190 res = delegate (ss);
2191 if (! ((res.i == -2) && (res.j == -3)))
2192 return 1;
2194 return 0;
2197 typedef struct {
2198 gint16 i;
2199 gint8 j;
2200 } SmallStruct3;
2202 typedef SmallStruct3 (STDCALL *SmallStructDelegate3) (SmallStruct3 ss);
2204 LIBTEST_API int STDCALL
2205 mono_test_marshal_small_struct_delegate3 (SmallStructDelegate3 delegate)
2207 SmallStruct3 ss, res;
2209 ss.i = 1;
2210 ss.j = 2;
2212 res = delegate (ss);
2213 if (! ((res.i == -1) && (res.j == -2)))
2214 return 1;
2216 return 0;
2219 typedef struct {
2220 gint16 i;
2221 } SmallStruct4;
2223 typedef SmallStruct4 (STDCALL *SmallStructDelegate4) (SmallStruct4 ss);
2225 LIBTEST_API int STDCALL
2226 mono_test_marshal_small_struct_delegate4 (SmallStructDelegate4 delegate)
2228 SmallStruct4 ss, res;
2230 ss.i = 1;
2232 res = delegate (ss);
2233 if (! (res.i == -1))
2234 return 1;
2236 return 0;
2239 typedef struct {
2240 gint64 i;
2241 } SmallStruct5;
2243 typedef SmallStruct5 (STDCALL *SmallStructDelegate5) (SmallStruct5 ss);
2245 LIBTEST_API int STDCALL
2246 mono_test_marshal_small_struct_delegate5 (SmallStructDelegate5 delegate)
2248 SmallStruct5 ss, res;
2250 ss.i = 5;
2252 res = delegate (ss);
2253 if (! (res.i == -5))
2254 return 1;
2256 return 0;
2259 typedef struct {
2260 int i, j;
2261 } SmallStruct6;
2263 typedef SmallStruct6 (STDCALL *SmallStructDelegate6) (SmallStruct6 ss);
2265 LIBTEST_API int STDCALL
2266 mono_test_marshal_small_struct_delegate6 (SmallStructDelegate6 delegate)
2268 SmallStruct6 ss, res;
2270 ss.i = 1;
2271 ss.j = 2;
2273 res = delegate (ss);
2274 if (! ((res.i == -1) && (res.j == -2)))
2275 return 1;
2277 return 0;
2280 typedef struct {
2281 int i;
2282 gint16 j;
2283 } SmallStruct7;
2285 typedef SmallStruct7 (STDCALL *SmallStructDelegate7) (SmallStruct7 ss);
2287 LIBTEST_API int STDCALL
2288 mono_test_marshal_small_struct_delegate7 (SmallStructDelegate7 delegate)
2290 SmallStruct7 ss, res;
2292 ss.i = 1;
2293 ss.j = 2;
2295 res = delegate (ss);
2296 if (! ((res.i == -1) && (res.j == -2)))
2297 return 1;
2299 return 0;
2302 typedef struct {
2303 float i;
2304 } SmallStruct8;
2306 typedef SmallStruct8 (STDCALL *SmallStructDelegate8) (SmallStruct8 ss);
2308 LIBTEST_API int STDCALL
2309 mono_test_marshal_small_struct_delegate8 (SmallStructDelegate8 delegate)
2311 SmallStruct8 ss, res;
2313 ss.i = 1.0;
2315 res = delegate (ss);
2316 if (! ((res.i == -1.0)))
2317 return 1;
2319 return 0;
2322 typedef struct {
2323 double i;
2324 } SmallStruct9;
2326 typedef SmallStruct9 (STDCALL *SmallStructDelegate9) (SmallStruct9 ss);
2328 LIBTEST_API int STDCALL
2329 mono_test_marshal_small_struct_delegate9 (SmallStructDelegate9 delegate)
2331 SmallStruct9 ss, res;
2333 ss.i = 1.0;
2335 res = delegate (ss);
2336 if (! ((res.i == -1.0)))
2337 return 1;
2339 return 0;
2342 typedef struct {
2343 float i, j;
2344 } SmallStruct10;
2346 typedef SmallStruct10 (STDCALL *SmallStructDelegate10) (SmallStruct10 ss);
2348 LIBTEST_API int STDCALL
2349 mono_test_marshal_small_struct_delegate10 (SmallStructDelegate10 delegate)
2351 SmallStruct10 ss, res;
2353 ss.i = 1.0;
2354 ss.j = 2.0;
2356 res = delegate (ss);
2357 if (! ((res.i == -1.0) && (res.j == -2.0)))
2358 return 1;
2360 return 0;
2363 typedef struct {
2364 float i;
2365 int j;
2366 } SmallStruct11;
2368 typedef SmallStruct11 (STDCALL *SmallStructDelegate11) (SmallStruct11 ss);
2370 LIBTEST_API int STDCALL
2371 mono_test_marshal_small_struct_delegate11 (SmallStructDelegate11 delegate)
2373 SmallStruct11 ss, res;
2375 ss.i = 1.0;
2376 ss.j = 2;
2378 res = delegate (ss);
2379 if (! ((res.i == -1.0) && (res.j == -2)))
2380 return 1;
2382 return 0;
2385 typedef int (STDCALL *ArrayDelegate) (int i, char *j, void *arr);
2387 LIBTEST_API int STDCALL
2388 mono_test_marshal_array_delegate (void *arr, int len, ArrayDelegate del)
2390 return del (len, NULL, arr);
2393 typedef int (STDCALL *ArrayDelegateLong) (gint64 i, char *j, void *arr);
2395 LIBTEST_API int STDCALL
2396 mono_test_marshal_array_delegate_long (void *arr, gint64 len, ArrayDelegateLong del)
2398 return del (len, NULL, arr);
2401 LIBTEST_API int STDCALL
2402 mono_test_marshal_out_array_delegate (int *arr, int len, ArrayDelegate del)
2404 del (len, NULL, arr);
2406 if ((arr [0] != 1) || (arr [1] != 2))
2407 return 1;
2408 else
2409 return 0;
2412 typedef gunichar2* (STDCALL *UnicodeStringDelegate) (gunichar2 *message);
2414 LIBTEST_API int STDCALL
2415 mono_test_marshal_return_unicode_string_delegate (UnicodeStringDelegate del)
2417 const char m[] = "abcdef";
2418 gunichar2 *s2, *res;
2419 glong len;
2421 s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
2423 res = del (s2);
2425 marshal_free (res);
2427 return 0;
2430 LIBTEST_API int STDCALL
2431 mono_test_marshal_out_string_array_delegate (char **arr, int len, ArrayDelegate del)
2433 del (len, NULL, arr);
2435 if (!strcmp (arr [0], "ABC") && !strcmp (arr [1], "DEF"))
2436 return 0;
2437 else
2438 return 1;
2441 typedef int (*CdeclDelegate) (int i, int j);
2443 LIBTEST_API int STDCALL
2444 mono_test_marshal_cdecl_delegate (CdeclDelegate del)
2446 int i;
2448 for (i = 0; i < 1000; ++i)
2449 del (1, 2);
2451 return 0;
2454 typedef char** (STDCALL *ReturnStringArrayDelegate) (int i);
2456 LIBTEST_API int STDCALL
2457 mono_test_marshal_return_string_array_delegate (ReturnStringArrayDelegate d)
2459 char **arr = d (2);
2460 int res;
2462 if (arr == NULL)
2463 return 3;
2465 if (strcmp (arr [0], "ABC") || strcmp (arr [1], "DEF"))
2466 res = 1;
2467 else
2468 res = 0;
2470 marshal_free (arr);
2472 return res;
2475 typedef int (STDCALL *ByrefStringDelegate) (char **s);
2477 LIBTEST_API int STDCALL
2478 mono_test_marshal_byref_string_delegate (ByrefStringDelegate d)
2480 char *s = (char*)"ABC";
2481 int res;
2483 res = d (&s);
2484 if (res != 0)
2485 return res;
2487 if (!strcmp (s, "DEF"))
2488 res = 0;
2489 else
2490 res = 2;
2492 marshal_free (s);
2494 return res;
2497 LIBTEST_API int STDCALL
2498 add_delegate (int i, int j)
2500 return i + j;
2503 LIBTEST_API gpointer STDCALL
2504 mono_test_marshal_return_fnptr (void)
2506 return (gpointer)&add_delegate;
2509 LIBTEST_API int STDCALL
2510 mono_xr (int code)
2512 printf ("codigo %x\n", code);
2513 return code + 1234;
2516 typedef struct {
2517 int handle;
2518 } HandleRef;
2520 LIBTEST_API HandleRef STDCALL
2521 mono_xr_as_handle (int code)
2523 HandleRef ref;
2525 memset (&ref, 0, sizeof (ref));
2527 return ref;
2530 typedef struct {
2531 int a;
2532 void *handle1;
2533 void *handle2;
2534 int b;
2535 } HandleStructs;
2537 LIBTEST_API int STDCALL
2538 mono_safe_handle_struct_ref (HandleStructs *x)
2540 printf ("Dingus Ref! \n");
2541 printf ("Values: %d %d %p %p\n", x->a, x->b, x->handle1, x->handle2);
2542 if (x->a != 1234)
2543 return 1;
2544 if (x->b != 8743)
2545 return 2;
2547 if (x->handle1 != (void*) 0x7080feed)
2548 return 3;
2550 if (x->handle2 != (void*) 0x1234abcd)
2551 return 4;
2553 return 0xf00d;
2556 LIBTEST_API int STDCALL
2557 mono_safe_handle_struct (HandleStructs x)
2559 printf ("Dingus Standard! \n");
2560 printf ("Values: %d %d %p %p\n", x.a, x.b, x.handle1, x.handle2);
2561 if (x.a != 1234)
2562 return 1;
2563 if (x.b != 8743)
2564 return 2;
2566 if (x.handle1 != (void*) 0x7080feed)
2567 return 3;
2569 if (x.handle2 != (void*) 0x1234abcd)
2570 return 4;
2572 return 0xf00f;
2575 typedef struct {
2576 void *a;
2577 } TrivialHandle;
2579 LIBTEST_API int STDCALL
2580 mono_safe_handle_struct_simple (TrivialHandle x)
2582 printf ("The value is %p\n", x.a);
2583 return ((int)(gsize)x.a) * 2;
2586 LIBTEST_API int STDCALL
2587 mono_safe_handle_return (void)
2589 return 0x1000f00d;
2592 LIBTEST_API void STDCALL
2593 mono_safe_handle_ref (void **handle)
2595 if (*handle != 0){
2596 *handle = (void *) 0x800d;
2597 return;
2600 *handle = (void *) 0xbad;
2603 LIBTEST_API void* STDCALL
2604 mono_safe_handle_ref_nomod (void **handle)
2606 return *handle;
2609 LIBTEST_API double STDCALL
2610 mono_test_marshal_date_time (double d, double *d2)
2612 *d2 = d;
2613 return d;
2617 * COM INTEROP TESTS
2620 #ifndef WIN32
2622 typedef struct {
2623 guint16 vt;
2624 guint16 wReserved1;
2625 guint16 wReserved2;
2626 guint16 wReserved3;
2627 union {
2628 gint64 llVal;
2629 gint32 lVal;
2630 guint8 bVal;
2631 gint16 iVal;
2632 float fltVal;
2633 double dblVal;
2634 gint16 boolVal;
2635 gunichar2* bstrVal;
2636 gint8 cVal;
2637 guint16 uiVal;
2638 guint32 ulVal;
2639 guint64 ullVal;
2640 gpointer byref;
2641 struct {
2642 gpointer pvRecord;
2643 gpointer pRecInfo;
2646 } VARIANT;
2648 typedef enum {
2649 VARIANT_TRUE = -1,
2650 VARIANT_FALSE = 0
2651 } VariantBool;
2653 typedef enum {
2654 VT_EMPTY = 0,
2655 VT_NULL = 1,
2656 VT_I2 = 2,
2657 VT_I4 = 3,
2658 VT_R4 = 4,
2659 VT_R8 = 5,
2660 VT_CY = 6,
2661 VT_DATE = 7,
2662 VT_BSTR = 8,
2663 VT_DISPATCH = 9,
2664 VT_ERROR = 10,
2665 VT_BOOL = 11,
2666 VT_VARIANT = 12,
2667 VT_UNKNOWN = 13,
2668 VT_DECIMAL = 14,
2669 VT_I1 = 16,
2670 VT_UI1 = 17,
2671 VT_UI2 = 18,
2672 VT_UI4 = 19,
2673 VT_I8 = 20,
2674 VT_UI8 = 21,
2675 VT_INT = 22,
2676 VT_UINT = 23,
2677 VT_VOID = 24,
2678 VT_HRESULT = 25,
2679 VT_PTR = 26,
2680 VT_SAFEARRAY = 27,
2681 VT_CARRAY = 28,
2682 VT_USERDEFINED = 29,
2683 VT_LPSTR = 30,
2684 VT_LPWSTR = 31,
2685 VT_RECORD = 36,
2686 VT_FILETIME = 64,
2687 VT_BLOB = 65,
2688 VT_STREAM = 66,
2689 VT_STORAGE = 67,
2690 VT_STREAMED_OBJECT = 68,
2691 VT_STORED_OBJECT = 69,
2692 VT_BLOB_OBJECT = 70,
2693 VT_CF = 71,
2694 VT_CLSID = 72,
2695 VT_VECTOR = 4096,
2696 VT_ARRAY = 8192,
2697 VT_BYREF = 16384
2698 } VarEnum;
2700 void VariantInit(VARIANT* vt)
2702 vt->vt = VT_EMPTY;
2705 typedef struct
2707 guint32 a;
2708 guint16 b;
2709 guint16 c;
2710 guint8 d[8];
2711 } GUID;
2713 #define S_OK 0
2715 #endif
2717 LIBTEST_API int STDCALL
2718 mono_test_marshal_bstr_in(gunichar2* bstr)
2720 gint32 result = 0;
2721 gchar* bstr_utf8 = g_utf16_to_utf8 (bstr, -1, NULL, NULL, NULL);
2722 result = strcmp("mono_test_marshal_bstr_in", bstr_utf8);
2723 g_free(bstr_utf8);
2724 if (result == 0)
2725 return 0;
2726 return 1;
2729 LIBTEST_API int STDCALL
2730 mono_test_marshal_bstr_out(gunichar2** bstr)
2732 *bstr = marshal_bstr_alloc ("mono_test_marshal_bstr_out");
2733 return 0;
2736 LIBTEST_API int STDCALL
2737 mono_test_marshal_bstr_in_null(gunichar2* bstr)
2739 if (!bstr)
2740 return 0;
2741 return 1;
2744 LIBTEST_API int STDCALL
2745 mono_test_marshal_bstr_out_null(gunichar2** bstr)
2747 *bstr = NULL;
2748 return 0;
2751 LIBTEST_API int STDCALL
2752 mono_test_marshal_variant_in_sbyte(VARIANT variant)
2754 if (variant.vt == VT_I1 && variant.cVal == 100)
2755 return 0;
2756 return 1;
2759 LIBTEST_API int STDCALL
2760 mono_test_marshal_variant_in_byte(VARIANT variant)
2762 if (variant.vt == VT_UI1 && variant.bVal == 100)
2763 return 0;
2764 return 1;
2767 LIBTEST_API int STDCALL
2768 mono_test_marshal_variant_in_short(VARIANT variant)
2770 if (variant.vt == VT_I2 && variant.iVal == 314)
2771 return 0;
2772 return 1;
2775 LIBTEST_API int STDCALL
2776 mono_test_marshal_variant_in_ushort(VARIANT variant)
2778 if (variant.vt == VT_UI2 && variant.uiVal == 314)
2779 return 0;
2780 return 1;
2783 LIBTEST_API int STDCALL
2784 mono_test_marshal_variant_in_int(VARIANT variant)
2786 if (variant.vt == VT_I4 && variant.lVal == 314)
2787 return 0;
2788 return 1;
2791 LIBTEST_API int STDCALL
2792 mono_test_marshal_variant_in_uint(VARIANT variant)
2794 if (variant.vt == VT_UI4 && variant.ulVal == 314)
2795 return 0;
2796 return 1;
2799 LIBTEST_API int STDCALL
2800 mono_test_marshal_variant_in_long(VARIANT variant)
2802 if (variant.vt == VT_I8 && variant.llVal == 314)
2803 return 0;
2804 return 1;
2807 LIBTEST_API int STDCALL
2808 mono_test_marshal_variant_in_ulong(VARIANT variant)
2810 if (variant.vt == VT_UI8 && variant.ullVal == 314)
2811 return 0;
2812 return 1;
2815 LIBTEST_API int STDCALL
2816 mono_test_marshal_variant_in_float(VARIANT variant)
2818 if (variant.vt == VT_R4 && (variant.fltVal - 3.14)/3.14 < .001)
2819 return 0;
2820 return 1;
2823 LIBTEST_API int STDCALL
2824 mono_test_marshal_variant_in_double(VARIANT variant)
2826 if (variant.vt == VT_R8 && (variant.dblVal - 3.14)/3.14 < .001)
2827 return 0;
2828 return 1;
2831 LIBTEST_API int STDCALL
2832 mono_test_marshal_variant_in_bstr(VARIANT variant)
2834 gint32 result = 0;
2835 gchar* bstr_utf8 = g_utf16_to_utf8 (variant.bstrVal, -1, NULL, NULL, NULL);
2836 result = strcmp("PI", bstr_utf8);
2837 g_free(bstr_utf8);
2839 if (variant.vt == VT_BSTR && !result)
2840 return 0;
2841 return 1;
2844 LIBTEST_API int STDCALL
2845 mono_test_marshal_variant_in_bool_true (VARIANT variant)
2847 if (variant.vt == VT_BOOL && variant.boolVal == VARIANT_TRUE)
2848 return 0;
2849 return 1;
2852 LIBTEST_API int STDCALL
2853 mono_test_marshal_variant_in_bool_false (VARIANT variant)
2855 if (variant.vt == VT_BOOL && variant.boolVal == VARIANT_FALSE)
2856 return 0;
2857 return 1;
2860 LIBTEST_API int STDCALL
2861 mono_test_marshal_variant_out_sbyte(VARIANT* variant)
2863 variant->vt = VT_I1;
2864 variant->cVal = 100;
2866 return 0;
2869 LIBTEST_API int STDCALL
2870 mono_test_marshal_variant_out_sbyte_byref(VARIANT* variant)
2872 variant->vt = VT_I1|VT_BYREF;
2873 variant->byref = marshal_alloc(1);
2874 *((gint8*)variant->byref) = 100;
2876 return 0;
2879 LIBTEST_API int STDCALL
2880 mono_test_marshal_variant_out_byte(VARIANT* variant)
2882 variant->vt = VT_UI1;
2883 variant->bVal = 100;
2885 return 0;
2888 LIBTEST_API int STDCALL
2889 mono_test_marshal_variant_out_byte_byref(VARIANT* variant)
2891 variant->vt = VT_UI1|VT_BYREF;
2892 variant->byref = marshal_alloc(1);
2893 *((gint8*)variant->byref) = 100;
2895 return 0;
2898 LIBTEST_API int STDCALL
2899 mono_test_marshal_variant_out_short(VARIANT* variant)
2901 variant->vt = VT_I2;
2902 variant->iVal = 314;
2904 return 0;
2907 LIBTEST_API int STDCALL
2908 mono_test_marshal_variant_out_short_byref(VARIANT* variant)
2910 variant->vt = VT_I2|VT_BYREF;
2911 variant->byref = marshal_alloc(2);
2912 *((gint16*)variant->byref) = 314;
2914 return 0;
2917 LIBTEST_API int STDCALL
2918 mono_test_marshal_variant_out_ushort(VARIANT* variant)
2920 variant->vt = VT_UI2;
2921 variant->uiVal = 314;
2923 return 0;
2926 LIBTEST_API int STDCALL
2927 mono_test_marshal_variant_out_ushort_byref(VARIANT* variant)
2929 variant->vt = VT_UI2|VT_BYREF;
2930 variant->byref = marshal_alloc(2);
2931 *((guint16*)variant->byref) = 314;
2933 return 0;
2936 LIBTEST_API int STDCALL
2937 mono_test_marshal_variant_out_int(VARIANT* variant)
2939 variant->vt = VT_I4;
2940 variant->lVal = 314;
2942 return 0;
2945 LIBTEST_API int STDCALL
2946 mono_test_marshal_variant_out_int_byref(VARIANT* variant)
2948 variant->vt = VT_I4|VT_BYREF;
2949 variant->byref = marshal_alloc(4);
2950 *((gint32*)variant->byref) = 314;
2952 return 0;
2955 LIBTEST_API int STDCALL
2956 mono_test_marshal_variant_out_uint(VARIANT* variant)
2958 variant->vt = VT_UI4;
2959 variant->ulVal = 314;
2961 return 0;
2964 LIBTEST_API int STDCALL
2965 mono_test_marshal_variant_out_uint_byref(VARIANT* variant)
2967 variant->vt = VT_UI4|VT_BYREF;
2968 variant->byref = marshal_alloc(4);
2969 *((guint32*)variant->byref) = 314;
2971 return 0;
2974 LIBTEST_API int STDCALL
2975 mono_test_marshal_variant_out_long(VARIANT* variant)
2977 variant->vt = VT_I8;
2978 variant->llVal = 314;
2980 return 0;
2983 LIBTEST_API int STDCALL
2984 mono_test_marshal_variant_out_long_byref(VARIANT* variant)
2986 variant->vt = VT_I8|VT_BYREF;
2987 variant->byref = marshal_alloc(8);
2988 *((gint64*)variant->byref) = 314;
2990 return 0;
2993 LIBTEST_API int STDCALL
2994 mono_test_marshal_variant_out_ulong(VARIANT* variant)
2996 variant->vt = VT_UI8;
2997 variant->ullVal = 314;
2999 return 0;
3002 LIBTEST_API int STDCALL
3003 mono_test_marshal_variant_out_ulong_byref(VARIANT* variant)
3005 variant->vt = VT_UI8|VT_BYREF;
3006 variant->byref = marshal_alloc(8);
3007 *((guint64*)variant->byref) = 314;
3009 return 0;
3012 LIBTEST_API int STDCALL
3013 mono_test_marshal_variant_out_float(VARIANT* variant)
3015 variant->vt = VT_R4;
3016 variant->fltVal = 3.14;
3018 return 0;
3021 LIBTEST_API int STDCALL
3022 mono_test_marshal_variant_out_float_byref(VARIANT* variant)
3024 variant->vt = VT_R4|VT_BYREF;
3025 variant->byref = marshal_alloc(4);
3026 *((float*)variant->byref) = 3.14;
3028 return 0;
3031 LIBTEST_API int STDCALL
3032 mono_test_marshal_variant_out_double(VARIANT* variant)
3034 variant->vt = VT_R8;
3035 variant->dblVal = 3.14;
3037 return 0;
3040 LIBTEST_API int STDCALL
3041 mono_test_marshal_variant_out_double_byref(VARIANT* variant)
3043 variant->vt = VT_R8|VT_BYREF;
3044 variant->byref = marshal_alloc(8);
3045 *((double*)variant->byref) = 3.14;
3047 return 0;
3050 LIBTEST_API int STDCALL
3051 mono_test_marshal_variant_out_bstr(VARIANT* variant)
3053 variant->vt = VT_BSTR;
3054 variant->bstrVal = marshal_bstr_alloc("PI");
3056 return 0;
3059 LIBTEST_API int STDCALL
3060 mono_test_marshal_variant_out_bstr_byref(VARIANT* variant)
3062 variant->vt = VT_BSTR|VT_BYREF;
3063 variant->byref = marshal_alloc(sizeof(gpointer));
3064 *((gunichar**)variant->byref) = (gunichar*)marshal_bstr_alloc("PI");
3066 return 0;
3069 LIBTEST_API int STDCALL
3070 mono_test_marshal_variant_out_bool_true (VARIANT* variant)
3072 variant->vt = VT_BOOL;
3073 variant->boolVal = VARIANT_TRUE;
3075 return 0;
3078 LIBTEST_API int STDCALL
3079 mono_test_marshal_variant_out_bool_true_byref (VARIANT* variant)
3081 variant->vt = VT_BOOL|VT_BYREF;
3082 variant->byref = marshal_alloc(2);
3083 *((gint16*)variant->byref) = VARIANT_TRUE;
3085 return 0;
3088 LIBTEST_API int STDCALL
3089 mono_test_marshal_variant_out_bool_false (VARIANT* variant)
3091 variant->vt = VT_BOOL;
3092 variant->boolVal = VARIANT_FALSE;
3094 return 0;
3097 LIBTEST_API int STDCALL
3098 mono_test_marshal_variant_out_bool_false_byref (VARIANT* variant)
3100 variant->vt = VT_BOOL|VT_BYREF;
3101 variant->byref = marshal_alloc(2);
3102 *((gint16*)variant->byref) = VARIANT_FALSE;
3104 return 0;
3107 typedef int (STDCALL *VarFunc) (int vt, VARIANT variant);
3108 typedef int (STDCALL *VarRefFunc) (int vt, VARIANT* variant);
3110 LIBTEST_API int STDCALL
3111 mono_test_marshal_variant_in_sbyte_unmanaged(VarFunc func)
3113 VARIANT vt;
3114 vt.vt = VT_I1;
3115 vt.cVal = -100;
3116 return func (VT_I1, vt);
3119 LIBTEST_API int STDCALL
3120 mono_test_marshal_variant_in_byte_unmanaged(VarFunc func)
3122 VARIANT vt;
3123 vt.vt = VT_UI1;
3124 vt.bVal = 100;
3125 return func (VT_UI1, vt);
3128 LIBTEST_API int STDCALL
3129 mono_test_marshal_variant_in_short_unmanaged(VarFunc func)
3131 VARIANT vt;
3132 vt.vt = VT_I2;
3133 vt.iVal = -100;
3134 return func (VT_I2, vt);
3137 LIBTEST_API int STDCALL
3138 mono_test_marshal_variant_in_ushort_unmanaged(VarFunc func)
3140 VARIANT vt;
3141 vt.vt = VT_UI2;
3142 vt.uiVal = 100;
3143 return func (VT_UI2, vt);
3146 LIBTEST_API int STDCALL
3147 mono_test_marshal_variant_in_int_unmanaged(VarFunc func)
3149 VARIANT vt;
3150 vt.vt = VT_I4;
3151 vt.lVal = -100;
3152 return func (VT_I4, vt);
3155 LIBTEST_API int STDCALL
3156 mono_test_marshal_variant_in_uint_unmanaged(VarFunc func)
3158 VARIANT vt;
3159 vt.vt = VT_UI4;
3160 vt.ulVal = 100;
3161 return func (VT_UI4, vt);
3164 LIBTEST_API int STDCALL
3165 mono_test_marshal_variant_in_long_unmanaged(VarFunc func)
3167 VARIANT vt;
3168 vt.vt = VT_I8;
3169 vt.llVal = -100;
3170 return func (VT_I8, vt);
3173 LIBTEST_API int STDCALL
3174 mono_test_marshal_variant_in_ulong_unmanaged(VarFunc func)
3176 VARIANT vt;
3177 vt.vt = VT_UI8;
3178 vt.ullVal = 100;
3179 return func (VT_UI8, vt);
3182 LIBTEST_API int STDCALL
3183 mono_test_marshal_variant_in_float_unmanaged(VarFunc func)
3185 VARIANT vt;
3186 vt.vt = VT_R4;
3187 vt.fltVal = 3.14;
3188 return func (VT_R4, vt);
3191 LIBTEST_API int STDCALL
3192 mono_test_marshal_variant_in_double_unmanaged(VarFunc func)
3194 VARIANT vt;
3195 vt.vt = VT_R8;
3196 vt.dblVal = 3.14;
3197 return func (VT_R8, vt);
3200 LIBTEST_API int STDCALL
3201 mono_test_marshal_variant_in_bstr_unmanaged(VarFunc func)
3203 VARIANT vt;
3204 vt.vt = VT_BSTR;
3205 vt.bstrVal = marshal_bstr_alloc("PI");
3206 return func (VT_BSTR, vt);
3209 LIBTEST_API int STDCALL
3210 mono_test_marshal_variant_in_bool_true_unmanaged(VarFunc func)
3212 VARIANT vt;
3213 vt.vt = VT_BOOL;
3214 vt.boolVal = VARIANT_TRUE;
3215 return func (VT_BOOL, vt);
3218 LIBTEST_API int STDCALL
3219 mono_test_marshal_variant_in_bool_false_unmanaged(VarFunc func)
3221 VARIANT vt;
3222 vt.vt = VT_BOOL;
3223 vt.boolVal = VARIANT_FALSE;
3224 return func (VT_BOOL, vt);
3227 LIBTEST_API int STDCALL
3228 mono_test_marshal_variant_out_sbyte_unmanaged(VarRefFunc func)
3230 VARIANT vt;
3231 VariantInit (&vt);
3232 func (VT_I1, &vt);
3233 if (vt.vt == VT_I1 && vt.cVal == -100)
3234 return 0;
3235 return 1;
3238 LIBTEST_API int STDCALL
3239 mono_test_marshal_variant_out_byte_unmanaged(VarRefFunc func)
3241 VARIANT vt;
3242 VariantInit (&vt);
3243 func (VT_UI1, &vt);
3244 if (vt.vt == VT_UI1 && vt.bVal == 100)
3245 return 0;
3246 return 1;
3249 LIBTEST_API int STDCALL
3250 mono_test_marshal_variant_out_short_unmanaged(VarRefFunc func)
3252 VARIANT vt;
3253 VariantInit (&vt);
3254 func (VT_I2, &vt);
3255 if (vt.vt == VT_I2 && vt.iVal == -100)
3256 return 0;
3257 return 1;
3260 LIBTEST_API int STDCALL
3261 mono_test_marshal_variant_out_ushort_unmanaged(VarRefFunc func)
3263 VARIANT vt;
3264 VariantInit (&vt);
3265 func (VT_UI2, &vt);
3266 if (vt.vt == VT_UI2 && vt.uiVal == 100)
3267 return 0;
3268 return 1;
3271 LIBTEST_API int STDCALL
3272 mono_test_marshal_variant_out_int_unmanaged(VarRefFunc func)
3274 VARIANT vt;
3275 VariantInit (&vt);
3276 func (VT_I4, &vt);
3277 if (vt.vt == VT_I4 && vt.lVal == -100)
3278 return 0;
3279 return 1;
3282 LIBTEST_API int STDCALL
3283 mono_test_marshal_variant_out_uint_unmanaged(VarRefFunc func)
3285 VARIANT vt;
3286 VariantInit (&vt);
3287 func (VT_UI4, &vt);
3288 if (vt.vt == VT_UI4 && vt.ulVal == 100)
3289 return 0;
3290 return 1;
3293 LIBTEST_API int STDCALL
3294 mono_test_marshal_variant_out_long_unmanaged(VarRefFunc func)
3296 VARIANT vt;
3297 VariantInit (&vt);
3298 func (VT_I8, &vt);
3299 if (vt.vt == VT_I8 && vt.llVal == -100)
3300 return 0;
3301 return 1;
3304 LIBTEST_API int STDCALL
3305 mono_test_marshal_variant_out_ulong_unmanaged(VarRefFunc func)
3307 VARIANT vt;
3308 VariantInit (&vt);
3309 func (VT_UI8, &vt);
3310 if (vt.vt == VT_UI8 && vt.ullVal == 100)
3311 return 0;
3312 return 1;
3315 LIBTEST_API int STDCALL
3316 mono_test_marshal_variant_out_float_unmanaged(VarRefFunc func)
3318 VARIANT vt;
3319 VariantInit (&vt);
3320 func (VT_R4, &vt);
3321 if (vt.vt == VT_R4 && fabs (vt.fltVal - 3.14f) < 1e-10)
3322 return 0;
3323 return 1;
3326 LIBTEST_API int STDCALL
3327 mono_test_marshal_variant_out_double_unmanaged(VarRefFunc func)
3329 VARIANT vt;
3330 VariantInit (&vt);
3331 func (VT_R8, &vt);
3332 if (vt.vt == VT_R8 && fabs (vt.dblVal - 3.14) < 1e-10)
3333 return 0;
3334 return 1;
3337 LIBTEST_API int STDCALL
3338 mono_test_marshal_variant_out_bstr_unmanaged(VarRefFunc func)
3340 VARIANT vt;
3341 gchar* bstr_utf8;
3342 gint32 result = 0;
3345 VariantInit (&vt);
3346 func (VT_BSTR, &vt);
3347 bstr_utf8 = g_utf16_to_utf8 (vt.bstrVal, -1, NULL, NULL, NULL);
3348 result = strcmp("PI", bstr_utf8);
3349 g_free(bstr_utf8);
3350 if (vt.vt == VT_BSTR && !result)
3351 return 0;
3352 return 1;
3355 LIBTEST_API int STDCALL
3356 mono_test_marshal_variant_out_bool_true_unmanaged(VarRefFunc func)
3358 VARIANT vt;
3359 VariantInit (&vt);
3360 func (VT_BOOL, &vt);
3361 if (vt.vt == VT_BOOL && vt.boolVal == VARIANT_TRUE)
3362 return 0;
3363 return 1;
3366 LIBTEST_API int STDCALL
3367 mono_test_marshal_variant_out_bool_false_unmanaged(VarRefFunc func)
3369 VARIANT vt;
3370 VariantInit (&vt);
3371 func (VT_BOOL, &vt);
3372 if (vt.vt == VT_BOOL && vt.boolVal == VARIANT_TRUE)
3373 return 0;
3374 return 1;
3377 typedef struct MonoComObject MonoComObject;
3378 typedef struct MonoDefItfObject MonoDefItfObject;
3380 typedef struct
3382 int (STDCALL *QueryInterface)(MonoDefItfObject* pUnk, gpointer riid, gpointer* ppv);
3383 int (STDCALL *AddRef)(MonoDefItfObject* pUnk);
3384 int (STDCALL *Release)(MonoDefItfObject* pUnk);
3385 int (STDCALL *Method)(MonoDefItfObject* pUnk, int *value);
3386 } MonoDefItf;
3388 typedef struct
3390 int (STDCALL *QueryInterface)(MonoComObject* pUnk, gpointer riid, gpointer* ppv);
3391 int (STDCALL *AddRef)(MonoComObject* pUnk);
3392 int (STDCALL *Release)(MonoComObject* pUnk);
3393 int (STDCALL *get_ITest)(MonoComObject* pUnk, MonoComObject* *ppUnk);
3394 int (STDCALL *SByteIn)(MonoComObject* pUnk, char a);
3395 int (STDCALL *ByteIn)(MonoComObject* pUnk, unsigned char a);
3396 int (STDCALL *ShortIn)(MonoComObject* pUnk, short a);
3397 int (STDCALL *UShortIn)(MonoComObject* pUnk, unsigned short a);
3398 int (STDCALL *IntIn)(MonoComObject* pUnk, int a);
3399 int (STDCALL *UIntIn)(MonoComObject* pUnk, unsigned int a);
3400 int (STDCALL *LongIn)(MonoComObject* pUnk, gint64 a);
3401 int (STDCALL *ULongIn)(MonoComObject* pUnk, guint64 a);
3402 int (STDCALL *FloatIn)(MonoComObject* pUnk, float a);
3403 int (STDCALL *DoubleIn)(MonoComObject* pUnk, double a);
3404 int (STDCALL *ITestIn)(MonoComObject* pUnk, MonoComObject* pUnk2);
3405 int (STDCALL *ITestOut)(MonoComObject* pUnk, MonoComObject* *ppUnk);
3406 int (STDCALL *Return22NoICall)(MonoComObject* pUnk);
3407 int (STDCALL *IntOut)(MonoComObject* pUnk, int *a);
3408 int (STDCALL *ArrayIn)(MonoComObject* pUnk, void *array);
3409 int (STDCALL *ArrayIn2)(MonoComObject* pUnk, void *array);
3410 int (STDCALL *ArrayIn3)(MonoComObject* pUnk, void *array);
3411 int (STDCALL *GetDefInterface1)(MonoComObject* pUnk, MonoDefItfObject **iface);
3412 int (STDCALL *GetDefInterface2)(MonoComObject* pUnk, MonoDefItfObject **iface);
3413 } MonoIUnknown;
3415 struct MonoComObject
3417 MonoIUnknown* vtbl;
3418 int m_ref;
3421 struct MonoDefItfObject
3423 MonoDefItf* vtbl;
3426 static GUID IID_ITest = {0, 0, 0, {0,0,0,0,0,0,0,1}};
3427 static GUID IID_IMonoUnknown = {0, 0, 0, {0xc0,0,0,0,0,0,0,0x46}};
3428 static GUID IID_IMonoDispatch = {0x00020400, 0, 0, {0xc0,0,0,0,0,0,0,0x46}};
3429 static GUID IID_INotImplemented = {0x12345678, 0, 0, {0x9a, 0xbc, 0xde, 0xf0, 0, 0, 0, 0}};
3431 LIBTEST_API int STDCALL
3432 MonoQueryInterface(MonoComObject* pUnk, gpointer riid, gpointer* ppv)
3435 *ppv = NULL;
3436 if (!memcmp(riid, &IID_IMonoUnknown, sizeof(GUID))) {
3437 *ppv = pUnk;
3438 return S_OK;
3440 else if (!memcmp(riid, &IID_ITest, sizeof(GUID))) {
3441 *ppv = pUnk;
3442 return S_OK;
3444 else if (!memcmp(riid, &IID_IMonoDispatch, sizeof(GUID))) {
3445 *ppv = pUnk;
3446 return S_OK;
3448 return 0x80004002; //E_NOINTERFACE;
3451 LIBTEST_API int STDCALL
3452 MonoAddRef(MonoComObject* pUnk)
3454 return ++(pUnk->m_ref);
3457 LIBTEST_API int STDCALL
3458 MonoRelease(MonoComObject* pUnk)
3460 return --(pUnk->m_ref);
3463 LIBTEST_API int STDCALL
3464 SByteIn(MonoComObject* pUnk, char a)
3466 return S_OK;
3469 LIBTEST_API int STDCALL
3470 ByteIn(MonoComObject* pUnk, unsigned char a)
3472 return S_OK;
3475 LIBTEST_API int STDCALL
3476 ShortIn(MonoComObject* pUnk, short a)
3478 return S_OK;
3481 LIBTEST_API int STDCALL
3482 UShortIn(MonoComObject* pUnk, unsigned short a)
3484 return S_OK;
3487 LIBTEST_API int STDCALL
3488 IntIn(MonoComObject* pUnk, int a)
3490 return S_OK;
3493 LIBTEST_API int STDCALL
3494 UIntIn(MonoComObject* pUnk, unsigned int a)
3496 return S_OK;
3499 LIBTEST_API int STDCALL
3500 LongIn(MonoComObject* pUnk, gint64 a)
3502 return S_OK;
3505 LIBTEST_API int STDCALL
3506 ULongIn(MonoComObject* pUnk, guint64 a)
3508 return S_OK;
3511 LIBTEST_API int STDCALL
3512 FloatIn(MonoComObject* pUnk, float a)
3514 return S_OK;
3517 LIBTEST_API int STDCALL
3518 DoubleIn(MonoComObject* pUnk, double a)
3520 return S_OK;
3523 LIBTEST_API int STDCALL
3524 ITestIn(MonoComObject* pUnk, MonoComObject *pUnk2)
3526 return S_OK;
3529 LIBTEST_API int STDCALL
3530 ITestOut(MonoComObject* pUnk, MonoComObject* *ppUnk)
3532 return S_OK;
3535 LIBTEST_API int STDCALL
3536 Return22NoICall(MonoComObject* pUnk)
3538 return 22;
3541 LIBTEST_API int STDCALL
3542 IntOut(MonoComObject* pUnk, int *a)
3544 return S_OK;
3547 LIBTEST_API int STDCALL
3548 ArrayIn(MonoComObject* pUnk, void *array)
3550 return S_OK;
3553 LIBTEST_API int STDCALL
3554 ArrayIn2(MonoComObject* pUnk, void *array)
3556 return S_OK;
3559 LIBTEST_API int STDCALL
3560 ArrayIn3(MonoComObject* pUnk, void *array)
3562 return S_OK;
3565 LIBTEST_API int STDCALL
3566 GetDefInterface1(MonoComObject* pUnk, MonoDefItfObject **obj)
3568 return S_OK;
3571 LIBTEST_API int STDCALL
3572 GetDefInterface2(MonoComObject* pUnk, MonoDefItfObject **obj)
3574 return S_OK;
3577 static void create_com_object (MonoComObject** pOut);
3579 LIBTEST_API int STDCALL
3580 get_ITest(MonoComObject* pUnk, MonoComObject* *ppUnk)
3582 create_com_object (ppUnk);
3583 return S_OK;
3586 static void create_com_object (MonoComObject** pOut)
3588 *pOut = marshal_new0 (MonoComObject, 1);
3589 (*pOut)->vtbl = marshal_new0 (MonoIUnknown, 1);
3591 (*pOut)->m_ref = 1;
3592 (*pOut)->vtbl->QueryInterface = MonoQueryInterface;
3593 (*pOut)->vtbl->AddRef = MonoAddRef;
3594 (*pOut)->vtbl->Release = MonoRelease;
3595 (*pOut)->vtbl->SByteIn = SByteIn;
3596 (*pOut)->vtbl->ByteIn = ByteIn;
3597 (*pOut)->vtbl->ShortIn = ShortIn;
3598 (*pOut)->vtbl->UShortIn = UShortIn;
3599 (*pOut)->vtbl->IntIn = IntIn;
3600 (*pOut)->vtbl->UIntIn = UIntIn;
3601 (*pOut)->vtbl->LongIn = LongIn;
3602 (*pOut)->vtbl->ULongIn = ULongIn;
3603 (*pOut)->vtbl->FloatIn = FloatIn;
3604 (*pOut)->vtbl->DoubleIn = DoubleIn;
3605 (*pOut)->vtbl->ITestIn = ITestIn;
3606 (*pOut)->vtbl->ITestOut = ITestOut;
3607 (*pOut)->vtbl->get_ITest = get_ITest;
3608 (*pOut)->vtbl->Return22NoICall = Return22NoICall;
3609 (*pOut)->vtbl->IntOut = IntOut;
3610 (*pOut)->vtbl->ArrayIn = ArrayIn;
3611 (*pOut)->vtbl->ArrayIn2 = ArrayIn2;
3612 (*pOut)->vtbl->ArrayIn3 = ArrayIn3;
3613 (*pOut)->vtbl->GetDefInterface1 = GetDefInterface1;
3614 (*pOut)->vtbl->GetDefInterface2 = GetDefInterface2;
3617 static MonoComObject* same_object = NULL;
3619 LIBTEST_API int STDCALL
3620 mono_test_marshal_com_object_create(MonoComObject* *pUnk)
3622 create_com_object (pUnk);
3624 if (!same_object)
3625 same_object = *pUnk;
3627 return 0;
3630 LIBTEST_API int STDCALL
3631 mono_test_marshal_com_object_same(MonoComObject* *pUnk)
3633 *pUnk = same_object;
3635 return 0;
3638 LIBTEST_API int STDCALL
3639 mono_test_marshal_com_object_destroy(MonoComObject *pUnk)
3641 int ref = --(pUnk->m_ref);
3642 g_free(pUnk->vtbl);
3643 g_free(pUnk);
3645 return ref;
3648 LIBTEST_API int STDCALL
3649 mono_test_marshal_com_object_ref_count(MonoComObject *pUnk)
3651 return pUnk->m_ref;
3654 LIBTEST_API int STDCALL
3655 mono_test_marshal_ccw_itest (MonoComObject *pUnk)
3657 int hr = 0;
3658 MonoComObject* pTest;
3660 if (!pUnk)
3661 return 1;
3663 hr = pUnk->vtbl->SByteIn (pUnk, -100);
3664 if (hr != 0)
3665 return 2;
3666 hr = pUnk->vtbl->ByteIn (pUnk, 100);
3667 if (hr != 0)
3668 return 3;
3669 hr = pUnk->vtbl->ShortIn (pUnk, -100);
3670 if (hr != 0)
3671 return 4;
3672 hr = pUnk->vtbl->UShortIn (pUnk, 100);
3673 if (hr != 0)
3674 return 5;
3675 hr = pUnk->vtbl->IntIn (pUnk, -100);
3676 if (hr != 0)
3677 return 6;
3678 hr = pUnk->vtbl->UIntIn (pUnk, 100);
3679 if (hr != 0)
3680 return 7;
3681 hr = pUnk->vtbl->LongIn (pUnk, -100);
3682 if (hr != 0)
3683 return 8;
3684 hr = pUnk->vtbl->ULongIn (pUnk, 100);
3685 if (hr != 0)
3686 return 9;
3687 hr = pUnk->vtbl->FloatIn (pUnk, 3.14f);
3688 if (hr != 0)
3689 return 10;
3690 hr = pUnk->vtbl->DoubleIn (pUnk, 3.14);
3691 if (hr != 0)
3692 return 11;
3693 hr = pUnk->vtbl->ITestIn (pUnk, pUnk);
3694 if (hr != 0)
3695 return 12;
3696 hr = pUnk->vtbl->ITestOut (pUnk, &pTest);
3697 if (hr != 0)
3698 return 13;
3700 return 0;
3703 // Xamarin-47560
3704 LIBTEST_API int STDCALL
3705 mono_test_marshal_array_ccw_itest (int count, MonoComObject ** ppUnk)
3707 int hr = 0;
3709 if (!ppUnk)
3710 return 1;
3712 if (count < 1)
3713 return 2;
3715 if (!ppUnk[0])
3716 return 3;
3718 hr = ppUnk[0]->vtbl->SByteIn (ppUnk[0], -100);
3719 if (hr != 0)
3720 return 4;
3722 return 0;
3725 LIBTEST_API int STDCALL
3726 mono_test_marshal_retval_ccw_itest (MonoComObject *pUnk, int test_null)
3728 int hr = 0, i = 0;
3730 if (!pUnk)
3731 return 1;
3733 hr = pUnk->vtbl->IntOut (pUnk, &i);
3734 if (hr != 0)
3735 return 2;
3736 if (i != 33)
3737 return 3;
3738 if (test_null)
3740 hr = pUnk->vtbl->IntOut (pUnk, NULL);
3741 if (hr != 0)
3742 return 4;
3745 return 0;
3748 LIBTEST_API int STDCALL
3749 mono_test_default_interface_ccw (MonoComObject *pUnk)
3751 MonoDefItfObject *obj;
3752 int ret, value;
3754 ret = pUnk->vtbl->GetDefInterface1(pUnk, &obj);
3755 if (ret)
3756 return 1;
3757 value = 0;
3759 ret = obj->vtbl->Method(obj, &value);
3760 obj->vtbl->Release(obj);
3761 if (ret)
3762 return 2;
3763 if (value != 1)
3764 return 3;
3766 ret = pUnk->vtbl->GetDefInterface2(pUnk, &obj);
3767 if (ret)
3768 return 4;
3769 ret = obj->vtbl->Method(obj, &value);
3770 obj->vtbl->Release(obj);
3771 if (ret)
3772 return 5;
3773 if (value != 2)
3774 return 6;
3776 return 0;
3780 * mono_method_get_unmanaged_thunk tests
3783 #if defined(__GNUC__) && ((defined(__i386__) && (defined(__linux__) || defined (__APPLE__)) || defined (__FreeBSD__) || defined(__OpenBSD__)) || (defined(__ppc__) && defined(__APPLE__)))
3784 #define ALIGN(size) __attribute__ ((__aligned__(size)))
3785 #else
3786 #define ALIGN(size)
3787 #endif
3790 /* thunks.cs:TestStruct */
3791 typedef struct _TestStruct {
3792 int A;
3793 double B;
3794 } TestStruct;
3796 /* Searches for mono symbols in all loaded modules */
3797 static gpointer
3798 lookup_mono_symbol (const char *symbol_name)
3800 gpointer symbol = NULL;
3801 const gboolean success = g_module_symbol (g_module_open (NULL, G_MODULE_BIND_LAZY), symbol_name, &symbol);
3802 g_assertf (success, "%s", symbol_name);
3803 return success ? symbol : NULL;
3806 LIBTEST_API gpointer STDCALL
3807 mono_test_marshal_lookup_symbol (const char *symbol_name)
3809 return lookup_mono_symbol (symbol_name);
3813 // FIXME use runtime headers
3814 #define MONO_BEGIN_EFRAME { void *__dummy; void *__region_cookie = mono_threads_enter_gc_unsafe_region ? mono_threads_enter_gc_unsafe_region (&__dummy) : NULL;
3815 #define MONO_END_EFRAME if (mono_threads_exit_gc_unsafe_region) mono_threads_exit_gc_unsafe_region (__region_cookie, &__dummy); }
3818 * test_method_thunk:
3820 * @test_id: the test number
3821 * @test_method_handle: MonoMethod* of the C# test method
3822 * @create_object_method_handle: MonoMethod* of thunks.cs:Test.CreateObject
3824 LIBTEST_API int STDCALL
3825 test_method_thunk (int test_id, gpointer test_method_handle, gpointer create_object_method_handle)
3827 int ret = 0;
3829 // FIXME use runtime headers
3830 gpointer (*mono_method_get_unmanaged_thunk)(gpointer)
3831 = (gpointer (*)(gpointer))lookup_mono_symbol ("mono_method_get_unmanaged_thunk");
3833 // FIXME use runtime headers
3834 gpointer (*mono_string_new_wrapper)(const char *)
3835 = (gpointer (*)(const char *))lookup_mono_symbol ("mono_string_new_wrapper");
3837 // FIXME use runtime headers
3838 char *(*mono_string_to_utf8)(gpointer)
3839 = (char *(*)(gpointer))lookup_mono_symbol ("mono_string_to_utf8");
3841 // FIXME use runtime headers
3842 gpointer (*mono_object_unbox)(gpointer)
3843 = (gpointer (*)(gpointer))lookup_mono_symbol ("mono_object_unbox");
3845 // FIXME use runtime headers
3846 gpointer (*mono_threads_enter_gc_unsafe_region) (gpointer)
3847 = (gpointer (*)(gpointer))lookup_mono_symbol ("mono_threads_enter_gc_unsafe_region");
3849 // FIXME use runtime headers
3850 void (*mono_threads_exit_gc_unsafe_region) (gpointer, gpointer)
3851 = (void (*)(gpointer, gpointer))lookup_mono_symbol ("mono_threads_exit_gc_unsafe_region");
3855 gpointer test_method, ex = NULL;
3856 gpointer (STDCALL *CreateObject)(gpointer*);
3858 MONO_BEGIN_EFRAME;
3860 if (!mono_method_get_unmanaged_thunk) {
3861 ret = 1;
3862 goto done;
3865 test_method = mono_method_get_unmanaged_thunk (test_method_handle);
3866 if (!test_method) {
3867 ret = 2;
3868 goto done;
3871 CreateObject = (gpointer (STDCALL *)(gpointer *))mono_method_get_unmanaged_thunk (create_object_method_handle);
3872 if (!CreateObject) {
3873 ret = 3;
3874 goto done;
3878 switch (test_id) {
3880 case 0: {
3881 /* thunks.cs:Test.Test0 */
3882 void (STDCALL *F)(gpointer *) = (void (STDCALL *)(gpointer *))test_method;
3883 F (&ex);
3884 break;
3887 case 1: {
3888 /* thunks.cs:Test.Test1 */
3889 int (STDCALL *F)(gpointer *) = (int (STDCALL *)(gpointer *))test_method;
3890 if (F (&ex) != 42) {
3891 ret = 4;
3892 goto done;
3894 break;
3897 case 2: {
3898 /* thunks.cs:Test.Test2 */
3899 gpointer (STDCALL *F)(gpointer, gpointer*) = (gpointer (STDCALL *)(gpointer, gpointer *))test_method;
3900 gpointer str = mono_string_new_wrapper ("foo");
3901 if (str != F (str, &ex)) {
3902 ret = 4;
3903 goto done;
3905 break;
3908 case 3: {
3909 /* thunks.cs:Test.Test3 */
3910 gpointer (STDCALL *F)(gpointer, gpointer, gpointer*);
3911 gpointer obj;
3912 gpointer str;
3914 F = (gpointer (STDCALL *)(gpointer, gpointer, gpointer *))test_method;
3915 obj = CreateObject (&ex);
3916 str = mono_string_new_wrapper ("bar");
3918 if (str != F (obj, str, &ex)) {
3919 ret = 4;
3920 goto done;
3922 break;
3925 case 4: {
3926 /* thunks.cs:Test.Test4 */
3927 int (STDCALL *F)(gpointer, gpointer, int, gpointer*);
3928 gpointer obj;
3929 gpointer str;
3931 F = (int (STDCALL *)(gpointer, gpointer, int, gpointer *))test_method;
3932 obj = CreateObject (&ex);
3933 str = mono_string_new_wrapper ("bar");
3935 if (42 != F (obj, str, 42, &ex)) {
3936 ret = 4;
3937 goto done;
3940 break;
3943 case 5: {
3944 /* thunks.cs:Test.Test5 */
3945 int (STDCALL *F)(gpointer, gpointer, int, gpointer*);
3946 gpointer obj;
3947 gpointer str;
3949 F = (int (STDCALL *)(gpointer, gpointer, int, gpointer *))test_method;
3950 obj = CreateObject (&ex);
3951 str = mono_string_new_wrapper ("bar");
3953 F (obj, str, 42, &ex);
3954 if (!ex) {
3955 ret = 4;
3956 goto done;
3959 break;
3962 case 6: {
3963 /* thunks.cs:Test.Test6 */
3964 int (STDCALL *F)(gpointer, guint8, gint16, gint32, gint64, float, double,
3965 gpointer, gpointer*);
3966 gpointer obj;
3967 gpointer str = mono_string_new_wrapper ("Test6");
3968 int res;
3970 F = (int (STDCALL *)(gpointer, guint8, gint16, gint32, gint64, float, double, gpointer, gpointer *))test_method;
3971 obj = CreateObject (&ex);
3973 res = F (obj, 254, 32700, -245378, 6789600, 3.1415, 3.1415, str, &ex);
3974 if (ex) {
3975 ret = 4;
3976 goto done;
3979 if (!res) {
3980 ret = 5;
3981 goto done;
3984 break;
3987 case 7: {
3988 /* thunks.cs:Test.Test7 */
3989 gint64 (STDCALL *F)(gpointer*) = (gint64 (STDCALL *)(gpointer *))test_method;
3990 if (F (&ex) != G_MAXINT64) {
3991 ret = 4;
3992 goto done;
3994 break;
3997 case 8: {
3998 /* thunks.cs:Test.Test8 */
3999 void (STDCALL *F)(guint8*, gint16*, gint32*, gint64*, float*, double*,
4000 gpointer*, gpointer*);
4002 guint8 a1;
4003 gint16 a2;
4004 gint32 a3;
4005 gint64 a4;
4006 float a5;
4007 double a6;
4008 gpointer a7;
4010 F = (void (STDCALL *)(guint8 *, gint16 *, gint32 *, gint64 *, float *, double *,
4011 gpointer *, gpointer *))test_method;
4013 F (&a1, &a2, &a3, &a4, &a5, &a6, &a7, &ex);
4014 if (ex) {
4015 ret = 4;
4016 goto done;
4019 if (!(a1 == 254 &&
4020 a2 == 32700 &&
4021 a3 == -245378 &&
4022 a4 == 6789600 &&
4023 (fabs (a5 - 3.1415) < 0.001) &&
4024 (fabs (a6 - 3.1415) < 0.001) &&
4025 strcmp (mono_string_to_utf8 (a7), "Test8") == 0)){
4026 ret = 5;
4027 goto done;
4030 break;
4033 case 9: {
4034 /* thunks.cs:Test.Test9 */
4035 void (STDCALL *F)(guint8*, gint16*, gint32*, gint64*, float*, double*,
4036 gpointer*, gpointer*);
4038 guint8 a1;
4039 gint16 a2;
4040 gint32 a3;
4041 gint64 a4;
4042 float a5;
4043 double a6;
4044 gpointer a7;
4046 F = (void (STDCALL *)(guint8 *, gint16 *, gint32 *, gint64 *, float *, double *,
4047 gpointer *, gpointer *))test_method;
4049 F (&a1, &a2, &a3, &a4, &a5, &a6, &a7, &ex);
4050 if (!ex) {
4051 ret = 4;
4052 goto done;
4055 break;
4058 case 10: {
4059 /* thunks.cs:Test.Test10 */
4060 void (STDCALL *F)(gpointer*, gpointer*);
4062 gpointer obj1, obj2;
4064 obj1 = obj2 = CreateObject (&ex);
4065 if (ex) {
4066 ret = 4;
4067 goto done;
4070 F = (void (STDCALL *)(gpointer *, gpointer *))test_method;
4072 F (&obj1, &ex);
4073 if (ex) {
4074 ret = 5;
4075 goto done;
4078 if (obj1 == obj2) {
4079 ret = 6;
4080 goto done;
4083 break;
4086 case 100: {
4087 /* thunks.cs:TestStruct.Test0 */
4088 int (STDCALL *F)(gpointer*, gpointer*);
4090 gpointer obj;
4091 TestStruct *a1;
4092 int res;
4094 obj = CreateObject (&ex);
4095 if (ex) {
4096 ret = 4;
4097 goto done;
4100 if (!obj) {
4101 ret = 5;
4102 goto done;
4105 a1 = (TestStruct *)mono_object_unbox (obj);
4106 if (!a1) {
4107 ret = 6;
4108 goto done;
4111 a1->A = 42;
4112 a1->B = 3.1415;
4114 F = (int (STDCALL *)(gpointer *, gpointer *))test_method;
4116 res = F ((gpointer *)obj, &ex);
4117 if (ex) {
4118 ret = 7;
4119 goto done;
4122 if (!res) {
4123 ret = 8;
4124 goto done;
4127 /* check whether the call was really by value */
4128 if (a1->A != 42 || a1->B != 3.1415) {
4129 ret = 9;
4130 goto done;
4133 break;
4136 case 101: {
4137 /* thunks.cs:TestStruct.Test1 */
4138 void (STDCALL *F)(gpointer, gpointer*);
4140 TestStruct *a1;
4141 gpointer obj;
4143 obj = CreateObject (&ex);
4144 if (ex) {
4145 ret = 4;
4146 goto done;
4149 if (!obj) {
4150 ret = 5;
4151 goto done;
4154 a1 = (TestStruct *)mono_object_unbox (obj);
4155 if (!a1) {
4156 ret = 6;
4157 goto done;
4160 F = (void (STDCALL *)(gpointer, gpointer *))test_method;
4162 F (obj, &ex);
4163 if (ex) {
4164 ret = 7;
4165 goto done;
4168 if (a1->A != 42) {
4169 ret = 8;
4170 goto done;
4173 if (!(fabs (a1->B - 3.1415) < 0.001)) {
4174 ret = 9;
4175 goto done;
4178 break;
4181 case 102: {
4182 /* thunks.cs:TestStruct.Test2 */
4183 gpointer (STDCALL *F)(gpointer*);
4185 TestStruct *a1;
4186 gpointer obj;
4188 F = (gpointer (STDCALL *)(gpointer *))test_method;
4190 obj = F (&ex);
4191 if (ex) {
4192 ret = 4;
4193 goto done;
4196 if (!obj) {
4197 ret = 5;
4198 goto done;
4201 a1 = (TestStruct *)mono_object_unbox (obj);
4203 if (a1->A != 42) {
4204 ret = 5;
4205 goto done;
4208 if (!(fabs (a1->B - 3.1415) < 0.001)) {
4209 ret = 6;
4210 goto done;
4213 break;
4216 case 103: {
4217 /* thunks.cs:TestStruct.Test3 */
4218 void (STDCALL *F)(gpointer, gpointer*);
4220 TestStruct *a1;
4221 gpointer obj;
4223 obj = CreateObject (&ex);
4224 if (ex) {
4225 ret = 4;
4226 goto done;
4229 if (!obj) {
4230 ret = 5;
4231 goto done;
4234 a1 = (TestStruct *)mono_object_unbox (obj);
4236 if (!a1) {
4237 ret = 6;
4238 goto done;
4241 a1->A = 42;
4242 a1->B = 3.1415;
4244 F = (void (STDCALL *)(gpointer, gpointer *))test_method;
4246 F (obj, &ex);
4247 if (ex) {
4248 ret = 4;
4249 goto done;
4252 if (a1->A != 1) {
4253 ret = 5;
4254 goto done;
4257 if (a1->B != 17) {
4258 ret = 6;
4259 goto done;
4262 break;
4265 default:
4266 ret = 9;
4269 done:
4270 MONO_END_EFRAME;
4272 return ret;
4275 typedef struct
4277 char a;
4278 } winx64_struct1;
4280 LIBTEST_API int STDCALL
4281 mono_test_Winx64_struct1_in (winx64_struct1 var)
4283 if (var.a != 123)
4284 return 1;
4285 return 0;
4288 typedef struct
4290 char a;
4291 char b;
4292 } winx64_struct2;
4294 LIBTEST_API int STDCALL
4295 mono_test_Winx64_struct2_in (winx64_struct2 var)
4297 if (var.a != 4)
4298 return 1;
4299 if (var.b != 5)
4300 return 2;
4301 return 0;
4305 typedef struct
4307 char a;
4308 char b;
4309 short c;
4310 } winx64_struct3;
4312 LIBTEST_API int STDCALL
4313 mono_test_Winx64_struct3_in (winx64_struct3 var)
4315 if (var.a != 4)
4316 return 1;
4317 if (var.b != 5)
4318 return 2;
4319 if (var.c != 0x1234)
4320 return 3;
4321 return 0;
4324 typedef struct
4326 char a;
4327 char b;
4328 short c;
4329 unsigned int d;
4330 } winx64_struct4;
4332 LIBTEST_API int STDCALL
4333 mono_test_Winx64_struct4_in (winx64_struct4 var)
4335 if (var.a != 4)
4336 return 1;
4337 if (var.b != 5)
4338 return 2;
4339 if (var.c != 0x1234)
4340 return 3;
4341 if (var.d != 0x87654321)
4342 return 4;
4343 return 0;
4346 typedef struct
4348 char a;
4349 char b;
4350 char c;
4351 } winx64_struct5;
4353 LIBTEST_API int STDCALL
4354 mono_test_Winx64_struct5_in (winx64_struct5 var)
4356 if (var.a != 4)
4357 return 1;
4358 if (var.b != 5)
4359 return 2;
4360 if (var.c != 6)
4361 return 3;
4362 return 0;
4365 typedef struct
4367 winx64_struct1 a;
4368 short b;
4369 char c;
4370 } winx64_struct6;
4372 LIBTEST_API int STDCALL
4373 mono_test_Winx64_struct6_in (winx64_struct6 var)
4375 if (var.a.a != 4)
4376 return 1;
4377 if (var.b != 5)
4378 return 2;
4379 if (var.c != 6)
4380 return 3;
4381 return 0;
4384 LIBTEST_API int STDCALL
4385 mono_test_Winx64_structs_in1 (winx64_struct1 var1,
4386 winx64_struct2 var2,
4387 winx64_struct3 var3,
4388 winx64_struct4 var4)
4390 if (var1.a != 123)
4391 return 1;
4393 if (var2.a != 4)
4394 return 2;
4395 if (var2.b != 5)
4396 return 3;
4398 if (var3.a != 4)
4399 return 4;
4400 if (var3.b != 5)
4401 return 2;
4402 if (var3.c != 0x1234)
4403 return 5;
4405 if (var4.a != 4)
4406 return 6;
4407 if (var4.b != 5)
4408 return 7;
4409 if (var4.c != 0x1234)
4410 return 8;
4411 if (var4.d != 0x87654321)
4412 return 9;
4413 return 0;
4416 LIBTEST_API int STDCALL
4417 mono_test_Winx64_structs_in2 (winx64_struct1 var1,
4418 winx64_struct1 var2,
4419 winx64_struct1 var3,
4420 winx64_struct1 var4,
4421 winx64_struct1 var5)
4423 if (var1.a != 1)
4424 return 1;
4425 if (var2.a != 2)
4426 return 2;
4427 if (var3.a != 3)
4428 return 3;
4429 if (var4.a != 4)
4430 return 4;
4431 if (var5.a != 5)
4432 return 5;
4434 return 0;
4437 LIBTEST_API int STDCALL
4438 mono_test_Winx64_structs_in3 (winx64_struct1 var1,
4439 winx64_struct5 var2,
4440 winx64_struct1 var3,
4441 winx64_struct5 var4,
4442 winx64_struct1 var5,
4443 winx64_struct5 var6)
4445 if (var1.a != 1)
4446 return 1;
4448 if (var2.a != 2)
4449 return 2;
4450 if (var2.b != 3)
4451 return 2;
4452 if (var2.c != 4)
4453 return 4;
4455 if (var3.a != 5)
4456 return 5;
4458 if (var4.a != 6)
4459 return 6;
4460 if (var4.b != 7)
4461 return 7;
4462 if (var4.c != 8)
4463 return 8;
4465 if (var5.a != 9)
4466 return 9;
4468 if (var6.a != 10)
4469 return 10;
4470 if (var6.b != 11)
4471 return 11;
4472 if (var6.c != 12)
4473 return 12;
4475 return 0;
4478 LIBTEST_API winx64_struct1 STDCALL
4479 mono_test_Winx64_struct1_ret (void)
4481 winx64_struct1 ret;
4482 ret.a = 123;
4483 return ret;
4486 LIBTEST_API winx64_struct2 STDCALL
4487 mono_test_Winx64_struct2_ret (void)
4489 winx64_struct2 ret;
4490 ret.a = 4;
4491 ret.b = 5;
4492 return ret;
4495 LIBTEST_API winx64_struct3 STDCALL
4496 mono_test_Winx64_struct3_ret (void)
4498 winx64_struct3 ret;
4499 ret.a = 4;
4500 ret.b = 5;
4501 ret.c = 0x1234;
4502 return ret;
4505 LIBTEST_API winx64_struct4 STDCALL
4506 mono_test_Winx64_struct4_ret (void)
4508 winx64_struct4 ret;
4509 ret.a = 4;
4510 ret.b = 5;
4511 ret.c = 0x1234;
4512 ret.d = 0x87654321;
4513 return ret;
4516 LIBTEST_API winx64_struct5 STDCALL
4517 mono_test_Winx64_struct5_ret (void)
4519 winx64_struct5 ret;
4520 ret.a = 4;
4521 ret.b = 5;
4522 ret.c = 6;
4523 return ret;
4526 LIBTEST_API winx64_struct1 STDCALL
4527 mono_test_Winx64_struct1_ret_5_args (char a, char b, char c, char d, char e)
4529 winx64_struct1 ret;
4530 ret.a = a + b + c + d + e;
4531 return ret;
4534 LIBTEST_API winx64_struct5 STDCALL
4535 mono_test_Winx64_struct5_ret6_args (char a, char b, char c, char d, char e)
4537 winx64_struct5 ret;
4538 ret.a = a + b;
4539 ret.b = c + d;
4540 ret.c = e;
4541 return ret;
4544 typedef struct
4546 float a;
4547 float b;
4548 } winx64_floatStruct;
4550 LIBTEST_API int STDCALL
4551 mono_test_Winx64_floatStruct (winx64_floatStruct a)
4553 if (a.a > 5.6 || a.a < 5.4)
4554 return 1;
4556 if (a.b > 9.6 || a.b < 9.4)
4557 return 2;
4559 return 0;
4562 typedef struct
4564 double a;
4565 } winx64_doubleStruct;
4567 LIBTEST_API int STDCALL
4568 mono_test_Winx64_doubleStruct (winx64_doubleStruct a)
4570 if (a.a > 5.6 || a.a < 5.4)
4571 return 1;
4573 return 0;
4576 typedef int (STDCALL *managed_struct1_delegate) (winx64_struct1 a);
4578 LIBTEST_API int STDCALL
4579 mono_test_managed_Winx64_struct1_in(managed_struct1_delegate func)
4581 winx64_struct1 val;
4582 val.a = 5;
4583 return func (val);
4586 typedef int (STDCALL *managed_struct5_delegate) (winx64_struct5 a);
4588 LIBTEST_API int STDCALL
4589 mono_test_managed_Winx64_struct5_in(managed_struct5_delegate func)
4591 winx64_struct5 val;
4592 val.a = 5;
4593 val.b = 0x10;
4594 val.c = (char)0x99;
4595 return func (val);
4598 typedef int (STDCALL *managed_struct1_struct5_delegate) (winx64_struct1 a, winx64_struct5 b,
4599 winx64_struct1 c, winx64_struct5 d,
4600 winx64_struct1 e, winx64_struct5 f);
4602 LIBTEST_API int STDCALL
4603 mono_test_managed_Winx64_struct1_struct5_in(managed_struct1_struct5_delegate func)
4605 winx64_struct1 a, c, e;
4606 winx64_struct5 b, d, f;
4607 a.a = 1;
4608 b.a = 2; b.b = 3; b.c = 4;
4609 c.a = 5;
4610 d.a = 6; d.b = 7; d.c = 8;
4611 e.a = 9;
4612 f.a = 10; f.b = 11; f.c = 12;
4614 return func (a, b, c, d, e, f);
4617 typedef winx64_struct1 (STDCALL *managed_struct1_ret_delegate) (void);
4619 LIBTEST_API int STDCALL
4620 mono_test_Winx64_struct1_ret_managed (managed_struct1_ret_delegate func)
4622 winx64_struct1 ret;
4624 ret = func ();
4626 if (ret.a != 0x45)
4627 return 1;
4629 return 0;
4632 typedef winx64_struct5 (STDCALL *managed_struct5_ret_delegate) (void);
4634 LIBTEST_API int STDCALL
4635 mono_test_Winx64_struct5_ret_managed (managed_struct5_ret_delegate func)
4637 winx64_struct5 ret;
4639 ret = func ();
4641 if (ret.a != 0x12)
4642 return 1;
4643 if (ret.b != 0x34)
4644 return 2;
4645 if (ret.c != 0x56)
4646 return 3;
4648 return 0;
4651 LIBTEST_API int STDCALL
4652 mono_test_marshal_bool_in (int arg, unsigned int expected, unsigned int bDefaultMarsh, unsigned int bBoolCustMarsh,
4653 char bI1CustMarsh, unsigned char bU1CustMarsh, short bVBCustMarsh)
4655 switch (arg) {
4656 case 1:
4657 if (bDefaultMarsh != expected)
4658 return 1;
4659 break;
4660 case 2:
4661 if (bBoolCustMarsh != expected)
4662 return 2;
4663 break;
4664 case 3:
4665 if (bI1CustMarsh != expected)
4666 return 3;
4667 break;
4668 case 4:
4669 if (bU1CustMarsh != expected)
4670 return 4;
4671 break;
4672 case 5:
4673 if (bVBCustMarsh != expected)
4674 return 5;
4675 break;
4676 default:
4677 return 999;
4679 return 0;
4682 LIBTEST_API int STDCALL
4683 mono_test_marshal_bool_out (int arg, unsigned int testVal, unsigned int* bDefaultMarsh, unsigned int* bBoolCustMarsh,
4684 char* bI1CustMarsh, unsigned char* bU1CustMarsh, unsigned short* bVBCustMarsh)
4686 switch (arg) {
4687 case 1:
4688 if (!bDefaultMarsh)
4689 return 1;
4690 *bDefaultMarsh = testVal;
4691 break;
4692 case 2:
4693 if (!bBoolCustMarsh)
4694 return 2;
4695 *bBoolCustMarsh = testVal;
4696 break;
4697 case 3:
4698 if (!bI1CustMarsh)
4699 return 3;
4700 *bI1CustMarsh = (char)testVal;
4701 break;
4702 case 4:
4703 if (!bU1CustMarsh)
4704 return 4;
4705 *bU1CustMarsh = (unsigned char)testVal;
4706 break;
4707 case 5:
4708 if (!bVBCustMarsh)
4709 return 5;
4710 *bVBCustMarsh = (unsigned short)testVal;
4711 break;
4712 default:
4713 return 999;
4715 return 0;
4718 LIBTEST_API int STDCALL
4719 mono_test_marshal_bool_ref (int arg, unsigned int expected, unsigned int testVal, unsigned int* bDefaultMarsh,
4720 unsigned int* bBoolCustMarsh, char* bI1CustMarsh, unsigned char* bU1CustMarsh,
4721 unsigned short* bVBCustMarsh)
4723 switch (arg) {
4724 case 1:
4725 if (!bDefaultMarsh)
4726 return 1;
4727 if (*bDefaultMarsh != expected)
4728 return 2;
4729 *bDefaultMarsh = testVal;
4730 break;
4731 case 2:
4732 if (!bBoolCustMarsh)
4733 return 3;
4734 if (*bBoolCustMarsh != expected)
4735 return 4;
4736 *bBoolCustMarsh = testVal;
4737 break;
4738 case 3:
4739 if (!bI1CustMarsh)
4740 return 5;
4741 if (*bI1CustMarsh != expected)
4742 return 6;
4743 *bI1CustMarsh = (char)testVal;
4744 break;
4745 case 4:
4746 if (!bU1CustMarsh)
4747 return 7;
4748 if (*bU1CustMarsh != expected)
4749 return 8;
4750 *bU1CustMarsh = (unsigned char)testVal;
4751 break;
4752 case 5:
4753 if (!bVBCustMarsh)
4754 return 9;
4755 if (*bVBCustMarsh != expected)
4756 return 10;
4757 *bVBCustMarsh = (unsigned short)testVal;
4758 break;
4759 default:
4760 return 999;
4762 return 0;
4766 typedef int (STDCALL *MarshalBoolInDelegate) (int arg, unsigned int expected, unsigned int bDefaultMarsh,
4767 unsigned int bBoolCustMarsh, char bI1CustMarsh, unsigned char bU1CustMarsh, unsigned short bVBCustMarsh);
4769 LIBTEST_API int STDCALL
4770 mono_test_managed_marshal_bool_in (int arg, unsigned int expected, unsigned int testVal, MarshalBoolInDelegate pfcn)
4772 if (!pfcn)
4773 return 0x9900;
4775 switch (arg) {
4776 case 1:
4777 return pfcn (arg, expected, testVal, 0, 0, 0, 0);
4778 case 2:
4779 return pfcn (arg, expected, 0, testVal, 0, 0, 0);
4780 case 3:
4781 return pfcn (arg, expected, 0, 0, testVal, 0, 0);
4782 case 4:
4783 return pfcn (arg, expected, 0, 0, 0, testVal, 0);
4784 case 5:
4785 return pfcn (arg, expected, 0, 0, 0, 0, testVal);
4786 default:
4787 return 0x9800;
4790 return 0;
4793 typedef int (STDCALL *MarshalBoolOutDelegate) (int arg, unsigned int expected, unsigned int* bDefaultMarsh,
4794 unsigned int* bBoolCustMarsh, char* bI1CustMarsh, unsigned char* bU1CustMarsh, unsigned short* bVBCustMarsh);
4796 LIBTEST_API int STDCALL
4797 mono_test_managed_marshal_bool_out (int arg, unsigned int expected, unsigned int testVal, MarshalBoolOutDelegate pfcn)
4799 int ret;
4800 unsigned int lDefaultMarsh, lBoolCustMarsh;
4801 char lI1CustMarsh = 0;
4802 unsigned char lU1CustMarsh = 0;
4803 unsigned short lVBCustMarsh = 0;
4804 lDefaultMarsh = lBoolCustMarsh = 0;
4806 if (!pfcn)
4807 return 0x9900;
4809 switch (arg) {
4810 case 1: {
4811 unsigned int ltVal = 0;
4812 ret = pfcn (arg, testVal, &ltVal, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4813 if (ret)
4814 return 0x0100 + ret;
4815 if (expected != ltVal)
4816 return 0x0200;
4817 break;
4819 case 2: {
4820 unsigned int ltVal = 0;
4821 ret = pfcn (arg, testVal, &lDefaultMarsh, &ltVal, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4822 if (ret)
4823 return 0x0300 + ret;
4824 if (expected != ltVal)
4825 return 0x0400;
4826 break;
4828 case 3: {
4829 char ltVal = 0;
4830 ret = pfcn (arg, testVal, &lDefaultMarsh, &lBoolCustMarsh, &ltVal, &lU1CustMarsh, &lVBCustMarsh);
4831 if (ret)
4832 return 0x0500 + ret;
4833 if (expected != ltVal)
4834 return 0x0600;
4835 break;
4837 case 4: {
4838 unsigned char ltVal = 0;
4839 ret = pfcn (arg, testVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &ltVal, &lVBCustMarsh);
4840 if (ret)
4841 return 0x0700 + ret;
4842 if (expected != ltVal)
4843 return 0x0800;
4844 break;
4846 case 5: {
4847 unsigned short ltVal = 0;
4848 ret = pfcn (arg, testVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &ltVal);
4849 if (ret)
4850 return 0x0900 + ret;
4851 if (expected != ltVal)
4852 return 0x1000;
4853 break;
4855 default:
4856 return 0x9800;
4859 return 0;
4862 typedef int (STDCALL *MarshalBoolRefDelegate) (int arg, unsigned int expected, unsigned int testVal, unsigned int* bDefaultMarsh,
4863 unsigned int* bBoolCustMarsh, char* bI1CustMarsh, unsigned char* bU1CustMarsh, unsigned short* bVBCustMarsh);
4865 LIBTEST_API int STDCALL
4866 mono_test_managed_marshal_bool_ref (int arg, unsigned int expected, unsigned int testVal, unsigned int outExpected,
4867 unsigned int outTestVal, MarshalBoolRefDelegate pfcn)
4869 int ret;
4870 unsigned int lDefaultMarsh, lBoolCustMarsh;
4871 char lI1CustMarsh = 0;
4872 unsigned char lU1CustMarsh = 0;
4873 unsigned short lVBCustMarsh = 0;
4874 lDefaultMarsh = lBoolCustMarsh = 0;
4876 if (!pfcn)
4877 return 0x9900;
4879 switch (arg) {
4880 case 1:
4882 unsigned int ltestVal = testVal;
4883 ret = pfcn (arg, expected, outTestVal, &ltestVal, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4884 if (ret)
4885 return 0x0100 + ret;
4886 if (outExpected != ltestVal)
4887 return 0x0200;
4888 break;
4890 case 2:
4892 unsigned int ltestVal = testVal;
4893 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &ltestVal, &lI1CustMarsh, &lU1CustMarsh, &lVBCustMarsh);
4894 if (ret)
4895 return 0x0300 + ret;
4896 if (outExpected != ltestVal)
4897 return 0x0400;
4898 break;
4900 case 3:
4902 char ltestVal = testVal;
4903 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &lBoolCustMarsh, &ltestVal, &lU1CustMarsh, &lVBCustMarsh);
4904 if (ret)
4905 return 0x0500 + ret;
4906 if (outExpected != ltestVal)
4907 return 0x0600;
4908 break;
4910 case 4:
4912 unsigned char ltestVal = testVal;
4913 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &ltestVal, &lVBCustMarsh);
4914 if (ret)
4915 return 0x0700 + ret;
4916 if (outExpected != ltestVal)
4917 return 0x0800;
4918 break;
4920 case 5:
4922 unsigned short ltestVal = testVal;
4923 ret = pfcn (arg, expected, outTestVal, &lDefaultMarsh, &lBoolCustMarsh, &lI1CustMarsh, &lU1CustMarsh, &ltestVal);
4924 if (ret)
4925 return 0x0900 + ret;
4926 if (outExpected != ltestVal)
4927 return 0x1000;
4928 break;
4930 default:
4931 return 0x9800;
4934 return 0;
4937 #ifdef WIN32
4939 LIBTEST_API int STDCALL
4940 mono_test_marshal_safearray_out_1dim_vt_bstr_empty (SAFEARRAY** safearray)
4942 /* Create an empty one-dimensional array of variants */
4943 SAFEARRAY *pSA;
4944 SAFEARRAYBOUND dimensions [1];
4946 dimensions [0].lLbound = 0;
4947 dimensions [0].cElements = 0;
4949 pSA = SafeArrayCreate (VT_VARIANT, 1, dimensions);
4950 *safearray = pSA;
4951 return S_OK;
4954 LIBTEST_API int STDCALL
4955 mono_test_marshal_safearray_out_1dim_vt_bstr (SAFEARRAY** safearray)
4957 /* Create a one-dimensional array of 10 variants filled with "0" to "9" */
4958 SAFEARRAY *pSA;
4959 SAFEARRAYBOUND dimensions [1];
4960 long i;
4961 gchar buffer [20];
4962 HRESULT hr = S_OK;
4963 long indices [1];
4965 dimensions [0].lLbound = 0;
4966 dimensions [0].cElements = 10;
4968 pSA= SafeArrayCreate (VT_VARIANT, 1, dimensions);
4969 for (i= dimensions [0].lLbound; i< (dimensions [0].cElements + dimensions [0].lLbound); i++) {
4970 VARIANT vOut;
4971 VariantInit (&vOut);
4972 vOut.vt = VT_BSTR;
4973 _ltoa (i,buffer,10);
4974 vOut.bstrVal= marshal_bstr_alloc (buffer);
4975 indices [0] = i;
4976 if ((hr = SafeArrayPutElement (pSA, indices, &vOut)) != S_OK) {
4977 VariantClear (&vOut);
4978 SafeArrayDestroy (pSA);
4979 return hr;
4981 VariantClear (&vOut);
4983 *safearray = pSA;
4984 return hr;
4987 LIBTEST_API int STDCALL
4988 mono_test_marshal_safearray_out_2dim_vt_i4 (SAFEARRAY** safearray)
4990 /* Create a two-dimensional array of 4x3 variants filled with 11, 12, 13, etc. */
4991 SAFEARRAY *pSA;
4992 SAFEARRAYBOUND dimensions [2];
4993 long i, j;
4994 HRESULT hr = S_OK;
4995 long indices [2];
4997 dimensions [0].lLbound = 0;
4998 dimensions [0].cElements = 4;
4999 dimensions [1].lLbound = 0;
5000 dimensions [1].cElements = 3;
5002 pSA= SafeArrayCreate(VT_VARIANT, 2, dimensions);
5003 for (i= dimensions [0].lLbound; i< (dimensions [0].cElements + dimensions [0].lLbound); i++) {
5004 for (j= dimensions [1].lLbound; j< (dimensions [1].cElements + dimensions [1].lLbound); j++) {
5005 VARIANT vOut;
5006 VariantInit (&vOut);
5007 vOut.vt = VT_I4;
5008 vOut.lVal = (i+1)*10+(j+1);
5009 indices [0] = i;
5010 indices [1] = j;
5011 if ((hr = SafeArrayPutElement (pSA, indices, &vOut)) != S_OK) {
5012 VariantClear (&vOut);
5013 SafeArrayDestroy (pSA);
5014 return hr;
5016 VariantClear (&vOut); // does a deep destroy of source VARIANT
5019 *safearray = pSA;
5020 return hr;
5023 LIBTEST_API int STDCALL
5024 mono_test_marshal_safearray_out_4dim_vt_i4 (SAFEARRAY** safearray)
5026 /* Create a four-dimensional array of 10x3x6x7 variants filled with their indices */
5027 /* Also use non zero lower bounds */
5028 SAFEARRAY *pSA;
5029 SAFEARRAYBOUND dimensions [4];
5030 long i;
5031 HRESULT hr = S_OK;
5032 VARIANT *pData;
5034 dimensions [0].lLbound = 15;
5035 dimensions [0].cElements = 10;
5036 dimensions [1].lLbound = 20;
5037 dimensions [1].cElements = 3;
5038 dimensions [2].lLbound = 5;
5039 dimensions [2].cElements = 6;
5040 dimensions [3].lLbound = 12;
5041 dimensions [3].cElements = 7;
5043 pSA= SafeArrayCreate (VT_VARIANT, 4, dimensions);
5045 SafeArrayAccessData (pSA, (void **)&pData);
5047 for (i= 0; i< 10*3*6*7; i++) {
5048 VariantInit(&pData [i]);
5049 pData [i].vt = VT_I4;
5050 pData [i].lVal = i;
5052 SafeArrayUnaccessData (pSA);
5053 *safearray = pSA;
5054 return hr;
5057 LIBTEST_API int STDCALL
5058 mono_test_marshal_safearray_in_byval_1dim_empty (SAFEARRAY* safearray)
5060 /* Check that array is one dimensional and empty */
5062 UINT dim;
5063 long lbound, ubound;
5065 dim = SafeArrayGetDim (safearray);
5066 if (dim != 1)
5067 return 1;
5069 SafeArrayGetLBound (safearray, 1, &lbound);
5070 SafeArrayGetUBound (safearray, 1, &ubound);
5072 if ((lbound > 0) || (ubound > 0))
5073 return 1;
5075 return 0;
5078 LIBTEST_API int STDCALL
5079 mono_test_marshal_safearray_in_byval_1dim_vt_i4 (SAFEARRAY* safearray)
5081 /* Check that array is one dimensional containing integers from 1 to 10 */
5083 UINT dim;
5084 long lbound, ubound;
5085 VARIANT *pData;
5086 long i;
5087 int result=0;
5089 dim = SafeArrayGetDim (safearray);
5090 if (dim != 1)
5091 return 1;
5093 SafeArrayGetLBound (safearray, 1, &lbound);
5094 SafeArrayGetUBound (safearray, 1, &ubound);
5096 if ((lbound != 0) || (ubound != 9))
5097 return 1;
5099 SafeArrayAccessData (safearray, (void **)&pData);
5100 for (i= lbound; i <= ubound; i++) {
5101 if ((VariantChangeType (&pData [i], &pData [i], VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK) || (pData [i].lVal != i + 1))
5102 result = 1;
5104 SafeArrayUnaccessData (safearray);
5106 return result;
5109 LIBTEST_API int STDCALL
5110 mono_test_marshal_safearray_in_byval_1dim_vt_mixed (SAFEARRAY* safearray)
5112 /* Check that array is one dimensional containing integers mixed with strings from 0 to 12 */
5114 UINT dim;
5115 long lbound, ubound;
5116 VARIANT *pData;
5117 long i;
5118 long indices [1];
5119 VARIANT element;
5120 int result=0;
5122 VariantInit (&element);
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 != 12))
5132 return 1;
5134 SafeArrayAccessData (safearray, (void **)&pData);
5135 for (i= lbound; i <= ubound; i++) {
5136 if ((i%2 == 0) && (pData [i].vt != VT_I4))
5137 result = 1;
5138 if ((i%2 == 1) && (pData [i].vt != VT_BSTR))
5139 result = 1;
5140 if ((VariantChangeType (&pData [i], &pData [i], VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK) || (pData [i].lVal != i))
5141 result = 1;
5143 SafeArrayUnaccessData (safearray);
5145 /* Change the first element of the array to verify that [in] parameters are not marshalled back to the managed side */
5147 indices [0] = 0;
5148 element.vt = VT_I4;
5149 element.lVal = 333;
5150 SafeArrayPutElement (safearray, indices, &element);
5151 VariantClear (&element);
5153 return result;
5156 LIBTEST_API int STDCALL
5157 mono_test_marshal_safearray_in_byval_2dim_vt_i4 (SAFEARRAY* safearray)
5159 /* Check that array is one dimensional containing integers mixed with strings from 0 to 12 */
5161 UINT dim;
5162 long lbound1, ubound1, lbound2, ubound2;
5163 long i, j, failed;
5164 long indices [2];
5165 VARIANT element;
5167 VariantInit (&element);
5169 dim = SafeArrayGetDim (safearray);
5170 if (dim != 2)
5171 return 1;
5173 SafeArrayGetLBound (safearray, 1, &lbound1);
5174 SafeArrayGetUBound (safearray, 1, &ubound1);
5176 if ((lbound1 != 0) || (ubound1 != 1))
5177 return 1;
5179 SafeArrayGetLBound (safearray, 2, &lbound2);
5180 SafeArrayGetUBound (safearray, 2, &ubound2);
5182 if ((lbound2 != 0) || (ubound2 != 3)) {
5183 return 1;
5186 for (i= lbound1; i <= ubound1; i++) {
5187 indices [0] = i;
5188 for (j= lbound2; j <= ubound2; j++) {
5189 indices [1] = j;
5190 if (SafeArrayGetElement (safearray, indices, &element) != S_OK)
5191 return 1;
5192 failed = ((element.vt != VT_I4) || (element.lVal != 10*(i+1)+(j+1)));
5193 VariantClear (&element);
5194 if (failed)
5195 return 1;
5199 /* Change the first element of the array to verify that [in] parameters are not marshalled back to the managed side */
5201 indices [0] = 0;
5202 indices [1] = 0;
5203 element.vt = VT_I4;
5204 element.lVal = 333;
5205 SafeArrayPutElement (safearray, indices, &element);
5206 VariantClear (&element);
5208 return 0;
5211 LIBTEST_API int STDCALL
5212 mono_test_marshal_safearray_in_byval_3dim_vt_bstr (SAFEARRAY* safearray)
5214 /* Check that array is one dimensional containing integers mixed with strings from 0 to 12 */
5216 UINT dim;
5217 long lbound1, ubound1, lbound2, ubound2, lbound3, ubound3;
5218 long i, j, k, failed;
5219 long indices [3];
5220 VARIANT element;
5222 VariantInit (&element);
5224 dim = SafeArrayGetDim (safearray);
5225 if (dim != 3)
5226 return 1;
5228 SafeArrayGetLBound (safearray, 1, &lbound1);
5229 SafeArrayGetUBound (safearray, 1, &ubound1);
5231 if ((lbound1 != 0) || (ubound1 != 1))
5232 return 1;
5234 SafeArrayGetLBound (safearray, 2, &lbound2);
5235 SafeArrayGetUBound (safearray, 2, &ubound2);
5237 if ((lbound2 != 0) || (ubound2 != 1))
5238 return 1;
5240 SafeArrayGetLBound (safearray, 3, &lbound3);
5241 SafeArrayGetUBound (safearray, 3, &ubound3);
5243 if ((lbound3 != 0) || (ubound3 != 2))
5244 return 1;
5246 for (i= lbound1; i <= ubound1; i++) {
5247 indices [0] = i;
5248 for (j= lbound2; j <= ubound2; j++) {
5249 indices [1] = j;
5250 for (k= lbound3; k <= ubound3; k++) {
5251 indices [2] = k;
5252 if (SafeArrayGetElement (safearray, indices, &element) != S_OK)
5253 return 1;
5254 failed = ((element.vt != VT_BSTR)
5255 || (VariantChangeType (&element, &element, VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK)
5256 || (element.lVal != 100*(i+1)+10*(j+1)+(k+1)));
5257 VariantClear (&element);
5258 if (failed)
5259 return 1;
5264 /* Change the first element of the array to verify that [in] parameters are not marshalled back to the managed side */
5266 indices [0] = 0;
5267 indices [1] = 0;
5268 indices [2] = 0;
5269 element.vt = VT_BSTR;
5270 element.bstrVal = SysAllocString(L"Should not be copied");
5271 SafeArrayPutElement (safearray, indices, &element);
5272 VariantClear (&element);
5274 return 0;
5277 LIBTEST_API int STDCALL
5278 mono_test_marshal_safearray_in_byref_3dim_vt_bstr (SAFEARRAY** safearray)
5280 return mono_test_marshal_safearray_in_byval_3dim_vt_bstr (*safearray);
5283 LIBTEST_API int STDCALL
5284 mono_test_marshal_safearray_in_out_byref_1dim_empty (SAFEARRAY** safearray)
5286 /* Check that the input array is what is expected and change it so the caller can check */
5287 /* correct marshalling back to managed code */
5289 UINT dim;
5290 long lbound, ubound;
5291 SAFEARRAYBOUND dimensions [1];
5292 long i;
5293 wchar_t buffer [20];
5294 HRESULT hr = S_OK;
5295 long indices [1];
5297 /* Check that in array is one dimensional and empty */
5299 dim = SafeArrayGetDim (*safearray);
5300 if (dim != 1) {
5301 return 1;
5304 SafeArrayGetLBound (*safearray, 1, &lbound);
5305 SafeArrayGetUBound (*safearray, 1, &ubound);
5307 if ((lbound > 0) || (ubound > 0)) {
5308 return 1;
5311 /* Re-dimension the array and return a one-dimensional array of 8 variants filled with "0" to "7" */
5313 dimensions [0].lLbound = 0;
5314 dimensions [0].cElements = 8;
5316 hr = SafeArrayRedim (*safearray, dimensions);
5317 if (hr != S_OK)
5318 return 1;
5320 for (i= dimensions [0].lLbound; i< (dimensions [0].lLbound + dimensions [0].cElements); i++) {
5321 VARIANT vOut;
5322 VariantInit (&vOut);
5323 vOut.vt = VT_BSTR;
5324 _ltow (i,buffer,10);
5325 vOut.bstrVal = SysAllocString (buffer);
5326 indices [0] = i;
5327 if ((hr = SafeArrayPutElement (*safearray, indices, &vOut)) != S_OK) {
5328 VariantClear (&vOut);
5329 SafeArrayDestroy (*safearray);
5330 return hr;
5332 VariantClear (&vOut);
5334 return hr;
5337 LIBTEST_API int STDCALL
5338 mono_test_marshal_safearray_in_out_byref_3dim_vt_bstr (SAFEARRAY** safearray)
5340 /* Check that the input array is what is expected and change it so the caller can check */
5341 /* correct marshalling back to managed code */
5343 UINT dim;
5344 long lbound1, ubound1, lbound2, ubound2, lbound3, ubound3;
5345 SAFEARRAYBOUND dimensions [1];
5346 long i, j, k, failed;
5347 wchar_t buffer [20];
5348 HRESULT hr = S_OK;
5349 long indices [3];
5350 VARIANT element;
5352 VariantInit (&element);
5354 /* Check that in array is three dimensional and contains the expected values */
5356 dim = SafeArrayGetDim (*safearray);
5357 if (dim != 3)
5358 return 1;
5360 SafeArrayGetLBound (*safearray, 1, &lbound1);
5361 SafeArrayGetUBound (*safearray, 1, &ubound1);
5363 if ((lbound1 != 0) || (ubound1 != 1))
5364 return 1;
5366 SafeArrayGetLBound (*safearray, 2, &lbound2);
5367 SafeArrayGetUBound (*safearray, 2, &ubound2);
5369 if ((lbound2 != 0) || (ubound2 != 1))
5370 return 1;
5372 SafeArrayGetLBound (*safearray, 3, &lbound3);
5373 SafeArrayGetUBound (*safearray, 3, &ubound3);
5375 if ((lbound3 != 0) || (ubound3 != 2))
5376 return 1;
5378 for (i= lbound1; i <= ubound1; i++) {
5379 indices [0] = i;
5380 for (j= lbound2; j <= ubound2; j++) {
5381 indices [1] = j;
5382 for (k= lbound3; k <= ubound3; k++) {
5383 indices [2] = k;
5384 if (SafeArrayGetElement (*safearray, indices, &element) != S_OK)
5385 return 1;
5386 failed = ((element.vt != VT_BSTR)
5387 || (VariantChangeType (&element, &element, VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK)
5388 || (element.lVal != 100*(i+1)+10*(j+1)+(k+1)));
5389 VariantClear (&element);
5390 if (failed)
5391 return 1;
5396 hr = SafeArrayDestroy (*safearray);
5397 if (hr != S_OK)
5398 return 1;
5400 /* Return a new one-dimensional array of 8 variants filled with "0" to "7" */
5402 dimensions [0].lLbound = 0;
5403 dimensions [0].cElements = 8;
5405 *safearray = SafeArrayCreate (VT_VARIANT, 1, dimensions);
5407 for (i= dimensions [0].lLbound; i< (dimensions [0].lLbound + dimensions [0].cElements); i++) {
5408 VARIANT vOut;
5409 VariantInit (&vOut);
5410 vOut.vt = VT_BSTR;
5411 _ltow (i,buffer,10);
5412 vOut.bstrVal = SysAllocString (buffer);
5413 indices [0] = i;
5414 if ((hr = SafeArrayPutElement (*safearray, indices, &vOut)) != S_OK) {
5415 VariantClear (&vOut);
5416 SafeArrayDestroy (*safearray);
5417 return hr;
5419 VariantClear (&vOut);
5421 return hr;
5424 LIBTEST_API int STDCALL
5425 mono_test_marshal_safearray_in_out_byref_1dim_vt_i4 (SAFEARRAY** safearray)
5427 /* Check that the input array is what is expected and change it so the caller can check */
5428 /* correct marshalling back to managed code */
5430 UINT dim;
5431 long lbound1, ubound1;
5432 long i, failed;
5433 HRESULT hr = S_OK;
5434 long indices [1];
5435 VARIANT element;
5437 VariantInit (&element);
5439 /* Check that in array is one dimensional and contains the expected value */
5441 dim = SafeArrayGetDim (*safearray);
5442 if (dim != 1)
5443 return 1;
5445 SafeArrayGetLBound (*safearray, 1, &lbound1);
5446 SafeArrayGetUBound (*safearray, 1, &ubound1);
5448 ubound1 = 1;
5449 if ((lbound1 != 0) || (ubound1 != 1))
5450 return 1;
5451 ubound1 = 0;
5453 for (i= lbound1; i <= ubound1; i++) {
5454 indices [0] = i;
5455 if (SafeArrayGetElement (*safearray, indices, &element) != S_OK)
5456 return 1;
5457 failed = (element.vt != VT_I4) || (element.lVal != i+1);
5458 VariantClear (&element);
5459 if (failed)
5460 return 1;
5463 /* Change one of the elements of the array to verify that [out] parameter is marshalled back to the managed side */
5465 indices [0] = 0;
5466 element.vt = VT_I4;
5467 element.lVal = -1;
5468 SafeArrayPutElement (*safearray, indices, &element);
5469 VariantClear (&element);
5471 return hr;
5474 LIBTEST_API int STDCALL
5475 mono_test_marshal_safearray_in_out_byval_1dim_vt_i4 (SAFEARRAY* safearray)
5477 /* Check that the input array is what is expected and change it so the caller can check */
5478 /* correct marshalling back to managed code */
5480 UINT dim;
5481 long lbound1, ubound1;
5482 SAFEARRAYBOUND dimensions [1];
5483 long i, failed;
5484 HRESULT hr = S_OK;
5485 long indices [1];
5486 VARIANT element;
5488 VariantInit (&element);
5490 /* Check that in array is one dimensional and contains the expected value */
5492 dim = SafeArrayGetDim (safearray);
5493 if (dim != 1)
5494 return 1;
5496 SafeArrayGetLBound (safearray, 1, &lbound1);
5497 SafeArrayGetUBound (safearray, 1, &ubound1);
5499 if ((lbound1 != 0) || (ubound1 != 0))
5500 return 1;
5502 for (i= lbound1; i <= ubound1; i++) {
5503 indices [0] = i;
5504 if (SafeArrayGetElement (safearray, indices, &element) != S_OK)
5505 return 1;
5506 failed = (element.vt != VT_I4) || (element.lVal != i+1);
5507 VariantClear (&element);
5508 if (failed)
5509 return 1;
5512 /* Change the array to verify how [out] parameter is marshalled back to the managed side */
5514 /* Redimension the array */
5515 dimensions [0].lLbound = lbound1;
5516 dimensions [0].cElements = 2;
5517 hr = SafeArrayRedim(safearray, dimensions);
5519 indices [0] = 0;
5520 element.vt = VT_I4;
5521 element.lVal = 12345;
5522 SafeArrayPutElement (safearray, indices, &element);
5523 VariantClear (&element);
5525 indices [0] = 1;
5526 element.vt = VT_I4;
5527 element.lVal = -12345;
5528 SafeArrayPutElement (safearray, indices, &element);
5529 VariantClear (&element);
5531 return hr;
5534 LIBTEST_API int STDCALL
5535 mono_test_marshal_safearray_in_out_byval_3dim_vt_bstr (SAFEARRAY* safearray)
5537 /* Check that the input array is what is expected and change it so the caller can check */
5538 /* correct marshalling back to managed code */
5540 UINT dim;
5541 long lbound1, ubound1, lbound2, ubound2, lbound3, ubound3;
5542 long i, j, k, failed;
5543 HRESULT hr = S_OK;
5544 long indices [3];
5545 VARIANT element;
5547 VariantInit (&element);
5549 /* Check that in array is three dimensional and contains the expected values */
5551 dim = SafeArrayGetDim (safearray);
5552 if (dim != 3)
5553 return 1;
5555 SafeArrayGetLBound (safearray, 1, &lbound1);
5556 SafeArrayGetUBound (safearray, 1, &ubound1);
5558 if ((lbound1 != 0) || (ubound1 != 1))
5559 return 1;
5561 SafeArrayGetLBound (safearray, 2, &lbound2);
5562 SafeArrayGetUBound (safearray, 2, &ubound2);
5564 if ((lbound2 != 0) || (ubound2 != 1))
5565 return 1;
5567 SafeArrayGetLBound (safearray, 3, &lbound3);
5568 SafeArrayGetUBound (safearray, 3, &ubound3);
5570 if ((lbound3 != 0) || (ubound3 != 2))
5571 return 1;
5573 for (i= lbound1; i <= ubound1; i++) {
5574 indices [0] = i;
5575 for (j= lbound2; j <= ubound2; j++) {
5576 indices [1] = j;
5577 for (k= lbound3; k <= ubound3; k++) {
5578 indices [2] = k;
5579 if (SafeArrayGetElement (safearray, indices, &element) != S_OK)
5580 return 1;
5581 failed = ((element.vt != VT_BSTR)
5582 || (VariantChangeType (&element, &element, VARIANT_NOUSEROVERRIDE, VT_I4) != S_OK)
5583 || (element.lVal != 100*(i+1)+10*(j+1)+(k+1)));
5584 VariantClear (&element);
5585 if (failed)
5586 return 1;
5591 /* Change the elements of the array to verify that [out] parameter is marshalled back to the managed side */
5593 indices [0] = 1;
5594 indices [1] = 1;
5595 indices [2] = 2;
5596 element.vt = VT_I4;
5597 element.lVal = 333;
5598 SafeArrayPutElement (safearray, indices, &element);
5599 VariantClear (&element);
5601 indices [0] = 1;
5602 indices [1] = 1;
5603 indices [2] = 1;
5604 element.vt = VT_I4;
5605 element.lVal = 111;
5606 SafeArrayPutElement (safearray, indices, &element);
5607 VariantClear (&element);
5609 indices [0] = 0;
5610 indices [1] = 1;
5611 indices [2] = 0;
5612 element.vt = VT_BSTR;
5613 element.bstrVal = marshal_bstr_alloc("ABCDEFG");
5614 SafeArrayPutElement (safearray, indices, &element);
5615 VariantClear (&element);
5617 return hr;
5620 LIBTEST_API int STDCALL
5621 mono_test_marshal_safearray_mixed(
5622 SAFEARRAY *safearray1,
5623 SAFEARRAY **safearray2,
5624 SAFEARRAY *safearray3,
5625 SAFEARRAY **safearray4
5628 HRESULT hr = S_OK;
5630 /* Initialize out parameters */
5631 *safearray2 = NULL;
5633 /* array1: Check that in array is one dimensional and contains the expected value */
5634 hr = mono_test_marshal_safearray_in_out_byval_1dim_vt_i4 (safearray1);
5636 /* array2: Fill in with some values to check on the managed side */
5637 if (hr == S_OK)
5638 hr = mono_test_marshal_safearray_out_1dim_vt_bstr (safearray2);
5640 /* array3: Check that in array is one dimensional and contains the expected value */
5641 if (hr == S_OK)
5642 hr = mono_test_marshal_safearray_in_byval_1dim_vt_mixed(safearray3);
5644 /* array4: Check input values and fill in with some values to check on the managed side */
5645 if (hr == S_OK)
5646 hr = mono_test_marshal_safearray_in_out_byref_3dim_vt_bstr(safearray4);
5648 return hr;
5651 LIBTEST_API int STDCALL
5652 mono_test_marshal_safearray_in_ccw(MonoComObject *pUnk)
5654 SAFEARRAY *array;
5655 VARIANT var;
5656 long index;
5657 int ret;
5659 array = SafeArrayCreateVector(VT_VARIANT, 0, 2);
5661 var.vt = VT_BSTR;
5662 var.bstrVal = marshal_bstr_alloc("Test");
5663 index = 0;
5664 SafeArrayPutElement(array, &index, &var);
5666 var.vt = VT_I4;
5667 var.intVal = 2345;
5668 index = 1;
5669 SafeArrayPutElement(array, &index, &var);
5671 ret = pUnk->vtbl->ArrayIn (pUnk, (void *)array);
5672 if (!ret)
5673 ret = pUnk->vtbl->ArrayIn2 (pUnk, (void *)array);
5674 if (!ret)
5675 ret = pUnk->vtbl->ArrayIn3 (pUnk, (void *)array);
5677 SafeArrayDestroy(array);
5679 return ret;
5682 #endif
5684 static int call_managed_res;
5686 static void
5687 call_managed (gpointer arg)
5689 SimpleDelegate del = (SimpleDelegate)arg;
5691 call_managed_res = del (42);
5694 LIBTEST_API int STDCALL
5695 mono_test_marshal_thread_attach (SimpleDelegate del)
5697 #ifdef WIN32
5698 return 43;
5699 #else
5700 int res;
5701 pthread_t t;
5703 res = pthread_create (&t, NULL, (gpointer (*)(gpointer))call_managed, (gpointer)del);
5704 g_assert (res == 0);
5705 pthread_join (t, NULL);
5707 return call_managed_res;
5708 #endif
5711 typedef struct {
5712 char arr [4 * 1024];
5713 } LargeStruct;
5715 typedef int (STDCALL *LargeStructDelegate) (LargeStruct *s);
5717 static void
5718 call_managed_large_vt (gpointer arg)
5720 LargeStructDelegate del = (LargeStructDelegate)arg;
5721 LargeStruct s;
5723 call_managed_res = del (&s);
5726 LIBTEST_API int STDCALL
5727 mono_test_marshal_thread_attach_large_vt (SimpleDelegate del)
5729 #ifdef WIN32
5730 return 43;
5731 #else
5732 int res;
5733 pthread_t t;
5735 res = pthread_create (&t, NULL, (gpointer (*)(gpointer))call_managed_large_vt, (gpointer)del);
5736 g_assert (res == 0);
5737 pthread_join (t, NULL);
5739 return call_managed_res;
5740 #endif
5743 typedef int (STDCALL *Callback) (void);
5745 static Callback callback;
5747 LIBTEST_API void STDCALL
5748 mono_test_marshal_set_callback (Callback cb)
5750 callback = cb;
5753 LIBTEST_API int STDCALL
5754 mono_test_marshal_call_callback (void)
5756 return callback ();
5759 LIBTEST_API int STDCALL
5760 mono_test_marshal_lpstr (char *str)
5762 return strcmp ("ABC", str);
5765 LIBTEST_API int STDCALL
5766 mono_test_marshal_lpwstr (gunichar2 *str)
5768 char *s;
5769 int res;
5771 s = g_utf16_to_utf8 (str, -1, NULL, NULL, NULL);
5772 res = strcmp ("ABC", s);
5773 g_free (s);
5775 return res;
5778 LIBTEST_API char* STDCALL
5779 mono_test_marshal_return_lpstr (void)
5781 char *res = (char *)marshal_alloc (4);
5782 strcpy (res, "XYZ");
5783 return res;
5786 LIBTEST_API gunichar2* STDCALL
5787 mono_test_marshal_return_lpwstr (void)
5789 gunichar2 *res = (gunichar2 *)marshal_alloc (8);
5790 gunichar2* tmp = g_utf8_to_utf16 ("XYZ", -1, NULL, NULL, NULL);
5792 memcpy (res, tmp, 8);
5793 g_free (tmp);
5795 return res;
5798 typedef
5799 #if defined (HOST_WIN32) && defined (HOST_X86) && defined (__GNUC__)
5800 // Workaround gcc ABI bug. It returns the struct in ST0 instead of edx:eax.
5801 // Mono and Visual C++ agree.
5802 union
5803 #else
5804 struct
5805 #endif
5807 double d;
5808 } SingleDoubleStruct;
5810 LIBTEST_API SingleDoubleStruct STDCALL
5811 mono_test_marshal_return_single_double_struct (void)
5813 SingleDoubleStruct res = {3.0};
5814 return res;
5817 LIBTEST_API int STDCALL
5818 mono_test_has_thiscall_globals (void)
5820 // Visual C++ does not accept __thiscall on global functions, only
5821 // member function and function pointers. Gcc accepts it also on global functions.
5822 #if defined (HOST_X86) && defined (HOST_WIN32) && !defined (_MSC_VER)
5823 return 1;
5824 #else
5825 return 0;
5826 #endif
5829 LIBTEST_API int STDCALL
5830 mono_test_has_thiscall_pointers (void)
5832 #if defined (HOST_X86) && defined (HOST_WIN32)
5833 return 1;
5834 #else
5835 return 0;
5836 #endif
5839 LIBTEST_API int
5840 #ifndef _MSC_VER
5841 __thiscall
5842 #endif
5843 _mono_test_native_thiscall1 (int arg)
5845 return arg;
5848 LIBTEST_API int
5849 #ifndef _MSC_VER
5850 __thiscall
5851 #endif
5852 _mono_test_native_thiscall2 (int arg, int arg2)
5854 return arg + (arg2^1);
5857 LIBTEST_API int
5858 #ifndef _MSC_VER
5859 __thiscall
5860 #endif
5861 _mono_test_native_thiscall3 (int arg, int arg2, int arg3)
5863 return arg + (arg2^1) + (arg3^2);
5866 typedef int (
5867 #ifndef _MSC_VER
5868 __thiscall
5869 #endif
5870 *ThiscallFunction)(int arg, int arg2);
5872 LIBTEST_API ThiscallFunction STDCALL
5873 mono_test_get_native_thiscall2 (void)
5875 return _mono_test_native_thiscall2;
5878 LIBTEST_API int STDCALL
5879 _mono_test_managed_thiscall1 (int (__thiscall*fn)(int), int arg)
5881 return fn(arg);
5884 LIBTEST_API int STDCALL
5885 _mono_test_managed_thiscall2 (int (__thiscall*fn)(int,int), int arg, int arg2)
5887 return fn(arg, arg2);
5890 LIBTEST_API int STDCALL
5891 _mono_test_managed_thiscall3 (int (__thiscall*fn)(int,int,int), int arg, int arg2, int arg3)
5893 return fn(arg, arg2, arg3);
5896 typedef struct {
5897 char f1;
5898 } sbyte1;
5900 LIBTEST_API sbyte1 STDCALL
5901 mono_return_sbyte1 (sbyte1 s1, int addend) {
5902 if (s1.f1 != 1) {
5903 fprintf(stderr, "mono_return_sbyte1 s1.f1: got %d but expected %d\n", s1.f1, 1);
5905 s1.f1+=addend;
5906 return s1;
5909 typedef struct {
5910 char f1,f2;
5911 } sbyte2;
5913 LIBTEST_API sbyte2 STDCALL
5914 mono_return_sbyte2 (sbyte2 s2, int addend) {
5915 if (s2.f1 != 1) {
5916 fprintf(stderr, "mono_return_sbyte2 s2.f1: got %d but expected %d\n", s2.f1, 1);
5918 if (s2.f2 != 2) {
5919 fprintf(stderr, "mono_return_sbyte2 s2.f2: got %d but expected %d\n", s2.f2, 2);
5921 s2.f1+=addend; s2.f2+=addend;
5922 return s2;
5925 typedef struct {
5926 char f1,f2,f3;
5927 } sbyte3;
5929 LIBTEST_API sbyte3 STDCALL
5930 mono_return_sbyte3 (sbyte3 s3, int addend) {
5931 if (s3.f1 != 1) {
5932 fprintf(stderr, "mono_return_sbyte3 s3.f1: got %d but expected %d\n", s3.f1, 1);
5934 if (s3.f2 != 2) {
5935 fprintf(stderr, "mono_return_sbyte3 s3.f2: got %d but expected %d\n", s3.f2, 2);
5937 if (s3.f3 != 3) {
5938 fprintf(stderr, "mono_return_sbyte3 s3.f3: got %d but expected %d\n", s3.f3, 3);
5940 s3.f1+=addend; s3.f2+=addend; s3.f3+=addend;
5941 return s3;
5944 typedef struct {
5945 char f1,f2,f3,f4;
5946 } sbyte4;
5948 LIBTEST_API sbyte4 STDCALL
5949 mono_return_sbyte4 (sbyte4 s4, int addend) {
5950 if (s4.f1 != 1) {
5951 fprintf(stderr, "mono_return_sbyte4 s4.f1: got %d but expected %d\n", s4.f1, 1);
5953 if (s4.f2 != 2) {
5954 fprintf(stderr, "mono_return_sbyte4 s4.f2: got %d but expected %d\n", s4.f2, 2);
5956 if (s4.f3 != 3) {
5957 fprintf(stderr, "mono_return_sbyte4 s4.f3: got %d but expected %d\n", s4.f3, 3);
5959 if (s4.f4 != 4) {
5960 fprintf(stderr, "mono_return_sbyte4 s4.f4: got %d but expected %d\n", s4.f4, 4);
5962 s4.f1+=addend; s4.f2+=addend; s4.f3+=addend; s4.f4+=addend;
5963 return s4;
5966 typedef struct {
5967 char f1,f2,f3,f4,f5;
5968 } sbyte5;
5970 LIBTEST_API sbyte5 STDCALL
5971 mono_return_sbyte5 (sbyte5 s5, int addend) {
5972 if (s5.f1 != 1) {
5973 fprintf(stderr, "mono_return_sbyte5 s5.f1: got %d but expected %d\n", s5.f1, 1);
5975 if (s5.f2 != 2) {
5976 fprintf(stderr, "mono_return_sbyte5 s5.f2: got %d but expected %d\n", s5.f2, 2);
5978 if (s5.f3 != 3) {
5979 fprintf(stderr, "mono_return_sbyte5 s5.f3: got %d but expected %d\n", s5.f3, 3);
5981 if (s5.f4 != 4) {
5982 fprintf(stderr, "mono_return_sbyte5 s5.f4: got %d but expected %d\n", s5.f4, 4);
5984 if (s5.f5 != 5) {
5985 fprintf(stderr, "mono_return_sbyte5 s5.f5: got %d but expected %d\n", s5.f5, 5);
5987 s5.f1+=addend; s5.f2+=addend; s5.f3+=addend; s5.f4+=addend; s5.f5+=addend;
5988 return s5;
5991 typedef struct {
5992 char f1,f2,f3,f4,f5,f6;
5993 } sbyte6;
5995 LIBTEST_API sbyte6 STDCALL
5996 mono_return_sbyte6 (sbyte6 s6, int addend) {
5997 if (s6.f1 != 1) {
5998 fprintf(stderr, "mono_return_sbyte6 s6.f1: got %d but expected %d\n", s6.f1, 1);
6000 if (s6.f2 != 2) {
6001 fprintf(stderr, "mono_return_sbyte6 s6.f2: got %d but expected %d\n", s6.f2, 2);
6003 if (s6.f3 != 3) {
6004 fprintf(stderr, "mono_return_sbyte6 s6.f3: got %d but expected %d\n", s6.f3, 3);
6006 if (s6.f4 != 4) {
6007 fprintf(stderr, "mono_return_sbyte6 s6.f4: got %d but expected %d\n", s6.f4, 4);
6009 if (s6.f5 != 5) {
6010 fprintf(stderr, "mono_return_sbyte6 s6.f5: got %d but expected %d\n", s6.f5, 5);
6012 if (s6.f6 != 6) {
6013 fprintf(stderr, "mono_return_sbyte6 s6.f6: got %d but expected %d\n", s6.f6, 6);
6015 s6.f1+=addend; s6.f2+=addend; s6.f3+=addend; s6.f4+=addend; s6.f5+=addend; s6.f6+=addend;
6016 return s6;
6019 typedef struct {
6020 char f1,f2,f3,f4,f5,f6,f7;
6021 } sbyte7;
6023 LIBTEST_API sbyte7 STDCALL
6024 mono_return_sbyte7 (sbyte7 s7, int addend) {
6025 if (s7.f1 != 1) {
6026 fprintf(stderr, "mono_return_sbyte7 s7.f1: got %d but expected %d\n", s7.f1, 1);
6028 if (s7.f2 != 2) {
6029 fprintf(stderr, "mono_return_sbyte7 s7.f2: got %d but expected %d\n", s7.f2, 2);
6031 if (s7.f3 != 3) {
6032 fprintf(stderr, "mono_return_sbyte7 s7.f3: got %d but expected %d\n", s7.f3, 3);
6034 if (s7.f4 != 4) {
6035 fprintf(stderr, "mono_return_sbyte7 s7.f4: got %d but expected %d\n", s7.f4, 4);
6037 if (s7.f5 != 5) {
6038 fprintf(stderr, "mono_return_sbyte7 s7.f5: got %d but expected %d\n", s7.f5, 5);
6040 if (s7.f6 != 6) {
6041 fprintf(stderr, "mono_return_sbyte7 s7.f6: got %d but expected %d\n", s7.f6, 6);
6043 if (s7.f7 != 7) {
6044 fprintf(stderr, "mono_return_sbyte7 s7.f7: got %d but expected %d\n", s7.f7, 7);
6046 s7.f1+=addend; s7.f2+=addend; s7.f3+=addend; s7.f4+=addend; s7.f5+=addend; s7.f6+=addend; s7.f7+=addend;
6047 return s7;
6050 typedef struct {
6051 char f1,f2,f3,f4,f5,f6,f7,f8;
6052 } sbyte8;
6054 LIBTEST_API sbyte8 STDCALL
6055 mono_return_sbyte8 (sbyte8 s8, int addend) {
6056 if (s8.f1 != 1) {
6057 fprintf(stderr, "mono_return_sbyte8 s8.f1: got %d but expected %d\n", s8.f1, 1);
6059 if (s8.f2 != 2) {
6060 fprintf(stderr, "mono_return_sbyte8 s8.f2: got %d but expected %d\n", s8.f2, 2);
6062 if (s8.f3 != 3) {
6063 fprintf(stderr, "mono_return_sbyte8 s8.f3: got %d but expected %d\n", s8.f3, 3);
6065 if (s8.f4 != 4) {
6066 fprintf(stderr, "mono_return_sbyte8 s8.f4: got %d but expected %d\n", s8.f4, 4);
6068 if (s8.f5 != 5) {
6069 fprintf(stderr, "mono_return_sbyte8 s8.f5: got %d but expected %d\n", s8.f5, 5);
6071 if (s8.f6 != 6) {
6072 fprintf(stderr, "mono_return_sbyte8 s8.f6: got %d but expected %d\n", s8.f6, 6);
6074 if (s8.f7 != 7) {
6075 fprintf(stderr, "mono_return_sbyte8 s8.f7: got %d but expected %d\n", s8.f7, 7);
6077 if (s8.f8 != 8) {
6078 fprintf(stderr, "mono_return_sbyte8 s8.f8: got %d but expected %d\n", s8.f8, 8);
6080 s8.f1+=addend; s8.f2+=addend; s8.f3+=addend; s8.f4+=addend; s8.f5+=addend; s8.f6+=addend; s8.f7+=addend; s8.f8+=addend;
6081 return s8;
6084 typedef struct {
6085 char f1,f2,f3,f4,f5,f6,f7,f8,f9;
6086 } sbyte9;
6088 LIBTEST_API sbyte9 STDCALL
6089 mono_return_sbyte9 (sbyte9 s9, int addend) {
6090 if (s9.f1 != 1) {
6091 fprintf(stderr, "mono_return_sbyte9 s9.f1: got %d but expected %d\n", s9.f1, 1);
6093 if (s9.f2 != 2) {
6094 fprintf(stderr, "mono_return_sbyte9 s9.f2: got %d but expected %d\n", s9.f2, 2);
6096 if (s9.f3 != 3) {
6097 fprintf(stderr, "mono_return_sbyte9 s9.f3: got %d but expected %d\n", s9.f3, 3);
6099 if (s9.f4 != 4) {
6100 fprintf(stderr, "mono_return_sbyte9 s9.f4: got %d but expected %d\n", s9.f4, 4);
6102 if (s9.f5 != 5) {
6103 fprintf(stderr, "mono_return_sbyte9 s9.f5: got %d but expected %d\n", s9.f5, 5);
6105 if (s9.f6 != 6) {
6106 fprintf(stderr, "mono_return_sbyte9 s9.f6: got %d but expected %d\n", s9.f6, 6);
6108 if (s9.f7 != 7) {
6109 fprintf(stderr, "mono_return_sbyte9 s9.f7: got %d but expected %d\n", s9.f7, 7);
6111 if (s9.f8 != 8) {
6112 fprintf(stderr, "mono_return_sbyte9 s9.f8: got %d but expected %d\n", s9.f8, 8);
6114 if (s9.f9 != 9) {
6115 fprintf(stderr, "mono_return_sbyte9 s9.f9: got %d but expected %d\n", s9.f9, 9);
6117 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;
6118 return s9;
6121 typedef struct {
6122 char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10;
6123 } sbyte10;
6125 LIBTEST_API sbyte10 STDCALL
6126 mono_return_sbyte10 (sbyte10 s10, int addend) {
6127 if (s10.f1 != 1) {
6128 fprintf(stderr, "mono_return_sbyte10 s10.f1: got %d but expected %d\n", s10.f1, 1);
6130 if (s10.f2 != 2) {
6131 fprintf(stderr, "mono_return_sbyte10 s10.f2: got %d but expected %d\n", s10.f2, 2);
6133 if (s10.f3 != 3) {
6134 fprintf(stderr, "mono_return_sbyte10 s10.f3: got %d but expected %d\n", s10.f3, 3);
6136 if (s10.f4 != 4) {
6137 fprintf(stderr, "mono_return_sbyte10 s10.f4: got %d but expected %d\n", s10.f4, 4);
6139 if (s10.f5 != 5) {
6140 fprintf(stderr, "mono_return_sbyte10 s10.f5: got %d but expected %d\n", s10.f5, 5);
6142 if (s10.f6 != 6) {
6143 fprintf(stderr, "mono_return_sbyte10 s10.f6: got %d but expected %d\n", s10.f6, 6);
6145 if (s10.f7 != 7) {
6146 fprintf(stderr, "mono_return_sbyte10 s10.f7: got %d but expected %d\n", s10.f7, 7);
6148 if (s10.f8 != 8) {
6149 fprintf(stderr, "mono_return_sbyte10 s10.f8: got %d but expected %d\n", s10.f8, 8);
6151 if (s10.f9 != 9) {
6152 fprintf(stderr, "mono_return_sbyte10 s10.f9: got %d but expected %d\n", s10.f9, 9);
6154 if (s10.f10 != 10) {
6155 fprintf(stderr, "mono_return_sbyte10 s10.f10: got %d but expected %d\n", s10.f10, 10);
6157 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;
6158 return s10;
6161 typedef struct {
6162 char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11;
6163 } sbyte11;
6165 LIBTEST_API sbyte11 STDCALL
6166 mono_return_sbyte11 (sbyte11 s11, int addend) {
6167 if (s11.f1 != 1) {
6168 fprintf(stderr, "mono_return_sbyte11 s11.f1: got %d but expected %d\n", s11.f1, 1);
6170 if (s11.f2 != 2) {
6171 fprintf(stderr, "mono_return_sbyte11 s11.f2: got %d but expected %d\n", s11.f2, 2);
6173 if (s11.f3 != 3) {
6174 fprintf(stderr, "mono_return_sbyte11 s11.f3: got %d but expected %d\n", s11.f3, 3);
6176 if (s11.f4 != 4) {
6177 fprintf(stderr, "mono_return_sbyte11 s11.f4: got %d but expected %d\n", s11.f4, 4);
6179 if (s11.f5 != 5) {
6180 fprintf(stderr, "mono_return_sbyte11 s11.f5: got %d but expected %d\n", s11.f5, 5);
6182 if (s11.f6 != 6) {
6183 fprintf(stderr, "mono_return_sbyte11 s11.f6: got %d but expected %d\n", s11.f6, 6);
6185 if (s11.f7 != 7) {
6186 fprintf(stderr, "mono_return_sbyte11 s11.f7: got %d but expected %d\n", s11.f7, 7);
6188 if (s11.f8 != 8) {
6189 fprintf(stderr, "mono_return_sbyte11 s11.f8: got %d but expected %d\n", s11.f8, 8);
6191 if (s11.f9 != 9) {
6192 fprintf(stderr, "mono_return_sbyte11 s11.f9: got %d but expected %d\n", s11.f9, 9);
6194 if (s11.f10 != 10) {
6195 fprintf(stderr, "mono_return_sbyte11 s11.f10: got %d but expected %d\n", s11.f10, 10);
6197 if (s11.f11 != 11) {
6198 fprintf(stderr, "mono_return_sbyte11 s11.f11: got %d but expected %d\n", s11.f11, 11);
6200 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;
6201 return s11;
6204 typedef struct {
6205 char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12;
6206 } sbyte12;
6208 LIBTEST_API sbyte12 STDCALL
6209 mono_return_sbyte12 (sbyte12 s12, int addend) {
6210 if (s12.f1 != 1) {
6211 fprintf(stderr, "mono_return_sbyte12 s12.f1: got %d but expected %d\n", s12.f1, 1);
6213 if (s12.f2 != 2) {
6214 fprintf(stderr, "mono_return_sbyte12 s12.f2: got %d but expected %d\n", s12.f2, 2);
6216 if (s12.f3 != 3) {
6217 fprintf(stderr, "mono_return_sbyte12 s12.f3: got %d but expected %d\n", s12.f3, 3);
6219 if (s12.f4 != 4) {
6220 fprintf(stderr, "mono_return_sbyte12 s12.f4: got %d but expected %d\n", s12.f4, 4);
6222 if (s12.f5 != 5) {
6223 fprintf(stderr, "mono_return_sbyte12 s12.f5: got %d but expected %d\n", s12.f5, 5);
6225 if (s12.f6 != 6) {
6226 fprintf(stderr, "mono_return_sbyte12 s12.f6: got %d but expected %d\n", s12.f6, 6);
6228 if (s12.f7 != 7) {
6229 fprintf(stderr, "mono_return_sbyte12 s12.f7: got %d but expected %d\n", s12.f7, 7);
6231 if (s12.f8 != 8) {
6232 fprintf(stderr, "mono_return_sbyte12 s12.f8: got %d but expected %d\n", s12.f8, 8);
6234 if (s12.f9 != 9) {
6235 fprintf(stderr, "mono_return_sbyte12 s12.f9: got %d but expected %d\n", s12.f9, 9);
6237 if (s12.f10 != 10) {
6238 fprintf(stderr, "mono_return_sbyte12 s12.f10: got %d but expected %d\n", s12.f10, 10);
6240 if (s12.f11 != 11) {
6241 fprintf(stderr, "mono_return_sbyte12 s12.f11: got %d but expected %d\n", s12.f11, 11);
6243 if (s12.f12 != 12) {
6244 fprintf(stderr, "mono_return_sbyte12 s12.f12: got %d but expected %d\n", s12.f12, 12);
6246 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;
6247 return s12;
6250 typedef struct {
6251 char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13;
6252 } sbyte13;
6254 LIBTEST_API sbyte13 STDCALL
6255 mono_return_sbyte13 (sbyte13 s13, int addend) {
6256 if (s13.f1 != 1) {
6257 fprintf(stderr, "mono_return_sbyte13 s13.f1: got %d but expected %d\n", s13.f1, 1);
6259 if (s13.f2 != 2) {
6260 fprintf(stderr, "mono_return_sbyte13 s13.f2: got %d but expected %d\n", s13.f2, 2);
6262 if (s13.f3 != 3) {
6263 fprintf(stderr, "mono_return_sbyte13 s13.f3: got %d but expected %d\n", s13.f3, 3);
6265 if (s13.f4 != 4) {
6266 fprintf(stderr, "mono_return_sbyte13 s13.f4: got %d but expected %d\n", s13.f4, 4);
6268 if (s13.f5 != 5) {
6269 fprintf(stderr, "mono_return_sbyte13 s13.f5: got %d but expected %d\n", s13.f5, 5);
6271 if (s13.f6 != 6) {
6272 fprintf(stderr, "mono_return_sbyte13 s13.f6: got %d but expected %d\n", s13.f6, 6);
6274 if (s13.f7 != 7) {
6275 fprintf(stderr, "mono_return_sbyte13 s13.f7: got %d but expected %d\n", s13.f7, 7);
6277 if (s13.f8 != 8) {
6278 fprintf(stderr, "mono_return_sbyte13 s13.f8: got %d but expected %d\n", s13.f8, 8);
6280 if (s13.f9 != 9) {
6281 fprintf(stderr, "mono_return_sbyte13 s13.f9: got %d but expected %d\n", s13.f9, 9);
6283 if (s13.f10 != 10) {
6284 fprintf(stderr, "mono_return_sbyte13 s13.f10: got %d but expected %d\n", s13.f10, 10);
6286 if (s13.f11 != 11) {
6287 fprintf(stderr, "mono_return_sbyte13 s13.f11: got %d but expected %d\n", s13.f11, 11);
6289 if (s13.f12 != 12) {
6290 fprintf(stderr, "mono_return_sbyte13 s13.f12: got %d but expected %d\n", s13.f12, 12);
6292 if (s13.f13 != 13) {
6293 fprintf(stderr, "mono_return_sbyte13 s13.f13: got %d but expected %d\n", s13.f13, 13);
6295 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;
6296 return s13;
6299 typedef struct {
6300 char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14;
6301 } sbyte14;
6303 LIBTEST_API sbyte14 STDCALL
6304 mono_return_sbyte14 (sbyte14 s14, int addend) {
6305 if (s14.f1 != 1) {
6306 fprintf(stderr, "mono_return_sbyte14 s14.f1: got %d but expected %d\n", s14.f1, 1);
6308 if (s14.f2 != 2) {
6309 fprintf(stderr, "mono_return_sbyte14 s14.f2: got %d but expected %d\n", s14.f2, 2);
6311 if (s14.f3 != 3) {
6312 fprintf(stderr, "mono_return_sbyte14 s14.f3: got %d but expected %d\n", s14.f3, 3);
6314 if (s14.f4 != 4) {
6315 fprintf(stderr, "mono_return_sbyte14 s14.f4: got %d but expected %d\n", s14.f4, 4);
6317 if (s14.f5 != 5) {
6318 fprintf(stderr, "mono_return_sbyte14 s14.f5: got %d but expected %d\n", s14.f5, 5);
6320 if (s14.f6 != 6) {
6321 fprintf(stderr, "mono_return_sbyte14 s14.f6: got %d but expected %d\n", s14.f6, 6);
6323 if (s14.f7 != 7) {
6324 fprintf(stderr, "mono_return_sbyte14 s14.f7: got %d but expected %d\n", s14.f7, 7);
6326 if (s14.f8 != 8) {
6327 fprintf(stderr, "mono_return_sbyte14 s14.f8: got %d but expected %d\n", s14.f8, 8);
6329 if (s14.f9 != 9) {
6330 fprintf(stderr, "mono_return_sbyte14 s14.f9: got %d but expected %d\n", s14.f9, 9);
6332 if (s14.f10 != 10) {
6333 fprintf(stderr, "mono_return_sbyte14 s14.f10: got %d but expected %d\n", s14.f10, 10);
6335 if (s14.f11 != 11) {
6336 fprintf(stderr, "mono_return_sbyte14 s14.f11: got %d but expected %d\n", s14.f11, 11);
6338 if (s14.f12 != 12) {
6339 fprintf(stderr, "mono_return_sbyte14 s14.f12: got %d but expected %d\n", s14.f12, 12);
6341 if (s14.f13 != 13) {
6342 fprintf(stderr, "mono_return_sbyte14 s14.f13: got %d but expected %d\n", s14.f13, 13);
6344 if (s14.f14 != 14) {
6345 fprintf(stderr, "mono_return_sbyte14 s14.f14: got %d but expected %d\n", s14.f14, 14);
6347 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;
6348 return s14;
6351 typedef struct {
6352 char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15;
6353 } sbyte15;
6355 LIBTEST_API sbyte15 STDCALL
6356 mono_return_sbyte15 (sbyte15 s15, int addend) {
6357 if (s15.f1 != 1) {
6358 fprintf(stderr, "mono_return_sbyte15 s15.f1: got %d but expected %d\n", s15.f1, 1);
6360 if (s15.f2 != 2) {
6361 fprintf(stderr, "mono_return_sbyte15 s15.f2: got %d but expected %d\n", s15.f2, 2);
6363 if (s15.f3 != 3) {
6364 fprintf(stderr, "mono_return_sbyte15 s15.f3: got %d but expected %d\n", s15.f3, 3);
6366 if (s15.f4 != 4) {
6367 fprintf(stderr, "mono_return_sbyte15 s15.f4: got %d but expected %d\n", s15.f4, 4);
6369 if (s15.f5 != 5) {
6370 fprintf(stderr, "mono_return_sbyte15 s15.f5: got %d but expected %d\n", s15.f5, 5);
6372 if (s15.f6 != 6) {
6373 fprintf(stderr, "mono_return_sbyte15 s15.f6: got %d but expected %d\n", s15.f6, 6);
6375 if (s15.f7 != 7) {
6376 fprintf(stderr, "mono_return_sbyte15 s15.f7: got %d but expected %d\n", s15.f7, 7);
6378 if (s15.f8 != 8) {
6379 fprintf(stderr, "mono_return_sbyte15 s15.f8: got %d but expected %d\n", s15.f8, 8);
6381 if (s15.f9 != 9) {
6382 fprintf(stderr, "mono_return_sbyte15 s15.f9: got %d but expected %d\n", s15.f9, 9);
6384 if (s15.f10 != 10) {
6385 fprintf(stderr, "mono_return_sbyte15 s15.f10: got %d but expected %d\n", s15.f10, 10);
6387 if (s15.f11 != 11) {
6388 fprintf(stderr, "mono_return_sbyte15 s15.f11: got %d but expected %d\n", s15.f11, 11);
6390 if (s15.f12 != 12) {
6391 fprintf(stderr, "mono_return_sbyte15 s15.f12: got %d but expected %d\n", s15.f12, 12);
6393 if (s15.f13 != 13) {
6394 fprintf(stderr, "mono_return_sbyte15 s15.f13: got %d but expected %d\n", s15.f13, 13);
6396 if (s15.f14 != 14) {
6397 fprintf(stderr, "mono_return_sbyte15 s15.f14: got %d but expected %d\n", s15.f14, 14);
6399 if (s15.f15 != 15) {
6400 fprintf(stderr, "mono_return_sbyte15 s15.f15: got %d but expected %d\n", s15.f15, 15);
6402 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;
6403 return s15;
6406 typedef struct {
6407 char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16;
6408 } sbyte16;
6410 LIBTEST_API sbyte16 STDCALL
6411 mono_return_sbyte16 (sbyte16 s16, int addend) {
6412 if (s16.f1 != 1) {
6413 fprintf(stderr, "mono_return_sbyte16 s16.f1: got %d but expected %d\n", s16.f1, 1);
6415 if (s16.f2 != 2) {
6416 fprintf(stderr, "mono_return_sbyte16 s16.f2: got %d but expected %d\n", s16.f2, 2);
6418 if (s16.f3 != 3) {
6419 fprintf(stderr, "mono_return_sbyte16 s16.f3: got %d but expected %d\n", s16.f3, 3);
6421 if (s16.f4 != 4) {
6422 fprintf(stderr, "mono_return_sbyte16 s16.f4: got %d but expected %d\n", s16.f4, 4);
6424 if (s16.f5 != 5) {
6425 fprintf(stderr, "mono_return_sbyte16 s16.f5: got %d but expected %d\n", s16.f5, 5);
6427 if (s16.f6 != 6) {
6428 fprintf(stderr, "mono_return_sbyte16 s16.f6: got %d but expected %d\n", s16.f6, 6);
6430 if (s16.f7 != 7) {
6431 fprintf(stderr, "mono_return_sbyte16 s16.f7: got %d but expected %d\n", s16.f7, 7);
6433 if (s16.f8 != 8) {
6434 fprintf(stderr, "mono_return_sbyte16 s16.f8: got %d but expected %d\n", s16.f8, 8);
6436 if (s16.f9 != 9) {
6437 fprintf(stderr, "mono_return_sbyte16 s16.f9: got %d but expected %d\n", s16.f9, 9);
6439 if (s16.f10 != 10) {
6440 fprintf(stderr, "mono_return_sbyte16 s16.f10: got %d but expected %d\n", s16.f10, 10);
6442 if (s16.f11 != 11) {
6443 fprintf(stderr, "mono_return_sbyte16 s16.f11: got %d but expected %d\n", s16.f11, 11);
6445 if (s16.f12 != 12) {
6446 fprintf(stderr, "mono_return_sbyte16 s16.f12: got %d but expected %d\n", s16.f12, 12);
6448 if (s16.f13 != 13) {
6449 fprintf(stderr, "mono_return_sbyte16 s16.f13: got %d but expected %d\n", s16.f13, 13);
6451 if (s16.f14 != 14) {
6452 fprintf(stderr, "mono_return_sbyte16 s16.f14: got %d but expected %d\n", s16.f14, 14);
6454 if (s16.f15 != 15) {
6455 fprintf(stderr, "mono_return_sbyte16 s16.f15: got %d but expected %d\n", s16.f15, 15);
6457 if (s16.f16 != 16) {
6458 fprintf(stderr, "mono_return_sbyte16 s16.f16: got %d but expected %d\n", s16.f16, 16);
6460 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;
6461 return s16;
6464 typedef struct {
6465 char f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15,f16,f17;
6466 } sbyte17;
6468 LIBTEST_API sbyte17 STDCALL
6469 mono_return_sbyte17 (sbyte17 s17, int addend) {
6470 if (s17.f1 != 1) {
6471 fprintf(stderr, "mono_return_sbyte17 s17.f1: got %d but expected %d\n", s17.f1, 1);
6473 if (s17.f2 != 2) {
6474 fprintf(stderr, "mono_return_sbyte17 s17.f2: got %d but expected %d\n", s17.f2, 2);
6476 if (s17.f3 != 3) {
6477 fprintf(stderr, "mono_return_sbyte17 s17.f3: got %d but expected %d\n", s17.f3, 3);
6479 if (s17.f4 != 4) {
6480 fprintf(stderr, "mono_return_sbyte17 s17.f4: got %d but expected %d\n", s17.f4, 4);
6482 if (s17.f5 != 5) {
6483 fprintf(stderr, "mono_return_sbyte17 s17.f5: got %d but expected %d\n", s17.f5, 5);
6485 if (s17.f6 != 6) {
6486 fprintf(stderr, "mono_return_sbyte17 s17.f6: got %d but expected %d\n", s17.f6, 6);
6488 if (s17.f7 != 7) {
6489 fprintf(stderr, "mono_return_sbyte17 s17.f7: got %d but expected %d\n", s17.f7, 7);
6491 if (s17.f8 != 8) {
6492 fprintf(stderr, "mono_return_sbyte17 s17.f8: got %d but expected %d\n", s17.f8, 8);
6494 if (s17.f9 != 9) {
6495 fprintf(stderr, "mono_return_sbyte17 s17.f9: got %d but expected %d\n", s17.f9, 9);
6497 if (s17.f10 != 10) {
6498 fprintf(stderr, "mono_return_sbyte17 s17.f10: got %d but expected %d\n", s17.f10, 10);
6500 if (s17.f11 != 11) {
6501 fprintf(stderr, "mono_return_sbyte17 s17.f11: got %d but expected %d\n", s17.f11, 11);
6503 if (s17.f12 != 12) {
6504 fprintf(stderr, "mono_return_sbyte17 s17.f12: got %d but expected %d\n", s17.f12, 12);
6506 if (s17.f13 != 13) {
6507 fprintf(stderr, "mono_return_sbyte17 s17.f13: got %d but expected %d\n", s17.f13, 13);
6509 if (s17.f14 != 14) {
6510 fprintf(stderr, "mono_return_sbyte17 s17.f14: got %d but expected %d\n", s17.f14, 14);
6512 if (s17.f15 != 15) {
6513 fprintf(stderr, "mono_return_sbyte17 s17.f15: got %d but expected %d\n", s17.f15, 15);
6515 if (s17.f16 != 16) {
6516 fprintf(stderr, "mono_return_sbyte17 s17.f16: got %d but expected %d\n", s17.f16, 16);
6518 if (s17.f17 != 17) {
6519 fprintf(stderr, "mono_return_sbyte17 s17.f17: got %d but expected %d\n", s17.f17, 17);
6521 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;
6522 return s17;
6525 typedef struct {
6526 struct {
6527 char f1;
6528 } nested1;
6529 char f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,f12,f13,f14,f15;
6530 struct {
6531 char f16;
6532 } nested2;
6533 } sbyte16_nested;
6535 LIBTEST_API sbyte16_nested STDCALL
6536 mono_return_sbyte16_nested (sbyte16_nested sn16, int addend) {
6537 if (sn16.nested1.f1 != 1) {
6538 fprintf(stderr, "mono_return_sbyte16_nested sn16.nested1.f1: got %d but expected %d\n", sn16.nested1.f1, 1);
6540 if (sn16.f2 != 2) {
6541 fprintf(stderr, "mono_return_sbyte16_nested sn16.f2: got %d but expected %d\n", sn16.f2, 2);
6543 if (sn16.f3 != 3) {
6544 fprintf(stderr, "mono_return_sbyte16_nested sn16.f3: got %d but expected %d\n", sn16.f3, 3);
6546 if (sn16.f4 != 4) {
6547 fprintf(stderr, "mono_return_sbyte16_nested sn16.f4: got %d but expected %d\n", sn16.f4, 4);
6549 if (sn16.f5 != 5) {
6550 fprintf(stderr, "mono_return_sbyte16_nested sn16.f5: got %d but expected %d\n", sn16.f5, 5);
6552 if (sn16.f6 != 6) {
6553 fprintf(stderr, "mono_return_sbyte16_nested sn16.f6: got %d but expected %d\n", sn16.f6, 6);
6555 if (sn16.f7 != 7) {
6556 fprintf(stderr, "mono_return_sbyte16_nested sn16.f7: got %d but expected %d\n", sn16.f7, 7);
6558 if (sn16.f8 != 8) {
6559 fprintf(stderr, "mono_return_sbyte16_nested sn16.f8: got %d but expected %d\n", sn16.f8, 8);
6561 if (sn16.f9 != 9) {
6562 fprintf(stderr, "mono_return_sbyte16_nested sn16.f9: got %d but expected %d\n", sn16.f9, 9);
6564 if (sn16.f10 != 10) {
6565 fprintf(stderr, "mono_return_sbyte16_nested sn16.f10: got %d but expected %d\n", sn16.f10, 10);
6567 if (sn16.f11 != 11) {
6568 fprintf(stderr, "mono_return_sbyte16_nested sn16.f11: got %d but expected %d\n", sn16.f11, 11);
6570 if (sn16.f12 != 12) {
6571 fprintf(stderr, "mono_return_sbyte16_nested sn16.f12: got %d but expected %d\n", sn16.f12, 12);
6573 if (sn16.f13 != 13) {
6574 fprintf(stderr, "mono_return_sbyte16_nested sn16.f13: got %d but expected %d\n", sn16.f13, 13);
6576 if (sn16.f14 != 14) {
6577 fprintf(stderr, "mono_return_sbyte16_nested sn16.f14: got %d but expected %d\n", sn16.f14, 14);
6579 if (sn16.f15 != 15) {
6580 fprintf(stderr, "mono_return_sbyte16_nested sn16.f15: got %d but expected %d\n", sn16.f15, 15);
6582 if (sn16.nested2.f16 != 16) {
6583 fprintf(stderr, "mono_return_sbyte16_nested sn16.nested2.f16: got %d but expected %d\n", sn16.nested2.f16, 16);
6585 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;
6586 return sn16;
6590 typedef struct {
6591 short f1;
6592 } short1;
6594 LIBTEST_API short1 STDCALL
6595 mono_return_short1 (short1 s1, int addend) {
6596 if (s1.f1 != 1) {
6597 fprintf(stderr, "mono_return_short1 s1.f1: got %d but expected %d\n", s1.f1, 1);
6599 s1.f1+=addend;
6600 return s1;
6603 typedef struct {
6604 short f1,f2;
6605 } short2;
6607 LIBTEST_API short2 STDCALL
6608 mono_return_short2 (short2 s2, int addend) {
6609 if (s2.f1 != 1) {
6610 fprintf(stderr, "mono_return_short2 s2.f1: got %d but expected %d\n", s2.f1, 1);
6612 if (s2.f2 != 2) {
6613 fprintf(stderr, "mono_return_short2 s2.f2: got %d but expected %d\n", s2.f2, 2);
6615 s2.f1+=addend; s2.f2+=addend;
6616 return s2;
6619 typedef struct {
6620 short f1,f2,f3;
6621 } short3;
6623 LIBTEST_API short3 STDCALL
6624 mono_return_short3 (short3 s3, int addend) {
6625 if (s3.f1 != 1) {
6626 fprintf(stderr, "mono_return_short3 s3.f1: got %d but expected %d\n", s3.f1, 1);
6628 if (s3.f2 != 2) {
6629 fprintf(stderr, "mono_return_short3 s3.f2: got %d but expected %d\n", s3.f2, 2);
6631 if (s3.f3 != 3) {
6632 fprintf(stderr, "mono_return_short3 s3.f3: got %d but expected %d\n", s3.f3, 3);
6634 s3.f1+=addend; s3.f2+=addend; s3.f3+=addend;
6635 return s3;
6638 typedef struct {
6639 short f1,f2,f3,f4;
6640 } short4;
6642 LIBTEST_API short4 STDCALL
6643 mono_return_short4 (short4 s4, int addend) {
6644 if (s4.f1 != 1) {
6645 fprintf(stderr, "mono_return_short4 s4.f1: got %d but expected %d\n", s4.f1, 1);
6647 if (s4.f2 != 2) {
6648 fprintf(stderr, "mono_return_short4 s4.f2: got %d but expected %d\n", s4.f2, 2);
6650 if (s4.f3 != 3) {
6651 fprintf(stderr, "mono_return_short4 s4.f3: got %d but expected %d\n", s4.f3, 3);
6653 if (s4.f4 != 4) {
6654 fprintf(stderr, "mono_return_short4 s4.f4: got %d but expected %d\n", s4.f4, 4);
6656 s4.f1+=addend; s4.f2+=addend; s4.f3+=addend; s4.f4+=addend;
6657 return s4;
6660 typedef struct {
6661 short f1,f2,f3,f4,f5;
6662 } short5;
6664 LIBTEST_API short5 STDCALL
6665 mono_return_short5 (short5 s5, int addend) {
6666 if (s5.f1 != 1) {
6667 fprintf(stderr, "mono_return_short5 s5.f1: got %d but expected %d\n", s5.f1, 1);
6669 if (s5.f2 != 2) {
6670 fprintf(stderr, "mono_return_short5 s5.f2: got %d but expected %d\n", s5.f2, 2);
6672 if (s5.f3 != 3) {
6673 fprintf(stderr, "mono_return_short5 s5.f3: got %d but expected %d\n", s5.f3, 3);
6675 if (s5.f4 != 4) {
6676 fprintf(stderr, "mono_return_short5 s5.f4: got %d but expected %d\n", s5.f4, 4);
6678 if (s5.f5 != 5) {
6679 fprintf(stderr, "mono_return_short5 s5.f5: got %d but expected %d\n", s5.f5, 5);
6681 s5.f1+=addend; s5.f2+=addend; s5.f3+=addend; s5.f4+=addend; s5.f5+=addend;
6682 return s5;
6685 typedef struct {
6686 short f1,f2,f3,f4,f5,f6;
6687 } short6;
6689 LIBTEST_API short6 STDCALL
6690 mono_return_short6 (short6 s6, int addend) {
6691 if (s6.f1 != 1) {
6692 fprintf(stderr, "mono_return_short6 s6.f1: got %d but expected %d\n", s6.f1, 1);
6694 if (s6.f2 != 2) {
6695 fprintf(stderr, "mono_return_short6 s6.f2: got %d but expected %d\n", s6.f2, 2);
6697 if (s6.f3 != 3) {
6698 fprintf(stderr, "mono_return_short6 s6.f3: got %d but expected %d\n", s6.f3, 3);
6700 if (s6.f4 != 4) {
6701 fprintf(stderr, "mono_return_short6 s6.f4: got %d but expected %d\n", s6.f4, 4);
6703 if (s6.f5 != 5) {
6704 fprintf(stderr, "mono_return_short6 s6.f5: got %d but expected %d\n", s6.f5, 5);
6706 if (s6.f6 != 6) {
6707 fprintf(stderr, "mono_return_short6 s6.f6: got %d but expected %d\n", s6.f6, 6);
6709 s6.f1+=addend; s6.f2+=addend; s6.f3+=addend; s6.f4+=addend; s6.f5+=addend; s6.f6+=addend;
6710 return s6;
6713 typedef struct {
6714 short f1,f2,f3,f4,f5,f6,f7;
6715 } short7;
6717 LIBTEST_API short7 STDCALL
6718 mono_return_short7 (short7 s7, int addend) {
6719 if (s7.f1 != 1) {
6720 fprintf(stderr, "mono_return_short7 s7.f1: got %d but expected %d\n", s7.f1, 1);
6722 if (s7.f2 != 2) {
6723 fprintf(stderr, "mono_return_short7 s7.f2: got %d but expected %d\n", s7.f2, 2);
6725 if (s7.f3 != 3) {
6726 fprintf(stderr, "mono_return_short7 s7.f3: got %d but expected %d\n", s7.f3, 3);
6728 if (s7.f4 != 4) {
6729 fprintf(stderr, "mono_return_short7 s7.f4: got %d but expected %d\n", s7.f4, 4);
6731 if (s7.f5 != 5) {
6732 fprintf(stderr, "mono_return_short7 s7.f5: got %d but expected %d\n", s7.f5, 5);
6734 if (s7.f6 != 6) {
6735 fprintf(stderr, "mono_return_short7 s7.f6: got %d but expected %d\n", s7.f6, 6);
6737 if (s7.f7 != 7) {
6738 fprintf(stderr, "mono_return_short7 s7.f7: got %d but expected %d\n", s7.f7, 7);
6740 s7.f1+=addend; s7.f2+=addend; s7.f3+=addend; s7.f4+=addend; s7.f5+=addend; s7.f6+=addend; s7.f7+=addend;
6741 return s7;
6744 typedef struct {
6745 short f1,f2,f3,f4,f5,f6,f7,f8;
6746 } short8;
6748 LIBTEST_API short8 STDCALL
6749 mono_return_short8 (short8 s8, int addend) {
6750 if (s8.f1 != 1) {
6751 fprintf(stderr, "mono_return_short8 s8.f1: got %d but expected %d\n", s8.f1, 1);
6753 if (s8.f2 != 2) {
6754 fprintf(stderr, "mono_return_short8 s8.f2: got %d but expected %d\n", s8.f2, 2);
6756 if (s8.f3 != 3) {
6757 fprintf(stderr, "mono_return_short8 s8.f3: got %d but expected %d\n", s8.f3, 3);
6759 if (s8.f4 != 4) {
6760 fprintf(stderr, "mono_return_short8 s8.f4: got %d but expected %d\n", s8.f4, 4);
6762 if (s8.f5 != 5) {
6763 fprintf(stderr, "mono_return_short8 s8.f5: got %d but expected %d\n", s8.f5, 5);
6765 if (s8.f6 != 6) {
6766 fprintf(stderr, "mono_return_short8 s8.f6: got %d but expected %d\n", s8.f6, 6);
6768 if (s8.f7 != 7) {
6769 fprintf(stderr, "mono_return_short8 s8.f7: got %d but expected %d\n", s8.f7, 7);
6771 if (s8.f8 != 8) {
6772 fprintf(stderr, "mono_return_short8 s8.f8: got %d but expected %d\n", s8.f8, 8);
6774 s8.f1+=addend; s8.f2+=addend; s8.f3+=addend; s8.f4+=addend; s8.f5+=addend; s8.f6+=addend; s8.f7+=addend; s8.f8+=addend;
6775 return s8;
6778 typedef struct {
6779 short f1,f2,f3,f4,f5,f6,f7,f8,f9;
6780 } short9;
6782 LIBTEST_API short9 STDCALL
6783 mono_return_short9 (short9 s9, int addend) {
6784 if (s9.f1 != 1) {
6785 fprintf(stderr, "mono_return_short9 s9.f1: got %d but expected %d\n", s9.f1, 1);
6787 if (s9.f2 != 2) {
6788 fprintf(stderr, "mono_return_short9 s9.f2: got %d but expected %d\n", s9.f2, 2);
6790 if (s9.f3 != 3) {
6791 fprintf(stderr, "mono_return_short9 s9.f3: got %d but expected %d\n", s9.f3, 3);
6793 if (s9.f4 != 4) {
6794 fprintf(stderr, "mono_return_short9 s9.f4: got %d but expected %d\n", s9.f4, 4);
6796 if (s9.f5 != 5) {
6797 fprintf(stderr, "mono_return_short9 s9.f5: got %d but expected %d\n", s9.f5, 5);
6799 if (s9.f6 != 6) {
6800 fprintf(stderr, "mono_return_short9 s9.f6: got %d but expected %d\n", s9.f6, 6);
6802 if (s9.f7 != 7) {
6803 fprintf(stderr, "mono_return_short9 s9.f7: got %d but expected %d\n", s9.f7, 7);
6805 if (s9.f8 != 8) {
6806 fprintf(stderr, "mono_return_short9 s9.f8: got %d but expected %d\n", s9.f8, 8);
6808 if (s9.f9 != 9) {
6809 fprintf(stderr, "mono_return_short9 s9.f9: got %d but expected %d\n", s9.f9, 9);
6811 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;
6812 return s9;
6815 typedef struct {
6816 struct {
6817 short f1;
6818 } nested1;
6819 short f2,f3,f4,f5,f6,f7;
6820 struct {
6821 short f8;
6822 } nested2;
6823 } short8_nested;
6825 LIBTEST_API short8_nested STDCALL
6826 mono_return_short8_nested (short8_nested sn8, int addend) {
6827 if (sn8.nested1.f1 != 1) {
6828 fprintf(stderr, "mono_return_short8_nested sn8.nested1.f1: got %d but expected %d\n", sn8.nested1.f1, 1);
6830 if (sn8.f2 != 2) {
6831 fprintf(stderr, "mono_return_short8_nested sn8.f2: got %d but expected %d\n", sn8.f2, 2);
6833 if (sn8.f3 != 3) {
6834 fprintf(stderr, "mono_return_short8_nested sn8.f3: got %d but expected %d\n", sn8.f3, 3);
6836 if (sn8.f4 != 4) {
6837 fprintf(stderr, "mono_return_short8_nested sn8.f4: got %d but expected %d\n", sn8.f4, 4);
6839 if (sn8.f5 != 5) {
6840 fprintf(stderr, "mono_return_short8_nested sn8.f5: got %d but expected %d\n", sn8.f5, 5);
6842 if (sn8.f6 != 6) {
6843 fprintf(stderr, "mono_return_short8_nested sn8.f6: got %d but expected %d\n", sn8.f6, 6);
6845 if (sn8.f7 != 7) {
6846 fprintf(stderr, "mono_return_short8_nested sn8.f7: got %d but expected %d\n", sn8.f7, 7);
6848 if (sn8.nested2.f8 != 8) {
6849 fprintf(stderr, "mono_return_short8_nested sn8.nested2.f8: got %d but expected %d\n", sn8.nested2.f8, 8);
6851 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;
6852 return sn8;
6856 typedef struct {
6857 int f1;
6858 } int1;
6860 LIBTEST_API int1 STDCALL
6861 mono_return_int1 (int1 s1, int addend) {
6862 if (s1.f1 != 1) {
6863 fprintf(stderr, "mono_return_int1 s1.f1: got %d but expected %d\n", s1.f1, 1);
6865 s1.f1+=addend;
6866 return s1;
6869 typedef struct {
6870 int f1,f2;
6871 } int2;
6873 LIBTEST_API int2 STDCALL
6874 mono_return_int2 (int2 s2, int addend) {
6875 if (s2.f1 != 1) {
6876 fprintf(stderr, "mono_return_int2 s2.f1: got %d but expected %d\n", s2.f1, 1);
6878 if (s2.f2 != 2) {
6879 fprintf(stderr, "mono_return_int2 s2.f2: got %d but expected %d\n", s2.f2, 2);
6881 s2.f1+=addend; s2.f2+=addend;
6882 return s2;
6885 typedef struct {
6886 int f1,f2,f3;
6887 } int3;
6889 LIBTEST_API int3 STDCALL
6890 mono_return_int3 (int3 s3, int addend) {
6891 if (s3.f1 != 1) {
6892 fprintf(stderr, "mono_return_int3 s3.f1: got %d but expected %d\n", s3.f1, 1);
6894 if (s3.f2 != 2) {
6895 fprintf(stderr, "mono_return_int3 s3.f2: got %d but expected %d\n", s3.f2, 2);
6897 if (s3.f3 != 3) {
6898 fprintf(stderr, "mono_return_int3 s3.f3: got %d but expected %d\n", s3.f3, 3);
6900 s3.f1+=addend; s3.f2+=addend; s3.f3+=addend;
6901 return s3;
6904 typedef struct {
6905 int f1,f2,f3,f4;
6906 } int4;
6908 LIBTEST_API int4 STDCALL
6909 mono_return_int4 (int4 s4, int addend) {
6910 if (s4.f1 != 1) {
6911 fprintf(stderr, "mono_return_int4 s4.f1: got %d but expected %d\n", s4.f1, 1);
6913 if (s4.f2 != 2) {
6914 fprintf(stderr, "mono_return_int4 s4.f2: got %d but expected %d\n", s4.f2, 2);
6916 if (s4.f3 != 3) {
6917 fprintf(stderr, "mono_return_int4 s4.f3: got %d but expected %d\n", s4.f3, 3);
6919 if (s4.f4 != 4) {
6920 fprintf(stderr, "mono_return_int4 s4.f4: got %d but expected %d\n", s4.f4, 4);
6922 s4.f1+=addend; s4.f2+=addend; s4.f3+=addend; s4.f4+=addend;
6923 return s4;
6926 typedef struct {
6927 int f1,f2,f3,f4,f5;
6928 } int5;
6930 LIBTEST_API int5 STDCALL
6931 mono_return_int5 (int5 s5, int addend) {
6932 if (s5.f1 != 1) {
6933 fprintf(stderr, "mono_return_int5 s5.f1: got %d but expected %d\n", s5.f1, 1);
6935 if (s5.f2 != 2) {
6936 fprintf(stderr, "mono_return_int5 s5.f2: got %d but expected %d\n", s5.f2, 2);
6938 if (s5.f3 != 3) {
6939 fprintf(stderr, "mono_return_int5 s5.f3: got %d but expected %d\n", s5.f3, 3);
6941 if (s5.f4 != 4) {
6942 fprintf(stderr, "mono_return_int5 s5.f4: got %d but expected %d\n", s5.f4, 4);
6944 if (s5.f5 != 5) {
6945 fprintf(stderr, "mono_return_int5 s5.f5: got %d but expected %d\n", s5.f5, 5);
6947 s5.f1+=addend; s5.f2+=addend; s5.f3+=addend; s5.f4+=addend; s5.f5+=addend;
6948 return s5;
6951 typedef struct {
6952 struct {
6953 int f1;
6954 } nested1;
6955 int f2,f3;
6956 struct {
6957 int f4;
6958 } nested2;
6959 } int4_nested;
6961 LIBTEST_API int4_nested STDCALL
6962 mono_return_int4_nested (int4_nested sn4, int addend) {
6963 if (sn4.nested1.f1 != 1) {
6964 fprintf(stderr, "mono_return_int4_nested sn4.nested1.f1: got %d but expected %d\n", sn4.nested1.f1, 1);
6966 if (sn4.f2 != 2) {
6967 fprintf(stderr, "mono_return_int4_nested sn4.f2: got %d but expected %d\n", sn4.f2, 2);
6969 if (sn4.f3 != 3) {
6970 fprintf(stderr, "mono_return_int4_nested sn4.f3: got %d but expected %d\n", sn4.f3, 3);
6972 if (sn4.nested2.f4 != 4) {
6973 fprintf(stderr, "mono_return_int4_nested sn4.nested2.f4: got %d but expected %d\n", sn4.nested2.f4, 4);
6975 sn4.nested1.f1+=addend; sn4.f2+=addend; sn4.f3+=addend; sn4.nested2.f4+=addend;
6976 return sn4;
6979 typedef struct {
6980 float f1;
6981 } float1;
6983 LIBTEST_API float1 STDCALL
6984 mono_return_float1 (float1 s1, int addend) {
6985 if (s1.f1 != 1) {
6986 fprintf(stderr, "mono_return_float1 s1.f1: got %f but expected %d\n", s1.f1, 1);
6988 s1.f1+=addend;
6989 return s1;
6992 typedef struct {
6993 float f1,f2;
6994 } float2;
6996 LIBTEST_API float2 STDCALL
6997 mono_return_float2 (float2 s2, int addend) {
6998 if (s2.f1 != 1) {
6999 fprintf(stderr, "mono_return_float2 s2.f1: got %f but expected %d\n", s2.f1, 1);
7001 if (s2.f2 != 2) {
7002 fprintf(stderr, "mono_return_float2 s2.f2: got %f but expected %d\n", s2.f2, 2);
7004 s2.f1+=addend; s2.f2+=addend;
7005 return s2;
7008 typedef struct {
7009 float f1,f2,f3;
7010 } float3;
7012 LIBTEST_API float3 STDCALL
7013 mono_return_float3 (float3 s3, int addend) {
7014 if (s3.f1 != 1) {
7015 fprintf(stderr, "mono_return_float3 s3.f1: got %f but expected %d\n", s3.f1, 1);
7017 if (s3.f2 != 2) {
7018 fprintf(stderr, "mono_return_float3 s3.f2: got %f but expected %d\n", s3.f2, 2);
7020 if (s3.f3 != 3) {
7021 fprintf(stderr, "mono_return_float3 s3.f3: got %f but expected %d\n", s3.f3, 3);
7023 s3.f1+=addend; s3.f2+=addend; s3.f3+=addend;
7024 return s3;
7027 typedef struct {
7028 float f1,f2,f3,f4;
7029 } float4;
7031 LIBTEST_API float4 STDCALL
7032 mono_return_float4 (float4 s4, int addend) {
7033 if (s4.f1 != 1) {
7034 fprintf(stderr, "mono_return_float4 s4.f1: got %f but expected %d\n", s4.f1, 1);
7036 if (s4.f2 != 2) {
7037 fprintf(stderr, "mono_return_float4 s4.f2: got %f but expected %d\n", s4.f2, 2);
7039 if (s4.f3 != 3) {
7040 fprintf(stderr, "mono_return_float4 s4.f3: got %f but expected %d\n", s4.f3, 3);
7042 if (s4.f4 != 4) {
7043 fprintf(stderr, "mono_return_float4 s4.f4: got %f but expected %d\n", s4.f4, 4);
7045 s4.f1+=addend; s4.f2+=addend; s4.f3+=addend; s4.f4+=addend;
7046 return s4;
7049 typedef struct {
7050 float f1,f2,f3,f4,f5;
7051 } float5;
7053 LIBTEST_API float5 STDCALL
7054 mono_return_float5 (float5 s5, int addend) {
7055 if (s5.f1 != 1) {
7056 fprintf(stderr, "mono_return_float5 s5.f1: got %f but expected %d\n", s5.f1, 1);
7058 if (s5.f2 != 2) {
7059 fprintf(stderr, "mono_return_float5 s5.f2: got %f but expected %d\n", s5.f2, 2);
7061 if (s5.f3 != 3) {
7062 fprintf(stderr, "mono_return_float5 s5.f3: got %f but expected %d\n", s5.f3, 3);
7064 if (s5.f4 != 4) {
7065 fprintf(stderr, "mono_return_float5 s5.f4: got %f but expected %d\n", s5.f4, 4);
7067 if (s5.f5 != 5) {
7068 fprintf(stderr, "mono_return_float5 s5.f5: got %f but expected %d\n", s5.f5, 5);
7070 s5.f1+=addend; s5.f2+=addend; s5.f3+=addend; s5.f4+=addend; s5.f5+=addend;
7071 return s5;
7074 typedef struct {
7075 float f1,f2,f3,f4,f5,f6;
7076 } float6;
7078 LIBTEST_API float6 STDCALL
7079 mono_return_float6 (float6 s6, int addend) {
7080 if (s6.f1 != 1) {
7081 fprintf(stderr, "mono_return_float6 s6.f1: got %f but expected %d\n", s6.f1, 1);
7083 if (s6.f2 != 2) {
7084 fprintf(stderr, "mono_return_float6 s6.f2: got %f but expected %d\n", s6.f2, 2);
7086 if (s6.f3 != 3) {
7087 fprintf(stderr, "mono_return_float6 s6.f3: got %f but expected %d\n", s6.f3, 3);
7089 if (s6.f4 != 4) {
7090 fprintf(stderr, "mono_return_float6 s6.f4: got %f but expected %d\n", s6.f4, 4);
7092 if (s6.f5 != 5) {
7093 fprintf(stderr, "mono_return_float6 s6.f5: got %f but expected %d\n", s6.f5, 5);
7095 if (s6.f6 != 6) {
7096 fprintf(stderr, "mono_return_float6 s6.f6: got %f but expected %d\n", s6.f6, 6);
7098 s6.f1+=addend; s6.f2+=addend; s6.f3+=addend; s6.f4+=addend; s6.f5+=addend; s6.f6+=addend;
7099 return s6;
7102 typedef struct {
7103 float f1,f2,f3,f4,f5,f6,f7;
7104 } float7;
7106 LIBTEST_API float7 STDCALL
7107 mono_return_float7 (float7 s7, int addend) {
7108 if (s7.f1 != 1) {
7109 fprintf(stderr, "mono_return_float7 s7.f1: got %f but expected %d\n", s7.f1, 1);
7111 if (s7.f2 != 2) {
7112 fprintf(stderr, "mono_return_float7 s7.f2: got %f but expected %d\n", s7.f2, 2);
7114 if (s7.f3 != 3) {
7115 fprintf(stderr, "mono_return_float7 s7.f3: got %f but expected %d\n", s7.f3, 3);
7117 if (s7.f4 != 4) {
7118 fprintf(stderr, "mono_return_float7 s7.f4: got %f but expected %d\n", s7.f4, 4);
7120 if (s7.f5 != 5) {
7121 fprintf(stderr, "mono_return_float7 s7.f5: got %f but expected %d\n", s7.f5, 5);
7123 if (s7.f6 != 6) {
7124 fprintf(stderr, "mono_return_float7 s7.f6: got %f but expected %d\n", s7.f6, 6);
7126 if (s7.f7 != 7) {
7127 fprintf(stderr, "mono_return_float7 s7.f7: got %f but expected %d\n", s7.f7, 7);
7129 s7.f1+=addend; s7.f2+=addend; s7.f3+=addend; s7.f4+=addend; s7.f5+=addend; s7.f6+=addend; s7.f7+=addend;
7130 return s7;
7133 typedef struct {
7134 float f1,f2,f3,f4,f5,f6,f7,f8;
7135 } float8;
7137 LIBTEST_API float8 STDCALL
7138 mono_return_float8 (float8 s8, int addend) {
7139 if (s8.f1 != 1) {
7140 fprintf(stderr, "mono_return_float8 s8.f1: got %f but expected %d\n", s8.f1, 1);
7142 if (s8.f2 != 2) {
7143 fprintf(stderr, "mono_return_float8 s8.f2: got %f but expected %d\n", s8.f2, 2);
7145 if (s8.f3 != 3) {
7146 fprintf(stderr, "mono_return_float8 s8.f3: got %f but expected %d\n", s8.f3, 3);
7148 if (s8.f4 != 4) {
7149 fprintf(stderr, "mono_return_float8 s8.f4: got %f but expected %d\n", s8.f4, 4);
7151 if (s8.f5 != 5) {
7152 fprintf(stderr, "mono_return_float8 s8.f5: got %f but expected %d\n", s8.f5, 5);
7154 if (s8.f6 != 6) {
7155 fprintf(stderr, "mono_return_float8 s8.f6: got %f but expected %d\n", s8.f6, 6);
7157 if (s8.f7 != 7) {
7158 fprintf(stderr, "mono_return_float8 s8.f7: got %f but expected %d\n", s8.f7, 7);
7160 if (s8.f8 != 8) {
7161 fprintf(stderr, "mono_return_float8 s8.f8: got %f but expected %d\n", s8.f8, 8);
7163 s8.f1+=addend; s8.f2+=addend; s8.f3+=addend; s8.f4+=addend; s8.f5+=addend; s8.f6+=addend; s8.f7+=addend; s8.f8+=addend;
7164 return s8;
7167 typedef struct {
7168 float f1,f2,f3,f4,f5,f6,f7,f8,f9;
7169 } float9;
7171 LIBTEST_API float9 STDCALL
7172 mono_return_float9 (float9 s9, int addend) {
7173 if (s9.f1 != 1) {
7174 fprintf(stderr, "mono_return_float9 s9.f1: got %f but expected %d\n", s9.f1, 1);
7176 if (s9.f2 != 2) {
7177 fprintf(stderr, "mono_return_float9 s9.f2: got %f but expected %d\n", s9.f2, 2);
7179 if (s9.f3 != 3) {
7180 fprintf(stderr, "mono_return_float9 s9.f3: got %f but expected %d\n", s9.f3, 3);
7182 if (s9.f4 != 4) {
7183 fprintf(stderr, "mono_return_float9 s9.f4: got %f but expected %d\n", s9.f4, 4);
7185 if (s9.f5 != 5) {
7186 fprintf(stderr, "mono_return_float9 s9.f5: got %f but expected %d\n", s9.f5, 5);
7188 if (s9.f6 != 6) {
7189 fprintf(stderr, "mono_return_float9 s9.f6: got %f but expected %d\n", s9.f6, 6);
7191 if (s9.f7 != 7) {
7192 fprintf(stderr, "mono_return_float9 s9.f7: got %f but expected %d\n", s9.f7, 7);
7194 if (s9.f8 != 8) {
7195 fprintf(stderr, "mono_return_float9 s9.f8: got %f but expected %d\n", s9.f8, 8);
7197 if (s9.f9 != 9) {
7198 fprintf(stderr, "mono_return_float9 s9.f9: got %f but expected %d\n", s9.f9, 9);
7200 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;
7201 return s9;
7204 typedef struct {
7205 struct {
7206 float f1;
7207 } nested1;
7208 float f2,f3;
7209 struct {
7210 float f4;
7211 } nested2;
7212 } float4_nested;
7214 LIBTEST_API float4_nested STDCALL
7215 mono_return_float4_nested (float4_nested sn4, int addend) {
7216 if (sn4.nested1.f1 != 1) {
7217 fprintf(stderr, "mono_return_float4_nested sn4.nested1.f1: got %f but expected %d\n", sn4.nested1.f1, 1);
7219 if (sn4.f2 != 2) {
7220 fprintf(stderr, "mono_return_float4_nested sn4.f2: got %f but expected %d\n", sn4.f2, 2);
7222 if (sn4.f3 != 3) {
7223 fprintf(stderr, "mono_return_float4_nested sn4.f3: got %f but expected %d\n", sn4.f3, 3);
7225 if (sn4.nested2.f4 != 4) {
7226 fprintf(stderr, "mono_return_float4_nested sn4.nested2.f4: got %f but expected %d\n", sn4.nested2.f4, 4);
7228 sn4.nested1.f1+=addend; sn4.f2+=addend; sn4.f3+=addend; sn4.nested2.f4+=addend;
7229 return sn4;
7232 typedef struct {
7233 double f1;
7234 } double1;
7236 LIBTEST_API double1 STDCALL
7237 mono_return_double1 (double1 s1, int addend) {
7238 if (s1.f1 != 1) {
7239 fprintf(stderr, "mono_return_double1 s1.f1: got %f but expected %d\n", s1.f1, 1);
7241 s1.f1+=addend;
7242 return s1;
7245 typedef struct {
7246 double f1,f2;
7247 } double2;
7249 LIBTEST_API double2 STDCALL
7250 mono_return_double2 (double2 s2, int addend) {
7251 if (s2.f1 != 1) {
7252 fprintf(stderr, "mono_return_double2 s2.f1: got %f but expected %d\n", s2.f1, 1);
7254 if (s2.f2 != 2) {
7255 fprintf(stderr, "mono_return_double2 s2.f2: got %f but expected %d\n", s2.f2, 2);
7257 s2.f1+=addend; s2.f2+=addend;
7258 return s2;
7261 typedef struct {
7262 double f1,f2,f3;
7263 } double3;
7265 LIBTEST_API double3 STDCALL
7266 mono_return_double3 (double3 s3, int addend) {
7267 if (s3.f1 != 1) {
7268 fprintf(stderr, "mono_return_double3 s3.f1: got %f but expected %d\n", s3.f1, 1);
7270 if (s3.f2 != 2) {
7271 fprintf(stderr, "mono_return_double3 s3.f2: got %f but expected %d\n", s3.f2, 2);
7273 if (s3.f3 != 3) {
7274 fprintf(stderr, "mono_return_double3 s3.f3: got %f but expected %d\n", s3.f3, 3);
7276 s3.f1+=addend; s3.f2+=addend; s3.f3+=addend;
7277 return s3;
7280 typedef struct {
7281 double f1,f2,f3,f4;
7282 } double4;
7284 LIBTEST_API double4 STDCALL
7285 mono_return_double4 (double4 s4, int addend) {
7286 if (s4.f1 != 1) {
7287 fprintf(stderr, "mono_return_double4 s4.f1: got %f but expected %d\n", s4.f1, 1);
7289 if (s4.f2 != 2) {
7290 fprintf(stderr, "mono_return_double4 s4.f2: got %f but expected %d\n", s4.f2, 2);
7292 if (s4.f3 != 3) {
7293 fprintf(stderr, "mono_return_double4 s4.f3: got %f but expected %d\n", s4.f3, 3);
7295 if (s4.f4 != 4) {
7296 fprintf(stderr, "mono_return_double4 s4.f4: got %f but expected %d\n", s4.f4, 4);
7298 s4.f1+=addend; s4.f2+=addend; s4.f3+=addend; s4.f4+=addend;
7299 return s4;
7302 typedef struct {
7303 double f1,f2,f3,f4,f5;
7304 } double5;
7306 LIBTEST_API double5 STDCALL
7307 mono_return_double5 (double5 s5, int addend) {
7308 if (s5.f1 != 1) {
7309 fprintf(stderr, "mono_return_double5 s5.f1: got %f but expected %d\n", s5.f1, 1);
7311 if (s5.f2 != 2) {
7312 fprintf(stderr, "mono_return_double5 s5.f2: got %f but expected %d\n", s5.f2, 2);
7314 if (s5.f3 != 3) {
7315 fprintf(stderr, "mono_return_double5 s5.f3: got %f but expected %d\n", s5.f3, 3);
7317 if (s5.f4 != 4) {
7318 fprintf(stderr, "mono_return_double5 s5.f4: got %f but expected %d\n", s5.f4, 4);
7320 if (s5.f5 != 5) {
7321 fprintf(stderr, "mono_return_double5 s5.f5: got %f but expected %d\n", s5.f5, 5);
7323 s5.f1+=addend; s5.f2+=addend; s5.f3+=addend; s5.f4+=addend; s5.f5+=addend;
7324 return s5;
7327 typedef struct {
7328 double f1,f2,f3,f4,f5,f6;
7329 } double6;
7331 LIBTEST_API double6 STDCALL
7332 mono_return_double6 (double6 s6, int addend) {
7333 if (s6.f1 != 1) {
7334 fprintf(stderr, "mono_return_double6 s6.f1: got %f but expected %d\n", s6.f1, 1);
7336 if (s6.f2 != 2) {
7337 fprintf(stderr, "mono_return_double6 s6.f2: got %f but expected %d\n", s6.f2, 2);
7339 if (s6.f3 != 3) {
7340 fprintf(stderr, "mono_return_double6 s6.f3: got %f but expected %d\n", s6.f3, 3);
7342 if (s6.f4 != 4) {
7343 fprintf(stderr, "mono_return_double6 s6.f4: got %f but expected %d\n", s6.f4, 4);
7345 if (s6.f5 != 5) {
7346 fprintf(stderr, "mono_return_double6 s6.f5: got %f but expected %d\n", s6.f5, 5);
7348 if (s6.f6 != 6) {
7349 fprintf(stderr, "mono_return_double6 s6.f6: got %f but expected %d\n", s6.f6, 6);
7351 s6.f1+=addend; s6.f2+=addend; s6.f3+=addend; s6.f4+=addend; s6.f5+=addend; s6.f6+=addend;
7352 return s6;
7355 typedef struct {
7356 double f1,f2,f3,f4,f5,f6,f7;
7357 } double7;
7359 LIBTEST_API double7 STDCALL
7360 mono_return_double7 (double7 s7, int addend) {
7361 if (s7.f1 != 1) {
7362 fprintf(stderr, "mono_return_double7 s7.f1: got %f but expected %d\n", s7.f1, 1);
7364 if (s7.f2 != 2) {
7365 fprintf(stderr, "mono_return_double7 s7.f2: got %f but expected %d\n", s7.f2, 2);
7367 if (s7.f3 != 3) {
7368 fprintf(stderr, "mono_return_double7 s7.f3: got %f but expected %d\n", s7.f3, 3);
7370 if (s7.f4 != 4) {
7371 fprintf(stderr, "mono_return_double7 s7.f4: got %f but expected %d\n", s7.f4, 4);
7373 if (s7.f5 != 5) {
7374 fprintf(stderr, "mono_return_double7 s7.f5: got %f but expected %d\n", s7.f5, 5);
7376 if (s7.f6 != 6) {
7377 fprintf(stderr, "mono_return_double7 s7.f6: got %f but expected %d\n", s7.f6, 6);
7379 if (s7.f7 != 7) {
7380 fprintf(stderr, "mono_return_double7 s7.f7: got %f but expected %d\n", s7.f7, 7);
7382 s7.f1+=addend; s7.f2+=addend; s7.f3+=addend; s7.f4+=addend; s7.f5+=addend; s7.f6+=addend; s7.f7+=addend;
7383 return s7;
7386 typedef struct {
7387 double f1,f2,f3,f4,f5,f6,f7,f8;
7388 } double8;
7390 LIBTEST_API double8 STDCALL
7391 mono_return_double8 (double8 s8, int addend) {
7392 if (s8.f1 != 1) {
7393 fprintf(stderr, "mono_return_double8 s8.f1: got %f but expected %d\n", s8.f1, 1);
7395 if (s8.f2 != 2) {
7396 fprintf(stderr, "mono_return_double8 s8.f2: got %f but expected %d\n", s8.f2, 2);
7398 if (s8.f3 != 3) {
7399 fprintf(stderr, "mono_return_double8 s8.f3: got %f but expected %d\n", s8.f3, 3);
7401 if (s8.f4 != 4) {
7402 fprintf(stderr, "mono_return_double8 s8.f4: got %f but expected %d\n", s8.f4, 4);
7404 if (s8.f5 != 5) {
7405 fprintf(stderr, "mono_return_double8 s8.f5: got %f but expected %d\n", s8.f5, 5);
7407 if (s8.f6 != 6) {
7408 fprintf(stderr, "mono_return_double8 s8.f6: got %f but expected %d\n", s8.f6, 6);
7410 if (s8.f7 != 7) {
7411 fprintf(stderr, "mono_return_double8 s8.f7: got %f but expected %d\n", s8.f7, 7);
7413 if (s8.f8 != 8) {
7414 fprintf(stderr, "mono_return_double8 s8.f8: got %f but expected %d\n", s8.f8, 8);
7416 s8.f1+=addend; s8.f2+=addend; s8.f3+=addend; s8.f4+=addend; s8.f5+=addend; s8.f6+=addend; s8.f7+=addend; s8.f8+=addend;
7417 return s8;
7420 typedef struct {
7421 double f1,f2,f3,f4,f5,f6,f7,f8,f9;
7422 } double9;
7424 LIBTEST_API double9 STDCALL
7425 mono_return_double9 (double9 s9, int addend) {
7426 if (s9.f1 != 1) {
7427 fprintf(stderr, "mono_return_double9 s9.f1: got %f but expected %d\n", s9.f1, 1);
7429 if (s9.f2 != 2) {
7430 fprintf(stderr, "mono_return_double9 s9.f2: got %f but expected %d\n", s9.f2, 2);
7432 if (s9.f3 != 3) {
7433 fprintf(stderr, "mono_return_double9 s9.f3: got %f but expected %d\n", s9.f3, 3);
7435 if (s9.f4 != 4) {
7436 fprintf(stderr, "mono_return_double9 s9.f4: got %f but expected %d\n", s9.f4, 4);
7438 if (s9.f5 != 5) {
7439 fprintf(stderr, "mono_return_double9 s9.f5: got %f but expected %d\n", s9.f5, 5);
7441 if (s9.f6 != 6) {
7442 fprintf(stderr, "mono_return_double9 s9.f6: got %f but expected %d\n", s9.f6, 6);
7444 if (s9.f7 != 7) {
7445 fprintf(stderr, "mono_return_double9 s9.f7: got %f but expected %d\n", s9.f7, 7);
7447 if (s9.f8 != 8) {
7448 fprintf(stderr, "mono_return_double9 s9.f8: got %f but expected %d\n", s9.f8, 8);
7450 if (s9.f9 != 9) {
7451 fprintf(stderr, "mono_return_double9 s9.f9: got %f but expected %d\n", s9.f9, 9);
7453 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;
7454 return s9;
7457 typedef struct {
7458 struct {
7459 double f1;
7460 } nested1;
7461 struct {
7462 double f2;
7463 } nested2;
7464 } double2_nested;
7466 LIBTEST_API double2_nested STDCALL
7467 mono_return_double2_nested (double2_nested sn2, int addend) {
7468 if (sn2.nested1.f1 != 1) {
7469 fprintf(stderr, "mono_return_double2_nested sn2.nested1.f1: got %f but expected %d\n", sn2.nested1.f1, 1);
7471 if (sn2.nested2.f2 != 2) {
7472 fprintf(stderr, "mono_return_double2_nested sn2.nested2.f2: got %f but expected %d\n", sn2.nested2.f2, 2);
7474 sn2.nested1.f1+=addend; sn2.nested2.f2+=addend;
7475 return sn2;
7480 typedef struct {
7481 double f1[4];
7482 } double_array4;
7484 LIBTEST_API double_array4 STDCALL
7485 mono_return_double_array4 (double_array4 sa4, int addend) {
7486 if (sa4.f1[0] != 1) {
7487 fprintf(stderr, "mono_return_double_array4 sa4.f1[0]: got %f but expected %d\n", sa4.f1[0], 1);
7489 if (sa4.f1[1] != 2) {
7490 fprintf(stderr, "mono_return_double_array4 sa4.f1[1]: got %f but expected %d\n", sa4.f1[1], 2);
7492 if (sa4.f1[2] != 3) {
7493 fprintf(stderr, "mono_return_double_array4 sa4.f1[2]: got %f but expected %d\n", sa4.f1[2], 3);
7495 if (sa4.f1[3] != 4) {
7496 fprintf(stderr, "mono_return_double_array4 sa4.f1[3]: got %f but expected %d\n", sa4.f1[3], 4);
7498 sa4.f1[0]+=addend; sa4.f1[1]+=addend; sa4.f1[2]+=addend; sa4.f1[3]+=addend;
7499 return sa4;
7502 typedef struct {
7503 int array [3];
7504 } FixedArrayStruct;
7506 LIBTEST_API int STDCALL
7507 mono_test_marshal_fixed_array (FixedArrayStruct s)
7509 return s.array [0] + s.array [1] + s.array [2];
7512 typedef struct {
7513 char array [16];
7514 char c;
7515 } FixedBufferChar;
7517 LIBTEST_API int STDCALL
7518 mono_test_marshal_fixed_buffer_char (FixedBufferChar *s)
7520 if (!(s->array [0] == 'A' && s->array [1] == 'B' && s->array [2] == 'C' && s->c == 'D'))
7521 return 1;
7522 s->array [0] = 'E';
7523 s->array [1] = 'F';
7524 s->c = 'G';
7525 return 0;
7528 typedef struct {
7529 short array [16];
7530 short c;
7531 } FixedBufferUnicode;
7533 LIBTEST_API int STDCALL
7534 mono_test_marshal_fixed_buffer_unicode (FixedBufferUnicode *s)
7536 if (!(s->array [0] == 'A' && s->array [1] == 'B' && s->array [2] == 'C' && s->c == 'D'))
7537 return 1;
7538 s->array [0] = 'E';
7539 s->array [1] = 'F';
7540 s->c = 'G';
7541 return 0;
7544 const int NSTRINGS = 6;
7545 //test strings
7546 const char *utf8Strings[] = {
7547 "Managed",
7548 "Sîne klâwen durh die wolken sint geslagen" ,
7549 "काचं शक्नोम्यत्तुम् । नोपहिनस्ति माम्",
7550 "我能吞下玻璃而不伤身体",
7551 "ღმერთსი შემვედრე,შემვედრე, ნუთუ კვლა დამხსნას შემვედრე,სოფლისა შემვედრე, შემვედრე,შემვედრე,შემვედრე,შრომასა, ცეცხლს, წყალსა და მიწასა, ჰაერთა თანა მრომასა; მომცნეს ფრთენი და აღვფრინდე, მივჰხვდე მას ჩემსა ნდომასა, დღისით და ღამით ვჰხედვიდე მზისა ელვათა კრთომაასაშემვედრე,შემვედრე,",
7552 "Τη γλώσσα μου έδωσαν ελληνική",
7553 "\0"
7556 LIBTEST_API char *
7557 build_return_string(const char* pReturn)
7559 char *ret = 0;
7560 if (pReturn == 0 || *pReturn == 0)
7561 return ret;
7563 size_t strLength = strlen(pReturn);
7564 ret = (char *)(marshal_alloc (sizeof(char)* (strLength + 1)));
7565 memcpy(ret, pReturn, strLength);
7566 ret [strLength] = '\0';
7567 return ret;
7570 LIBTEST_API char *
7571 StringParameterInOut(/*[In,Out]*/ char *s, int index)
7573 // return a copy
7574 return build_return_string(s);
7577 LIBTEST_API void
7578 StringParameterRefOut(/*out*/ char **s, int index)
7580 char *pszTextutf8 = (char*)utf8Strings[index];
7581 size_t strLength = strlen(pszTextutf8);
7582 *s = (char *)(marshal_alloc (sizeof(char)* (strLength + 1)));
7583 memcpy(*s, pszTextutf8, strLength);
7584 (*s)[strLength] = '\0';
7587 LIBTEST_API void
7588 StringParameterRef(/*ref*/ char **s, int index)
7590 char *pszTextutf8 = (char*)utf8Strings[index];
7591 size_t strLength = strlen(pszTextutf8);
7592 // do byte by byte validation of in string
7593 size_t szLen = strlen(*s);
7594 for (size_t i = 0; i < szLen; i++)
7596 if ((*s)[i] != pszTextutf8[i])
7598 printf("[in] managed string do not match native string\n");
7599 abort ();
7603 if (*s)
7605 marshal_free (*s);
7607 // overwrite the orginal
7608 *s = (char *)(marshal_alloc (sizeof(char)* (strLength + 1)));
7609 memcpy(*s, pszTextutf8, strLength);
7610 (*s)[strLength] = '\0';
7613 LIBTEST_API void
7614 StringBuilderParameterInOut(/*[In,Out] StringBuilder*/ char *s, int index)
7616 // if string.empty
7617 if (s == 0 || *s == 0)
7618 return;
7620 char *pszTextutf8 = (char*)utf8Strings[index];
7622 // do byte by byte validation of in string
7623 size_t szLen = strlen(s);
7624 for (size_t i = 0; i < szLen; i++)
7626 if (s[i] != pszTextutf8[i])
7628 printf("[in] managed string do not match native string\n");
7629 abort ();
7633 // modify the string inplace
7634 size_t outLen = strlen(pszTextutf8);
7635 for (size_t i = 0; i < outLen; i++) {
7636 s[i] = pszTextutf8[i];
7638 s[outLen] = '\0';
7641 //out string builder
7642 LIBTEST_API void
7643 StringBuilderParameterOut(/*[Out] StringBuilder*/ char *s, int index)
7645 char *pszTextutf8 = (char*)utf8Strings[index];
7647 printf ("SBPO: Receiving %s\n", s);
7648 // modify the string inplace
7649 size_t outLen = strlen(pszTextutf8);
7650 for (size_t i = 0; i < outLen; i++) {
7651 s[i] = pszTextutf8[i];
7653 s[outLen] = '\0';
7656 LIBTEST_API char *
7657 StringParameterOut(/*[Out]*/ char *s, int index)
7659 // return a copy
7660 return build_return_string(s);
7663 // Utf8 field
7664 typedef struct FieldWithUtf8
7666 char *pFirst;
7667 int index;
7668 }FieldWithUtf8;
7670 //utf8 struct field
7671 LIBTEST_API void
7672 TestStructWithUtf8Field(struct FieldWithUtf8 fieldStruct)
7674 char *pszManagedutf8 = fieldStruct.pFirst;
7675 int stringIndex = fieldStruct.index;
7676 char *pszNative = 0;
7677 size_t outLen = 0;
7679 if (pszManagedutf8 == 0 || *pszManagedutf8 == 0)
7680 return;
7682 pszNative = (char*)utf8Strings[stringIndex];
7684 outLen = strlen(pszNative);
7685 // do byte by byte comparision
7686 for (size_t i = 0; i < outLen; i++)
7688 if (pszNative[i] != pszManagedutf8[i])
7690 printf("Native and managed string do not match.\n");
7691 abort ();
7696 typedef void (* Callback2)(char *text, int index);
7698 LIBTEST_API void
7699 Utf8DelegateAsParameter(Callback2 managedCallback)
7701 for (int i = 0; i < NSTRINGS; ++i)
7703 char *pszNative = 0;
7704 pszNative = (char*)utf8Strings[i];
7705 managedCallback(pszNative, i);
7710 LIBTEST_API char*
7711 StringBuilderParameterReturn(int index)
7713 char *pszTextutf8 = (char*)utf8Strings[index];
7714 size_t strLength = strlen(pszTextutf8);
7715 char * ret = (char *)(marshal_alloc (sizeof(char)* (strLength + 1)));
7716 memcpy(ret, pszTextutf8, strLength);
7717 ret[strLength] = '\0';
7719 return ret;
7722 LIBTEST_API int STDCALL
7723 mono_test_marshal_pointer_array (int *arr[])
7725 int i;
7727 for (i = 0; i < 10; ++i) {
7728 if (*arr [i] != -1)
7729 return 1;
7731 return 0;
7734 #ifndef WIN32
7736 typedef void (*NativeToManagedExceptionRethrowFunc) (void);
7738 void *mono_test_native_to_managed_exception_rethrow_thread (void *arg)
7740 NativeToManagedExceptionRethrowFunc func = (NativeToManagedExceptionRethrowFunc) arg;
7741 func ();
7742 return NULL;
7745 LIBTEST_API void STDCALL
7746 mono_test_native_to_managed_exception_rethrow (NativeToManagedExceptionRethrowFunc func)
7748 pthread_t t;
7749 pthread_create (&t, NULL, mono_test_native_to_managed_exception_rethrow_thread, (gpointer)func);
7750 pthread_join (t, NULL);
7752 #endif
7754 typedef void (*VoidVoidCallback) (void);
7755 typedef void (*MonoFtnPtrEHCallback) (guint32 gchandle);
7757 typedef long long MonoObject;
7758 typedef MonoObject MonoException;
7759 typedef int32_t mono_bool;
7761 static int sym_inited = 0;
7762 static void (*sym_mono_install_ftnptr_eh_callback) (MonoFtnPtrEHCallback);
7763 static MonoObject* (*sym_mono_gchandle_get_target) (guint32 gchandle);
7764 static guint32 (*sym_mono_gchandle_new) (MonoObject *, mono_bool pinned);
7765 static void (*sym_mono_gchandle_free) (guint32 gchandle);
7766 static void (*sym_mono_raise_exception) (MonoException *ex);
7767 static void (*sym_mono_domain_unload) (gpointer);
7768 static void (*sym_mono_threads_exit_gc_safe_region_unbalanced) (gpointer, gpointer *);
7769 static void (*null_function_ptr) (void);
7771 static void
7772 mono_test_init_symbols (void)
7774 if (sym_inited)
7775 return;
7777 sym_mono_install_ftnptr_eh_callback = (void (*) (MonoFtnPtrEHCallback)) (lookup_mono_symbol ("mono_install_ftnptr_eh_callback"));
7779 sym_mono_gchandle_get_target = (MonoObject* (*) (guint32 gchandle)) (lookup_mono_symbol ("mono_gchandle_get_target"));
7781 sym_mono_gchandle_new = (guint32 (*) (MonoObject *, mono_bool)) (lookup_mono_symbol ("mono_gchandle_new"));
7783 sym_mono_gchandle_free = (void (*) (guint32 gchandle)) (lookup_mono_symbol ("mono_gchandle_free"));
7785 sym_mono_raise_exception = (void (*) (MonoException *)) (lookup_mono_symbol ("mono_raise_exception"));
7787 sym_mono_domain_unload = (void (*) (gpointer)) (lookup_mono_symbol ("mono_domain_unload"));
7789 sym_mono_threads_exit_gc_safe_region_unbalanced = (void (*) (gpointer, gpointer *)) (lookup_mono_symbol ("mono_threads_exit_gc_safe_region_unbalanced"));
7791 sym_inited = 1;
7794 #ifndef TARGET_WASM
7796 static jmp_buf test_jmp_buf;
7797 static guint32 test_gchandle;
7799 static void
7800 mono_test_longjmp_callback (guint32 gchandle)
7802 test_gchandle = gchandle;
7803 longjmp (test_jmp_buf, 1);
7806 LIBTEST_API void STDCALL
7807 mono_test_setjmp_and_call (VoidVoidCallback managedCallback, intptr_t *out_handle)
7809 mono_test_init_symbols ();
7810 if (setjmp (test_jmp_buf) == 0) {
7811 *out_handle = 0;
7812 sym_mono_install_ftnptr_eh_callback (mono_test_longjmp_callback);
7813 managedCallback ();
7814 *out_handle = 0; /* Do not expect to return here */
7815 } else {
7816 sym_mono_install_ftnptr_eh_callback (NULL);
7817 *out_handle = test_gchandle;
7821 #endif
7823 LIBTEST_API void STDCALL
7824 mono_test_marshal_bstr (void *ptr)
7828 static void (*mono_test_capture_throw_callback) (guint32 gchandle, guint32 *exception_out);
7830 static void
7831 mono_test_ftnptr_eh_callback (guint32 gchandle)
7833 guint32 exception_handle = 0;
7835 g_assert (gchandle != 0);
7836 MonoObject *exc = sym_mono_gchandle_get_target (gchandle);
7837 sym_mono_gchandle_free (gchandle);
7839 guint32 handle = sym_mono_gchandle_new (exc, FALSE);
7840 mono_test_capture_throw_callback (handle, &exception_handle);
7841 sym_mono_gchandle_free (handle);
7843 g_assert (exception_handle != 0);
7844 exc = sym_mono_gchandle_get_target (exception_handle);
7845 sym_mono_gchandle_free (exception_handle);
7847 sym_mono_raise_exception (exc);
7848 g_error ("mono_raise_exception should not return");
7851 LIBTEST_API void STDCALL
7852 mono_test_setup_ftnptr_eh_callback (VoidVoidCallback managed_entry, void (*capture_throw_callback) (guint32, guint32 *))
7854 mono_test_init_symbols ();
7855 mono_test_capture_throw_callback = capture_throw_callback;
7856 sym_mono_install_ftnptr_eh_callback (mono_test_ftnptr_eh_callback);
7857 managed_entry ();
7860 LIBTEST_API void STDCALL
7861 mono_test_cleanup_ftptr_eh_callback (void)
7863 mono_test_init_symbols ();
7864 sym_mono_install_ftnptr_eh_callback (NULL);
7867 LIBTEST_API int STDCALL
7868 mono_test_cominterop_ccw_queryinterface (MonoComObject *pUnk)
7870 void *pp;
7871 int hr = pUnk->vtbl->QueryInterface (pUnk, &IID_INotImplemented, &pp);
7873 // Return true if we can't get INotImplemented
7874 return pUnk == NULL && hr == S_OK;
7877 LIBTEST_API void STDCALL
7878 mono_test_MerpCrashSnprintf (void)
7880 fprintf (stderr, "Before overwrite\n");
7882 char buff [1] = { '\0' };
7883 char overflow [1] = { 'a' }; // Not null-terminated
7884 g_snprintf (buff, sizeof(buff) * 10, "THISSHOULDOVERRUNTERRIBLY%s", overflow);
7885 g_snprintf ((char *) GINT_TO_POINTER(-1), sizeof(buff) * 10, "THISSHOULDOVERRUNTERRIBLY%s", overflow);
7888 LIBTEST_API void STDCALL
7889 mono_test_MerpCrashDladdr (void)
7891 #ifndef HOST_WIN32
7892 dlopen (GINT_TO_POINTER(-1), -1);
7893 #endif
7896 LIBTEST_API void STDCALL
7897 mono_test_MerpCrashMalloc (void)
7899 gpointer x = g_malloc (sizeof(gpointer));
7900 g_free (x);
7902 // Double free
7903 g_free (x);
7906 LIBTEST_API void STDCALL
7907 mono_test_MerpCrashNullFp (void)
7909 null_function_ptr ();
7912 LIBTEST_API void STDCALL
7913 mono_test_MerpCrashDomainUnload (void)
7915 mono_test_init_symbols ();
7916 sym_mono_domain_unload (GINT_TO_POINTER (-1));
7919 LIBTEST_API void STDCALL
7920 mono_test_MerpCrashUnbalancedGCSafe (void)
7922 mono_test_init_symbols ();
7923 gpointer foo = GINT_TO_POINTER (-1);
7924 gpointer bar = GINT_TO_POINTER (-2);
7925 sym_mono_threads_exit_gc_safe_region_unbalanced (foo, &bar);
7928 LIBTEST_API void STDCALL
7929 mono_test_MerpCrashUnhandledExceptionHook (void)
7931 g_assert_not_reached ();
7934 #ifdef __cplusplus
7935 } // extern C
7936 #endif