* atomic.h: More tinkering with InterlockedExchange/InterlockedCompareExchange
[mono.git] / mono / tests / libtest.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <glib.h>
5 #include <errno.h>
6 #include <time.h>
7
8 #ifdef WIN32
9 #include <windows.h>
10 #endif
11
12 #ifdef WIN32
13 #define STDCALL __stdcall
14 #else
15 #define STDCALL
16 #endif
17
18 #ifdef WIN32
19 extern __declspec(dllimport) __stdcall void CoTaskMemFree(void *ptr);
20 #endif
21
22 typedef int (STDCALL *SimpleDelegate) (int a);
23
24 static void marshal_free (void *ptr)
25 {
26 #ifdef WIN32
27         CoTaskMemFree (ptr);
28 #else
29         g_free (ptr);
30 #endif
31 }
32
33 STDCALL unsigned short*
34 test_lpwstr_marshal (unsigned short* chars, long length)
35 {
36         int i = 0;
37         unsigned short *res;
38
39         res = malloc (2 * (length + 1));
40
41         // printf("test_lpwstr_marshal()\n");
42         
43         while ( i < length ) {
44                 // printf("X|%u|\n", chars[i]);
45                 res [i] = chars[i];
46                 i++;
47         }
48
49         res [i] = 0;
50
51         return res;
52 }
53
54 typedef struct {
55         int b;
56         int a;
57         int c;
58 } union_test_1_type;
59
60 STDCALL int 
61 mono_union_test_1 (union_test_1_type u1) {
62         // printf ("Got values %d %d %d\n", u1.b, u1.a, u1.c);
63         return u1.a + u1.b + u1.c;
64 }
65
66 STDCALL int 
67 mono_return_int (int a) {
68         // printf ("Got value %d\n", a);
69         return a;
70 }
71
72 struct ss
73 {
74         int i;
75 };
76
77 STDCALL int 
78 mono_return_int_ss (struct ss a) {
79         // printf ("Got value %d\n", a.i);
80         return a.i;
81 }
82
83 STDCALL struct ss 
84 mono_return_ss (struct ss a) {
85         // printf ("Got value %d\n", a.i);
86         a.i++;
87         return a;
88 }
89
90 struct sc1
91 {
92         char c[1];
93 };
94
95 STDCALL struct sc1 
96 mono_return_sc1 (struct sc1 a) {
97         // printf ("Got value %d\n", a.c[0]);
98         a.c[0]++;
99         return a;
100 }
101
102
103 struct sc3
104 {
105         char c[3];
106 };
107
108 STDCALL struct sc3 
109 mono_return_sc3 (struct sc3 a) {
110         // printf ("Got values %d %d %d\n", a.c[0], a.c[1], a.c[2]);
111         a.c[0]++;
112         a.c[1] += 2;
113         a.c[2] += 3;
114         return a;
115 }
116
117 struct sc5
118 {
119         char c[5];
120 };
121
122 STDCALL struct sc5 
123 mono_return_sc5 (struct sc5 a) {
124         // printf ("Got values %d %d %d %d %d\n", a.c[0], a.c[1], a.c[2], a.c[3], a.c[4]);
125         a.c[0]++;
126         a.c[1] += 2;
127         a.c[2] += 3;
128         a.c[3] += 4;
129         a.c[4] += 5;
130         return a;
131 }
132
133 union su
134 {
135         int i1;
136         int i2;
137 };
138
139 STDCALL int 
140 mono_return_int_su (union su a) {
141         // printf ("Got value %d\n", a.i1);
142         return a.i1;
143 }
144
145 STDCALL int 
146 mono_test_many_int_arguments (int a, int b, int c, int d, int e,
147                                                           int f, int g, int h, int i, int j);
148 STDCALL short 
149 mono_test_many_short_arguments (short a, short b, short c, short d, short e,
150                                                                 short f, short g, short h, short i, short j);
151 STDCALL char 
152 mono_test_many_char_arguments (char a, char b, char c, char d, char e,
153                                                            char f, char g, char h, char i, char j);
154
155 STDCALL int
156 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)
157 {
158         return a + b + c + d + e + f + g + h + i + j;
159 }
160
161 STDCALL short
162 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)
163 {
164         return a + b + c + d + e + f + g + h + i + j;
165 }
166
167 STDCALL char
168 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)
169 {
170         return a + b + c + d + e + f + g + h + i + j;
171 }
172
173 STDCALL float
174 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)
175 {
176         return a + b + c + d + e + f + g + h + i + j;
177 }
178
179 STDCALL double
180 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)
181 {
182         return a + b + c + d + e + f + g + h + i + j;
183 }
184
185 STDCALL double
186 mono_test_split_double_arguments (double a, double b, float c, double d, double e)
187 {
188         return a + b + c + d + e;
189 }
190
191 STDCALL int
192 mono_test_puts_static (char *s)
193 {
194         // printf ("TEST %s\n", s);
195         return 1;
196 }
197
198 typedef int (STDCALL *SimpleDelegate3) (int a, int b);
199
200 STDCALL int
201 mono_invoke_delegate (SimpleDelegate3 delegate)
202 {
203         int res;
204
205         // printf ("start invoke %p\n", delegate);
206
207         res = delegate (2, 3);
208
209         // printf ("end invoke\n");
210
211         return res;
212 }
213
214 STDCALL int 
215 mono_test_marshal_char (short a1)
216 {
217         if (a1 == 'a')
218                 return 0;
219         
220         return 1;
221 }
222
223 STDCALL void
224 mono_test_marshal_char_array (gunichar2 *s)
225 {
226         const char m[] = "abcdef";
227         gunichar2* s2;
228         glong len;
229
230         s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
231         
232         len = (len * 2) + 2;
233         memcpy (s, s2, len);
234
235         g_free (s2);
236 }
237
238 STDCALL int
239 mono_test_empty_pinvoke (int i)
240 {
241         return i;
242 }
243
244 STDCALL int 
245 mono_test_marshal_bool_byref (int a, int *b, int c)
246 {
247     int res = *b;
248
249         *b = 1;
250
251         return res;
252 }
253
254 STDCALL int 
255 mono_test_marshal_array (int *a1)
256 {
257         int i, sum = 0;
258
259         for (i = 0; i < 50; i++)
260                 sum += a1 [i];
261         
262         return sum;
263 }
264
265 STDCALL int 
266 mono_test_marshal_inout_array (int *a1)
267 {
268         int i, sum = 0;
269
270         for (i = 0; i < 50; i++) {
271                 sum += a1 [i];
272                 a1 [i] = 50 - a1 [i];
273         }
274         
275         return sum;
276 }
277
278 STDCALL int 
279 mono_test_marshal_out_array (int *a1)
280 {
281         int i;
282
283         for (i = 0; i < 50; i++) {
284                 a1 [i] = i;
285         }
286         
287         return 0;
288 }
289
290 STDCALL int 
291 mono_test_marshal_inout_nonblittable_array (gunichar2 *a1)
292 {
293         int i, sum = 0;
294
295         for (i = 0; i < 10; i++) {
296                 a1 [i] = 'F';
297         }
298         
299         return sum;
300 }
301
302 typedef struct {
303         int a;
304         int b;
305         int c;
306         const char *d;
307         gunichar2 *d2;
308 } simplestruct;
309
310 typedef struct {
311         double x;
312         double y;
313 } point;
314
315 STDCALL simplestruct
316 mono_test_return_vtype (int i)
317 {
318         simplestruct res;
319         static gunichar2 test2 [] = { 'T', 'E', 'S', 'T', '2', 0 };
320
321         res.a = 0;
322         res.b = 1;
323         res.c = 0;
324         res.d = "TEST";
325         res.d2 = test2;
326
327         return res;
328 }
329
330 STDCALL void
331 mono_test_delegate_struct (void)
332 {
333         // printf ("TEST\n");
334 }
335
336 typedef char* (STDCALL *ReturnStringDelegate) (const char *s);
337
338 STDCALL char *
339 mono_test_return_string (ReturnStringDelegate func)
340 {
341         char *res;
342
343         // printf ("mono_test_return_string\n");
344
345         res = func ("TEST");
346         marshal_free (res);
347
348         // printf ("got string: %s\n", res);
349         return g_strdup ("12345");
350 }
351
352 typedef int (STDCALL *RefVTypeDelegate) (int a, simplestruct *ss, int b);
353
354 STDCALL int
355 mono_test_ref_vtype (int a, simplestruct *ss, int b, RefVTypeDelegate func)
356 {
357         if (a == 1 && b == 2 && ss->a == 0 && ss->b == 1 && ss->c == 0 &&
358             !strcmp (ss->d, "TEST1")) {
359                 ss->a = 1;
360                 ss->b = 0;
361                 ss->c = 1;
362                 ss->d = "TEST2";
363
364                 printf ("A1\n");
365                 return func (a, ss, b);
366                 printf ("A2\n");
367         }
368
369         return 1;
370 }
371
372 typedef int (STDCALL *OutVTypeDelegate) (int a, simplestruct *ss, int b);
373
374 STDCALL int
375 mono_test_marshal_out_struct (int a, simplestruct *ss, int b, OutVTypeDelegate func)
376 {
377         /* Check that the input pointer is ignored */
378         ss->d = (gpointer)0x12345678;
379
380         func (a, ss, b);
381
382         if (ss->a && ss->b && ss->c && !strcmp (ss->d, "TEST3"))
383                 return 0;
384         else
385                 return 1;
386 }
387
388 typedef struct {
389         int a;
390         SimpleDelegate func, func2;
391 } DelegateStruct;
392
393 STDCALL DelegateStruct
394 mono_test_marshal_delegate_struct (DelegateStruct ds)
395 {
396         DelegateStruct res;
397
398         res.a = ds.func (ds.a) + ds.func2 (ds.a);
399         res.func = ds.func;
400         res.func2 = ds.func2;
401
402         return res;
403 }
404
405 STDCALL int 
406 mono_test_marshal_struct (simplestruct ss)
407 {
408         if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
409             !strcmp (ss.d, "TEST"))
410                 return 0;
411
412         return 1;
413 }
414
415 STDCALL int
416 mono_test_marshal_byref_struct (simplestruct *ss, int a, int b, int c, char *d)
417 {
418         gboolean res = (ss->a == a && ss->b == b && ss->c == c && strcmp (ss->d, d) == 0);
419
420         ss->a = !ss->a;
421         ss->b = !ss->b;
422         ss->c = !ss->c;
423         ss->d = g_strdup ("DEF");
424
425         return res ? 0 : 1;
426 }
427
428 typedef struct {
429         int a;
430         int b;
431         int c;
432         char *d;
433         unsigned char e;
434         double f;
435         unsigned char g;
436         guint64 h;
437 } simplestruct2;
438
439 STDCALL int
440 mono_test_marshal_struct2 (simplestruct2 ss)
441 {
442         if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
443             !strcmp (ss.d, "TEST") && 
444             ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
445                 return 0;
446
447         return 1;
448 }
449
450 /* on HP some of the struct should be on the stack and not in registers */
451 STDCALL int
452 mono_test_marshal_struct2_2 (int i, int j, int k, simplestruct2 ss)
453 {
454         if (i != 10 || j != 11 || k != 12)
455                 return 1;
456         if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
457             !strcmp (ss.d, "TEST") && 
458             ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
459                 return 0;
460
461         return 1;
462 }
463
464 STDCALL int 
465 mono_test_marshal_lpstruct (simplestruct *ss)
466 {
467         if (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
468             !strcmp (ss->d, "TEST"))
469                 return 0;
470
471         return 1;
472 }
473
474 STDCALL int 
475 mono_test_marshal_lpstruct_blittable (point *p)
476 {
477         if (p->x == 1.0 && p->y == 2.0)
478                 return 0;
479         else
480                 return 1;
481 }
482
483 STDCALL int
484 mono_test_marshal_struct_array (simplestruct2 *ss)
485 {
486         if (! (ss[0].a == 0 && ss[0].b == 1 && ss[0].c == 0 &&
487                    !strcmp (ss[0].d, "TEST") && 
488                    ss[0].e == 99 && ss[0].f == 1.5 && ss[0].g == 42 && ss[0].h == (guint64)123))
489                 return 1;
490
491         if (! (ss[1].a == 0 && ss[1].b == 0 && ss[1].c == 0 &&
492                    !strcmp (ss[1].d, "TEST2") && 
493                    ss[1].e == 100 && ss[1].f == 2.5 && ss[1].g == 43 && ss[1].h == (guint64)124))
494                 return 1;
495
496         return 0;
497 }
498
499 typedef struct long_align_struct {
500         gint32 a;
501         gint64 b;
502         gint64 c;
503 } long_align_struct;
504
505 STDCALL int
506 mono_test_marshal_long_align_struct_array (long_align_struct *ss)
507 {
508         return ss[0].a + ss[0].b + ss[0].c + ss[1].a + ss[1].b + ss[1].c;
509 }
510
511 STDCALL simplestruct2 *
512 mono_test_marshal_class (int i, int j, int k, simplestruct2 *ss, int l)
513 {
514         simplestruct2 *res;
515
516         if (!ss)
517                 return NULL;
518
519         if (i != 10 || j != 11 || k != 12 || l != 14)
520                 return NULL;
521         if (! (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
522                    !strcmp (ss->d, "TEST") && 
523                    ss->e == 99 && ss->f == 1.5 && ss->g == 42 && ss->h == (guint64)123))
524                 return NULL;
525
526         res = g_new0 (simplestruct2, 1);
527         memcpy (res, ss, sizeof (simplestruct2));
528         res->d = g_strdup ("TEST");
529         return res;
530 }
531
532 STDCALL int
533 mono_test_marshal_byref_class (simplestruct2 **ssp)
534 {
535         simplestruct2 *ss = *ssp;
536         simplestruct2 *res;
537         
538         if (! (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
539                    !strcmp (ss->d, "TEST") && 
540                    ss->e == 99 && ss->f == 1.5 && ss->g == 42 && ss->h == (guint64)123))
541                 return 1;
542
543         res = g_new0 (simplestruct2, 1);
544         memcpy (res, ss, sizeof (simplestruct2));
545         res->d = g_strdup ("TEST-RES");
546
547         *ssp = res;
548         return 0;
549 }
550
551 static void *
552 get_sp (void)
553 {
554         int i;
555         void *p;
556
557         /* Yes, this is correct, we are only trying to determine the value of the stack here */
558         p = &i;
559         return p;
560 }
561
562 STDCALL int
563 reliable_delegate (int a)
564 {
565         return a;
566 }
567
568 /*
569  * Checks whether get_sp() works as expected. It doesn't work with gcc-2.95.3 on linux.
570  */
571 static gboolean
572 is_get_sp_reliable (void)
573 {
574         void *sp1, *sp2;
575
576         reliable_delegate(1);
577         sp1 = get_sp();
578         reliable_delegate(1);
579         sp2 = get_sp();
580         return sp1 == sp2;
581
582
583 STDCALL int
584 mono_test_marshal_delegate (SimpleDelegate delegate)
585 {
586         void *sp1, *sp2;
587
588         /* Check that the delegate wrapper is stdcall */
589         delegate (2);
590         sp1 = get_sp ();
591         delegate (2);
592         sp2 = get_sp ();
593         if (is_get_sp_reliable())
594                 g_assert (sp1 == sp2);
595
596         return delegate (2);
597 }
598
599 STDCALL SimpleDelegate
600 mono_test_marshal_return_delegate (SimpleDelegate delegate)
601 {
602         return delegate;
603 }
604
605 static STDCALL int
606 return_plus_one (int i)
607 {
608         return i + 1;
609 }
610
611 STDCALL SimpleDelegate
612 mono_test_marshal_return_delegate_2 ()
613 {
614         return return_plus_one;
615 }
616
617 typedef simplestruct (STDCALL *SimpleDelegate2) (simplestruct ss);
618
619 static gboolean
620 is_utf16_equals (gunichar2 *s1, const char *s2)
621 {
622         char *s;
623         int res;
624
625         s = g_utf16_to_utf8 (s1, -1, NULL, NULL, NULL);
626         res = strcmp (s, s2);
627         g_free (s);
628
629         return res == 0;
630 }
631
632 STDCALL int
633 mono_test_marshal_delegate2 (SimpleDelegate2 delegate)
634 {
635         simplestruct ss, res;
636
637         ss.a = 0;
638         ss.b = 1;
639         ss.c = 0;
640         ss.d = "TEST";
641         ss.d2 = g_utf8_to_utf16 ("TEST2", -1, NULL, NULL, NULL); 
642
643         res = delegate (ss);
644         if (! (res.a && !res.b && res.c && !strcmp (res.d, "TEST-RES") && is_utf16_equals (res.d2, "TEST2-RES")))
645                 return 1;
646
647         return 0;
648 }
649
650 typedef simplestruct* (STDCALL *SimpleDelegate4) (simplestruct *ss);
651
652 STDCALL int
653 mono_test_marshal_delegate4 (SimpleDelegate4 delegate)
654 {
655         simplestruct ss;
656         simplestruct *res;
657
658         ss.a = 0;
659         ss.b = 1;
660         ss.c = 0;
661         ss.d = "TEST";
662
663         /* Check argument */
664         res = delegate (&ss);
665         if (!res)
666                 return 1;
667
668         /* Check return value */
669         if (! (!res->a && res->b && !res->c && !strcmp (res->d, "TEST")))
670                 return 2;
671
672         /* Check NULL argument and NULL result */
673         res = delegate (NULL);
674         if (res)
675                 return 3;
676
677         return 0;
678 }
679
680 typedef int (STDCALL *SimpleDelegate5) (simplestruct **ss);
681
682 STDCALL int
683 mono_test_marshal_delegate5 (SimpleDelegate5 delegate)
684 {
685         simplestruct ss;
686         int res;
687         simplestruct *ptr;
688
689         ss.a = 0;
690         ss.b = 1;
691         ss.c = 0;
692         ss.d = "TEST";
693
694         ptr = &ss;
695
696         res = delegate (&ptr);
697         if (res != 0)
698                 return 1;
699
700         if (!(ptr->a && !ptr->b && ptr->c && !strcmp (ptr->d, "RES")))
701                 return 2;
702
703         return 0;
704 }
705
706 STDCALL int
707 mono_test_marshal_delegate6 (SimpleDelegate5 delegate)
708 {
709         int res;
710
711         res = delegate (NULL);
712
713         return 0;
714 }
715
716 typedef int (STDCALL *SimpleDelegate7) (simplestruct **ss);
717
718 STDCALL int
719 mono_test_marshal_delegate7 (SimpleDelegate7 delegate)
720 {
721         int res;
722         simplestruct *ptr;
723
724         /* Check that the input pointer is ignored */
725         ptr = (gpointer)0x12345678;
726
727         res = delegate (&ptr);
728         if (res != 0)
729                 return 1;
730
731         if (!(ptr->a && !ptr->b && ptr->c && !strcmp (ptr->d, "RES")))
732                 return 2;
733
734         return 0;
735 }
736
737 typedef int (STDCALL *SimpleDelegate8) (gunichar2 *s);
738
739 STDCALL int
740 mono_test_marshal_delegate8 (SimpleDelegate8 delegate, gunichar2 *s)
741 {
742         return delegate (s);
743 }
744
745 typedef int (STDCALL *return_int_fnt) (int i);
746 typedef int (STDCALL *SimpleDelegate9) (return_int_fnt d);
747
748 STDCALL int
749 mono_test_marshal_delegate9 (SimpleDelegate9 delegate, gpointer ftn)
750 {
751         return delegate (ftn);
752 }
753
754 STDCALL static int
755 return_self (int i)
756 {
757         return i;
758 }
759
760 STDCALL int
761 mono_test_marshal_delegate10 (SimpleDelegate9 delegate)
762 {
763         return delegate (return_self);
764 }
765
766 typedef int (STDCALL *PrimitiveByrefDelegate) (int *i);
767
768 STDCALL int
769 mono_test_marshal_primitive_byref_delegate (PrimitiveByrefDelegate delegate)
770 {
771         int i = 1;
772
773         int res = delegate (&i);
774         if (res != 0)
775                 return res;
776
777         if (i != 2)
778                 return 2;
779
780         return 0;
781 }
782
783 typedef int (STDCALL *return_int_delegate) (int i);
784
785 typedef return_int_delegate (STDCALL *ReturnDelegateDelegate) (void);
786
787 STDCALL int
788 mono_test_marshal_return_delegate_delegate (ReturnDelegateDelegate d)
789 {
790         return (d ()) (55);
791 }
792
793 STDCALL int 
794 mono_test_marshal_stringbuilder (char *s, int n)
795 {
796         const char m[] = "This is my message.  Isn't it nice?";
797
798         if (strcmp (s, "ABCD") != 0)
799                 return 1;
800         strncpy(s, m, n);
801         return 0;
802 }
803
804 STDCALL int 
805 mono_test_marshal_stringbuilder_unicode (gunichar2 *s, int n)
806 {
807         const char m[] = "This is my message.  Isn't it nice?";
808         gunichar2* s2;
809         glong len;
810
811         s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
812         
813         len = (len * 2) + 2;
814         if (len > n)
815                 len = n;
816         memcpy (s, s2, len);
817
818         g_free (s2);
819
820         return 0;
821 }
822
823 typedef struct {
824 #ifndef __GNUC__
825     char a;
826 #endif
827 } EmptyStruct;
828
829 STDCALL int
830 mono_test_marshal_empty_string_array (char **array)
831 {
832         return (array == NULL) ? 0 : 1;
833 }
834
835 STDCALL int
836 mono_test_marshal_string_array (char **array)
837 {
838         if (strcmp (array [0], "ABC"))
839                 return 1;
840         if (strcmp (array [1], "DEF"))
841                 return 2;
842
843         if (array [2] != NULL)
844                 return 3;
845
846         return 0;
847 }
848
849 STDCALL int
850 mono_test_marshal_byref_string_array (char ***array)
851 {
852         if (*array == NULL)
853                 return 0;
854
855         if (strcmp ((*array) [0], "Alpha"))
856                 return 2;
857         if (strcmp ((*array) [1], "Beta"))
858                 return 2;
859         if (strcmp ((*array) [2], "Gamma"))
860                 return 2;
861
862         return 1;
863 }
864
865 STDCALL int
866 mono_test_marshal_stringbuilder_array (char **array)
867 {
868         if (strcmp (array [0], "ABC"))
869                 return 1;
870         if (strcmp (array [1], "DEF"))
871                 return 2;
872
873         strcpy (array [0], "DEF");
874         strcpy (array [1], "ABC");
875
876         return 0;
877 }
878
879 STDCALL int
880 mono_test_marshal_unicode_string_array (gunichar2 **array, char **array2)
881 {
882         GError *error = NULL;
883         char *s;
884         
885         s = g_utf16_to_utf8 (array [0], -1, NULL, NULL, &error);
886         if (strcmp (s, "ABC")) {
887                 g_free (s);
888                 return 1;
889         }
890         else
891                 g_free (s);
892
893         s = g_utf16_to_utf8 (array [1], -1, NULL, NULL, &error);
894         if (strcmp (s, "DEF")) {
895                 g_free (s);
896                 return 2;
897         }
898         else
899                 g_free (s);
900
901         if (strcmp (array2 [0], "ABC"))
902                 return 3;
903
904         if (strcmp (array2 [1], "DEF")) 
905                 return 4;
906
907         return 0;
908 }
909
910 /* this does not work on Redhat gcc 2.96 */
911 STDCALL int 
912 mono_test_empty_struct (int a, EmptyStruct es, int b)
913 {
914         // printf ("mono_test_empty_struct %d %d\n", a, b);
915
916         // Intel icc on ia64 passes 'es' in 2 registers
917 #if defined(__ia64) && defined(__INTEL_COMPILER)
918         return 0;
919 #else
920         if (a == 1 && b == 2)
921                 return 0;
922         return 1;
923 #endif
924 }
925
926 typedef struct {
927        char a[100];
928 } ByValStrStruct;
929
930 STDCALL ByValStrStruct *
931 mono_test_byvalstr_gen (void)
932 {
933         ByValStrStruct *ret;
934        
935         ret = malloc(sizeof(ByValStrStruct));
936         memset(ret, 'a', sizeof(ByValStrStruct)-1);
937         ret->a[sizeof(ByValStrStruct)-1] = 0;
938
939         return ret;
940 }
941
942 STDCALL int
943 mono_test_byvalstr_check (ByValStrStruct* data, char* correctString)
944 {
945         int ret;
946
947         ret = strcmp(data->a, correctString);
948         // printf ("T1: %s\n", data->a);
949         // printf ("T2: %s\n", correctString);
950
951         marshal_free (data);
952         return (ret != 0);
953 }
954
955 STDCALL int
956 NameManglingAnsi (char *data)
957 {
958         return data [0] + data [1] + data [2];
959 }
960
961 STDCALL int
962 NameManglingAnsiA (char *data)
963 {
964         g_assert_not_reached ();
965 }
966
967 STDCALL int
968 NameManglingAnsiW (char *data)
969 {
970         g_assert_not_reached ();
971 }
972
973 STDCALL int
974 NameManglingAnsi2A (char *data)
975 {
976         return data [0] + data [1] + data [2];
977 }
978
979 STDCALL int
980 NameManglingAnsi2W (char *data)
981 {
982         g_assert_not_reached ();
983 }
984
985 STDCALL int
986 NameManglingUnicode (char *data)
987 {
988         g_assert_not_reached ();
989 }
990
991 STDCALL int
992 NameManglingUnicodeW (gunichar2 *data)
993 {
994         return data [0] + data [1] + data [2];
995 }
996
997 STDCALL int
998 NameManglingUnicode2 (gunichar2 *data)
999 {
1000         return data [0] + data [1] + data [2];
1001 }
1002
1003 STDCALL int
1004 NameManglingAutoW (char *data)
1005 {
1006 #ifdef WIN32
1007         return (data [0] + data [1] + data [2]) == 131 ? 0 : 1;
1008 #else
1009         g_assert_not_reached ();
1010 #endif
1011 }
1012
1013 STDCALL int
1014 NameManglingAuto (char *data)
1015 {
1016 #ifndef WIN32
1017         return (data [0] + data [1] + data [2]) == 198 ? 0 : 1;
1018 #else
1019         g_assert_not_reached ();
1020 #endif
1021 }
1022
1023 typedef int (STDCALL *intcharFunc)(const char*);
1024
1025 STDCALL void 
1026 callFunction (intcharFunc f)
1027 {
1028         f ("ABC");
1029 }
1030
1031 typedef struct {
1032         const char* str;
1033         int i;
1034 } SimpleObj;
1035
1036 STDCALL int
1037 class_marshal_test0 (SimpleObj *obj1)
1038 {
1039         // printf ("class_marshal_test0 %s %d\n", obj1->str, obj1->i);
1040
1041         if (strcmp(obj1->str, "T1"))
1042                 return -1;
1043         if (obj1->i != 4)
1044                 return -2;
1045
1046         return 0;
1047 }
1048
1049 STDCALL int
1050 class_marshal_test4 (SimpleObj *obj1)
1051 {
1052         if (obj1)
1053                 return -1;
1054
1055         return 0;
1056 }
1057
1058 STDCALL void
1059 class_marshal_test1 (SimpleObj **obj1)
1060 {
1061         SimpleObj *res = malloc (sizeof (SimpleObj));
1062
1063         res->str = g_strdup ("ABC");
1064         res->i = 5;
1065
1066         *obj1 = res;
1067 }
1068
1069 STDCALL int
1070 class_marshal_test2 (SimpleObj **obj1)
1071 {
1072         // printf ("class_marshal_test2 %s %d\n", (*obj1)->str, (*obj1)->i);
1073
1074         if (strcmp((*obj1)->str, "ABC"))
1075                 return -1;
1076         if ((*obj1)->i != 5)
1077                 return -2;
1078
1079         return 0;
1080 }
1081
1082 STDCALL int
1083 string_marshal_test0 (char *str)
1084 {
1085         if (strcmp (str, "TEST0"))
1086                 return -1;
1087
1088         return 0;
1089 }
1090
1091 STDCALL void
1092 string_marshal_test1 (const char **str)
1093 {
1094         *str = "TEST1";
1095 }
1096
1097 STDCALL int
1098 string_marshal_test2 (char **str)
1099 {
1100         // printf ("string_marshal_test2 %s\n", *str);
1101
1102         if (strcmp (*str, "TEST1"))
1103                 return -1;
1104
1105         return 0;
1106 }
1107
1108 STDCALL int
1109 string_marshal_test3 (char *str)
1110 {
1111         if (str)
1112                 return -1;
1113
1114         return 0;
1115 }
1116
1117 typedef struct {
1118         int a;
1119         int b;
1120 } VectorList;
1121
1122 STDCALL VectorList* 
1123 TestVectorList (VectorList *vl)
1124 {
1125         VectorList *res;
1126
1127         // printf ("TestVectorList %d %d\n", vl->a, vl->b);
1128
1129         vl->a++;
1130         vl->b++;
1131
1132         res = g_new0 (VectorList, 1);
1133         memcpy (res, vl, sizeof (VectorList));
1134
1135         return res;
1136 }
1137
1138 typedef struct OSVERSIONINFO_STRUCT
1139
1140         int a; 
1141         int b; 
1142 } OSVERSIONINFO_STRUCT;
1143
1144 STDCALL int 
1145 MyGetVersionEx (OSVERSIONINFO_STRUCT *osvi)
1146 {
1147
1148         // printf ("GOT %d %d\n", osvi->a, osvi->b);
1149
1150         osvi->a += 1;
1151         osvi->b += 1;
1152
1153         return osvi->a + osvi->b;
1154 }
1155
1156 STDCALL int 
1157 BugGetVersionEx (int a, int b, int c, int d, int e, int f, int g, int h, OSVERSIONINFO_STRUCT *osvi)
1158 {
1159
1160         // printf ("GOT %d %d\n", osvi->a, osvi->b);
1161
1162         osvi->a += 1;
1163         osvi->b += 1;
1164
1165         return osvi->a + osvi->b;
1166 }
1167
1168 STDCALL int
1169 mono_test_marshal_point (point pt)
1170 {
1171         // printf("point %g %g\n", pt.x, pt.y);
1172         if (pt.x == 1.25 && pt.y == 3.5)
1173                 return 0;
1174
1175         return 1;
1176 }
1177
1178 typedef struct {
1179         int x;
1180         double y;
1181 } mixed_point;
1182
1183 STDCALL int
1184 mono_test_marshal_mixed_point (mixed_point pt)
1185 {
1186         // printf("mixed point %d %g\n", pt.x, pt.y);
1187         if (pt.x == 5 && pt.y == 6.75)
1188                 return 0;
1189
1190         return 1;
1191 }
1192
1193 STDCALL int
1194 mono_test_marshal_mixed_point_2 (mixed_point *pt)
1195 {
1196         if (pt->x != 5 || pt->y != 6.75)
1197                 return 1;
1198
1199         pt->x = 10;
1200         pt->y = 12.35;
1201
1202         return 0;
1203 }
1204
1205 STDCALL int 
1206 marshal_test_ref_bool(int i, char *b1, short *b2, int *b3)
1207 {
1208     int res = 1;
1209     if (*b1 != 0 && *b1 != 1)
1210         return 1;
1211     if (*b2 != 0 && *b2 != -1) /* variant_bool */
1212         return 1;
1213     if (*b3 != 0 && *b3 != 1)
1214         return 1;
1215     if (i == ((*b1 << 2) | (-*b2 << 1) | *b3))
1216         res = 0;
1217     *b1 = !*b1;
1218     *b2 = ~*b2;
1219     *b3 = !*b3;
1220     return res;
1221 }
1222
1223 struct BoolStruct
1224 {
1225     int i;
1226     char b1;
1227     short b2; /* variant_bool */
1228     int b3;
1229 };
1230
1231 STDCALL int 
1232 marshal_test_bool_struct(struct BoolStruct *s)
1233 {
1234     int res = 1;
1235     if (s->b1 != 0 && s->b1 != 1)
1236         return 1;
1237     if (s->b2 != 0 && s->b2 != -1)
1238         return 1;
1239     if (s->b3 != 0 && s->b3 != 1)
1240         return 1;
1241     if (s->i == ((s->b1 << 2) | (-s->b2 << 1) | s->b3))
1242         res = 0;
1243     s->b1 = !s->b1;
1244     s->b2 = ~s->b2;
1245     s->b3 = !s->b3;
1246     return res;
1247 }
1248
1249 STDCALL void
1250 mono_test_last_error (int err)
1251 {
1252 #ifdef WIN32
1253         SetLastError (err);
1254 #else
1255         errno = err;
1256 #endif
1257 }
1258
1259 STDCALL int
1260 mono_test_asany (void *ptr, int what)
1261 {
1262         switch (what) {
1263         case 1:
1264                 return (*(int*)ptr == 5) ? 0 : 1;
1265         case 2:
1266                 return strcmp (ptr, "ABC") == 0 ? 0 : 1;
1267         case 3: {
1268                 simplestruct2 ss = *(simplestruct2*)ptr;
1269
1270                 if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
1271             !strcmp (ss.d, "TEST") && 
1272             ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
1273                         return 0;
1274                 else
1275                         return 1;
1276         }
1277         case 4: {
1278                 GError *error = NULL;
1279                 char *s;
1280
1281                 s = g_utf16_to_utf8 (ptr, -1, NULL, NULL, &error);
1282                 if (!strcmp (s, "ABC")) {
1283                         g_free (s);
1284                         return 0;
1285                 }
1286                 else {
1287                         g_free (s);
1288                         return 1;
1289                 }
1290         }
1291         default:
1292                 g_assert_not_reached ();
1293         }
1294
1295         return 1;
1296 }
1297
1298 typedef struct
1299 {
1300         int i;
1301         int j;
1302         int k;
1303         char *s;
1304 } AsAnyStruct;
1305
1306 STDCALL int
1307 mono_test_marshal_asany_inout (void* ptr)
1308 {
1309         AsAnyStruct* asAny = ptr;
1310         int res = asAny->i + asAny->j + asAny->k;
1311
1312         asAny->i = 10;
1313         asAny->j = 20;
1314         asAny->k = 30;
1315         asAny->s = 0;
1316
1317         return res;
1318 }
1319
1320 /*
1321  * AMD64 marshalling tests.
1322  */
1323
1324 typedef struct amd64_struct1 {
1325         int i;
1326         int j;
1327         int k;
1328         int l;
1329 } amd64_struct1;
1330
1331 STDCALL amd64_struct1
1332 mono_test_marshal_amd64_pass_return_struct1 (amd64_struct1 s)
1333 {
1334         s.i ++;
1335         s.j ++;
1336         s.k ++;
1337         s.l ++;
1338
1339         return s;
1340 }
1341
1342 typedef struct amd64_struct2 {
1343         int i;
1344         int j;
1345 } amd64_struct2;
1346
1347 STDCALL amd64_struct2
1348 mono_test_marshal_amd64_pass_return_struct2 (amd64_struct2 s)
1349 {
1350         s.i ++;
1351         s.j ++;
1352
1353         return s;
1354 }
1355
1356 typedef struct amd64_struct3 {
1357         int i;
1358 } amd64_struct3;
1359
1360 STDCALL amd64_struct3
1361 mono_test_marshal_amd64_pass_return_struct3 (amd64_struct3 s)
1362 {
1363         s.i ++;
1364
1365         return s;
1366 }
1367
1368 typedef struct amd64_struct4 {
1369         double d1, d2;
1370 } amd64_struct4;
1371
1372 STDCALL amd64_struct4
1373 mono_test_marshal_amd64_pass_return_struct4 (amd64_struct4 s)
1374 {
1375         s.d1 ++;
1376         s.d2 ++;
1377
1378         return s;
1379 }
1380
1381 /*
1382  * IA64 marshalling tests.
1383  */
1384 typedef struct test_struct5 {
1385         float d1, d2;
1386 } test_struct5;
1387
1388 STDCALL test_struct5
1389 mono_test_marshal_ia64_pass_return_struct5 (double d1, double d2, test_struct5 s, double d3, double d4)
1390 {
1391         s.d1 += d1 + d2;
1392         s.d2 += d3 + d4;
1393
1394         return s;
1395 }
1396
1397 typedef struct test_struct6 {
1398         double d1, d2;
1399 } test_struct6;
1400
1401 STDCALL test_struct6
1402 mono_test_marshal_ia64_pass_return_struct6 (double d1, double d2, test_struct6 s, double d3, double d4)
1403 {
1404         s.d1 += d1 + d2;
1405         s.d2 += d3 + d4;
1406
1407         return s;
1408 }
1409
1410 static guint32 custom_res [2];
1411
1412 STDCALL void*
1413 mono_test_marshal_pass_return_custom (int i, guint32 *ptr, int j)
1414 {
1415         /* ptr will be freed by CleanupNative, so make a copy */
1416         custom_res [0] = 0; /* not allocated by AllocHGlobal */
1417         custom_res [1] = ptr [1];
1418
1419         return &custom_res;
1420 }
1421
1422 STDCALL int
1423 mono_test_marshal_pass_out_custom (int i, guint32 **ptr, int j)
1424 {
1425         custom_res [0] = 0;
1426         custom_res [1] = i + j + 10;
1427
1428         *ptr = custom_res;
1429
1430         return 0;
1431 }
1432
1433 STDCALL int
1434 mono_test_marshal_pass_byref_custom (int i, guint32 **ptr, int j)
1435 {
1436         (*ptr)[1] += i + j;
1437
1438         return 0;
1439 }
1440
1441 STDCALL void*
1442 mono_test_marshal_pass_return_custom2 (int i, guint32 *ptr, int j)
1443 {
1444         g_assert_not_reached ();
1445
1446         return NULL;
1447 }
1448
1449 STDCALL void*
1450 mono_test_marshal_pass_return_custom_null (int i, guint32 *ptr, int j)
1451 {
1452         g_assert (ptr == NULL);
1453
1454         return NULL;
1455 }
1456
1457 typedef void *(STDCALL *PassReturnPtrDelegate) (void *ptr);
1458
1459 STDCALL int
1460 mono_test_marshal_pass_return_custom_in_delegate (PassReturnPtrDelegate del)
1461 {
1462         guint32 buf [2];
1463         guint32 res;
1464         guint32 *ptr;
1465
1466         buf [0] = 0;
1467         buf [1] = 10;
1468
1469         ptr = del (&buf);
1470
1471         res = ptr [1];
1472
1473 #ifdef WIN32
1474         /* FIXME: Freed with FreeHGlobal */
1475 #else
1476         g_free (ptr);
1477 #endif
1478
1479         return res;
1480 }
1481
1482 STDCALL int
1483 mono_test_marshal_pass_return_custom_null_in_delegate (PassReturnPtrDelegate del)
1484 {
1485         void *ptr = del (NULL);
1486
1487         return (ptr == NULL) ? 15 : 0;
1488 }
1489
1490 typedef int (STDCALL *ReturnEnumDelegate) (int e);
1491
1492 STDCALL int
1493 mono_test_marshal_return_enum_delegate (ReturnEnumDelegate func)
1494 {
1495         return func (1);
1496 }
1497
1498 typedef struct {
1499         int a, b, c;
1500         gint64 d;
1501 } BlittableStruct;
1502         
1503 typedef BlittableStruct (STDCALL *SimpleDelegate10) (BlittableStruct ss);
1504
1505 STDCALL int
1506 mono_test_marshal_blittable_struct_delegate (SimpleDelegate10 delegate)
1507 {
1508         BlittableStruct ss, res;
1509
1510         ss.a = 1;
1511         ss.b = 2;
1512         ss.c = 3;
1513         ss.d = 55;
1514
1515         res = delegate (ss);
1516         if (! ((res.a == -1) && (res.b == -2) && (res.c == -3) && (res.d == -55)))
1517                 return 1;
1518
1519         return 0;
1520 }
1521
1522 STDCALL int
1523 mono_test_stdcall_name_mangling (int a, int b, int c)
1524 {
1525         return a + b + c;
1526 }
1527
1528 /*
1529  * PASSING AND RETURNING SMALL STRUCTURES FROM DELEGATES TESTS
1530  */
1531
1532 typedef struct {
1533         int i;
1534 } SmallStruct1;
1535         
1536 typedef SmallStruct1 (STDCALL *SmallStructDelegate1) (SmallStruct1 ss);
1537
1538 STDCALL int
1539 mono_test_marshal_small_struct_delegate1 (SmallStructDelegate1 delegate)
1540 {
1541         SmallStruct1 ss, res;
1542
1543         ss.i = 1;
1544
1545         res = delegate (ss);
1546         if (! (res.i == -1))
1547                 return 1;
1548
1549         return 0;
1550 }
1551
1552 typedef struct {
1553         gint16 i, j;
1554 } SmallStruct2;
1555         
1556 typedef SmallStruct2 (STDCALL *SmallStructDelegate2) (SmallStruct2 ss);
1557
1558 STDCALL int
1559 mono_test_marshal_small_struct_delegate2 (SmallStructDelegate2 delegate)
1560 {
1561         SmallStruct2 ss, res;
1562
1563         ss.i = 2;
1564         ss.j = 3;
1565
1566         res = delegate (ss);
1567         if (! ((res.i == -2) && (res.j == -3)))
1568                 return 1;
1569
1570         return 0;
1571 }
1572
1573 typedef struct {
1574         gint16 i;
1575         gint8 j;
1576 } SmallStruct3;
1577         
1578 typedef SmallStruct3 (STDCALL *SmallStructDelegate3) (SmallStruct3 ss);
1579
1580 STDCALL int
1581 mono_test_marshal_small_struct_delegate3 (SmallStructDelegate3 delegate)
1582 {
1583         SmallStruct3 ss, res;
1584
1585         ss.i = 1;
1586         ss.j = 2;
1587
1588         res = delegate (ss);
1589         if (! ((res.i == -1) && (res.j == -2)))
1590                 return 1;
1591
1592         return 0;
1593 }
1594
1595 typedef struct {
1596         gint16 i;
1597 } SmallStruct4;
1598         
1599 typedef SmallStruct4 (STDCALL *SmallStructDelegate4) (SmallStruct4 ss);
1600
1601 STDCALL int
1602 mono_test_marshal_small_struct_delegate4 (SmallStructDelegate4 delegate)
1603 {
1604         SmallStruct4 ss, res;
1605
1606         ss.i = 1;
1607
1608         res = delegate (ss);
1609         if (! (res.i == -1))
1610                 return 1;
1611
1612         return 0;
1613 }
1614
1615 typedef struct {
1616         gint64 i;
1617 } SmallStruct5;
1618         
1619 typedef SmallStruct5 (STDCALL *SmallStructDelegate5) (SmallStruct5 ss);
1620
1621 STDCALL int
1622 mono_test_marshal_small_struct_delegate5 (SmallStructDelegate5 delegate)
1623 {
1624         SmallStruct5 ss, res;
1625
1626         ss.i = 5;
1627
1628         res = delegate (ss);
1629         if (! (res.i == -5))
1630                 return 1;
1631
1632         return 0;
1633 }
1634
1635 typedef struct {
1636         int i, j;
1637 } SmallStruct6;
1638         
1639 typedef SmallStruct6 (STDCALL *SmallStructDelegate6) (SmallStruct6 ss);
1640
1641 STDCALL int
1642 mono_test_marshal_small_struct_delegate6 (SmallStructDelegate6 delegate)
1643 {
1644         SmallStruct6 ss, res;
1645
1646         ss.i = 1;
1647         ss.j = 2;
1648
1649         res = delegate (ss);
1650         if (! ((res.i == -1) && (res.j == -2)))
1651                 return 1;
1652
1653         return 0;
1654 }
1655
1656 typedef struct {
1657         int i;
1658         gint16 j;
1659 } SmallStruct7;
1660         
1661 typedef SmallStruct7 (STDCALL *SmallStructDelegate7) (SmallStruct7 ss);
1662
1663 STDCALL int
1664 mono_test_marshal_small_struct_delegate7 (SmallStructDelegate7 delegate)
1665 {
1666         SmallStruct7 ss, res;
1667
1668         ss.i = 1;
1669         ss.j = 2;
1670
1671         res = delegate (ss);
1672         if (! ((res.i == -1) && (res.j == -2)))
1673                 return 1;
1674
1675         return 0;
1676 }
1677
1678 typedef struct {
1679         float i;
1680 } SmallStruct8;
1681         
1682 typedef SmallStruct8 (STDCALL *SmallStructDelegate8) (SmallStruct8 ss);
1683
1684 STDCALL int
1685 mono_test_marshal_small_struct_delegate8 (SmallStructDelegate8 delegate)
1686 {
1687         SmallStruct8 ss, res;
1688
1689         ss.i = 1.0;
1690
1691         res = delegate (ss);
1692         if (! ((res.i == -1.0)))
1693                 return 1;
1694
1695         return 0;
1696 }
1697
1698 typedef struct {
1699         double i;
1700 } SmallStruct9;
1701         
1702 typedef SmallStruct9 (STDCALL *SmallStructDelegate9) (SmallStruct9 ss);
1703
1704 STDCALL int
1705 mono_test_marshal_small_struct_delegate9 (SmallStructDelegate9 delegate)
1706 {
1707         SmallStruct9 ss, res;
1708
1709         ss.i = 1.0;
1710
1711         res = delegate (ss);
1712         if (! ((res.i == -1.0)))
1713                 return 1;
1714
1715         return 0;
1716 }
1717
1718 typedef struct {
1719         float i, j;
1720 } SmallStruct10;
1721         
1722 typedef SmallStruct10 (STDCALL *SmallStructDelegate10) (SmallStruct10 ss);
1723
1724 STDCALL int
1725 mono_test_marshal_small_struct_delegate10 (SmallStructDelegate10 delegate)
1726 {
1727         SmallStruct10 ss, res;
1728
1729         ss.i = 1.0;
1730         ss.j = 2.0;
1731
1732         res = delegate (ss);
1733         if (! ((res.i == -1.0) && (res.j == -2.0)))
1734                 return 1;
1735
1736         return 0;
1737 }
1738
1739 typedef struct {
1740         float i;
1741         int j;
1742 } SmallStruct11;
1743         
1744 typedef SmallStruct11 (STDCALL *SmallStructDelegate11) (SmallStruct11 ss);
1745
1746 STDCALL int
1747 mono_test_marshal_small_struct_delegate11 (SmallStructDelegate11 delegate)
1748 {
1749         SmallStruct11 ss, res;
1750
1751         ss.i = 1.0;
1752         ss.j = 2;
1753
1754         res = delegate (ss);
1755         if (! ((res.i == -1.0) && (res.j == -2)))
1756                 return 1;
1757
1758         return 0;
1759 }
1760
1761 typedef int (STDCALL *ArrayDelegate) (int i, char *j, void *arr);
1762
1763 STDCALL int
1764 mono_test_marshal_array_delegate (void *arr, int len, ArrayDelegate del)
1765 {
1766         return del (len, NULL, arr);
1767 }
1768
1769 STDCALL int
1770 mono_test_marshal_out_array_delegate (int *arr, int len, ArrayDelegate del)
1771 {
1772         del (len, NULL, arr);
1773
1774         if ((arr [0] != 1) || (arr [1] != 2))
1775                 return 1;
1776         else
1777                 return 0;
1778 }
1779
1780 STDCALL int
1781 mono_test_marshal_out_string_array_delegate (char **arr, int len, ArrayDelegate del)
1782 {
1783         del (len, NULL, arr);
1784
1785         if (!strcmp (arr [0], "ABC") && !strcmp (arr [1], "DEF"))
1786                 return 0;
1787         else
1788                 return 1;
1789 }
1790
1791 typedef int (*CdeclDelegate) (int i, int j);
1792
1793 STDCALL int
1794 mono_test_marshal_cdecl_delegate (CdeclDelegate del)
1795 {
1796         int i;
1797
1798         for (i = 0; i < 1000; ++i)
1799                 del (1, 2);
1800
1801         return 0;
1802 }
1803
1804 typedef char** (*ReturnStringArrayDelegate) (int i);
1805
1806 STDCALL int
1807 mono_test_marshal_return_string_array_delegate (ReturnStringArrayDelegate d)
1808 {
1809         char **arr = d (2);
1810         int res;
1811
1812         if (arr == NULL)
1813                 return 3;
1814
1815         if (strcmp (arr [0], "ABC") || strcmp (arr [1], "DEF"))
1816                 res = 1;
1817         else
1818                 res = 0;
1819
1820         marshal_free (arr);
1821
1822         return res;
1823 }
1824
1825 /*
1826  * COM INTEROP TESTS
1827  */
1828
1829 #ifdef WIN32
1830
1831 STDCALL int
1832 mono_test_marshal_bstr_in(BSTR bstr)
1833 {
1834         if (!wcscmp(bstr, L"mono_test_marshal_bstr_in"))
1835                 return 0;
1836         return 1;
1837 }
1838
1839 STDCALL int
1840 mono_test_marshal_bstr_out(BSTR* bstr)
1841 {
1842         *bstr = SysAllocString(L"mono_test_marshal_bstr_out");
1843         return 0;
1844 }
1845
1846 STDCALL int
1847 mono_test_marshal_variant_in_sbyte(VARIANT variant)
1848 {
1849         if (variant.vt == VT_I1 && variant.cVal == 100)
1850                 return 0;
1851         return 1;
1852 }
1853
1854 STDCALL int
1855 mono_test_marshal_variant_in_byte(VARIANT variant)
1856 {
1857         if (variant.vt == VT_UI1 && variant.bVal == 100)
1858                 return 0;
1859         return 1;
1860 }
1861
1862 STDCALL int
1863 mono_test_marshal_variant_in_short(VARIANT variant)
1864 {
1865         if (variant.vt == VT_I2 && variant.iVal == 314)
1866                 return 0;
1867         return 1;
1868 }
1869
1870 STDCALL int
1871 mono_test_marshal_variant_in_ushort(VARIANT variant)
1872 {
1873         if (variant.vt == VT_UI2 && variant.uiVal == 314)
1874                 return 0;
1875         return 1;
1876 }
1877
1878 STDCALL int
1879 mono_test_marshal_variant_in_int(VARIANT variant)
1880 {
1881         if (variant.vt == VT_I4 && variant.lVal == 314)
1882                 return 0;
1883         return 1;
1884 }
1885
1886 STDCALL int
1887 mono_test_marshal_variant_in_uint(VARIANT variant)
1888 {
1889         if (variant.vt == VT_UI4 && variant.ulVal == 314)
1890                 return 0;
1891         return 1;
1892 }
1893
1894 STDCALL int
1895 mono_test_marshal_variant_in_long(VARIANT variant)
1896 {
1897         if (variant.vt == VT_I8 && variant.llVal == 314)
1898                 return 0;
1899         return 1;
1900 }
1901
1902 STDCALL int
1903 mono_test_marshal_variant_in_ulong(VARIANT variant)
1904 {
1905         if (variant.vt == VT_UI8 && variant.ullVal == 314)
1906                 return 0;
1907         return 1;
1908 }
1909
1910 STDCALL int
1911 mono_test_marshal_variant_in_float(VARIANT variant)
1912 {
1913         if (variant.vt == VT_R4 && (variant.fltVal - 3.14)/3.14 < .001)
1914                 return 0;
1915         return 1;
1916 }
1917
1918 STDCALL int
1919 mono_test_marshal_variant_in_double(VARIANT variant)
1920 {
1921         if (variant.vt == VT_R8 && (variant.dblVal - 3.14)/3.14 < .001)
1922                 return 0;
1923         return 1;
1924 }
1925
1926 STDCALL int
1927 mono_test_marshal_variant_in_bstr(VARIANT variant)
1928 {
1929         if (variant.vt == VT_BSTR && !wcscmp(variant.bstrVal, L"PI"))
1930                 return 0;
1931         return 1;
1932 }
1933
1934 STDCALL int
1935 mono_test_marshal_variant_out_sbyte(VARIANT* variant)
1936 {
1937         variant->vt = VT_I1;
1938         variant->cVal = 100;
1939
1940         return 0;
1941 }
1942
1943 STDCALL int
1944 mono_test_marshal_variant_out_byte(VARIANT* variant)
1945 {       
1946         variant->vt = VT_UI1;
1947         variant->bVal = 100;
1948
1949         return 0;
1950 }
1951
1952 STDCALL int
1953 mono_test_marshal_variant_out_short(VARIANT* variant)
1954 {
1955         variant->vt = VT_I2;
1956         variant->iVal = 314;
1957
1958         return 0;
1959 }
1960
1961 STDCALL int
1962 mono_test_marshal_variant_out_ushort(VARIANT* variant)
1963 {
1964         variant->vt = VT_UI2;
1965         variant->uiVal = 314;
1966
1967         return 0;
1968 }
1969
1970 STDCALL int
1971 mono_test_marshal_variant_out_int(VARIANT* variant)
1972 {
1973         variant->vt = VT_I4;
1974         variant->lVal = 314;
1975
1976         return 0;
1977 }
1978
1979 STDCALL int
1980 mono_test_marshal_variant_out_uint(VARIANT* variant)
1981 {
1982         variant->vt = VT_UI4;
1983         variant->ulVal = 314;
1984
1985         return 0;
1986 }
1987
1988 STDCALL int
1989 mono_test_marshal_variant_out_long(VARIANT* variant)
1990 {
1991         variant->vt = VT_I8;
1992         variant->llVal = 314;
1993
1994         return 0;
1995 }
1996
1997 STDCALL int
1998 mono_test_marshal_variant_out_ulong(VARIANT* variant)
1999 {
2000         variant->vt = VT_UI8;
2001         variant->ullVal = 314;
2002
2003         return 0;
2004 }
2005
2006 STDCALL int
2007 mono_test_marshal_variant_out_float(VARIANT* variant)
2008 {
2009         variant->vt = VT_R4;
2010         variant->fltVal = 3.14;
2011
2012         return 0;
2013 }
2014
2015 STDCALL int
2016 mono_test_marshal_variant_out_double(VARIANT* variant)
2017 {
2018         variant->vt = VT_R8;
2019         variant->dblVal = 3.14;
2020
2021         return 0;
2022 }
2023
2024 STDCALL int
2025 mono_test_marshal_variant_out_bstr(VARIANT* variant)
2026 {
2027         variant->vt = VT_BSTR;
2028         variant->bstrVal = SysAllocString(L"PI");
2029
2030         return 0;
2031 }
2032
2033 #endif