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