2005-05-12 Zoltan Varga <vargaz@freemail.hu>
[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 #define STDCALL __stdcall
10 #else
11 #define STDCALL
12 #endif
13
14 #ifdef WIN32
15 extern __declspec(dllimport) __stdcall void CoTaskMemFree(void *ptr);
16 #endif
17
18 typedef int (STDCALL *SimpleDelegate) (int a);
19
20 static void marshal_free (void *ptr)
21 {
22 #ifdef WIN32
23         CoTaskMemFree (ptr);
24 #else
25         g_free (ptr);
26 #endif
27 }
28
29 STDCALL unsigned short*
30 test_lpwstr_marshal (unsigned short* chars, long length)
31 {
32         int i = 0;
33         unsigned short *res;
34
35         res = malloc (2 * (length + 1));
36
37         // printf("test_lpwstr_marshal()\n");
38         
39         while ( i < length ) {
40                 // printf("X|%u|\n", chars[i]);
41                 res [i] = chars[i];
42                 i++;
43         }
44
45         res [i] = 0;
46
47         return res;
48 }
49
50 typedef struct {
51         int b;
52         int a;
53         int c;
54 } union_test_1_type;
55
56 STDCALL int 
57 mono_union_test_1 (union_test_1_type u1) {
58         // printf ("Got values %d %d %d\n", u1.b, u1.a, u1.c);
59         return u1.a + u1.b + u1.c;
60 }
61
62 STDCALL int 
63 mono_return_int (int a) {
64         // printf ("Got value %d\n", a);
65         return a;
66 }
67
68 struct ss
69 {
70         int i;
71 };
72
73 STDCALL int 
74 mono_return_int_ss (struct ss a) {
75         // printf ("Got value %d\n", a.i);
76         return a.i;
77 }
78
79 STDCALL struct ss 
80 mono_return_ss (struct ss a) {
81         // printf ("Got value %d\n", a.i);
82         a.i++;
83         return a;
84 }
85
86 struct sc1
87 {
88         char c[1];
89 };
90
91 STDCALL struct sc1 
92 mono_return_sc1 (struct sc1 a) {
93         // printf ("Got value %d\n", a.c[0]);
94         a.c[0]++;
95         return a;
96 }
97
98
99 struct sc3
100 {
101         char c[3];
102 };
103
104 STDCALL struct sc3 
105 mono_return_sc3 (struct sc3 a) {
106         // printf ("Got values %d %d %d\n", a.c[0], a.c[1], a.c[2]);
107         a.c[0]++;
108         a.c[1] += 2;
109         a.c[2] += 3;
110         return a;
111 }
112
113 struct sc5
114 {
115         char c[5];
116 };
117
118 STDCALL struct sc5 
119 mono_return_sc5 (struct sc5 a) {
120         // printf ("Got values %d %d %d %d %d\n", a.c[0], a.c[1], a.c[2], a.c[3], a.c[4]);
121         a.c[0]++;
122         a.c[1] += 2;
123         a.c[2] += 3;
124         a.c[3] += 4;
125         a.c[4] += 5;
126         return a;
127 }
128
129 union su
130 {
131         int i1;
132         int i2;
133 };
134
135 STDCALL int 
136 mono_return_int_su (union su a) {
137         // printf ("Got value %d\n", a.i1);
138         return a.i1;
139 }
140
141 STDCALL int 
142 mono_test_many_int_arguments (int a, int b, int c, int d, int e,
143                                                           int f, int g, int h, int i, int j);
144 STDCALL short 
145 mono_test_many_short_arguments (short a, short b, short c, short d, short e,
146                                                                 short f, short g, short h, short i, short j);
147 STDCALL char 
148 mono_test_many_char_arguments (char a, char b, char c, char d, char e,
149                                                            char f, char g, char h, char i, char j);
150
151 STDCALL int
152 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)
153 {
154         return a + b + c + d + e + f + g + h + i + j;
155 }
156
157 STDCALL short
158 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)
159 {
160         return a + b + c + d + e + f + g + h + i + j;
161 }
162
163 STDCALL char
164 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)
165 {
166         return a + b + c + d + e + f + g + h + i + j;
167 }
168
169 STDCALL float
170 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)
171 {
172         return a + b + c + d + e + f + g + h + i + j;
173 }
174
175 STDCALL double
176 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)
177 {
178         return a + b + c + d + e + f + g + h + i + j;
179 }
180
181 STDCALL double
182 mono_test_split_double_arguments (double a, double b, float c, double d, double e)
183 {
184         return a + b + c + d + e;
185 }
186
187 STDCALL int
188 mono_test_puts_static (char *s)
189 {
190         // printf ("TEST %s\n", s);
191         return 1;
192 }
193
194 typedef int (STDCALL *SimpleDelegate3) (int a, int b);
195
196 STDCALL int
197 mono_invoke_delegate (SimpleDelegate3 delegate)
198 {
199         int res;
200
201         // printf ("start invoke %p\n", delegate);
202
203         res = delegate (2, 3);
204
205         // printf ("end invoke\n");
206
207         return res;
208 }
209
210 STDCALL int 
211 mono_test_marshal_char (short a1)
212 {
213         if (a1 == 'a')
214                 return 0;
215         
216         return 1;
217 }
218
219 STDCALL void
220 mono_test_marshal_char_array (gunichar2 *s)
221 {
222         const char m[] = "abcdef";
223         gunichar2* s2;
224         glong len;
225
226         s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
227         
228         len = (len * 2) + 2;
229         memcpy (s, s2, len);
230
231         g_free (s2);
232 }
233
234 STDCALL int
235 mono_test_empty_pinvoke (int i)
236 {
237         return i;
238 }
239
240 STDCALL int 
241 mono_test_marshal_bool_byref (int a, int *b, int c)
242 {
243     int res = *b;
244
245         *b = 1;
246
247         return res;
248 }
249
250 STDCALL int 
251 mono_test_marshal_array (int *a1)
252 {
253         int i, sum = 0;
254
255         for (i = 0; i < 50; i++)
256                 sum += a1 [i];
257         
258         return sum;
259 }
260
261 STDCALL int 
262 mono_test_marshal_inout_array (int *a1)
263 {
264         int i, sum = 0;
265
266         for (i = 0; i < 50; i++) {
267                 sum += a1 [i];
268                 a1 [i] = 50 - a1 [i];
269         }
270         
271         return sum;
272 }
273
274 STDCALL int 
275 mono_test_marshal_inout_nonblittable_array (gunichar2 *a1)
276 {
277         int i, sum = 0;
278
279         for (i = 0; i < 10; i++) {
280                 a1 [i] = 'F';
281         }
282         
283         return sum;
284 }
285
286 typedef struct {
287         int a;
288         int b;
289         int c;
290         const char *d;
291         gunichar2 *d2;
292 } simplestruct;
293
294 STDCALL simplestruct
295 mono_test_return_vtype (int i)
296 {
297         simplestruct res;
298         static gunichar2 test2 [] = { 'T', 'E', 'S', 'T', '2', 0 };
299
300         res.a = 0;
301         res.b = 1;
302         res.c = 0;
303         res.d = "TEST";
304         res.d2 = test2;
305
306         return res;
307 }
308
309 STDCALL void
310 mono_test_delegate_struct (void)
311 {
312         // printf ("TEST\n");
313 }
314
315 typedef char* (STDCALL *ReturnStringDelegate) (const char *s);
316
317 STDCALL char *
318 mono_test_return_string (ReturnStringDelegate func)
319 {
320         char *res;
321
322         // printf ("mono_test_return_string\n");
323
324         res = func ("TEST");
325         marshal_free (res);
326
327         // printf ("got string: %s\n", res);
328         return g_strdup ("12345");
329 }
330
331 typedef int (STDCALL *RefVTypeDelegate) (int a, simplestruct *ss, int b);
332
333 STDCALL int
334 mono_test_ref_vtype (int a, simplestruct *ss, int b, RefVTypeDelegate func)
335 {
336         if (a == 1 && b == 2 && ss->a == 0 && ss->b == 1 && ss->c == 0 &&
337             !strcmp (ss->d, "TEST1")) {
338                 ss->a = 1;
339                 ss->b = 0;
340                 ss->c = 1;
341                 ss->d = "TEST2";
342         
343                 return func (a, ss, b);
344         }
345
346         return 1;
347 }
348
349 typedef int (STDCALL *OutVTypeDelegate) (int a, simplestruct *ss, int b);
350
351 STDCALL int
352 mono_test_marshal_out_struct (int a, simplestruct *ss, int b, OutVTypeDelegate func)
353 {
354         /* Check that the input pointer is ignored */
355         ss->d = (gpointer)0x12345678;
356
357         func (a, ss, b);
358
359         if (ss->a && ss->b && ss->c && !strcmp (ss->d, "TEST3"))
360                 return 0;
361         else
362                 return 1;
363 }
364
365 typedef struct {
366         int a;
367         SimpleDelegate func, func2;
368 } DelegateStruct;
369
370 STDCALL DelegateStruct
371 mono_test_marshal_delegate_struct (DelegateStruct ds)
372 {
373         DelegateStruct res;
374
375         res.a = ds.func (ds.a) + ds.func2 (ds.a);
376         res.func = ds.func;
377         res.func2 = ds.func2;
378
379         return res;
380 }
381
382 STDCALL int 
383 mono_test_marshal_struct (simplestruct ss)
384 {
385         if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
386             !strcmp (ss.d, "TEST"))
387                 return 0;
388
389         return 1;
390 }
391
392 typedef struct {
393         int a;
394         int b;
395         int c;
396         char *d;
397         unsigned char e;
398         double f;
399         unsigned char g;
400         guint64 h;
401 } simplestruct2;
402
403 STDCALL int
404 mono_test_marshal_struct2 (simplestruct2 ss)
405 {
406         if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
407             !strcmp (ss.d, "TEST") && 
408             ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
409                 return 0;
410
411         return 1;
412 }
413
414 /* on HP some of the struct should be on the stack and not in registers */
415 STDCALL int
416 mono_test_marshal_struct2_2 (int i, int j, int k, simplestruct2 ss)
417 {
418         if (i != 10 || j != 11 || k != 12)
419                 return 1;
420         if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
421             !strcmp (ss.d, "TEST") && 
422             ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
423                 return 0;
424
425         return 1;
426 }
427
428 STDCALL int
429 mono_test_marshal_struct_array (simplestruct2 *ss)
430 {
431         if (! (ss[0].a == 0 && ss[0].b == 1 && ss[0].c == 0 &&
432                    !strcmp (ss[0].d, "TEST") && 
433                    ss[0].e == 99 && ss[0].f == 1.5 && ss[0].g == 42 && ss[0].h == (guint64)123))
434                 return 1;
435
436         if (! (ss[1].a == 0 && ss[1].b == 0 && ss[1].c == 0 &&
437                    !strcmp (ss[1].d, "TEST2") && 
438                    ss[1].e == 100 && ss[1].f == 2.5 && ss[1].g == 43 && ss[1].h == (guint64)124))
439                 return 1;
440
441         return 0;
442 }
443
444 typedef struct long_align_struct {
445         gint32 a;
446         gint64 b;
447         gint64 c;
448 } long_align_struct;
449
450 STDCALL int
451 mono_test_marshal_long_align_struct_array (long_align_struct *ss)
452 {
453         return ss[0].a + ss[0].b + ss[0].c + ss[1].a + ss[1].b + ss[1].c;
454 }
455
456 STDCALL simplestruct2 *
457 mono_test_marshal_class (int i, int j, int k, simplestruct2 *ss, int l)
458 {
459         simplestruct2 *res;
460
461         if (!ss)
462                 return NULL;
463
464         if (i != 10 || j != 11 || k != 12 || l != 14)
465                 return NULL;
466         if (! (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
467                    !strcmp (ss->d, "TEST") && 
468                    ss->e == 99 && ss->f == 1.5 && ss->g == 42 && ss->h == (guint64)123))
469                 return NULL;
470
471         res = g_new0 (simplestruct2, 1);
472         memcpy (res, ss, sizeof (simplestruct2));
473         res->d = g_strdup ("TEST");
474         return res;
475 }
476
477 STDCALL int
478 mono_test_marshal_byref_class (simplestruct2 **ssp)
479 {
480         simplestruct2 *ss = *ssp;
481         simplestruct2 *res;
482         
483         if (! (ss->a == 0 && ss->b == 1 && ss->c == 0 &&
484                    !strcmp (ss->d, "TEST") && 
485                    ss->e == 99 && ss->f == 1.5 && ss->g == 42 && ss->h == (guint64)123))
486                 return 1;
487
488         res = g_new0 (simplestruct2, 1);
489         memcpy (res, ss, sizeof (simplestruct2));
490         res->d = g_strdup ("TEST-RES");
491
492         *ssp = res;
493         return 0;
494 }
495
496 static void *
497 get_sp (void)
498 {
499         int i;
500         void *p;
501
502         p = &i;
503         return p;
504 }
505
506 STDCALL int
507 reliable_delegate (int a)
508 {
509         return a;
510 }
511
512 /*
513  * Checks whether get_sp() works as expected. It doesn't work with gcc-2.95.3 on linux.
514  */
515 static gboolean
516 is_get_sp_reliable (void)
517 {
518         void *sp1, *sp2;
519
520         reliable_delegate(1);
521         sp1 = get_sp();
522         reliable_delegate(1);
523         sp2 = get_sp();
524         return sp1 == sp2;
525
526
527 STDCALL int
528 mono_test_marshal_delegate (SimpleDelegate delegate)
529 {
530         void *sp1, *sp2;
531
532         /* Check that the delegate wrapper is stdcall */
533         delegate (2);
534         sp1 = get_sp ();
535         delegate (2);
536         sp2 = get_sp ();
537         if (is_get_sp_reliable())
538                 g_assert (sp1 == sp2);
539
540         return delegate (2);
541 }
542
543 STDCALL SimpleDelegate
544 mono_test_marshal_return_delegate (SimpleDelegate delegate)
545 {
546         return delegate;
547 }
548
549 static STDCALL int
550 return_plus_one (int i)
551 {
552         return i + 1;
553 }
554
555 STDCALL SimpleDelegate
556 mono_test_marshal_return_delegate_2 ()
557 {
558         return return_plus_one;
559 }
560
561 typedef simplestruct (STDCALL *SimpleDelegate2) (simplestruct ss);
562
563 static gboolean
564 is_utf16_equals (gunichar2 *s1, const char *s2)
565 {
566         char *s;
567         int res;
568
569         s = g_utf16_to_utf8 (s1, -1, NULL, NULL, NULL);
570         res = strcmp (s, s2);
571         g_free (s);
572
573         return res == 0;
574 }
575
576 STDCALL int
577 mono_test_marshal_delegate2 (SimpleDelegate2 delegate)
578 {
579         simplestruct ss, res;
580
581         ss.a = 0;
582         ss.b = 1;
583         ss.c = 0;
584         ss.d = "TEST";
585         ss.d2 = g_utf8_to_utf16 ("TEST2", -1, NULL, NULL, NULL); 
586
587         res = delegate (ss);
588         if (! (res.a && !res.b && res.c && !strcmp (res.d, "TEST-RES") && is_utf16_equals (res.d2, "TEST2-RES")))
589                 return 1;
590
591         return 0;
592 }
593
594 typedef simplestruct* (STDCALL *SimpleDelegate4) (simplestruct *ss);
595
596 STDCALL int
597 mono_test_marshal_delegate4 (SimpleDelegate4 delegate)
598 {
599         simplestruct ss;
600         simplestruct *res;
601
602         ss.a = 0;
603         ss.b = 1;
604         ss.c = 0;
605         ss.d = "TEST";
606
607         /* Check argument */
608         res = delegate (&ss);
609         if (!res)
610                 return 1;
611
612         /* Check return value */
613         if (! (!res->a && res->b && !res->c && !strcmp (res->d, "TEST")))
614                 return 2;
615
616         /* Check NULL argument and NULL result */
617         res = delegate (NULL);
618         if (res)
619                 return 3;
620
621         return 0;
622 }
623
624 typedef int (STDCALL *SimpleDelegate5) (simplestruct **ss);
625
626 STDCALL int
627 mono_test_marshal_delegate5 (SimpleDelegate5 delegate)
628 {
629         simplestruct ss;
630         int res;
631         simplestruct *ptr;
632
633         ss.a = 0;
634         ss.b = 1;
635         ss.c = 0;
636         ss.d = "TEST";
637
638         ptr = &ss;
639
640         res = delegate (&ptr);
641         if (res != 0)
642                 return 1;
643
644         if (!(ptr->a && !ptr->b && ptr->c && !strcmp (ptr->d, "RES")))
645                 return 2;
646
647         return 0;
648 }
649
650 STDCALL int
651 mono_test_marshal_delegate6 (SimpleDelegate5 delegate)
652 {
653         int res;
654
655         res = delegate (NULL);
656
657         return 0;
658 }
659
660 typedef int (STDCALL *SimpleDelegate7) (simplestruct **ss);
661
662 STDCALL int
663 mono_test_marshal_delegate7 (SimpleDelegate7 delegate)
664 {
665         int res;
666         simplestruct *ptr;
667
668         /* Check that the input pointer is ignored */
669         ptr = (gpointer)0x12345678;
670
671         res = delegate (&ptr);
672         if (res != 0)
673                 return 1;
674
675         if (!(ptr->a && !ptr->b && ptr->c && !strcmp (ptr->d, "RES")))
676                 return 2;
677
678         return 0;
679 }
680
681 typedef int (STDCALL *SimpleDelegate8) (gunichar2 *s);
682
683 STDCALL int
684 mono_test_marshal_delegate8 (SimpleDelegate8 delegate, gunichar2 *s)
685 {
686         return delegate (s);
687 }
688
689 typedef int (STDCALL *return_int_fnt) (int i);
690 typedef int (STDCALL *SimpleDelegate9) (return_int_fnt d);
691
692 STDCALL int
693 mono_test_marshal_delegate9 (SimpleDelegate9 delegate, gpointer ftn)
694 {
695         return delegate (ftn);
696 }
697
698 STDCALL static int
699 return_self (int i)
700 {
701         return i;
702 }
703
704 STDCALL int
705 mono_test_marshal_delegate10 (SimpleDelegate9 delegate)
706 {
707         return delegate (return_self);
708 }
709
710 typedef int (STDCALL *PrimitiveByrefDelegate) (int *i);
711
712 STDCALL int
713 mono_test_marshal_primitive_byref_delegate (PrimitiveByrefDelegate delegate)
714 {
715         int i = 1;
716
717         int res = delegate (&i);
718         if (res != 0)
719                 return res;
720
721         if (i != 2)
722                 return 2;
723
724         return 0;
725 }
726
727 typedef int (STDCALL *return_int_delegate) (int i);
728
729 typedef return_int_delegate (STDCALL *ReturnDelegateDelegate) (void);
730
731 STDCALL int
732 mono_test_marshal_return_delegate_delegate (ReturnDelegateDelegate d)
733 {
734         return (d ()) (55);
735 }
736
737 STDCALL int 
738 mono_test_marshal_stringbuilder (char *s, int n)
739 {
740         const char m[] = "This is my message.  Isn't it nice?";
741
742         if (strcmp (s, "ABCD") != 0)
743                 return 1;
744         strncpy(s, m, n);
745         return 0;
746 }
747
748 STDCALL int 
749 mono_test_marshal_stringbuilder_unicode (gunichar2 *s, int n)
750 {
751         const char m[] = "This is my message.  Isn't it nice?";
752         gunichar2* s2;
753         glong len;
754
755         s2 = g_utf8_to_utf16 (m, -1, NULL, &len, NULL);
756         
757         len = (len * 2) + 2;
758         if (len > n)
759                 len = n;
760         memcpy (s, s2, len);
761
762         g_free (s2);
763
764         return 0;
765 }
766
767 typedef struct {
768 #ifndef __GNUC__
769     char a;
770 #endif
771 } EmptyStruct;
772
773 STDCALL int
774 mono_test_marshal_empty_string_array (char **array)
775 {
776         return (array == NULL) ? 0 : 1;
777 }
778
779 STDCALL int
780 mono_test_marshal_string_array (char **array)
781 {
782         if (strcmp (array [0], "ABC"))
783                 return 1;
784         if (strcmp (array [1], "DEF"))
785                 return 2;
786
787         if (array [2] != NULL)
788                 return 3;
789
790         return 0;
791 }
792
793 STDCALL int
794 mono_test_marshal_byref_string_array (char ***array)
795 {
796         if (*array == NULL)
797                 return 0;
798
799         if (strcmp ((*array) [0], "Alpha"))
800                 return 2;
801         if (strcmp ((*array) [1], "Beta"))
802                 return 2;
803         if (strcmp ((*array) [2], "Gamma"))
804                 return 2;
805
806         return 1;
807 }
808
809 STDCALL int
810 mono_test_marshal_stringbuilder_array (char **array)
811 {
812         if (strcmp (array [0], "ABC"))
813                 return 1;
814         if (strcmp (array [1], "DEF"))
815                 return 2;
816
817         strcpy (array [0], "DEF");
818         strcpy (array [1], "ABC");
819
820         return 0;
821 }
822
823 STDCALL int
824 mono_test_marshal_unicode_string_array (gunichar2 **array, char **array2)
825 {
826         GError *error = NULL;
827         char *s;
828         
829         s = g_utf16_to_utf8 (array [0], -1, NULL, NULL, &error);
830         if (strcmp (s, "ABC")) {
831                 g_free (s);
832                 return 1;
833         }
834         else
835                 g_free (s);
836
837         s = g_utf16_to_utf8 (array [1], -1, NULL, NULL, &error);
838         if (strcmp (s, "DEF")) {
839                 g_free (s);
840                 return 2;
841         }
842         else
843                 g_free (s);
844
845         if (strcmp (array2 [0], "ABC"))
846                 return 3;
847
848         if (strcmp (array2 [1], "DEF")) 
849                 return 4;
850
851         return 0;
852 }
853
854 /* this does not work on Redhat gcc 2.96 */
855 STDCALL int 
856 mono_test_empty_struct (int a, EmptyStruct es, int b)
857 {
858         // printf ("mono_test_empty_struct %d %d\n", a, b);
859
860         if (a == 1 && b == 2)
861                 return 0;
862         return 1;
863 }
864
865 typedef struct {
866        char a[100];
867 } ByValStrStruct;
868
869 STDCALL ByValStrStruct *
870 mono_test_byvalstr_gen (void)
871 {
872         ByValStrStruct *ret;
873        
874         ret = malloc(sizeof(ByValStrStruct));
875         memset(ret, 'a', sizeof(ByValStrStruct)-1);
876         ret->a[sizeof(ByValStrStruct)-1] = 0;
877
878         return ret;
879 }
880
881 STDCALL int
882 mono_test_byvalstr_check (ByValStrStruct* data, char* correctString)
883 {
884         int ret;
885
886         ret = strcmp(data->a, correctString);
887         // printf ("T1: %s\n", data->a);
888         // printf ("T2: %s\n", correctString);
889
890         marshal_free (data);
891         return (ret != 0);
892 }
893
894 STDCALL int
895 NameManglingAnsi (char *data)
896 {
897         return data [0] + data [1] + data [2];
898 }
899
900 STDCALL int
901 NameManglingAnsiA (char *data)
902 {
903         g_assert_not_reached ();
904 }
905
906 STDCALL int
907 NameManglingAnsiW (char *data)
908 {
909         g_assert_not_reached ();
910 }
911
912 STDCALL int
913 NameManglingAnsi2A (char *data)
914 {
915         return data [0] + data [1] + data [2];
916 }
917
918 STDCALL int
919 NameManglingAnsi2W (char *data)
920 {
921         g_assert_not_reached ();
922 }
923
924 STDCALL int
925 NameManglingUnicode (char *data)
926 {
927         g_assert_not_reached ();
928 }
929
930 STDCALL int
931 NameManglingUnicodeW (gunichar2 *data)
932 {
933         return data [0] + data [1] + data [2];
934 }
935
936 STDCALL int
937 NameManglingUnicode2 (gunichar2 *data)
938 {
939         return data [0] + data [1] + data [2];
940 }
941
942 STDCALL int
943 NameManglingAutoW (char *data)
944 {
945 #ifdef WIN32
946         return (data [0] + data [1] + data [2]) == 131 ? 0 : 1;
947 #else
948         g_assert_not_reached ();
949 #endif
950 }
951
952 STDCALL int
953 NameManglingAuto (char *data)
954 {
955 #ifndef WIN32
956         return (data [0] + data [1] + data [2]) == 198 ? 0 : 1;
957 #else
958         g_assert_not_reached ();
959 #endif
960 }
961
962 typedef int (STDCALL *intcharFunc)(const char*);
963
964 STDCALL void 
965 callFunction (intcharFunc f)
966 {
967         f ("ABC");
968 }
969
970 typedef struct {
971         const char* str;
972         int i;
973 } SimpleObj;
974
975 STDCALL int
976 class_marshal_test0 (SimpleObj *obj1)
977 {
978         // printf ("class_marshal_test0 %s %d\n", obj1->str, obj1->i);
979
980         if (strcmp(obj1->str, "T1"))
981                 return -1;
982         if (obj1->i != 4)
983                 return -2;
984
985         return 0;
986 }
987
988 STDCALL int
989 class_marshal_test4 (SimpleObj *obj1)
990 {
991         if (obj1)
992                 return -1;
993
994         return 0;
995 }
996
997 STDCALL void
998 class_marshal_test1 (SimpleObj **obj1)
999 {
1000         SimpleObj *res = malloc (sizeof (SimpleObj));
1001
1002         res->str = g_strdup ("ABC");
1003         res->i = 5;
1004
1005         *obj1 = res;
1006 }
1007
1008 STDCALL int
1009 class_marshal_test2 (SimpleObj **obj1)
1010 {
1011         // printf ("class_marshal_test2 %s %d\n", (*obj1)->str, (*obj1)->i);
1012
1013         if (strcmp((*obj1)->str, "ABC"))
1014                 return -1;
1015         if ((*obj1)->i != 5)
1016                 return -2;
1017
1018         return 0;
1019 }
1020
1021 STDCALL int
1022 string_marshal_test0 (char *str)
1023 {
1024         if (strcmp (str, "TEST0"))
1025                 return -1;
1026
1027         return 0;
1028 }
1029
1030 STDCALL void
1031 string_marshal_test1 (const char **str)
1032 {
1033         *str = "TEST1";
1034 }
1035
1036 STDCALL int
1037 string_marshal_test2 (char **str)
1038 {
1039         // printf ("string_marshal_test2 %s\n", *str);
1040
1041         if (strcmp (*str, "TEST1"))
1042                 return -1;
1043
1044         return 0;
1045 }
1046
1047 STDCALL int
1048 string_marshal_test3 (char *str)
1049 {
1050         if (str)
1051                 return -1;
1052
1053         return 0;
1054 }
1055
1056 typedef struct {
1057         int a;
1058         int b;
1059 } VectorList;
1060
1061 STDCALL VectorList* 
1062 TestVectorList (VectorList *vl)
1063 {
1064         VectorList *res;
1065
1066         // printf ("TestVectorList %d %d\n", vl->a, vl->b);
1067
1068         vl->a++;
1069         vl->b++;
1070
1071         res = g_new0 (VectorList, 1);
1072         memcpy (res, vl, sizeof (VectorList));
1073
1074         return res;
1075 }
1076
1077 typedef struct _OSVERSIONINFO
1078
1079         int a; 
1080         int b; 
1081 } OSVERSIONINFO; 
1082
1083 STDCALL int 
1084 GetVersionEx (OSVERSIONINFO *osvi)
1085 {
1086
1087         // printf ("GOT %d %d\n", osvi->a, osvi->b);
1088
1089         osvi->a += 1;
1090         osvi->b += 1;
1091
1092         return osvi->a + osvi->b;
1093 }
1094
1095 STDCALL int 
1096 BugGetVersionEx (int a, int b, int c, int d, int e, int f, int g, int h, OSVERSIONINFO *osvi)
1097 {
1098
1099         // printf ("GOT %d %d\n", osvi->a, osvi->b);
1100
1101         osvi->a += 1;
1102         osvi->b += 1;
1103
1104         return osvi->a + osvi->b;
1105 }
1106
1107 typedef struct {
1108         double x;
1109         double y;
1110 } point;
1111
1112 STDCALL int
1113 mono_test_marshal_point (point pt)
1114 {
1115         // printf("point %g %g\n", pt.x, pt.y);
1116         if (pt.x == 1.25 && pt.y == 3.5)
1117                 return 0;
1118
1119         return 1;
1120 }
1121
1122 typedef struct {
1123         int x;
1124         double y;
1125 } mixed_point;
1126
1127 STDCALL int
1128 mono_test_marshal_mixed_point (mixed_point pt)
1129 {
1130         // printf("mixed point %d %g\n", pt.x, pt.y);
1131         if (pt.x == 5 && pt.y == 6.75)
1132                 return 0;
1133
1134         return 1;
1135 }
1136
1137 STDCALL int
1138 mono_test_marshal_mixed_point_2 (mixed_point *pt)
1139 {
1140         if (pt->x != 5 || pt->y != 6.75)
1141                 return 1;
1142
1143         pt->x = 10;
1144         pt->y = 12.35;
1145
1146         return 0;
1147 }
1148
1149 STDCALL int 
1150 marshal_test_ref_bool(int i, char *b1, short *b2, int *b3)
1151 {
1152     int res = 1;
1153     if (*b1 != 0 && *b1 != 1)
1154         return 1;
1155     if (*b2 != 0 && *b2 != -1) /* variant_bool */
1156         return 1;
1157     if (*b3 != 0 && *b3 != 1)
1158         return 1;
1159     if (i == ((*b1 << 2) | (-*b2 << 1) | *b3))
1160         res = 0;
1161     *b1 = !*b1;
1162     *b2 = ~*b2;
1163     *b3 = !*b3;
1164     return res;
1165 }
1166
1167 struct BoolStruct
1168 {
1169     int i;
1170     char b1;
1171     short b2; /* variant_bool */
1172     int b3;
1173 };
1174
1175 STDCALL int 
1176 marshal_test_bool_struct(struct BoolStruct *s)
1177 {
1178     int res = 1;
1179     if (s->b1 != 0 && s->b1 != 1)
1180         return 1;
1181     if (s->b2 != 0 && s->b2 != -1)
1182         return 1;
1183     if (s->b3 != 0 && s->b3 != 1)
1184         return 1;
1185     if (s->i == ((s->b1 << 2) | (-s->b2 << 1) | s->b3))
1186         res = 0;
1187     s->b1 = !s->b1;
1188     s->b2 = ~s->b2;
1189     s->b3 = !s->b3;
1190     return res;
1191 }
1192
1193 #ifdef WIN32
1194 extern __declspec(dllimport) __stdcall void SetLastError(int x);
1195 #endif
1196
1197 STDCALL void
1198 mono_test_last_error (int err)
1199 {
1200 #ifdef WIN32
1201         SetLastError (err);
1202 #else
1203         errno = err;
1204 #endif
1205 }
1206
1207 STDCALL int
1208 mono_test_asany (void *ptr, int what)
1209 {
1210         switch (what) {
1211         case 1:
1212                 return (*(int*)ptr == 5) ? 0 : 1;
1213         case 2:
1214                 return strcmp (ptr, "ABC") == 0 ? 0 : 1;
1215         case 3: {
1216                 simplestruct2 ss = *(simplestruct2*)ptr;
1217
1218                 if (ss.a == 0 && ss.b == 1 && ss.c == 0 &&
1219             !strcmp (ss.d, "TEST") && 
1220             ss.e == 99 && ss.f == 1.5 && ss.g == 42 && ss.h == (guint64)123)
1221                         return 0;
1222                 else
1223                         return 1;
1224         }
1225         case 4: {
1226                 GError *error = NULL;
1227                 char *s;
1228
1229                 s = g_utf16_to_utf8 (ptr, -1, NULL, NULL, &error);
1230                 if (!strcmp (s, "ABC")) {
1231                         g_free (s);
1232                         return 0;
1233                 }
1234                 else {
1235                         g_free (s);
1236                         return 1;
1237                 }
1238         }
1239         default:
1240                 g_assert_not_reached ();
1241         }
1242
1243         return 1;
1244 }
1245
1246 /*
1247  * AMD64 marshalling tests.
1248  */
1249
1250 typedef struct amd64_struct1 {
1251         int i;
1252         int j;
1253         int k;
1254         int l;
1255 } amd64_struct1;
1256
1257 STDCALL amd64_struct1
1258 mono_test_marshal_amd64_pass_return_struct1 (amd64_struct1 s)
1259 {
1260         s.i ++;
1261         s.j ++;
1262         s.k ++;
1263         s.l ++;
1264
1265         return s;
1266 }
1267
1268 typedef struct amd64_struct2 {
1269         int i;
1270         int j;
1271 } amd64_struct2;
1272
1273 STDCALL amd64_struct2
1274 mono_test_marshal_amd64_pass_return_struct2 (amd64_struct2 s)
1275 {
1276         s.i ++;
1277         s.j ++;
1278
1279         return s;
1280 }
1281
1282 typedef struct amd64_struct3 {
1283         int i;
1284 } amd64_struct3;
1285
1286 STDCALL amd64_struct3
1287 mono_test_marshal_amd64_pass_return_struct3 (amd64_struct3 s)
1288 {
1289         s.i ++;
1290
1291         return s;
1292 }
1293
1294 typedef struct amd64_struct4 {
1295         double d1, d2;
1296 } amd64_struct4;
1297
1298 STDCALL amd64_struct4
1299 mono_test_marshal_amd64_pass_return_struct4 (amd64_struct4 s)
1300 {
1301         s.d1 ++;
1302         s.d2 ++;
1303
1304         return s;
1305 }
1306
1307 static guint32 custom_res [2];
1308
1309 STDCALL void*
1310 mono_test_marshal_pass_return_custom (int i, guint32 *ptr, int j)
1311 {
1312         /* ptr will be freed by CleanupNative, so make a copy */
1313         custom_res [0] = 0; /* not allocated by AllocHGlobal */
1314         custom_res [1] = ptr [1];
1315
1316         return &custom_res;
1317 }
1318
1319 typedef void *(STDCALL *PassReturnPtrDelegate) (void *ptr);
1320
1321 STDCALL int
1322 mono_test_marshal_pass_return_custom_in_delegate (PassReturnPtrDelegate del)
1323 {
1324         guint32 buf [2];
1325         guint32 res;
1326         guint32 *ptr;
1327
1328         buf [0] = 0;
1329         buf [1] = 10;
1330
1331         ptr = del (&buf);
1332
1333         res = ptr [1];
1334
1335 #ifdef WIN32
1336         /* FIXME: Freed with FreeHGlobal */
1337 #else
1338         g_free (ptr);
1339 #endif
1340
1341         return res;
1342 }
1343
1344 typedef int (STDCALL *ReturnEnumDelegate) (int e);
1345
1346 STDCALL int
1347 mono_test_marshal_return_enum_delegate (ReturnEnumDelegate func)
1348 {
1349         return func (1);
1350 }
1351
1352 typedef struct {
1353         int a, b, c;
1354         gint64 d;
1355 } BlittableStruct;
1356         
1357 typedef BlittableStruct (STDCALL *SimpleDelegate10) (BlittableStruct ss);
1358
1359 STDCALL int
1360 mono_test_marshal_blittable_struct_delegate (SimpleDelegate10 delegate)
1361 {
1362         BlittableStruct ss, res;
1363
1364         ss.a = 1;
1365         ss.b = 2;
1366         ss.c = 3;
1367         ss.d = 55;
1368
1369         res = delegate (ss);
1370         if (! ((res.a == -1) && (res.b == -2) && (res.c == -3) && (res.d == -55)))
1371                 return 1;
1372
1373         return 0;
1374 }
1375
1376 STDCALL int
1377 mono_test_stdcall_name_mangling (int a, int b, int c)
1378 {
1379         return a + b + c;
1380 }
1381
1382 /*
1383  * PASSING AND RETURNING SMALL STRUCTURES FROM DELEGATES TESTS
1384  */
1385
1386 typedef struct {
1387         int i;
1388 } SmallStruct1;
1389         
1390 typedef SmallStruct1 (STDCALL *SmallStructDelegate1) (SmallStruct1 ss);
1391
1392 STDCALL int
1393 mono_test_marshal_small_struct_delegate1 (SmallStructDelegate1 delegate)
1394 {
1395         SmallStruct1 ss, res;
1396
1397         ss.i = 1;
1398
1399         res = delegate (ss);
1400         if (! (res.i == -1))
1401                 return 1;
1402
1403         return 0;
1404 }
1405
1406 typedef struct {
1407         gint16 i, j;
1408 } SmallStruct2;
1409         
1410 typedef SmallStruct2 (STDCALL *SmallStructDelegate2) (SmallStruct2 ss);
1411
1412 STDCALL int
1413 mono_test_marshal_small_struct_delegate2 (SmallStructDelegate2 delegate)
1414 {
1415         SmallStruct2 ss, res;
1416
1417         ss.i = 2;
1418         ss.j = 3;
1419
1420         res = delegate (ss);
1421         if (! ((res.i == -2) && (res.j == -3)))
1422                 return 1;
1423
1424         return 0;
1425 }
1426
1427 typedef struct {
1428         gint16 i;
1429         gint8 j;
1430 } SmallStruct3;
1431         
1432 typedef SmallStruct3 (STDCALL *SmallStructDelegate3) (SmallStruct3 ss);
1433
1434 STDCALL int
1435 mono_test_marshal_small_struct_delegate3 (SmallStructDelegate3 delegate)
1436 {
1437         SmallStruct3 ss, res;
1438
1439         ss.i = 1;
1440         ss.j = 2;
1441
1442         res = delegate (ss);
1443         if (! ((res.i == -1) && (res.j == -2)))
1444                 return 1;
1445
1446         return 0;
1447 }
1448
1449 typedef struct {
1450         gint16 i;
1451 } SmallStruct4;
1452         
1453 typedef SmallStruct4 (STDCALL *SmallStructDelegate4) (SmallStruct4 ss);
1454
1455 STDCALL int
1456 mono_test_marshal_small_struct_delegate4 (SmallStructDelegate4 delegate)
1457 {
1458         SmallStruct4 ss, res;
1459
1460         ss.i = 1;
1461
1462         res = delegate (ss);
1463         if (! (res.i == -1))
1464                 return 1;
1465
1466         return 0;
1467 }
1468
1469 typedef struct {
1470         gint64 i;
1471 } SmallStruct5;
1472         
1473 typedef SmallStruct5 (STDCALL *SmallStructDelegate5) (SmallStruct5 ss);
1474
1475 STDCALL int
1476 mono_test_marshal_small_struct_delegate5 (SmallStructDelegate5 delegate)
1477 {
1478         SmallStruct5 ss, res;
1479
1480         ss.i = 5;
1481
1482         res = delegate (ss);
1483         if (! (res.i == -5))
1484                 return 1;
1485
1486         return 0;
1487 }
1488
1489 typedef struct {
1490         int i, j;
1491 } SmallStruct6;
1492         
1493 typedef SmallStruct6 (STDCALL *SmallStructDelegate6) (SmallStruct6 ss);
1494
1495 STDCALL int
1496 mono_test_marshal_small_struct_delegate6 (SmallStructDelegate6 delegate)
1497 {
1498         SmallStruct6 ss, res;
1499
1500         ss.i = 1;
1501         ss.j = 2;
1502
1503         res = delegate (ss);
1504         if (! ((res.i == -1) && (res.j == -2)))
1505                 return 1;
1506
1507         return 0;
1508 }
1509
1510 typedef struct {
1511         int i;
1512         gint16 j;
1513 } SmallStruct7;
1514         
1515 typedef SmallStruct7 (STDCALL *SmallStructDelegate7) (SmallStruct7 ss);
1516
1517 STDCALL int
1518 mono_test_marshal_small_struct_delegate7 (SmallStructDelegate7 delegate)
1519 {
1520         SmallStruct7 ss, res;
1521
1522         ss.i = 1;
1523         ss.j = 2;
1524
1525         res = delegate (ss);
1526         if (! ((res.i == -1) && (res.j == -2)))
1527                 return 1;
1528
1529         return 0;
1530 }
1531
1532 typedef struct {
1533         float i;
1534 } SmallStruct8;
1535         
1536 typedef SmallStruct8 (STDCALL *SmallStructDelegate8) (SmallStruct8 ss);
1537
1538 STDCALL int
1539 mono_test_marshal_small_struct_delegate8 (SmallStructDelegate8 delegate)
1540 {
1541         SmallStruct8 ss, res;
1542
1543         ss.i = 1.0;
1544
1545         res = delegate (ss);
1546         if (! ((res.i == -1.0)))
1547                 return 1;
1548
1549         return 0;
1550 }
1551
1552 typedef struct {
1553         double i;
1554 } SmallStruct9;
1555         
1556 typedef SmallStruct9 (STDCALL *SmallStructDelegate9) (SmallStruct9 ss);
1557
1558 STDCALL int
1559 mono_test_marshal_small_struct_delegate9 (SmallStructDelegate9 delegate)
1560 {
1561         SmallStruct9 ss, res;
1562
1563         ss.i = 1.0;
1564
1565         res = delegate (ss);
1566         if (! ((res.i == -1.0)))
1567                 return 1;
1568
1569         return 0;
1570 }
1571
1572 typedef struct {
1573         float i, j;
1574 } SmallStruct10;
1575         
1576 typedef SmallStruct10 (STDCALL *SmallStructDelegate10) (SmallStruct10 ss);
1577
1578 STDCALL int
1579 mono_test_marshal_small_struct_delegate10 (SmallStructDelegate10 delegate)
1580 {
1581         SmallStruct10 ss, res;
1582
1583         ss.i = 1.0;
1584         ss.j = 2.0;
1585
1586         res = delegate (ss);
1587         if (! ((res.i == -1.0) && (res.j == -2.0)))
1588                 return 1;
1589
1590         return 0;
1591 }
1592
1593 typedef struct {
1594         float i;
1595         int j;
1596 } SmallStruct11;
1597         
1598 typedef SmallStruct11 (STDCALL *SmallStructDelegate11) (SmallStruct11 ss);
1599
1600 STDCALL int
1601 mono_test_marshal_small_struct_delegate11 (SmallStructDelegate11 delegate)
1602 {
1603         SmallStruct11 ss, res;
1604
1605         ss.i = 1.0;
1606         ss.j = 2;
1607
1608         res = delegate (ss);
1609         if (! ((res.i == -1.0) && (res.j == -2)))
1610                 return 1;
1611
1612         return 0;
1613 }
1614
1615 typedef int (STDCALL *ArrayDelegate) (int i, char *j, void *arr);
1616
1617 STDCALL int
1618 mono_test_marshal_array_delegate (void *arr, int len, ArrayDelegate del)
1619 {
1620         return del (len, NULL, arr);
1621 }
1622
1623 typedef int (*CdeclDelegate) (int i, int j);
1624
1625 STDCALL int
1626 mono_test_marshal_cdecl_delegate (CdeclDelegate del)
1627 {
1628         int i;
1629
1630         for (i = 0; i < 1000; ++i)
1631                 del (1, 2);
1632
1633         return 0;
1634 }