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