2005-06-29 Miguel de Icaza <miguel@ximian.com>
[mono.git] / mono / metadata / icall.c
1 /*
2  * icall.c:
3  *
4  * Authors:
5  *   Dietmar Maurer (dietmar@ximian.com)
6  *   Paolo Molaro (lupus@ximian.com)
7  *       Patrik Torstensson (patrik.torstensson@labs2.com)
8  *
9  * (C) 2001 Ximian, Inc.
10  */
11
12 #include <config.h>
13 #include <glib.h>
14 #include <stdarg.h>
15 #include <string.h>
16 #include <ctype.h>
17 #include <sys/time.h>
18 #include <unistd.h>
19 #if defined (PLATFORM_WIN32)
20 #include <stdlib.h>
21 #endif
22
23 #include <mono/metadata/object.h>
24 #include <mono/metadata/threads.h>
25 #include <mono/metadata/threads-types.h>
26 #include <mono/metadata/threadpool.h>
27 #include <mono/metadata/monitor.h>
28 #include <mono/metadata/reflection.h>
29 #include <mono/metadata/assembly.h>
30 #include <mono/metadata/tabledefs.h>
31 #include <mono/metadata/exception.h>
32 #include <mono/metadata/file-io.h>
33 #include <mono/metadata/console-io.h>
34 #include <mono/metadata/socket-io.h>
35 #include <mono/metadata/mono-endian.h>
36 #include <mono/metadata/tokentype.h>
37 #include <mono/metadata/unicode.h>
38 #include <mono/metadata/domain-internals.h>
39 #include <mono/metadata/metadata-internals.h>
40 #include <mono/metadata/class-internals.h>
41 #include <mono/metadata/marshal.h>
42 #include <mono/metadata/gc-internal.h>
43 #include <mono/metadata/rand.h>
44 #include <mono/metadata/sysmath.h>
45 #include <mono/metadata/string-icalls.h>
46 #include <mono/metadata/mono-debug-debugger.h>
47 #include <mono/metadata/process.h>
48 #include <mono/metadata/environment.h>
49 #include <mono/metadata/profiler-private.h>
50 #include <mono/metadata/locales.h>
51 #include <mono/metadata/filewatcher.h>
52 #include <mono/metadata/char-conversions.h>
53 #include <mono/metadata/security.h>
54 #include <mono/metadata/mono-config.h>
55 #include <mono/metadata/cil-coff.h>
56 #include <mono/metadata/security-manager.h>
57 #include <mono/io-layer/io-layer.h>
58 #include <mono/utils/strtod.h>
59 #include <mono/utils/monobitset.h>
60
61 #if defined (PLATFORM_WIN32)
62 #include <windows.h>
63 #include <shlobj.h>
64 #endif
65 #include "decimal.h"
66
67 static MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void);
68
69
70 /*
71  * We expect a pointer to a char, not a string
72  */
73 static double
74 mono_double_ParseImpl (char *ptr)
75 {
76         gchar *endptr = NULL;
77         gdouble result = 0.0;
78
79         MONO_ARCH_SAVE_REGS;
80
81         if (*ptr)
82                 result = bsd_strtod (ptr, &endptr);
83
84         if (!*ptr || (endptr && *endptr))
85                 mono_raise_exception (mono_exception_from_name (mono_get_corlib (),
86                                                                 "System",
87                                                                 "FormatException"));
88         
89         return result;
90 }
91
92 static void
93 ves_icall_System_Double_AssertEndianity (double *value)
94 {
95         MONO_ARCH_SAVE_REGS;
96
97         MONO_DOUBLE_ASSERT_ENDIANITY (value);
98 }
99
100 static MonoObject *
101 ves_icall_System_Array_GetValueImpl (MonoObject *this, guint32 pos)
102 {
103         MonoClass *ac;
104         MonoArray *ao;
105         gint32 esize;
106         gpointer *ea;
107
108         MONO_ARCH_SAVE_REGS;
109
110         ao = (MonoArray *)this;
111         ac = (MonoClass *)ao->obj.vtable->klass;
112
113         esize = mono_array_element_size (ac);
114         ea = (gpointer*)((char*)ao->vector + (pos * esize));
115
116         if (ac->element_class->valuetype)
117                 return mono_value_box (this->vtable->domain, ac->element_class, ea);
118         else
119                 return *ea;
120 }
121
122 static MonoObject *
123 ves_icall_System_Array_GetValue (MonoObject *this, MonoObject *idxs)
124 {
125         MonoClass *ac, *ic;
126         MonoArray *ao, *io;
127         gint32 i, pos, *ind;
128
129         MONO_ARCH_SAVE_REGS;
130
131         MONO_CHECK_ARG_NULL (idxs);
132
133         io = (MonoArray *)idxs;
134         ic = (MonoClass *)io->obj.vtable->klass;
135         
136         ao = (MonoArray *)this;
137         ac = (MonoClass *)ao->obj.vtable->klass;
138
139         g_assert (ic->rank == 1);
140         if (io->bounds != NULL || io->max_length !=  ac->rank)
141                 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
142
143         ind = (gint32 *)io->vector;
144
145         if (ao->bounds == NULL) {
146                 if (*ind < 0 || *ind >= ao->max_length)
147                         mono_raise_exception (mono_get_exception_index_out_of_range ());
148
149                 return ves_icall_System_Array_GetValueImpl (this, *ind);
150         }
151         
152         for (i = 0; i < ac->rank; i++)
153                 if ((ind [i] < ao->bounds [i].lower_bound) ||
154                     (ind [i] >= ao->bounds [i].length + ao->bounds [i].lower_bound))
155                         mono_raise_exception (mono_get_exception_index_out_of_range ());
156
157         pos = ind [0] - ao->bounds [0].lower_bound;
158         for (i = 1; i < ac->rank; i++)
159                 pos = pos*ao->bounds [i].length + ind [i] - 
160                         ao->bounds [i].lower_bound;
161
162         return ves_icall_System_Array_GetValueImpl (this, pos);
163 }
164
165 static void
166 ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32 pos)
167 {
168         MonoClass *ac, *vc, *ec;
169         gint32 esize, vsize;
170         gpointer *ea, *va;
171
172         guint64 u64 = 0;
173         gint64 i64 = 0;
174         gdouble r64 = 0;
175
176         MONO_ARCH_SAVE_REGS;
177
178         if (value)
179                 vc = value->vtable->klass;
180         else
181                 vc = NULL;
182
183         ac = this->obj.vtable->klass;
184         ec = ac->element_class;
185
186         esize = mono_array_element_size (ac);
187         ea = (gpointer*)((char*)this->vector + (pos * esize));
188         va = (gpointer*)((char*)value + sizeof (MonoObject));
189
190         if (!value) {
191                 memset (ea, 0,  esize);
192                 return;
193         }
194
195 #define NO_WIDENING_CONVERSION G_STMT_START{\
196         mono_raise_exception (mono_get_exception_argument ( \
197                 "value", "not a widening conversion")); \
198 }G_STMT_END
199
200 #define CHECK_WIDENING_CONVERSION(extra) G_STMT_START{\
201         if (esize < vsize + (extra)) \
202                 mono_raise_exception (mono_get_exception_argument ( \
203                         "value", "not a widening conversion")); \
204 }G_STMT_END
205
206 #define INVALID_CAST G_STMT_START{\
207         mono_raise_exception (mono_get_exception_invalid_cast ()); \
208 }G_STMT_END
209
210         /* Check element (destination) type. */
211         switch (ec->byval_arg.type) {
212         case MONO_TYPE_STRING:
213                 switch (vc->byval_arg.type) {
214                 case MONO_TYPE_STRING:
215                         break;
216                 default:
217                         INVALID_CAST;
218                 }
219                 break;
220         case MONO_TYPE_BOOLEAN:
221                 switch (vc->byval_arg.type) {
222                 case MONO_TYPE_BOOLEAN:
223                         break;
224                 case MONO_TYPE_CHAR:
225                 case MONO_TYPE_U1:
226                 case MONO_TYPE_U2:
227                 case MONO_TYPE_U4:
228                 case MONO_TYPE_U8:
229                 case MONO_TYPE_I1:
230                 case MONO_TYPE_I2:
231                 case MONO_TYPE_I4:
232                 case MONO_TYPE_I8:
233                 case MONO_TYPE_R4:
234                 case MONO_TYPE_R8:
235                         NO_WIDENING_CONVERSION;
236                 default:
237                         INVALID_CAST;
238                 }
239                 break;
240         }
241
242         if (!ec->valuetype) {
243                 if (!mono_object_isinst (value, ec))
244                         INVALID_CAST;
245                 *ea = (gpointer)value;
246                 return;
247         }
248
249         if (mono_object_isinst (value, ec)) {
250                 memcpy (ea, (char *)value + sizeof (MonoObject), esize);
251                 return;
252         }
253
254         if (!vc->valuetype)
255                 INVALID_CAST;
256
257         vsize = mono_class_instance_size (vc) - sizeof (MonoObject);
258
259 #define ASSIGN_UNSIGNED(etype) G_STMT_START{\
260         switch (vc->byval_arg.type) { \
261         case MONO_TYPE_U1: \
262         case MONO_TYPE_U2: \
263         case MONO_TYPE_U4: \
264         case MONO_TYPE_U8: \
265         case MONO_TYPE_CHAR: \
266                 CHECK_WIDENING_CONVERSION(0); \
267                 *(etype *) ea = (etype) u64; \
268                 return; \
269         /* You can't assign a signed value to an unsigned array. */ \
270         case MONO_TYPE_I1: \
271         case MONO_TYPE_I2: \
272         case MONO_TYPE_I4: \
273         case MONO_TYPE_I8: \
274         /* You can't assign a floating point number to an integer array. */ \
275         case MONO_TYPE_R4: \
276         case MONO_TYPE_R8: \
277                 NO_WIDENING_CONVERSION; \
278         } \
279 }G_STMT_END
280
281 #define ASSIGN_SIGNED(etype) G_STMT_START{\
282         switch (vc->byval_arg.type) { \
283         case MONO_TYPE_I1: \
284         case MONO_TYPE_I2: \
285         case MONO_TYPE_I4: \
286         case MONO_TYPE_I8: \
287                 CHECK_WIDENING_CONVERSION(0); \
288                 *(etype *) ea = (etype) i64; \
289                 return; \
290         /* You can assign an unsigned value to a signed array if the array's */ \
291         /* element size is larger than the value size. */ \
292         case MONO_TYPE_U1: \
293         case MONO_TYPE_U2: \
294         case MONO_TYPE_U4: \
295         case MONO_TYPE_U8: \
296         case MONO_TYPE_CHAR: \
297                 CHECK_WIDENING_CONVERSION(1); \
298                 *(etype *) ea = (etype) u64; \
299                 return; \
300         /* You can't assign a floating point number to an integer array. */ \
301         case MONO_TYPE_R4: \
302         case MONO_TYPE_R8: \
303                 NO_WIDENING_CONVERSION; \
304         } \
305 }G_STMT_END
306
307 #define ASSIGN_REAL(etype) G_STMT_START{\
308         switch (vc->byval_arg.type) { \
309         case MONO_TYPE_R4: \
310         case MONO_TYPE_R8: \
311                 CHECK_WIDENING_CONVERSION(0); \
312                 *(etype *) ea = (etype) r64; \
313                 return; \
314         /* All integer values fit into a floating point array, so we don't */ \
315         /* need to CHECK_WIDENING_CONVERSION here. */ \
316         case MONO_TYPE_I1: \
317         case MONO_TYPE_I2: \
318         case MONO_TYPE_I4: \
319         case MONO_TYPE_I8: \
320                 *(etype *) ea = (etype) i64; \
321                 return; \
322         case MONO_TYPE_U1: \
323         case MONO_TYPE_U2: \
324         case MONO_TYPE_U4: \
325         case MONO_TYPE_U8: \
326         case MONO_TYPE_CHAR: \
327                 *(etype *) ea = (etype) u64; \
328                 return; \
329         } \
330 }G_STMT_END
331
332         switch (vc->byval_arg.type) {
333         case MONO_TYPE_U1:
334                 u64 = *(guint8 *) va;
335                 break;
336         case MONO_TYPE_U2:
337                 u64 = *(guint16 *) va;
338                 break;
339         case MONO_TYPE_U4:
340                 u64 = *(guint32 *) va;
341                 break;
342         case MONO_TYPE_U8:
343                 u64 = *(guint64 *) va;
344                 break;
345         case MONO_TYPE_I1:
346                 i64 = *(gint8 *) va;
347                 break;
348         case MONO_TYPE_I2:
349                 i64 = *(gint16 *) va;
350                 break;
351         case MONO_TYPE_I4:
352                 i64 = *(gint32 *) va;
353                 break;
354         case MONO_TYPE_I8:
355                 i64 = *(gint64 *) va;
356                 break;
357         case MONO_TYPE_R4:
358                 r64 = *(gfloat *) va;
359                 break;
360         case MONO_TYPE_R8:
361                 r64 = *(gdouble *) va;
362                 break;
363         case MONO_TYPE_CHAR:
364                 u64 = *(guint16 *) va;
365                 break;
366         case MONO_TYPE_BOOLEAN:
367                 /* Boolean is only compatible with itself. */
368                 switch (ec->byval_arg.type) {
369                 case MONO_TYPE_CHAR:
370                 case MONO_TYPE_U1:
371                 case MONO_TYPE_U2:
372                 case MONO_TYPE_U4:
373                 case MONO_TYPE_U8:
374                 case MONO_TYPE_I1:
375                 case MONO_TYPE_I2:
376                 case MONO_TYPE_I4:
377                 case MONO_TYPE_I8:
378                 case MONO_TYPE_R4:
379                 case MONO_TYPE_R8:
380                         NO_WIDENING_CONVERSION;
381                 default:
382                         INVALID_CAST;
383                 }
384                 break;
385         }
386
387         /* If we can't do a direct copy, let's try a widening conversion. */
388         switch (ec->byval_arg.type) {
389         case MONO_TYPE_CHAR:
390                 ASSIGN_UNSIGNED (guint16);
391         case MONO_TYPE_U1:
392                 ASSIGN_UNSIGNED (guint8);
393         case MONO_TYPE_U2:
394                 ASSIGN_UNSIGNED (guint16);
395         case MONO_TYPE_U4:
396                 ASSIGN_UNSIGNED (guint32);
397         case MONO_TYPE_U8:
398                 ASSIGN_UNSIGNED (guint64);
399         case MONO_TYPE_I1:
400                 ASSIGN_SIGNED (gint8);
401         case MONO_TYPE_I2:
402                 ASSIGN_SIGNED (gint16);
403         case MONO_TYPE_I4:
404                 ASSIGN_SIGNED (gint32);
405         case MONO_TYPE_I8:
406                 ASSIGN_SIGNED (gint64);
407         case MONO_TYPE_R4:
408                 ASSIGN_REAL (gfloat);
409         case MONO_TYPE_R8:
410                 ASSIGN_REAL (gdouble);
411         }
412
413         INVALID_CAST;
414         /* Not reached, INVALID_CAST does not return. Just to avoid a compiler warning ... */
415         return;
416
417 #undef INVALID_CAST
418 #undef NO_WIDENING_CONVERSION
419 #undef CHECK_WIDENING_CONVERSION
420 #undef ASSIGN_UNSIGNED
421 #undef ASSIGN_SIGNED
422 #undef ASSIGN_REAL
423 }
424
425 static void 
426 ves_icall_System_Array_SetValue (MonoArray *this, MonoObject *value,
427                                  MonoArray *idxs)
428 {
429         MonoClass *ac, *ic;
430         gint32 i, pos, *ind;
431
432         MONO_ARCH_SAVE_REGS;
433
434         MONO_CHECK_ARG_NULL (idxs);
435
436         ic = idxs->obj.vtable->klass;
437         ac = this->obj.vtable->klass;
438
439         g_assert (ic->rank == 1);
440         if (idxs->bounds != NULL || idxs->max_length != ac->rank)
441                 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
442
443         ind = (gint32 *)idxs->vector;
444
445         if (this->bounds == NULL) {
446                 if (*ind < 0 || *ind >= this->max_length)
447                         mono_raise_exception (mono_get_exception_index_out_of_range ());
448
449                 ves_icall_System_Array_SetValueImpl (this, value, *ind);
450                 return;
451         }
452         
453         for (i = 0; i < ac->rank; i++)
454                 if ((ind [i] < this->bounds [i].lower_bound) ||
455                     (ind [i] >= this->bounds [i].length + this->bounds [i].lower_bound))
456                         mono_raise_exception (mono_get_exception_index_out_of_range ());
457
458         pos = ind [0] - this->bounds [0].lower_bound;
459         for (i = 1; i < ac->rank; i++)
460                 pos = pos * this->bounds [i].length + ind [i] - 
461                         this->bounds [i].lower_bound;
462
463         ves_icall_System_Array_SetValueImpl (this, value, pos);
464 }
465
466 static MonoArray *
467 ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
468 {
469         MonoClass *aklass;
470         MonoArray *array;
471         guint32 *sizes, i;
472         gboolean bounded = FALSE;
473
474         MONO_ARCH_SAVE_REGS;
475
476         MONO_CHECK_ARG_NULL (type);
477         MONO_CHECK_ARG_NULL (lengths);
478
479         MONO_CHECK_ARG (lengths, mono_array_length (lengths) > 0);
480         if (bounds)
481                 MONO_CHECK_ARG (bounds, mono_array_length (lengths) == mono_array_length (bounds));
482
483         for (i = 0; i < mono_array_length (lengths); i++)
484                 if (mono_array_get (lengths, gint32, i) < 0)
485                         mono_raise_exception (mono_get_exception_argument_out_of_range (NULL));
486
487         if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint32, 0) != 0))
488                 /* vectors are not the same as one dimensional arrays with no-zero bounds */
489                 bounded = TRUE;
490         else
491                 bounded = FALSE;
492
493         aklass = mono_bounded_array_class_get (mono_class_from_mono_type (type->type), mono_array_length (lengths), bounded);
494
495         sizes = alloca (aklass->rank * sizeof(guint32) * 2);
496         for (i = 0; i < aklass->rank; ++i) {
497                 sizes [i] = mono_array_get (lengths, guint32, i);
498                 if (bounds)
499                         sizes [i + aklass->rank] = mono_array_get (bounds, guint32, i);
500                 else
501                         sizes [i + aklass->rank] = 0;
502         }
503
504         array = mono_array_new_full (mono_object_domain (type), aklass, sizes, sizes + aklass->rank);
505
506         return array;
507 }
508
509 static gint32 
510 ves_icall_System_Array_GetRank (MonoObject *this)
511 {
512         MONO_ARCH_SAVE_REGS;
513
514         return this->vtable->klass->rank;
515 }
516
517 static gint32
518 ves_icall_System_Array_GetLength (MonoArray *this, gint32 dimension)
519 {
520         gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
521
522         MONO_ARCH_SAVE_REGS;
523
524         if ((dimension < 0) || (dimension >= rank))
525                 mono_raise_exception (mono_get_exception_index_out_of_range ());
526         
527         if (this->bounds == NULL)
528                 return this->max_length;
529         
530         return this->bounds [dimension].length;
531 }
532
533 static gint32
534 ves_icall_System_Array_GetLowerBound (MonoArray *this, gint32 dimension)
535 {
536         gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
537
538         MONO_ARCH_SAVE_REGS;
539
540         if ((dimension < 0) || (dimension >= rank))
541                 mono_raise_exception (mono_get_exception_index_out_of_range ());
542         
543         if (this->bounds == NULL)
544                 return 0;
545         
546         return this->bounds [dimension].lower_bound;
547 }
548
549 static void
550 ves_icall_System_Array_ClearInternal (MonoArray *arr, int idx, int length)
551 {
552         int sz = mono_array_element_size (mono_object_class (arr));
553         memset (mono_array_addr_with_size (arr, idx, sz), 0, length * sz);
554 }
555
556 static gboolean
557 ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* dest, int dest_idx, int length)
558 {
559         int element_size;
560         void * dest_addr;
561         void * source_addr;
562         MonoClass *src_class;
563         MonoClass *dest_class;
564         int i;
565
566         MONO_ARCH_SAVE_REGS;
567
568         if (source->obj.vtable->klass->rank != dest->obj.vtable->klass->rank)
569                 return FALSE;
570
571         if (source->bounds || dest->bounds)
572                 return FALSE;
573
574         if ((dest_idx + length > mono_array_length (dest)) ||
575                 (source_idx + length > mono_array_length (source)))
576                 return FALSE;
577
578         element_size = mono_array_element_size (source->obj.vtable->klass);
579         dest_addr = mono_array_addr_with_size (dest, element_size, dest_idx);
580         source_addr = mono_array_addr_with_size (source, element_size, source_idx);
581
582         src_class = source->obj.vtable->klass->element_class;
583         dest_class = dest->obj.vtable->klass->element_class;
584
585         /*
586          * Handle common cases.
587          */
588
589         /* Case1: object[] -> valuetype[] (ArrayList::ToArray) */
590         if (src_class == mono_defaults.object_class && dest_class->valuetype) {
591                 for (i = source_idx; i < source_idx + length; ++i) {
592                         MonoObject *elem = mono_array_get (source, MonoObject*, i);
593                         if (elem && !mono_object_isinst (elem, dest_class))
594                                 return FALSE;
595                 }
596
597                 element_size = mono_array_element_size (dest->obj.vtable->klass);
598                 for (i = 0; i < length; ++i) {
599                         MonoObject *elem = mono_array_get (source, MonoObject*, source_idx + i);
600                         void *addr = mono_array_addr_with_size (dest, element_size, dest_idx + i);
601                         if (!elem)
602                                 memset (addr, 0, element_size);
603                         else
604                                 memcpy (addr, (char *)elem + sizeof (MonoObject), element_size);
605                 }
606                 return TRUE;
607         }
608
609         /* Check if we're copying a char[] <==> (u)short[] */
610         if (src_class != dest_class) {
611                 if (dest_class->valuetype || dest_class->enumtype || src_class->valuetype || src_class->enumtype)
612                         return FALSE;
613
614                 if (mono_class_is_subclass_of (src_class, dest_class, FALSE))
615                         ;
616                 /* Case2: object[] -> reftype[] (ArrayList::ToArray) */
617                 else if (mono_class_is_subclass_of (dest_class, src_class, FALSE))
618                         for (i = source_idx; i < source_idx + length; ++i) {
619                                 MonoObject *elem = mono_array_get (source, MonoObject*, i);
620                                 if (elem && !mono_object_isinst (elem, dest_class))
621                                         return FALSE;
622                         }
623                 else
624                         return FALSE;
625         }
626
627         memmove (dest_addr, source_addr, element_size * length);
628
629         return TRUE;
630 }
631
632 static void
633 ves_icall_System_Array_InternalArray_GetGenericValueImpl (MonoObject *this, guint32 pos,
634                                                           gpointer value)
635 {
636         MonoClass *ac;
637         MonoArray *ao;
638         gint32 esize;
639         gpointer *ea;
640
641         MONO_ARCH_SAVE_REGS;
642
643         ao = (MonoArray *)this;
644         ac = (MonoClass *)ao->obj.vtable->klass;
645
646         esize = mono_array_element_size (ac);
647         ea = (gpointer*)((char*)ao->vector + (pos * esize));
648
649         memcpy (value, ea, esize);
650 }
651
652 static void
653 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoArray *array, MonoClassField *field_handle)
654 {
655         MonoClass *klass = array->obj.vtable->klass;
656         guint32 size = mono_array_element_size (klass);
657         int i;
658
659         MONO_ARCH_SAVE_REGS;
660
661         if (array->bounds == NULL)
662                 size *= array->max_length;
663         else
664                 for (i = 0; i < klass->rank; ++i) 
665                         size *= array->bounds [i].length;
666
667         memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
668
669 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
670 #define SWAP(n) {\
671         gint i; \
672         guint ## n tmp; \
673         guint ## n *data = (guint ## n *) mono_array_addr (array, char, 0); \
674 \
675         for (i = 0; i < size; i += n/8, data++) { \
676                 tmp = read ## n (data); \
677                 *data = tmp; \
678         } \
679 }
680
681         /* printf ("Initialize array with elements of %s type\n", klass->element_class->name); */
682
683         switch (mono_type_get_underlying_type (&klass->element_class->byval_arg)->type) {
684         case MONO_TYPE_CHAR:
685         case MONO_TYPE_I2:
686         case MONO_TYPE_U2:
687                 SWAP (16);
688                 break;
689         case MONO_TYPE_I4:
690         case MONO_TYPE_U4:
691                 SWAP (32);
692                 break;
693         case MONO_TYPE_I8:
694         case MONO_TYPE_U8:
695                 SWAP (64);
696                 break;
697         }
698                  
699 #endif
700 }
701
702 static gint
703 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData (void)
704 {
705         MONO_ARCH_SAVE_REGS;
706
707         return offsetof (MonoString, chars);
708 }
709
710 static MonoObject *
711 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue (MonoObject *obj)
712 {
713         MONO_ARCH_SAVE_REGS;
714
715         if ((obj == NULL) || (! (obj->vtable->klass->valuetype)))
716                 return obj;
717         else
718                 return mono_object_clone (obj);
719 }
720
721 static void
722 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (MonoType *handle)
723 {
724         MonoClass *klass;
725
726         MONO_ARCH_SAVE_REGS;
727
728         MONO_CHECK_ARG_NULL (handle);
729
730         klass = mono_class_from_mono_type (handle);
731         MONO_CHECK_ARG (handle, klass);
732
733         /* This will call the type constructor */
734         if (! (klass->flags & TYPE_ATTRIBUTE_INTERFACE))
735                 mono_runtime_class_init (mono_class_vtable (mono_domain_get (), klass));
736 }
737
738 static MonoObject *
739 ves_icall_System_Object_MemberwiseClone (MonoObject *this)
740 {
741         MONO_ARCH_SAVE_REGS;
742
743         return mono_object_clone (this);
744 }
745
746 #define MONO_OBJECT_ALIGNMENT_SHIFT     3
747
748 /*
749  * Return hashcode based on object address. This function will need to be
750  * smarter in the presence of a moving garbage collector, which will cache
751  * the address hash before relocating the object.
752  *
753  * Wang's address-based hash function:
754  *   http://www.concentric.net/~Ttwang/tech/addrhash.htm
755  */
756 static gint32
757 ves_icall_System_Object_GetHashCode (MonoObject *this)
758 {
759         MONO_ARCH_SAVE_REGS;
760
761         return (GPOINTER_TO_UINT (this) >> MONO_OBJECT_ALIGNMENT_SHIFT) * 2654435761u;
762 }
763
764 static gint32
765 ves_icall_System_ValueType_InternalGetHashCode (MonoObject *this, MonoArray **fields)
766 {
767         MonoClass *klass;
768         MonoObject **values = NULL;
769         MonoObject *o;
770         int count = 0;
771         gint32 result = 0;
772         MonoClassField* field;
773         gpointer iter;
774
775         MONO_ARCH_SAVE_REGS;
776
777         klass = mono_object_class (this);
778
779         if (mono_class_num_fields (klass) == 0)
780                 return ves_icall_System_Object_GetHashCode (this);
781
782         /*
783          * Compute the starting value of the hashcode for fields of primitive
784          * types, and return the remaining fields in an array to the managed side.
785          * This way, we can avoid costly reflection operations in managed code.
786          */
787         iter = NULL;
788         while ((field = mono_class_get_fields (klass, &iter))) {
789                 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
790                         continue;
791                 if (mono_field_is_deleted (field))
792                         continue;
793                 /* FIXME: Add more types */
794                 switch (field->type->type) {
795                 case MONO_TYPE_I4:
796                         result ^= *(gint32*)((guint8*)this + field->offset);
797                         break;
798                 case MONO_TYPE_STRING: {
799                         MonoString *s;
800                         s = *(MonoString**)((guint8*)this + field->offset);
801                         if (s != NULL)
802                                 result ^= mono_string_hash (s);
803                         break;
804                 }
805                 default:
806                         if (!values)
807                                 values = g_newa (MonoObject*, mono_class_num_fields (klass));
808                         o = mono_field_get_value_object (mono_object_domain (this), field, this);
809                         values [count++] = o;
810                 }
811         }
812
813         if (values) {
814                 *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
815                 memcpy (mono_array_addr (*fields, MonoObject*, 0), values, count * sizeof (MonoObject*));
816         }
817         else
818                 *fields = NULL;
819         return result;
820 }
821
822 static MonoBoolean
823 ves_icall_System_ValueType_Equals (MonoObject *this, MonoObject *that, MonoArray **fields)
824 {
825         MonoClass *klass;
826         MonoObject **values = NULL;
827         MonoObject *o;
828         MonoClassField* field;
829         gpointer iter;
830         int count = 0;
831
832         MONO_ARCH_SAVE_REGS;
833
834         MONO_CHECK_ARG_NULL (that);
835
836         if (this->vtable != that->vtable)
837                 return FALSE;
838
839         klass = mono_object_class (this);
840
841         /*
842          * Do the comparison for fields of primitive type and return a result if
843          * possible. Otherwise, return the remaining fields in an array to the 
844          * managed side. This way, we can avoid costly reflection operations in 
845          * managed code.
846          */
847         *fields = NULL;
848         iter = NULL;
849         while ((field = mono_class_get_fields (klass, &iter))) {
850                 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
851                         continue;
852                 if (mono_field_is_deleted (field))
853                         continue;
854                 /* FIXME: Add more types */
855                 switch (field->type->type) {
856                 case MONO_TYPE_I4:
857                         if (*(gint32*)((guint8*)this + field->offset) != *(gint32*)((guint8*)that + field->offset))
858                                 return FALSE;
859                         break;
860                 case MONO_TYPE_STRING: {
861                         MonoString *s1, *s2;
862                         guint32 s1len, s2len;
863                         s1 = *(MonoString**)((guint8*)this + field->offset);
864                         s2 = *(MonoString**)((guint8*)that + field->offset);
865                         if (s1 == s2)
866                                 break;
867                         if ((s1 == NULL) || (s2 == NULL))
868                                 return FALSE;
869                         s1len = mono_string_length (s1);
870                         s2len = mono_string_length (s2);
871                         if (s1len != s2len)
872                                 return FALSE;
873
874                         if (memcmp (mono_string_chars (s1), mono_string_chars (s2), s1len * sizeof (gunichar2)) != 0)
875                                 return FALSE;
876                         break;
877                 }
878                 default:
879                         if (!values)
880                                 values = g_newa (MonoObject*, mono_class_num_fields (klass) * 2);
881                         o = mono_field_get_value_object (mono_object_domain (this), field, this);
882                         values [count++] = o;
883                         o = mono_field_get_value_object (mono_object_domain (this), field, that);
884                         values [count++] = o;
885                 }
886         }
887
888         if (values) {
889                 *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
890                 memcpy (mono_array_addr (*fields, MonoObject*, 0), values, count * sizeof (MonoObject*));
891
892                 return FALSE;
893         }
894         else
895                 return TRUE;
896 }
897
898 static MonoReflectionType *
899 ves_icall_System_Object_GetType (MonoObject *obj)
900 {
901         MONO_ARCH_SAVE_REGS;
902
903         if (obj->vtable->klass != mono_defaults.transparent_proxy_class)
904                 return mono_type_get_object (mono_object_domain (obj), &obj->vtable->klass->byval_arg);
905         else
906                 return mono_type_get_object (mono_object_domain (obj), &((MonoTransparentProxy*)obj)->remote_class->proxy_class->byval_arg);
907 }
908
909 static void
910 mono_type_type_from_obj (MonoReflectionType *mtype, MonoObject *obj)
911 {
912         MONO_ARCH_SAVE_REGS;
913
914         mtype->type = &obj->vtable->klass->byval_arg;
915         g_assert (mtype->type->type);
916 }
917
918 static gint32
919 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj)
920 {
921         MONO_ARCH_SAVE_REGS;
922         
923         MONO_CHECK_ARG_NULL (obj);
924         
925         return mono_image_create_token (mb->dynamic_image, obj, TRUE);
926 }
927
928 static gint32
929 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder *mb,
930                                         MonoReflectionMethod *method,
931                                         MonoArray *opt_param_types)
932 {
933         MONO_ARCH_SAVE_REGS;
934
935         MONO_CHECK_ARG_NULL (method);
936         
937         return mono_image_create_method_token (
938                 mb->dynamic_image, (MonoObject *) method, opt_param_types);
939 }
940
941 static void
942 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder *mb, HANDLE file)
943 {
944         MONO_ARCH_SAVE_REGS;
945
946         mono_image_create_pefile (mb, file);
947 }
948
949 static void
950 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
951 {
952         MONO_ARCH_SAVE_REGS;
953
954         mono_image_build_metadata (mb);
955 }
956
957 static MonoReflectionType *
958 type_from_name (const char *str, MonoBoolean ignoreCase)
959 {
960         MonoType *type = NULL;
961         MonoAssembly *assembly;
962         MonoTypeNameParse info;
963         char *temp_str = g_strdup (str);
964         gboolean type_resolve = FALSE;
965
966         MONO_ARCH_SAVE_REGS;
967
968         /* mono_reflection_parse_type() mangles the string */
969         if (!mono_reflection_parse_type (temp_str, &info)) {
970                 g_list_free (info.modifiers);
971                 g_list_free (info.nested);
972                 g_free (temp_str);
973                 return NULL;
974         }
975
976         if (info.assembly.name) {
977                 assembly = mono_assembly_load (&info.assembly, NULL, NULL);
978         } else {
979                 MonoReflectionAssembly *refass;
980
981                 refass = ves_icall_System_Reflection_Assembly_GetCallingAssembly  ();
982                 assembly = refass->assembly;
983         }
984
985         if (assembly)
986                 type = mono_reflection_get_type (assembly->image, &info, ignoreCase, &type_resolve);
987         
988         if (!info.assembly.name && !type) /* try mscorlib */
989                 type = mono_reflection_get_type (NULL, &info, ignoreCase, &type_resolve);
990
991         g_list_free (info.modifiers);
992         g_list_free (info.nested);
993         g_free (temp_str);
994
995         if (!type) 
996                 return NULL;
997
998         return mono_type_get_object (mono_domain_get (), type);
999 }
1000
1001 #ifdef UNUSED
1002 MonoReflectionType *
1003 mono_type_get (const char *str)
1004 {
1005         char *copy = g_strdup (str);
1006         MonoReflectionType *type = type_from_name (copy, FALSE);
1007
1008         g_free (copy);
1009         return type;
1010 }
1011 #endif
1012
1013 static MonoReflectionType*
1014 ves_icall_type_from_name (MonoString *name,
1015                           MonoBoolean throwOnError,
1016                           MonoBoolean ignoreCase)
1017 {
1018         char *str = mono_string_to_utf8 (name);
1019         MonoReflectionType *type;
1020
1021         type = type_from_name (str, ignoreCase);
1022         g_free (str);
1023         if (type == NULL){
1024                 if (throwOnError)
1025                         mono_raise_exception (mono_get_exception_type_load (name));
1026         }
1027         
1028         return type;
1029 }
1030
1031
1032 static MonoReflectionType*
1033 ves_icall_type_from_handle (MonoType *handle)
1034 {
1035         MonoDomain *domain = mono_domain_get (); 
1036         MonoClass *klass = mono_class_from_mono_type (handle);
1037
1038         MONO_ARCH_SAVE_REGS;
1039
1040         mono_class_init (klass);
1041         return mono_type_get_object (domain, handle);
1042 }
1043
1044 static MonoBoolean
1045 ves_icall_type_Equals (MonoReflectionType *type, MonoReflectionType *c)
1046 {
1047         MONO_ARCH_SAVE_REGS;
1048
1049         if (type->type && c->type)
1050                 return mono_metadata_type_equal (type->type, c->type);
1051         else
1052                 return FALSE;
1053 }
1054
1055 /* System.TypeCode */
1056 typedef enum {
1057         TYPECODE_EMPTY,
1058         TYPECODE_OBJECT,
1059         TYPECODE_DBNULL,
1060         TYPECODE_BOOLEAN,
1061         TYPECODE_CHAR,
1062         TYPECODE_SBYTE,
1063         TYPECODE_BYTE,
1064         TYPECODE_INT16,
1065         TYPECODE_UINT16,
1066         TYPECODE_INT32,
1067         TYPECODE_UINT32,
1068         TYPECODE_INT64,
1069         TYPECODE_UINT64,
1070         TYPECODE_SINGLE,
1071         TYPECODE_DOUBLE,
1072         TYPECODE_DECIMAL,
1073         TYPECODE_DATETIME,
1074         TYPECODE_STRING = 18
1075 } TypeCode;
1076
1077 static guint32
1078 ves_icall_type_GetTypeCodeInternal (MonoReflectionType *type)
1079 {
1080         int t = type->type->type;
1081
1082         MONO_ARCH_SAVE_REGS;
1083
1084         if (type->type->byref)
1085                 return TYPECODE_OBJECT;
1086
1087 handle_enum:
1088         switch (t) {
1089         case MONO_TYPE_VOID:
1090                 return TYPECODE_OBJECT;
1091         case MONO_TYPE_BOOLEAN:
1092                 return TYPECODE_BOOLEAN;
1093         case MONO_TYPE_U1:
1094                 return TYPECODE_BYTE;
1095         case MONO_TYPE_I1:
1096                 return TYPECODE_SBYTE;
1097         case MONO_TYPE_U2:
1098                 return TYPECODE_UINT16;
1099         case MONO_TYPE_I2:
1100                 return TYPECODE_INT16;
1101         case MONO_TYPE_CHAR:
1102                 return TYPECODE_CHAR;
1103         case MONO_TYPE_PTR:
1104         case MONO_TYPE_U:
1105         case MONO_TYPE_I:
1106                 return TYPECODE_OBJECT;
1107         case MONO_TYPE_U4:
1108                 return TYPECODE_UINT32;
1109         case MONO_TYPE_I4:
1110                 return TYPECODE_INT32;
1111         case MONO_TYPE_U8:
1112                 return TYPECODE_UINT64;
1113         case MONO_TYPE_I8:
1114                 return TYPECODE_INT64;
1115         case MONO_TYPE_R4:
1116                 return TYPECODE_SINGLE;
1117         case MONO_TYPE_R8:
1118                 return TYPECODE_DOUBLE;
1119         case MONO_TYPE_VALUETYPE:
1120                 if (type->type->data.klass->enumtype) {
1121                         t = type->type->data.klass->enum_basetype->type;
1122                         goto handle_enum;
1123                 } else {
1124                         MonoClass *k =  type->type->data.klass;
1125                         if (strcmp (k->name_space, "System") == 0) {
1126                                 if (strcmp (k->name, "Decimal") == 0)
1127                                         return TYPECODE_DECIMAL;
1128                                 else if (strcmp (k->name, "DateTime") == 0)
1129                                         return TYPECODE_DATETIME;
1130                         }
1131                 }
1132                 return TYPECODE_OBJECT;
1133         case MONO_TYPE_STRING:
1134                 return TYPECODE_STRING;
1135         case MONO_TYPE_SZARRAY:
1136         case MONO_TYPE_ARRAY:
1137         case MONO_TYPE_OBJECT:
1138         case MONO_TYPE_VAR:
1139         case MONO_TYPE_MVAR:
1140                 return TYPECODE_OBJECT;
1141         case MONO_TYPE_CLASS:
1142                 {
1143                         MonoClass *k =  type->type->data.klass;
1144                         if (strcmp (k->name_space, "System") == 0) {
1145                                 if (strcmp (k->name, "DBNull") == 0)
1146                                         return TYPECODE_DBNULL;
1147                         }
1148                 }
1149                 return TYPECODE_OBJECT;
1150         case MONO_TYPE_GENERICINST:
1151                 return TYPECODE_OBJECT;
1152         default:
1153                 g_error ("type 0x%02x not handled in GetTypeCode()", t);
1154         }
1155         return 0;
1156 }
1157
1158 static guint32
1159 ves_icall_type_is_subtype_of (MonoReflectionType *type, MonoReflectionType *c, MonoBoolean check_interfaces)
1160 {
1161         MonoDomain *domain; 
1162         MonoClass *klass;
1163         MonoClass *klassc;
1164
1165         MONO_ARCH_SAVE_REGS;
1166
1167         g_assert (type != NULL);
1168         
1169         domain = ((MonoObject *)type)->vtable->domain;
1170
1171         if (!c) /* FIXME: dont know what do do here */
1172                 return 0;
1173
1174         klass = mono_class_from_mono_type (type->type);
1175         klassc = mono_class_from_mono_type (c->type);
1176
1177         if (type->type->byref)
1178                 return klassc == mono_defaults.object_class;
1179
1180         return mono_class_is_subclass_of (klass, klassc, check_interfaces);
1181 }
1182
1183 static guint32
1184 ves_icall_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType *c)
1185 {
1186         MonoDomain *domain; 
1187         MonoClass *klass;
1188         MonoClass *klassc;
1189
1190         MONO_ARCH_SAVE_REGS;
1191
1192         g_assert (type != NULL);
1193         
1194         domain = ((MonoObject *)type)->vtable->domain;
1195
1196         klass = mono_class_from_mono_type (type->type);
1197         klassc = mono_class_from_mono_type (c->type);
1198
1199         if (type->type->byref && !c->type->byref)
1200                 return FALSE;
1201
1202         return mono_class_is_assignable_from (klass, klassc);
1203 }
1204
1205 static guint32
1206 ves_icall_type_IsInstanceOfType (MonoReflectionType *type, MonoObject *obj)
1207 {
1208         MonoClass *klass = mono_class_from_mono_type (type->type);
1209         return mono_object_isinst (obj, klass) != NULL;
1210 }
1211
1212 static guint32
1213 ves_icall_get_attributes (MonoReflectionType *type)
1214 {
1215         MonoClass *klass = mono_class_from_mono_type (type->type);
1216
1217         MONO_ARCH_SAVE_REGS;
1218
1219         return klass->flags;
1220 }
1221
1222 static MonoReflectionMarshal*
1223 ves_icall_System_Reflection_FieldInfo_GetUnmanagedMarshal (MonoReflectionField *field)
1224 {
1225         MonoClass *klass = field->field->parent;
1226         MonoMarshalType *info;
1227         int i;
1228
1229         if (klass->generic_container ||
1230             (klass->generic_class && klass->generic_class->inst->is_open))
1231                 return NULL;
1232
1233         info = mono_marshal_load_type_info (klass);
1234
1235         for (i = 0; i < info->num_fields; ++i) {
1236                 if (info->fields [i].field == field->field) {
1237                         if (!info->fields [i].mspec)
1238                                 return NULL;
1239                         else
1240                                 return mono_reflection_marshal_from_marshal_spec (field->object.vtable->domain, klass, info->fields [i].mspec);
1241                 }
1242         }
1243
1244         return NULL;
1245 }
1246
1247 static MonoReflectionField*
1248 ves_icall_System_Reflection_FieldInfo_internal_from_handle (MonoClassField *handle)
1249 {
1250         MONO_ARCH_SAVE_REGS;
1251
1252         g_assert (handle);
1253
1254         return mono_field_get_object (mono_domain_get (), handle->parent, handle);
1255 }
1256
1257 static void
1258 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
1259 {
1260         MonoDomain *domain = mono_domain_get ();
1261         MonoMethodSignature* sig;
1262         MONO_ARCH_SAVE_REGS;
1263
1264         if (method->is_inflated)
1265                 method = mono_get_inflated_method (method);
1266
1267         sig = mono_method_signature (method);
1268         
1269         info->parent = mono_type_get_object (domain, &method->klass->byval_arg);
1270         info->ret = mono_type_get_object (domain, sig->ret);
1271         info->attrs = method->flags;
1272         info->implattrs = method->iflags;
1273         if (sig->call_convention == MONO_CALL_DEFAULT)
1274                 info->callconv = 1;
1275         else {
1276                 if (sig->call_convention == MONO_CALL_VARARG)
1277                         info->callconv = 2;
1278                 else
1279                         info->callconv = 0;
1280         }
1281         info->callconv |= (sig->hasthis << 5) | (sig->explicit_this << 6); 
1282 }
1283
1284 static MonoArray*
1285 ves_icall_get_parameter_info (MonoMethod *method)
1286 {
1287         MonoDomain *domain = mono_domain_get (); 
1288
1289         MONO_ARCH_SAVE_REGS;
1290
1291         if (method->is_inflated)
1292                 method = mono_get_inflated_method (method);
1293
1294         return mono_param_get_objects (domain, method);
1295 }
1296
1297 static gint32
1298 ves_icall_MonoField_GetFieldOffset (MonoReflectionField *field)
1299 {
1300         return field->field->offset - sizeof (MonoObject);
1301 }
1302
1303 static MonoReflectionType*
1304 ves_icall_MonoField_GetParentType (MonoReflectionField *field, MonoBoolean declaring)
1305 {
1306         MonoClass *parent;
1307         MONO_ARCH_SAVE_REGS;
1308
1309         parent = declaring? field->field->parent: field->klass;
1310
1311         return mono_type_get_object (mono_object_domain (field), &parent->byval_arg);
1312 }
1313
1314 static MonoObject *
1315 ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj)
1316 {       
1317         MonoObject *o;
1318         MonoClassField *cf = field->field;
1319         MonoClass *klass;
1320         MonoVTable *vtable;
1321         MonoDomain *domain = mono_object_domain (field); 
1322         gchar *v;
1323         gboolean is_static = FALSE;
1324         gboolean is_ref = FALSE;
1325
1326         MONO_ARCH_SAVE_REGS;
1327
1328         if (field->klass->image->assembly->ref_only)
1329                 mono_raise_exception (mono_get_exception_invalid_operation (
1330                                         "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
1331         
1332         mono_class_init (field->klass);
1333
1334         switch (cf->type->type) {
1335         case MONO_TYPE_STRING:
1336         case MONO_TYPE_OBJECT:
1337         case MONO_TYPE_CLASS:
1338         case MONO_TYPE_ARRAY:
1339         case MONO_TYPE_SZARRAY:
1340                 is_ref = TRUE;
1341                 break;
1342         case MONO_TYPE_U1:
1343         case MONO_TYPE_I1:
1344         case MONO_TYPE_BOOLEAN:
1345         case MONO_TYPE_U2:
1346         case MONO_TYPE_I2:
1347         case MONO_TYPE_CHAR:
1348         case MONO_TYPE_U:
1349         case MONO_TYPE_I:
1350         case MONO_TYPE_U4:
1351         case MONO_TYPE_I4:
1352         case MONO_TYPE_R4:
1353         case MONO_TYPE_U8:
1354         case MONO_TYPE_I8:
1355         case MONO_TYPE_R8:
1356         case MONO_TYPE_VALUETYPE:
1357                 is_ref = cf->type->byref;
1358                 break;
1359         default:
1360                 g_error ("type 0x%x not handled in "
1361                          "ves_icall_Monofield_GetValue", cf->type->type);
1362                 return NULL;
1363         }
1364
1365         vtable = NULL;
1366         if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) {
1367                 is_static = TRUE;
1368                 vtable = mono_class_vtable (domain, field->klass);
1369                 if (!vtable->initialized && !(cf->type->attrs & FIELD_ATTRIBUTE_LITERAL))
1370                         mono_runtime_class_init (vtable);
1371         }
1372         
1373         if (is_ref) {
1374                 if (is_static) {
1375                         mono_field_static_get_value (vtable, cf, &o);
1376                 } else {
1377                         mono_field_get_value (obj, cf, &o);
1378                 }
1379                 return o;
1380         }
1381
1382         /* boxed value type */
1383         klass = mono_class_from_mono_type (cf->type);
1384         o = mono_object_new (domain, klass);
1385         v = ((gchar *) o) + sizeof (MonoObject);
1386         if (is_static) {
1387                 mono_field_static_get_value (vtable, cf, v);
1388         } else {
1389                 mono_field_get_value (obj, cf, v);
1390         }
1391
1392         return o;
1393 }
1394
1395 static void
1396 ves_icall_FieldInfo_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value)
1397 {
1398         MonoClassField *cf = field->field;
1399         gchar *v;
1400
1401         MONO_ARCH_SAVE_REGS;
1402
1403         if (field->klass->image->assembly->ref_only)
1404                 mono_raise_exception (mono_get_exception_invalid_operation (
1405                                         "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
1406
1407         v = (gchar *) value;
1408         if (!cf->type->byref) {
1409                 switch (cf->type->type) {
1410                 case MONO_TYPE_U1:
1411                 case MONO_TYPE_I1:
1412                 case MONO_TYPE_BOOLEAN:
1413                 case MONO_TYPE_U2:
1414                 case MONO_TYPE_I2:
1415                 case MONO_TYPE_CHAR:
1416                 case MONO_TYPE_U:
1417                 case MONO_TYPE_I:
1418                 case MONO_TYPE_U4:
1419                 case MONO_TYPE_I4:
1420                 case MONO_TYPE_R4:
1421                 case MONO_TYPE_U8:
1422                 case MONO_TYPE_I8:
1423                 case MONO_TYPE_R8:
1424                 case MONO_TYPE_VALUETYPE:
1425                         if (v != NULL)
1426                                 v += sizeof (MonoObject);
1427                         break;
1428                 case MONO_TYPE_STRING:
1429                 case MONO_TYPE_OBJECT:
1430                 case MONO_TYPE_CLASS:
1431                 case MONO_TYPE_ARRAY:
1432                 case MONO_TYPE_SZARRAY:
1433                         /* Do nothing */
1434                         break;
1435                 default:
1436                         g_error ("type 0x%x not handled in "
1437                                  "ves_icall_FieldInfo_SetValueInternal", cf->type->type);
1438                         return;
1439                 }
1440         }
1441
1442         if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) {
1443                 MonoVTable *vtable = mono_class_vtable (mono_object_domain (field), field->klass);
1444                 if (!vtable->initialized)
1445                         mono_runtime_class_init (vtable);
1446                 mono_field_static_set_value (vtable, cf, v);
1447         } else {
1448                 mono_field_set_value (obj, cf, v);
1449         }
1450 }
1451
1452 static MonoReflectionField*
1453 ves_icall_MonoField_Mono_GetGenericFieldDefinition (MonoReflectionField *field)
1454 {
1455         MONO_ARCH_SAVE_REGS;
1456
1457         if (field->field->generic_info && field->field->generic_info->reflection_info)
1458                 return field->field->generic_info->reflection_info;
1459
1460         return field;
1461 }
1462
1463 static MonoReflectionType*
1464 ves_icall_MonoGenericMethod_get_ReflectedType (MonoReflectionGenericMethod *rmethod)
1465 {
1466         MonoMethod *method = mono_get_inflated_method (rmethod->method.method);
1467
1468         return mono_type_get_object (mono_object_domain (rmethod), &method->klass->byval_arg);
1469 }
1470
1471 /* From MonoProperty.cs */
1472 typedef enum {
1473         PInfo_Attributes = 1,
1474         PInfo_GetMethod  = 1 << 1,
1475         PInfo_SetMethod  = 1 << 2,
1476         PInfo_ReflectedType = 1 << 3,
1477         PInfo_DeclaringType = 1 << 4,
1478         PInfo_Name = 1 << 5
1479 } PInfo;
1480
1481 static void
1482 ves_icall_get_property_info (MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
1483 {
1484         MonoDomain *domain = mono_object_domain (property); 
1485
1486         MONO_ARCH_SAVE_REGS;
1487
1488         if ((req_info & PInfo_ReflectedType) != 0)
1489                 info->parent = mono_type_get_object (domain, &property->klass->byval_arg);
1490         else if ((req_info & PInfo_DeclaringType) != 0)
1491                 info->parent = mono_type_get_object (domain, &property->property->parent->byval_arg);
1492
1493         if ((req_info & PInfo_Name) != 0)
1494                 info->name = mono_string_new (domain, property->property->name);
1495
1496         if ((req_info & PInfo_Attributes) != 0)
1497                 info->attrs = property->property->attrs;
1498
1499         if ((req_info & PInfo_GetMethod) != 0)
1500                 info->get = property->property->get ?
1501                             mono_method_get_object (domain, property->property->get, NULL): NULL;
1502         
1503         if ((req_info & PInfo_SetMethod) != 0)
1504                 info->set = property->property->set ?
1505                             mono_method_get_object (domain, property->property->set, NULL): NULL;
1506         /* 
1507          * There may be other methods defined for properties, though, it seems they are not exposed 
1508          * in the reflection API 
1509          */
1510 }
1511
1512 static void
1513 ves_icall_get_event_info (MonoReflectionEvent *event, MonoEventInfo *info)
1514 {
1515         MonoDomain *domain = mono_object_domain (event); 
1516
1517         MONO_ARCH_SAVE_REGS;
1518
1519         info->declaring_type = mono_type_get_object (domain, &event->klass->byval_arg);
1520         info->reflected_type = mono_type_get_object (domain, &event->event->parent->byval_arg);
1521
1522         info->name = mono_string_new (domain, event->event->name);
1523         info->attrs = event->event->attrs;
1524         info->add_method = event->event->add ? mono_method_get_object (domain, event->event->add, NULL): NULL;
1525         info->remove_method = event->event->remove ? mono_method_get_object (domain, event->event->remove, NULL): NULL;
1526         info->raise_method = event->event->raise ? mono_method_get_object (domain, event->event->raise, NULL): NULL;
1527
1528         if (event->event->other) {
1529                 int i, n = 0;
1530                 while (event->event->other [n])
1531                         n++;
1532                 info->other_methods = mono_array_new (domain, mono_defaults.method_info_class, n);
1533
1534                 for (i = 0; i < n; i++)
1535                         mono_array_set (info->other_methods, gpointer, i,
1536                                                         mono_method_get_object (domain, event->event->other [i], NULL));
1537         }               
1538 }
1539
1540 static MonoArray*
1541 ves_icall_Type_GetInterfaces (MonoReflectionType* type)
1542 {
1543         MonoDomain *domain = mono_object_domain (type); 
1544         MonoArray *intf;
1545         GPtrArray *ifaces = NULL;
1546         int i;
1547         MonoClass *class = mono_class_from_mono_type (type->type);
1548         MonoClass *parent;
1549         MonoBitSet *slots = mono_bitset_new (class->max_interface_id + 1, 0);
1550
1551         MONO_ARCH_SAVE_REGS;
1552
1553         if (class->rank) {
1554                 /* GetInterfaces() returns an empty array in MS.NET (this may be a bug) */
1555                 mono_bitset_free (slots);
1556                 return mono_array_new (domain, mono_defaults.monotype_class, 0);
1557         }
1558
1559         for (parent = class; parent; parent = parent->parent) {
1560                 GPtrArray *tmp_ifaces = mono_class_get_implemented_interfaces (parent);
1561                 if (tmp_ifaces) {
1562                         for (i = 0; i < tmp_ifaces->len; ++i) {
1563                                 MonoClass *ic = g_ptr_array_index (tmp_ifaces, i);
1564
1565                                 if (mono_bitset_test (slots, ic->interface_id))
1566                                         continue;
1567
1568                                 mono_bitset_set (slots, ic->interface_id);
1569                                 if (ifaces == NULL)
1570                                         ifaces = g_ptr_array_new ();
1571                                 g_ptr_array_add (ifaces, ic);
1572                         }
1573                         g_ptr_array_free (tmp_ifaces, TRUE);
1574                 }
1575         }
1576         mono_bitset_free (slots);
1577
1578         if (!ifaces)
1579                 return mono_array_new (domain, mono_defaults.monotype_class, 0);
1580                 
1581         intf = mono_array_new (domain, mono_defaults.monotype_class, ifaces->len);
1582         for (i = 0; i < ifaces->len; ++i) {
1583                 MonoClass *ic = g_ptr_array_index (ifaces, i);
1584                 
1585                 mono_array_set (intf, gpointer, i,
1586                                                 mono_type_get_object (domain, &ic->byval_arg));
1587         }
1588         g_ptr_array_free (ifaces, TRUE);
1589
1590         return intf;
1591 }
1592
1593 static void
1594 ves_icall_Type_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType *iface, MonoArray **targets, MonoArray **methods)
1595 {
1596         MonoClass *class = mono_class_from_mono_type (type->type);
1597         MonoClass *iclass = mono_class_from_mono_type (iface->type);
1598         MonoReflectionMethod *member;
1599         MonoMethod* method;
1600         gpointer iter;
1601         int i = 0, len, ioffset;
1602         MonoDomain *domain;
1603
1604         MONO_ARCH_SAVE_REGS;
1605
1606         /* type doesn't implement iface: the exception is thrown in managed code */
1607         if ((iclass->interface_id > class->max_interface_id) || !class->interface_offsets [iclass->interface_id])
1608                         return;
1609
1610         len = mono_class_num_methods (iclass);
1611         ioffset = class->interface_offsets [iclass->interface_id];
1612         domain = mono_object_domain (type);
1613         *targets = mono_array_new (domain, mono_defaults.method_info_class, len);
1614         *methods = mono_array_new (domain, mono_defaults.method_info_class, len);
1615         iter = NULL;
1616         iter = NULL;
1617         while ((method = mono_class_get_methods (iclass, &iter))) {
1618                 member = mono_method_get_object (domain, method, iclass);
1619                 mono_array_set (*methods, gpointer, i, member);
1620                 member = mono_method_get_object (domain, class->vtable [i + ioffset], class);
1621                 mono_array_set (*targets, gpointer, i, member);
1622                 
1623                 i ++;
1624         }
1625 }
1626
1627 static void
1628 ves_icall_Type_GetPacking (MonoReflectionType *type, guint32 *packing, guint32 *size)
1629 {
1630         MonoClass *klass = mono_class_from_mono_type (type->type);
1631
1632         g_assert (!klass->image->dynamic);
1633
1634         mono_metadata_packing_from_typedef (klass->image, klass->type_token, packing, size);
1635 }
1636
1637 static MonoReflectionType*
1638 ves_icall_MonoType_GetElementType (MonoReflectionType *type)
1639 {
1640         MonoClass *class = mono_class_from_mono_type (type->type);
1641
1642         MONO_ARCH_SAVE_REGS;
1643
1644         // GelElementType should only return a type for:
1645         // Array Pointer PassedByRef
1646         if (type->type->byref)
1647                 return mono_type_get_object (mono_object_domain (type), &class->byval_arg);
1648         if (class->enumtype && class->enum_basetype) /* types that are modifierd typebuilkders may not have enum_basetype set */
1649                 return mono_type_get_object (mono_object_domain (type), class->enum_basetype);
1650         else if (class->element_class && MONO_CLASS_IS_ARRAY (class))
1651                 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
1652         else if (class->element_class && type->type->type == MONO_TYPE_PTR)
1653                 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
1654         else
1655                 return NULL;
1656 }
1657
1658 static MonoReflectionType*
1659 ves_icall_get_type_parent (MonoReflectionType *type)
1660 {
1661         MonoClass *class = mono_class_from_mono_type (type->type);
1662
1663         MONO_ARCH_SAVE_REGS;
1664
1665         return class->parent ? mono_type_get_object (mono_object_domain (type), &class->parent->byval_arg): NULL;
1666 }
1667
1668 static MonoBoolean
1669 ves_icall_type_ispointer (MonoReflectionType *type)
1670 {
1671         MONO_ARCH_SAVE_REGS;
1672
1673         return type->type->type == MONO_TYPE_PTR;
1674 }
1675
1676 static MonoBoolean
1677 ves_icall_type_isprimitive (MonoReflectionType *type)
1678 {
1679         MONO_ARCH_SAVE_REGS;
1680
1681         return (!type->type->byref && (((type->type->type >= MONO_TYPE_BOOLEAN) && (type->type->type <= MONO_TYPE_R8)) || (type->type->type == MONO_TYPE_I) || (type->type->type == MONO_TYPE_U)));
1682 }
1683
1684 static MonoBoolean
1685 ves_icall_type_isbyref (MonoReflectionType *type)
1686 {
1687         MONO_ARCH_SAVE_REGS;
1688
1689         return type->type->byref;
1690 }
1691
1692 static MonoReflectionModule*
1693 ves_icall_MonoType_get_Module (MonoReflectionType *type)
1694 {
1695         MonoClass *class = mono_class_from_mono_type (type->type);
1696
1697         MONO_ARCH_SAVE_REGS;
1698
1699         return mono_module_get_object (mono_object_domain (type), class->image);
1700 }
1701
1702 static MonoReflectionAssembly*
1703 ves_icall_MonoType_get_Assembly (MonoReflectionType *type)
1704 {
1705         MonoDomain *domain = mono_domain_get (); 
1706         MonoClass *class = mono_class_from_mono_type (type->type);
1707
1708         MONO_ARCH_SAVE_REGS;
1709
1710         return mono_assembly_get_object (domain, class->image->assembly);
1711 }
1712
1713 static MonoReflectionType*
1714 ves_icall_MonoType_get_DeclaringType (MonoReflectionType *type)
1715 {
1716         MonoDomain *domain = mono_domain_get (); 
1717         MonoClass *class = mono_class_from_mono_type (type->type);
1718
1719         MONO_ARCH_SAVE_REGS;
1720
1721         return class->nested_in ? mono_type_get_object (domain, &class->nested_in->byval_arg) : NULL;
1722 }
1723
1724 static MonoReflectionType*
1725 ves_icall_MonoType_get_UnderlyingSystemType (MonoReflectionType *type)
1726 {
1727         MonoDomain *domain = mono_domain_get (); 
1728         MonoClass *class = mono_class_from_mono_type (type->type);
1729
1730         MONO_ARCH_SAVE_REGS;
1731
1732         if (class->enumtype && class->enum_basetype) /* types that are modified typebuilders may not have enum_basetype set */
1733                 return mono_type_get_object (domain, class->enum_basetype);
1734         else if (class->element_class)
1735                 return mono_type_get_object (domain, &class->element_class->byval_arg);
1736         else
1737                 return NULL;
1738 }
1739
1740 static MonoString*
1741 ves_icall_MonoType_get_Name (MonoReflectionType *type)
1742 {
1743         MonoDomain *domain = mono_domain_get (); 
1744         MonoClass *class = mono_class_from_mono_type (type->type);
1745
1746         MONO_ARCH_SAVE_REGS;
1747
1748         return mono_string_new (domain, class->name);
1749 }
1750
1751 static MonoString*
1752 ves_icall_MonoType_get_Namespace (MonoReflectionType *type)
1753 {
1754         MonoDomain *domain = mono_domain_get (); 
1755         MonoClass *class = mono_class_from_mono_type (type->type);
1756
1757         MONO_ARCH_SAVE_REGS;
1758
1759         while (class->nested_in)
1760                 class = class->nested_in;
1761
1762         if (class->name_space [0] == '\0')
1763                 return NULL;
1764         else
1765                 return mono_string_new (domain, class->name_space);
1766 }
1767
1768 static gint32
1769 ves_icall_MonoType_GetArrayRank (MonoReflectionType *type)
1770 {
1771         MonoClass *class = mono_class_from_mono_type (type->type);
1772
1773         MONO_ARCH_SAVE_REGS;
1774
1775         return class->rank;
1776 }
1777
1778 static MonoArray*
1779 ves_icall_MonoType_GetGenericArguments (MonoReflectionType *type)
1780 {
1781         MonoArray *res;
1782         MonoClass *klass, *pklass;
1783         int i;
1784         MONO_ARCH_SAVE_REGS;
1785
1786         klass = mono_class_from_mono_type (type->type);
1787
1788         if (klass->generic_container) {
1789                 MonoGenericContainer *container = klass->generic_container;
1790                 res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, container->type_argc);
1791                 for (i = 0; i < container->type_argc; ++i) {
1792                         pklass = mono_class_from_generic_parameter (&container->type_params [i], klass->image, FALSE);
1793                         mono_array_set (res, gpointer, i, mono_type_get_object (mono_object_domain (type), &pklass->byval_arg));
1794                 }
1795         } else if (klass->generic_class) {
1796                 MonoGenericInst *inst = klass->generic_class->inst;
1797                 res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, inst->type_argc);
1798                 for (i = 0; i < inst->type_argc; ++i) {
1799                         mono_array_set (res, gpointer, i, mono_type_get_object (mono_object_domain (type), inst->type_argv [i]));
1800                 }
1801         } else {
1802                 res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, 0);
1803         }
1804         return res;
1805 }
1806
1807 static gboolean
1808 ves_icall_Type_get_IsGenericTypeDefinition (MonoReflectionType *type)
1809 {
1810         MonoClass *klass;
1811         MONO_ARCH_SAVE_REGS;
1812
1813         klass = mono_class_from_mono_type (type->type);
1814
1815         return klass->generic_container != NULL;
1816 }
1817
1818 static MonoReflectionType*
1819 ves_icall_Type_GetGenericTypeDefinition_impl (MonoReflectionType *type)
1820 {
1821         MonoClass *klass;
1822         MONO_ARCH_SAVE_REGS;
1823
1824         klass = mono_class_from_mono_type (type->type);
1825         if (klass->generic_container) {
1826                 return type; /* check this one */
1827         }
1828         if (klass->generic_class) {
1829                 MonoClass *generic_class = klass->generic_class->container_class;
1830
1831                 if (generic_class->wastypebuilder && generic_class->reflection_info)
1832                         return generic_class->reflection_info;
1833                 else
1834                         return mono_type_get_object (mono_object_domain (type), &generic_class->byval_arg);
1835         }
1836         return NULL;
1837 }
1838
1839 static MonoReflectionType*
1840 ves_icall_Type_BindGenericParameters (MonoReflectionType *type, MonoArray *type_array)
1841 {
1842         MonoType *geninst, **types;
1843         int i, count;
1844
1845         MONO_ARCH_SAVE_REGS;
1846
1847         count = mono_array_length (type_array);
1848         types = g_new0 (MonoType *, count);
1849
1850         for (i = 0; i < count; i++) {
1851                 MonoReflectionType *t = mono_array_get (type_array, gpointer, i);
1852                 types [i] = t->type;
1853         }
1854
1855         geninst = mono_reflection_bind_generic_parameters (type, count, types);
1856
1857         return mono_type_get_object (mono_object_domain (type), geninst);
1858 }
1859
1860 static gboolean
1861 ves_icall_Type_get_IsGenericInstance (MonoReflectionType *type)
1862 {
1863         MonoClass *klass;
1864         MONO_ARCH_SAVE_REGS;
1865
1866         klass = mono_class_from_mono_type (type->type);
1867         return klass->generic_class != NULL;
1868 }
1869
1870 static gint32
1871 ves_icall_Type_GetGenericParameterPosition (MonoReflectionType *type)
1872 {
1873         MONO_ARCH_SAVE_REGS;
1874
1875         if (type->type->type == MONO_TYPE_VAR || type->type->type == MONO_TYPE_MVAR)
1876                 return type->type->data.generic_param->num;
1877         return -1;
1878 }
1879
1880 static GenericParameterAttributes
1881 ves_icall_Type_GetGenericParameterAttributes (MonoReflectionType *type)
1882 {
1883         MONO_ARCH_SAVE_REGS;
1884         return type->type->data.generic_param->flags;
1885 }
1886
1887 static MonoArray *
1888 ves_icall_Type_GetGenericParameterConstraints (MonoReflectionType *type)
1889 {
1890         MonoGenericParam *param;
1891         MonoDomain *domain;
1892         MonoClass **ptr;
1893         MonoArray *res;
1894         int i, count;
1895
1896         MONO_ARCH_SAVE_REGS;
1897
1898         domain = mono_object_domain (type);
1899         param = type->type->data.generic_param;
1900         for (count = 0, ptr = param->constraints; ptr && *ptr; ptr++, count++)
1901                 ;
1902
1903         res = mono_array_new (domain, mono_defaults.monotype_class, count);
1904         for (i = 0; i < count; i++)
1905                 mono_array_set (res, gpointer, i,
1906                                 mono_type_get_object (domain, &param->constraints [i]->byval_arg));
1907
1908
1909         return res;
1910 }
1911
1912 static MonoBoolean
1913 ves_icall_MonoType_get_HasGenericArguments (MonoReflectionType *type)
1914 {
1915         MonoClass *klass;
1916         MONO_ARCH_SAVE_REGS;
1917
1918         klass = mono_class_from_mono_type (type->type);
1919         if (klass->generic_container || klass->generic_class)
1920                 return TRUE;
1921         return FALSE;
1922 }
1923
1924 static MonoBoolean
1925 ves_icall_MonoType_get_IsGenericParameter (MonoReflectionType *type)
1926 {
1927         MONO_ARCH_SAVE_REGS;
1928
1929         if (type->type->type == MONO_TYPE_VAR || type->type->type == MONO_TYPE_MVAR)
1930                 return TRUE;
1931         return FALSE;
1932 }
1933
1934 static MonoBoolean
1935 ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder *tb)
1936 {
1937         MONO_ARCH_SAVE_REGS;
1938
1939         if (tb->type.type->type == MONO_TYPE_VAR || tb->type.type->type == MONO_TYPE_MVAR)
1940                 return TRUE;
1941         return FALSE;
1942 }
1943
1944 static void
1945 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
1946                                                                            MonoReflectionType *t)
1947 {
1948         enumtype->type = t->type;
1949 }
1950
1951 static MonoReflectionType*
1952 ves_icall_MonoGenericClass_GetParentType (MonoReflectionGenericClass *type)
1953 {
1954         MonoGenericClass *gclass;
1955         MonoClass *klass;
1956
1957         MONO_ARCH_SAVE_REGS;
1958
1959         gclass = type->type.type->data.generic_class;
1960         if (!gclass || !gclass->parent || (gclass->parent->type != MONO_TYPE_GENERICINST))
1961                 return NULL;
1962
1963         klass = mono_class_from_mono_type (gclass->parent);
1964         if (!klass->generic_class && !klass->generic_container)
1965                 return NULL;
1966
1967         if (!klass->generic_class->is_dynamic)
1968                 return NULL;
1969
1970         return mono_type_get_object (mono_object_domain (type), gclass->parent);
1971 }
1972
1973 static MonoArray*
1974 ves_icall_MonoGenericClass_GetInterfaces (MonoReflectionGenericClass *type)
1975 {
1976         static MonoClass *System_Reflection_MonoGenericClass;
1977         MonoGenericClass *gclass;
1978         MonoDomain *domain;
1979         MonoClass *klass;
1980         MonoArray *res;
1981         int i;
1982
1983         MONO_ARCH_SAVE_REGS;
1984
1985         if (!System_Reflection_MonoGenericClass) {
1986                 System_Reflection_MonoGenericClass = mono_class_from_name (
1987                         mono_defaults.corlib, "System.Reflection", "MonoGenericClass");
1988                 g_assert (System_Reflection_MonoGenericClass);
1989         }
1990
1991         domain = mono_object_domain (type);
1992
1993         gclass = type->type.type->data.generic_class;
1994         if (!gclass || !gclass->ifaces)
1995                 return mono_array_new (domain, System_Reflection_MonoGenericClass, 0);
1996
1997         klass = gclass->container_class;
1998
1999         res = mono_array_new (domain, System_Reflection_MonoGenericClass, gclass->count_ifaces);
2000
2001         for (i = 0; i < gclass->count_ifaces; i++) {
2002                 MonoReflectionType *iface = mono_type_get_object (domain, gclass->ifaces [i]);
2003
2004                 mono_array_set (res, gpointer, i, iface);
2005         }
2006
2007         return res;
2008 }
2009
2010
2011 static MonoReflectionMethod*
2012 ves_icall_MonoGenericClass_GetCorrespondingInflatedMethod (MonoReflectionGenericClass *type, 
2013                                                            MonoReflectionMethod* generic)
2014 {
2015         MonoGenericClass *gclass;
2016         MonoDynamicGenericClass *dgclass;
2017         MonoDomain *domain;
2018         int i;
2019
2020         MONO_ARCH_SAVE_REGS;
2021
2022         gclass = type->type.type->data.generic_class;
2023         g_assert (gclass->is_dynamic);
2024
2025         dgclass = (MonoDynamicGenericClass *) gclass;
2026
2027         domain = mono_object_domain (type);
2028
2029         for (i = 0; i < dgclass->count_methods; i++)
2030                 if (generic->method->token == dgclass->methods [i]->token)
2031                         return mono_method_get_object (domain, dgclass->methods [i], NULL);
2032
2033         return NULL;
2034 }
2035
2036 static MonoReflectionMethod*
2037 ves_icall_MonoGenericClass_GetCorrespondingInflatedConstructor (MonoReflectionGenericClass *type, 
2038                                                                 MonoReflectionMethod* generic)
2039 {
2040         MonoGenericClass *gclass;
2041         MonoDynamicGenericClass *dgclass;
2042         MonoDomain *domain;
2043         int i;
2044
2045         MONO_ARCH_SAVE_REGS;
2046
2047         gclass = type->type.type->data.generic_class;
2048         g_assert (gclass->is_dynamic);
2049
2050         dgclass = (MonoDynamicGenericClass *) gclass;
2051
2052         domain = mono_object_domain (type);
2053
2054         for (i = 0; i < dgclass->count_ctors; i++)
2055                 if (generic->method->token == dgclass->ctors [i]->token)
2056                         return mono_method_get_object (domain, dgclass->ctors [i], NULL);
2057
2058         return NULL;
2059 }
2060
2061
2062 static MonoReflectionField*
2063 ves_icall_MonoGenericClass_GetCorrespondingInflatedField (MonoReflectionGenericClass *type, 
2064                                                           MonoString* generic_name)
2065 {
2066         MonoGenericClass *gclass;
2067         MonoDynamicGenericClass *dgclass;
2068         MonoDomain *domain;
2069         MonoClass *refclass;
2070         char *utf8_name = mono_string_to_utf8 (generic_name);
2071         int i;
2072
2073         MONO_ARCH_SAVE_REGS;
2074
2075         gclass = type->type.type->data.generic_class;
2076         g_assert (gclass->is_dynamic);
2077
2078         dgclass = (MonoDynamicGenericClass *) gclass;
2079
2080         refclass = mono_class_from_mono_type (type->type.type);
2081
2082         domain = mono_object_domain (type);
2083
2084         for (i = 0; i < dgclass->count_fields; i++)
2085                 if (strcmp (utf8_name, dgclass->fields [i].name) == 0) {
2086                         g_free (utf8_name);
2087                         return mono_field_get_object (domain, refclass, &dgclass->fields [i]);
2088                 }
2089         
2090         g_free (utf8_name);
2091
2092         return NULL;
2093 }
2094
2095
2096 static MonoReflectionMethod*
2097 ves_icall_MonoType_GetCorrespondingInflatedMethod (MonoReflectionType *type, 
2098                                                    MonoReflectionMethod* generic)
2099 {
2100         MonoDomain *domain; 
2101         MonoClass *klass;
2102         MonoMethod *method;
2103         gpointer iter;
2104                 
2105         MONO_ARCH_SAVE_REGS;
2106
2107         domain = ((MonoObject *)type)->vtable->domain;
2108
2109         klass = mono_class_from_mono_type (type->type);
2110
2111         iter = NULL;
2112         while ((method = mono_class_get_methods (klass, &iter))) {
2113                 if (method->token == generic->method->token)
2114                         return mono_method_get_object (domain, method, klass);
2115         }
2116
2117         return NULL;
2118 }
2119
2120 static MonoArray*
2121 ves_icall_MonoGenericClass_GetMethods (MonoReflectionGenericClass *type,
2122                                        MonoReflectionType *reflected_type)
2123 {
2124         MonoGenericClass *gclass;
2125         MonoDynamicGenericClass *dgclass;
2126         MonoDomain *domain;
2127         MonoClass *refclass;
2128         MonoArray *res;
2129         int i;
2130
2131         MONO_ARCH_SAVE_REGS;
2132
2133         gclass = type->type.type->data.generic_class;
2134         g_assert (gclass->is_dynamic);
2135         dgclass = (MonoDynamicGenericClass *) gclass;
2136
2137         refclass = mono_class_from_mono_type (reflected_type->type);
2138
2139         domain = mono_object_domain (type);
2140         res = mono_array_new (domain, mono_defaults.method_info_class, dgclass->count_methods);
2141
2142         for (i = 0; i < dgclass->count_methods; i++)
2143                 mono_array_set (res, gpointer, i,
2144                                 mono_method_get_object (domain, dgclass->methods [i], refclass));
2145
2146         return res;
2147 }
2148
2149 static MonoArray*
2150 ves_icall_MonoGenericClass_GetConstructors (MonoReflectionGenericClass *type,
2151                                             MonoReflectionType *reflected_type)
2152 {
2153         static MonoClass *System_Reflection_ConstructorInfo;
2154         MonoGenericClass *gclass;
2155         MonoDynamicGenericClass *dgclass;
2156         MonoDomain *domain;
2157         MonoClass *refclass;
2158         MonoArray *res;
2159         int i;
2160
2161         MONO_ARCH_SAVE_REGS;
2162
2163         if (!System_Reflection_ConstructorInfo)
2164                 System_Reflection_ConstructorInfo = mono_class_from_name (
2165                         mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
2166
2167         gclass = type->type.type->data.generic_class;
2168         g_assert (gclass->is_dynamic);
2169         dgclass = (MonoDynamicGenericClass *) gclass;
2170
2171         refclass = mono_class_from_mono_type (reflected_type->type);
2172
2173         domain = mono_object_domain (type);
2174         res = mono_array_new (domain, System_Reflection_ConstructorInfo, dgclass->count_ctors);
2175
2176         for (i = 0; i < dgclass->count_ctors; i++)
2177                 mono_array_set (res, gpointer, i,
2178                                 mono_method_get_object (domain, dgclass->ctors [i], refclass));
2179
2180         return res;
2181 }
2182
2183 static MonoArray*
2184 ves_icall_MonoGenericClass_GetFields (MonoReflectionGenericClass *type,
2185                                       MonoReflectionType *reflected_type)
2186 {
2187         MonoGenericClass *gclass;
2188         MonoDynamicGenericClass *dgclass;
2189         MonoDomain *domain;
2190         MonoClass *refclass;
2191         MonoArray *res;
2192         int i;
2193
2194         MONO_ARCH_SAVE_REGS;
2195
2196         gclass = type->type.type->data.generic_class;
2197         g_assert (gclass->is_dynamic);
2198         dgclass = (MonoDynamicGenericClass *) gclass;
2199
2200         refclass = mono_class_from_mono_type (reflected_type->type);
2201
2202         domain = mono_object_domain (type);
2203         res = mono_array_new (domain, mono_defaults.field_info_class, dgclass->count_fields);
2204
2205         for (i = 0; i < dgclass->count_fields; i++)
2206                 mono_array_set (res, gpointer, i,
2207                                 mono_field_get_object (domain, refclass, &dgclass->fields [i]));
2208
2209         return res;
2210 }
2211
2212 static MonoArray*
2213 ves_icall_MonoGenericClass_GetProperties (MonoReflectionGenericClass *type,
2214                                           MonoReflectionType *reflected_type)
2215 {
2216         static MonoClass *System_Reflection_PropertyInfo;
2217         MonoGenericClass *gclass;
2218         MonoDynamicGenericClass *dgclass;
2219         MonoDomain *domain;
2220         MonoClass *refclass;
2221         MonoArray *res;
2222         int i;
2223
2224         MONO_ARCH_SAVE_REGS;
2225
2226         if (!System_Reflection_PropertyInfo)
2227                 System_Reflection_PropertyInfo = mono_class_from_name (
2228                         mono_defaults.corlib, "System.Reflection", "PropertyInfo");
2229
2230         gclass = type->type.type->data.generic_class;
2231         g_assert (gclass->is_dynamic);
2232         dgclass = (MonoDynamicGenericClass *) gclass;
2233
2234         refclass = mono_class_from_mono_type (reflected_type->type);
2235
2236         domain = mono_object_domain (type);
2237         res = mono_array_new (domain, System_Reflection_PropertyInfo, dgclass->count_properties);
2238
2239         for (i = 0; i < dgclass->count_properties; i++)
2240                 mono_array_set (res, gpointer, i,
2241                                 mono_property_get_object (domain, refclass, &dgclass->properties [i]));
2242
2243         return res;
2244 }
2245
2246 static MonoArray*
2247 ves_icall_MonoGenericClass_GetEvents (MonoReflectionGenericClass *type,
2248                                       MonoReflectionType *reflected_type)
2249 {
2250         static MonoClass *System_Reflection_EventInfo;
2251         MonoGenericClass *gclass;
2252         MonoDynamicGenericClass *dgclass;
2253         MonoDomain *domain;
2254         MonoClass *refclass;
2255         MonoArray *res;
2256         int i;
2257
2258         MONO_ARCH_SAVE_REGS;
2259
2260         if (!System_Reflection_EventInfo)
2261                 System_Reflection_EventInfo = mono_class_from_name (
2262                         mono_defaults.corlib, "System.Reflection", "EventInfo");
2263
2264         gclass = type->type.type->data.generic_class;
2265         g_assert (gclass->is_dynamic);
2266         dgclass = (MonoDynamicGenericClass *) gclass;
2267
2268         refclass = mono_class_from_mono_type (reflected_type->type);
2269
2270         domain = mono_object_domain (type);
2271         res = mono_array_new (domain, System_Reflection_EventInfo, dgclass->count_events);
2272
2273         for (i = 0; i < dgclass->count_events; i++)
2274                 mono_array_set (res, gpointer, i,
2275                                 mono_event_get_object (domain, refclass, &dgclass->events [i]));
2276
2277         return res;
2278 }
2279
2280 static MonoReflectionMethod *
2281 ves_icall_MonoType_get_DeclaringMethod (MonoReflectionType *type)
2282 {
2283         MonoMethod *method;
2284         MonoClass *klass;
2285
2286         MONO_ARCH_SAVE_REGS;
2287
2288         method = type->type->data.generic_param->method;
2289         if (!method)
2290                 return NULL;
2291
2292         klass = mono_class_from_mono_type (type->type);
2293         return mono_method_get_object (mono_object_domain (type), method, klass);
2294 }
2295
2296 static MonoReflectionDllImportAttribute*
2297 ves_icall_MonoMethod_GetDllImportAttribute (MonoMethod *method)
2298 {
2299         static MonoClass *DllImportAttributeClass = NULL;
2300         MonoDomain *domain = mono_domain_get ();
2301         MonoReflectionDllImportAttribute *attr;
2302         MonoImage *image = method->klass->image;
2303         MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method;
2304         MonoTableInfo *tables = image->tables;
2305         MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
2306         MonoTableInfo *mr = &tables [MONO_TABLE_MODULEREF];
2307         guint32 im_cols [MONO_IMPLMAP_SIZE];
2308         guint32 scope_token;
2309         const char *import = NULL;
2310         const char *scope = NULL;
2311         guint32 flags;
2312
2313         if (!method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)
2314                 return NULL;
2315
2316         if (!DllImportAttributeClass) {
2317                 DllImportAttributeClass = 
2318                         mono_class_from_name (mono_defaults.corlib,
2319                                                                   "System.Runtime.InteropServices", "DllImportAttribute");
2320                 g_assert (DllImportAttributeClass);
2321         }
2322                                                                                                                 
2323         if (method->klass->image->dynamic) {
2324                 MonoReflectionMethodAux *method_aux = 
2325                         g_hash_table_lookup (
2326                                                                           ((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
2327                 if (method_aux) {
2328                         import = method_aux->dllentry;
2329                         scope = method_aux->dll;
2330                 }
2331         }
2332         else {
2333                 if (piinfo->implmap_idx) {
2334                         mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
2335                         
2336                         piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
2337                         import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
2338                         scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
2339                         scope = mono_metadata_string_heap (image, scope_token);
2340                 }
2341         }
2342         flags = piinfo->piflags;
2343         
2344         attr = (MonoReflectionDllImportAttribute*)mono_object_new (domain, DllImportAttributeClass);
2345
2346         attr->dll = mono_string_new (domain, scope);
2347         attr->entry_point = mono_string_new (domain, import);
2348         attr->call_conv = (flags & 0x700) >> 8;
2349         attr->charset = ((flags & 0x6) >> 1) + 1;
2350         if (attr->charset == 1)
2351                 attr->charset = 2;
2352         attr->exact_spelling = (flags & 0x1) != 0;
2353         attr->set_last_error = (flags & 0x40) != 0;
2354         attr->best_fit_mapping = (flags & 0x30) == 0x10;
2355         attr->throw_on_unmappable = (flags & 0x3000) == 0x1000;
2356         attr->preserve_sig = FALSE;
2357
2358         return attr;
2359 }
2360
2361 static MonoReflectionMethod *
2362 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
2363 {
2364         MonoMethodInflated *imethod;
2365
2366         MONO_ARCH_SAVE_REGS;
2367
2368         if (!method->method->is_inflated) {
2369                 if (mono_method_signature (method->method)->generic_param_count)
2370                         return method;
2371
2372                 return NULL;
2373         }
2374
2375         imethod = (MonoMethodInflated *) method->method;
2376         if (imethod->context->gmethod && imethod->context->gmethod->reflection_info)
2377                 return imethod->context->gmethod->reflection_info;
2378         else
2379                 return mono_method_get_object (
2380                         mono_object_domain (method), imethod->declaring, NULL);
2381 }
2382
2383 static gboolean
2384 ves_icall_MonoMethod_get_HasGenericParameters (MonoReflectionMethod *method)
2385 {
2386         MONO_ARCH_SAVE_REGS;
2387
2388         if ((method->method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
2389             (method->method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
2390                 return FALSE;
2391
2392         return mono_method_signature (method->method)->generic_param_count != 0;
2393 }
2394
2395 static gboolean
2396 ves_icall_MonoMethod_get_Mono_IsInflatedMethod (MonoReflectionMethod *method)
2397 {
2398         MONO_ARCH_SAVE_REGS;
2399
2400         if ((method->method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
2401             (method->method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
2402                 return FALSE;
2403
2404         return method->method->is_inflated;
2405 }
2406
2407 static gboolean
2408 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method)
2409 {
2410         MONO_ARCH_SAVE_REGS;
2411
2412         if ((method->method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
2413             (method->method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
2414                 return FALSE;
2415
2416         return mono_method_signature (method->method)->generic_param_count != 0;
2417 }
2418
2419 static MonoArray*
2420 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
2421 {
2422         MonoArray *res;
2423         MonoDomain *domain;
2424         MonoMethodNormal *mn;
2425         int count, i;
2426         MONO_ARCH_SAVE_REGS;
2427
2428         domain = mono_object_domain (method);
2429
2430         if ((method->method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
2431             (method->method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
2432                 return mono_array_new (domain, mono_defaults.monotype_class, 0);
2433
2434         if (method->method->is_inflated) {
2435                 MonoMethodInflated *imethod = (MonoMethodInflated *) method->method;
2436                 MonoGenericMethod *gmethod = imethod->context->gmethod;
2437
2438                 if (gmethod) {
2439                         count = gmethod->inst->type_argc;
2440                         res = mono_array_new (domain, mono_defaults.monotype_class, count);
2441
2442                         for (i = 0; i < count; i++) {
2443                                 MonoType *t = gmethod->inst->type_argv [i];
2444                                 mono_array_set (
2445                                         res, gpointer, i, mono_type_get_object (domain, t));
2446                         }
2447
2448                         return res;
2449                 }
2450         }
2451
2452         mn = (MonoMethodNormal *) method->method;
2453         count = mono_method_signature (method->method)->generic_param_count;
2454         res = mono_array_new (domain, mono_defaults.monotype_class, count);
2455
2456         for (i = 0; i < count; i++) {
2457                 MonoGenericParam *param = &mn->generic_container->type_params [i];
2458                 MonoClass *pklass = mono_class_from_generic_parameter (
2459                         param, method->method->klass->image, TRUE);
2460                 mono_array_set (res, gpointer, i,
2461                                 mono_type_get_object (domain, &pklass->byval_arg));
2462         }
2463
2464         return res;
2465 }
2466
2467 static MonoObject *
2468 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoArray *params) 
2469 {
2470         /* 
2471          * Invoke from reflection is supposed to always be a virtual call (the API
2472          * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
2473          * greater flexibility.
2474          */
2475         MonoMethod *m = method->method;
2476         int pcount;
2477         void *obj = this;
2478
2479         MONO_ARCH_SAVE_REGS;
2480
2481         if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
2482                 if (this) {
2483                         if (!mono_object_isinst (this, m->klass))
2484                                 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
2485                         m = mono_object_get_virtual_method (this, m);
2486                         /* must pass the pointer to the value for valuetype methods */
2487                         if (m->klass->valuetype)
2488                                 obj = mono_object_unbox (this);
2489                 } else if (strcmp (m->name, ".ctor") && !m->wrapper_type)
2490                         mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
2491         }
2492
2493         pcount = params? mono_array_length (params): 0;
2494         if (pcount != mono_method_signature (m)->param_count)
2495                 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
2496
2497         if ((m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) && !strcmp (m->name, ".ctor"))
2498                 mono_raise_exception (mono_exception_from_name_msg (mono_defaults.corlib, "System", "MethodAccessException", "Cannot invoke constructor of an abstract class."));
2499
2500         if (m->klass->image->assembly->ref_only)
2501                 mono_raise_exception (mono_get_exception_invalid_operation ("It is illegal to invoke a method on a type loaded using the ReflectionOnly api."));
2502         
2503         if (m->klass->rank && !strcmp (m->name, ".ctor")) {
2504                 int i;
2505                 guint32 *lengths;
2506                 guint32 *lower_bounds;
2507                 pcount = mono_array_length (params);
2508                 lengths = alloca (sizeof (guint32) * pcount);
2509                 for (i = 0; i < pcount; ++i)
2510                         lengths [i] = *(gint32*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
2511
2512                 if (m->klass->rank == pcount) {
2513                         /* Only lengths provided. */
2514                         lower_bounds = NULL;
2515                 } else {
2516                         g_assert (pcount == (m->klass->rank * 2));
2517                         /* lower bounds are first. */
2518                         lower_bounds = lengths;
2519                         lengths += m->klass->rank;
2520                 }
2521
2522                 return (MonoObject*)mono_array_new_full (mono_object_domain (params), m->klass, lengths, lower_bounds);
2523         }
2524         return mono_runtime_invoke_array (m, obj, params, NULL);
2525 }
2526
2527 static MonoObject *
2528 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this, MonoArray *params, MonoArray **outArgs) 
2529 {
2530         MonoDomain *domain = mono_object_domain (method); 
2531         MonoMethod *m = method->method;
2532         MonoMethodSignature *sig = mono_method_signature (m);
2533         MonoArray *out_args;
2534         MonoObject *result;
2535         int i, j, outarg_count = 0;
2536
2537         MONO_ARCH_SAVE_REGS;
2538
2539         if (m->klass == mono_defaults.object_class) {
2540
2541                 if (!strcmp (m->name, "FieldGetter")) {
2542                         MonoClass *k = this->vtable->klass;
2543                         MonoString *name;
2544                         char *str;
2545                         
2546                         /* If this is a proxy, then it must be a CBO */
2547                         if (k == mono_defaults.transparent_proxy_class) {
2548                                 MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
2549                                 this = tp->rp->unwrapped_server;
2550                                 g_assert (this);
2551                                 k = this->vtable->klass;
2552                         }
2553                         
2554                         name = mono_array_get (params, MonoString *, 1);
2555                         str = mono_string_to_utf8 (name);
2556                 
2557                         do {
2558                                 MonoClassField* field = mono_class_get_field_from_name (k, str);
2559                                 if (field) {
2560                                         MonoClass *field_klass =  mono_class_from_mono_type (field->type);
2561                                         if (field_klass->valuetype)
2562                                                 result = mono_value_box (domain, field_klass, (char *)this + field->offset);
2563                                         else 
2564                                                 result = *((gpointer *)((char *)this + field->offset));
2565                                 
2566                                         g_assert (result);
2567                                         out_args = mono_array_new (domain, mono_defaults.object_class, 1);
2568                                         *outArgs = out_args;
2569                                         mono_array_set (out_args, gpointer, 0, result);
2570                                         g_free (str);
2571                                         return NULL;
2572                                 }
2573                                 k = k->parent;
2574                         } while (k);
2575
2576                         g_free (str);
2577                         g_assert_not_reached ();
2578
2579                 } else if (!strcmp (m->name, "FieldSetter")) {
2580                         MonoClass *k = this->vtable->klass;
2581                         MonoString *name;
2582                         int size, align;
2583                         char *str;
2584                         
2585                         /* If this is a proxy, then it must be a CBO */
2586                         if (k == mono_defaults.transparent_proxy_class) {
2587                                 MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
2588                                 this = tp->rp->unwrapped_server;
2589                                 g_assert (this);
2590                                 k = this->vtable->klass;
2591                         }
2592                         
2593                         name = mono_array_get (params, MonoString *, 1);
2594                         str = mono_string_to_utf8 (name);
2595                 
2596                         do {
2597                                 MonoClassField* field = mono_class_get_field_from_name (k, str);
2598                                 if (field) {
2599                                         MonoClass *field_klass =  mono_class_from_mono_type (field->type);
2600                                         MonoObject *val = mono_array_get (params, gpointer, 2);
2601
2602                                         if (field_klass->valuetype) {
2603                                                 size = mono_type_size (field->type, &align);
2604                                                 memcpy ((char *)this + field->offset, 
2605                                                         ((char *)val) + sizeof (MonoObject), size);
2606                                         } else 
2607                                                 *(MonoObject**)((char *)this + field->offset) = val;
2608                                 
2609                                         out_args = mono_array_new (domain, mono_defaults.object_class, 0);
2610                                         *outArgs = out_args;
2611
2612                                         g_free (str);
2613                                         return NULL;
2614                                 }
2615                                 
2616                                 k = k->parent;
2617                         } while (k);
2618
2619                         g_free (str);
2620                         g_assert_not_reached ();
2621
2622                 }
2623         }
2624
2625         for (i = 0; i < mono_array_length (params); i++) {
2626                 if (sig->params [i]->byref) 
2627                         outarg_count++;
2628         }
2629
2630         out_args = mono_array_new (domain, mono_defaults.object_class, outarg_count);
2631         
2632         /* handle constructors only for objects already allocated */
2633         if (!strcmp (method->method->name, ".ctor"))
2634                 g_assert (this);
2635
2636         /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
2637         g_assert (!method->method->klass->valuetype);
2638         result = mono_runtime_invoke_array (method->method, this, params, NULL);
2639
2640         for (i = 0, j = 0; i < mono_array_length (params); i++) {
2641                 if (sig->params [i]->byref) {
2642                         gpointer arg;
2643                         arg = mono_array_get (params, gpointer, i);
2644                         mono_array_set (out_args, gpointer, j, arg);
2645                         j++;
2646                 }
2647         }
2648
2649         *outArgs = out_args;
2650
2651         return result;
2652 }
2653
2654 static MonoObject *
2655 ves_icall_System_Enum_ToObject (MonoReflectionType *type, MonoObject *obj)
2656 {
2657         MonoDomain *domain; 
2658         MonoClass *enumc, *objc;
2659         gint32 s1, s2;
2660         MonoObject *res;
2661         
2662         MONO_ARCH_SAVE_REGS;
2663
2664         MONO_CHECK_ARG_NULL (type);
2665         MONO_CHECK_ARG_NULL (obj);
2666
2667         domain = mono_object_domain (type); 
2668         enumc = mono_class_from_mono_type (type->type);
2669         objc = obj->vtable->klass;
2670
2671         MONO_CHECK_ARG (obj, enumc->enumtype == TRUE);
2672         MONO_CHECK_ARG (obj, (objc->enumtype) || (objc->byval_arg.type >= MONO_TYPE_I1 &&
2673                                                   objc->byval_arg.type <= MONO_TYPE_U8));
2674         
2675         s1 = mono_class_value_size (enumc, NULL);
2676         s2 = mono_class_value_size (objc, NULL);
2677
2678         res = mono_object_new (domain, enumc);
2679
2680 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
2681         memcpy ((char *)res + sizeof (MonoObject), (char *)obj + sizeof (MonoObject), MIN (s1, s2));
2682 #else
2683         memcpy ((char *)res + sizeof (MonoObject) + (s1 > s2 ? s1 - s2 : 0),
2684                 (char *)obj + sizeof (MonoObject) + (s2 > s1 ? s2 - s1 : 0),
2685                 MIN (s1, s2));
2686 #endif
2687         return res;
2688 }
2689
2690 static MonoObject *
2691 ves_icall_System_Enum_get_value (MonoObject *this)
2692 {
2693         MonoObject *res;
2694         MonoClass *enumc;
2695         gpointer dst;
2696         gpointer src;
2697         int size;
2698
2699         MONO_ARCH_SAVE_REGS;
2700
2701         if (!this)
2702                 return NULL;
2703
2704         g_assert (this->vtable->klass->enumtype);
2705         
2706         enumc = mono_class_from_mono_type (this->vtable->klass->enum_basetype);
2707         res = mono_object_new (mono_object_domain (this), enumc);
2708         dst = (char *)res + sizeof (MonoObject);
2709         src = (char *)this + sizeof (MonoObject);
2710         size = mono_class_value_size (enumc, NULL);
2711
2712         memcpy (dst, src, size);
2713
2714         return res;
2715 }
2716
2717 static void
2718 ves_icall_get_enum_info (MonoReflectionType *type, MonoEnumInfo *info)
2719 {
2720         MonoDomain *domain = mono_object_domain (type); 
2721         MonoClass *enumc = mono_class_from_mono_type (type->type);
2722         guint j = 0, nvalues, crow;
2723         gpointer iter;
2724         MonoClassField *field;
2725
2726         MONO_ARCH_SAVE_REGS;
2727
2728         info->utype = mono_type_get_object (domain, enumc->enum_basetype);
2729         nvalues = mono_class_num_fields (enumc) ? mono_class_num_fields (enumc) - 1 : 0;
2730         info->names = mono_array_new (domain, mono_defaults.string_class, nvalues);
2731         info->values = mono_array_new (domain, enumc, nvalues);
2732         
2733         crow = -1;
2734         iter = NULL;
2735         while ((field = mono_class_get_fields (enumc, &iter))) {
2736                 const char *p;
2737                 int len;
2738                 
2739                 if (strcmp ("value__", field->name) == 0)
2740                         continue;
2741                 if (mono_field_is_deleted (field))
2742                         continue;
2743                 mono_array_set (info->names, gpointer, j, mono_string_new (domain, field->name));
2744
2745                 if (!field->data) {
2746                         crow = mono_metadata_get_constant_index (enumc->image, mono_class_get_field_token (field), crow + 1);
2747                         field->def_type = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_TYPE);
2748                         crow = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_VALUE);
2749                         field->data = (gpointer)mono_metadata_blob_heap (enumc->image, crow);
2750                 }
2751
2752                 p = field->data;
2753                 len = mono_metadata_decode_blob_size (p, &p);
2754                 switch (enumc->enum_basetype->type) {
2755                 case MONO_TYPE_U1:
2756                 case MONO_TYPE_I1:
2757                         mono_array_set (info->values, gchar, j, *p);
2758                         break;
2759                 case MONO_TYPE_CHAR:
2760                 case MONO_TYPE_U2:
2761                 case MONO_TYPE_I2:
2762                         mono_array_set (info->values, gint16, j, read16 (p));
2763                         break;
2764                 case MONO_TYPE_U4:
2765                 case MONO_TYPE_I4:
2766                         mono_array_set (info->values, gint32, j, read32 (p));
2767                         break;
2768                 case MONO_TYPE_U8:
2769                 case MONO_TYPE_I8:
2770                         mono_array_set (info->values, gint64, j, read64 (p));
2771                         break;
2772                 default:
2773                         g_error ("Implement type 0x%02x in get_enum_info", enumc->enum_basetype->type);
2774                 }
2775                 ++j;
2776         }
2777 }
2778
2779 enum {
2780         BFLAGS_IgnoreCase = 1,
2781         BFLAGS_DeclaredOnly = 2,
2782         BFLAGS_Instance = 4,
2783         BFLAGS_Static = 8,
2784         BFLAGS_Public = 0x10,
2785         BFLAGS_NonPublic = 0x20,
2786         BFLAGS_FlattenHierarchy = 0x40,
2787         BFLAGS_InvokeMethod = 0x100,
2788         BFLAGS_CreateInstance = 0x200,
2789         BFLAGS_GetField = 0x400,
2790         BFLAGS_SetField = 0x800,
2791         BFLAGS_GetProperty = 0x1000,
2792         BFLAGS_SetProperty = 0x2000,
2793         BFLAGS_ExactBinding = 0x10000,
2794         BFLAGS_SuppressChangeType = 0x20000,
2795         BFLAGS_OptionalParamBinding = 0x40000
2796 };
2797
2798 static MonoReflectionField *
2799 ves_icall_Type_GetField (MonoReflectionType *type, MonoString *name, guint32 bflags)
2800 {
2801         MonoDomain *domain; 
2802         MonoClass *startklass, *klass;
2803         int match;
2804         MonoClassField *field;
2805         gpointer iter;
2806         char *utf8_name;
2807         int (*compare_func) (const char *s1, const char *s2) = NULL;
2808         domain = ((MonoObject *)type)->vtable->domain;
2809         klass = startklass = mono_class_from_mono_type (type->type);
2810
2811         MONO_ARCH_SAVE_REGS;
2812
2813         if (!name)
2814                 mono_raise_exception (mono_get_exception_argument_null ("name"));
2815         if (type->type->byref)
2816                 return NULL;
2817
2818         compare_func = (bflags & BFLAGS_IgnoreCase) ? g_strcasecmp : strcmp;
2819
2820 handle_parent:
2821         iter = NULL;
2822         while ((field = mono_class_get_fields (klass, &iter))) {
2823                 match = 0;
2824                 if (mono_field_is_deleted (field))
2825                         continue;
2826                 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
2827                         if (bflags & BFLAGS_Public)
2828                                 match++;
2829                 } else {
2830                         if (bflags & BFLAGS_NonPublic)
2831                                 match++;
2832                 }
2833                 if (!match)
2834                         continue;
2835                 match = 0;
2836                 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
2837                         if (bflags & BFLAGS_Static)
2838                                 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
2839                                         match++;
2840                 } else {
2841                         if (bflags & BFLAGS_Instance)
2842                                 match++;
2843                 }
2844
2845                 if (!match)
2846                         continue;
2847                 
2848                 utf8_name = mono_string_to_utf8 (name);
2849
2850                 if (compare_func (field->name, utf8_name)) {
2851                         g_free (utf8_name);
2852                         continue;
2853                 }
2854                 g_free (utf8_name);
2855                 
2856                 return mono_field_get_object (domain, startklass, field);
2857         }
2858         if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
2859                 goto handle_parent;
2860
2861         return NULL;
2862 }
2863
2864 static MonoArray*
2865 ves_icall_Type_GetFields_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
2866 {
2867         MonoDomain *domain; 
2868         GSList *l = NULL, *tmp;
2869         MonoClass *startklass, *klass, *refklass;
2870         MonoArray *res;
2871         MonoObject *member;
2872         int i, len, match;
2873         gpointer iter;
2874         MonoClassField *field;
2875
2876         MONO_ARCH_SAVE_REGS;
2877
2878         domain = ((MonoObject *)type)->vtable->domain;
2879         if (type->type->byref)
2880                 return mono_array_new (domain, mono_defaults.method_info_class, 0);
2881         klass = startklass = mono_class_from_mono_type (type->type);
2882         refklass = mono_class_from_mono_type (reftype->type);
2883
2884 handle_parent:  
2885         iter = NULL;
2886         while ((field = mono_class_get_fields (klass, &iter))) {
2887                 match = 0;
2888                 if (mono_field_is_deleted (field))
2889                         continue;
2890                 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
2891                         if (bflags & BFLAGS_Public)
2892                                 match++;
2893                 } else {
2894                         if (bflags & BFLAGS_NonPublic)
2895                                 match++;
2896                 }
2897                 if (!match)
2898                         continue;
2899                 match = 0;
2900                 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
2901                         if (bflags & BFLAGS_Static)
2902                                 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
2903                                         match++;
2904                 } else {
2905                         if (bflags & BFLAGS_Instance)
2906                                 match++;
2907                 }
2908
2909                 if (!match)
2910                         continue;
2911                 member = (MonoObject*)mono_field_get_object (domain, refklass, field);
2912                 l = g_slist_prepend (l, member);
2913         }
2914         if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
2915                 goto handle_parent;
2916         len = g_slist_length (l);
2917         res = mono_array_new (domain, mono_defaults.field_info_class, len);
2918         i = 0;
2919         tmp = l = g_slist_reverse (l);
2920         for (; tmp; tmp = tmp->next, ++i)
2921                 mono_array_set (res, gpointer, i, tmp->data);
2922         g_slist_free (l);
2923         return res;
2924 }
2925
2926 static MonoArray*
2927 ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
2928 {
2929         MonoDomain *domain; 
2930         GSList *l = NULL, *tmp;
2931         MonoClass *startklass, *klass, *refklass;
2932         MonoArray *res;
2933         MonoMethod *method;
2934         gpointer iter;
2935         MonoObject *member;
2936         int i, len, match;
2937         guint32 method_slots_default [8];
2938         guint32 *method_slots;
2939         gchar *mname = NULL;
2940         int (*compare_func) (const char *s1, const char *s2) = NULL;
2941                 
2942         MONO_ARCH_SAVE_REGS;
2943
2944         domain = ((MonoObject *)type)->vtable->domain;
2945         if (type->type->byref)
2946                 return mono_array_new (domain, mono_defaults.method_info_class, 0);
2947         klass = startklass = mono_class_from_mono_type (type->type);
2948         refklass = mono_class_from_mono_type (reftype->type);
2949         len = 0;
2950         if (name != NULL) {
2951                 mname = mono_string_to_utf8 (name);
2952                 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
2953         }
2954
2955         if (klass->vtable_size >= sizeof (method_slots_default) * 8) {
2956                 method_slots = g_new0 (guint32, klass->vtable_size / 32 + 1);
2957         } else {
2958                 method_slots = method_slots_default;
2959                 memset (method_slots, 0, sizeof (method_slots_default));
2960         }
2961 handle_parent:
2962         iter = NULL;
2963         while ((method = mono_class_get_methods (klass, &iter))) {
2964                 match = 0;
2965                 if (method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
2966                         continue;
2967                 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
2968                         if (bflags & BFLAGS_Public)
2969                                 match++;
2970                 } else {
2971                         if (bflags & BFLAGS_NonPublic)
2972                                 match++;
2973                 }
2974                 if (!match)
2975                         continue;
2976                 match = 0;
2977                 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
2978                         if (bflags & BFLAGS_Static)
2979                                 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
2980                                         match++;
2981                 } else {
2982                         if (bflags & BFLAGS_Instance)
2983                                 match++;
2984                 }
2985
2986                 if (!match)
2987                         continue;
2988
2989                 if (name != NULL) {
2990                         if (compare_func (mname, method->name))
2991                                 continue;
2992                 }
2993                 
2994                 match = 0;
2995                 if (method->slot != -1) {
2996                         if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
2997                                 continue;
2998                         method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
2999                 }
3000                 
3001                 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
3002                 
3003                 l = g_slist_prepend (l, member);
3004                 len++;
3005         }
3006         if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3007                 goto handle_parent;
3008
3009         g_free (mname);
3010         res = mono_array_new (domain, mono_defaults.method_info_class, len);
3011         i = 0;
3012
3013         tmp = l = g_slist_reverse (l);
3014
3015         for (; tmp; tmp = tmp->next, ++i)
3016                 mono_array_set (res, gpointer, i, tmp->data);
3017         g_slist_free (l);
3018         if (method_slots != method_slots_default)
3019                 g_free (method_slots);
3020         return res;
3021 }
3022
3023 static MonoArray*
3024 ves_icall_Type_GetConstructors_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3025 {
3026         MonoDomain *domain; 
3027         GSList *l = NULL, *tmp;
3028         static MonoClass *System_Reflection_ConstructorInfo;
3029         MonoClass *startklass, *klass, *refklass;
3030         MonoArray *res;
3031         MonoMethod *method;
3032         MonoObject *member;
3033         int i, len, match;
3034         gpointer iter = NULL;
3035         
3036         MONO_ARCH_SAVE_REGS;
3037
3038         domain = ((MonoObject *)type)->vtable->domain;
3039         if (type->type->byref)
3040                 return mono_array_new (domain, mono_defaults.method_info_class, 0);
3041         klass = startklass = mono_class_from_mono_type (type->type);
3042         refklass = mono_class_from_mono_type (reftype->type);
3043
3044         iter = NULL;
3045         while ((method = mono_class_get_methods (klass, &iter))) {
3046                 match = 0;
3047                 if (strcmp (method->name, ".ctor") && strcmp (method->name, ".cctor"))
3048                         continue;
3049                 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3050                         if (bflags & BFLAGS_Public)
3051                                 match++;
3052                 } else {
3053                         if (bflags & BFLAGS_NonPublic)
3054                                 match++;
3055                 }
3056                 if (!match)
3057                         continue;
3058                 match = 0;
3059                 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3060                         if (bflags & BFLAGS_Static)
3061                                 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3062                                         match++;
3063                 } else {
3064                         if (bflags & BFLAGS_Instance)
3065                                 match++;
3066                 }
3067
3068                 if (!match)
3069                         continue;
3070                 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
3071                         
3072                 l = g_slist_prepend (l, member);
3073         }
3074         len = g_slist_length (l);
3075         if (!System_Reflection_ConstructorInfo)
3076                 System_Reflection_ConstructorInfo = mono_class_from_name (
3077                         mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
3078         res = mono_array_new (domain, System_Reflection_ConstructorInfo, len);
3079         i = 0;
3080         tmp = l = g_slist_reverse (l);
3081         for (; tmp; tmp = tmp->next, ++i)
3082                 mono_array_set (res, gpointer, i, tmp->data);
3083         g_slist_free (l);
3084         return res;
3085 }
3086
3087 static MonoArray*
3088 ves_icall_Type_GetPropertiesByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
3089 {
3090         MonoDomain *domain; 
3091         GSList *l = NULL, *tmp;
3092         static MonoClass *System_Reflection_PropertyInfo;
3093         MonoClass *startklass, *klass;
3094         MonoArray *res;
3095         MonoMethod *method;
3096         MonoProperty *prop;
3097         int i, match;
3098         int len = 0;
3099         guint32 flags;
3100         guint32 method_slots_default [8];
3101         guint32 *method_slots;
3102         gchar *propname = NULL;
3103         int (*compare_func) (const char *s1, const char *s2) = NULL;
3104         gpointer iter;
3105
3106         MONO_ARCH_SAVE_REGS;
3107
3108         if (!System_Reflection_PropertyInfo)
3109                 System_Reflection_PropertyInfo = mono_class_from_name (
3110                         mono_defaults.corlib, "System.Reflection", "PropertyInfo");
3111
3112         domain = ((MonoObject *)type)->vtable->domain;
3113         if (type->type->byref)
3114                 return mono_array_new (domain, System_Reflection_PropertyInfo, 0);
3115         klass = startklass = mono_class_from_mono_type (type->type);
3116         if (name != NULL) {
3117                 propname = mono_string_to_utf8 (name);
3118                 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
3119         }
3120
3121         if (klass->vtable_size >= sizeof (method_slots_default) * 8) {
3122                 method_slots = g_new0 (guint32, klass->vtable_size / 32 + 1);
3123         } else {
3124                 method_slots = method_slots_default;
3125                 memset (method_slots, 0, sizeof (method_slots_default));
3126         }
3127 handle_parent:
3128         iter = NULL;
3129         while ((prop = mono_class_get_properties (klass, &iter))) {
3130                 match = 0;
3131                 method = prop->get;
3132                 if (!method)
3133                         method = prop->set;
3134                 if (method)
3135                         flags = method->flags;
3136                 else
3137                         flags = 0;
3138                 if ((prop->get && ((prop->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC)) ||
3139                         (prop->set && ((prop->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC))) {
3140                         if (bflags & BFLAGS_Public)
3141                                 match++;
3142                 } else {
3143                         if (bflags & BFLAGS_NonPublic)
3144                                 match++;
3145                 }
3146                 if (!match)
3147                         continue;
3148                 match = 0;
3149                 if (flags & METHOD_ATTRIBUTE_STATIC) {
3150                         if (bflags & BFLAGS_Static)
3151                                 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3152                                         match++;
3153                 } else {
3154                         if (bflags & BFLAGS_Instance)
3155                                 match++;
3156                 }
3157
3158                 if (!match)
3159                         continue;
3160                 match = 0;
3161
3162                 if (name != NULL) {
3163                         if (compare_func (propname, prop->name))
3164                                 continue;
3165                 }
3166                 
3167                 if (prop->get && prop->get->slot != -1) {
3168                         if (method_slots [prop->get->slot >> 5] & (1 << (prop->get->slot & 0x1f)))
3169                                 continue;
3170                         method_slots [prop->get->slot >> 5] |= 1 << (prop->get->slot & 0x1f);
3171                 }
3172                 if (prop->set && prop->set->slot != -1) {
3173                         if (method_slots [prop->set->slot >> 5] & (1 << (prop->set->slot & 0x1f)))
3174                                 continue;
3175                         method_slots [prop->set->slot >> 5] |= 1 << (prop->set->slot & 0x1f);
3176                 }
3177
3178                 l = g_slist_prepend (l, mono_property_get_object (domain, startklass, prop));
3179                 len++;
3180         }
3181         if ((!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent)))
3182                 goto handle_parent;
3183
3184         g_free (propname);
3185         res = mono_array_new (domain, System_Reflection_PropertyInfo, len);
3186         i = 0;
3187
3188         tmp = l = g_slist_reverse (l);
3189
3190         for (; tmp; tmp = tmp->next, ++i)
3191                 mono_array_set (res, gpointer, i, tmp->data);
3192         g_slist_free (l);
3193         if (method_slots != method_slots_default)
3194                 g_free (method_slots);
3195         return res;
3196 }
3197
3198 static MonoReflectionEvent *
3199 ves_icall_MonoType_GetEvent (MonoReflectionType *type, MonoString *name, guint32 bflags)
3200 {
3201         MonoDomain *domain;
3202         MonoClass *klass, *startklass;
3203         gpointer iter;
3204         MonoEvent *event;
3205         MonoMethod *method;
3206         gchar *event_name;
3207
3208         MONO_ARCH_SAVE_REGS;
3209
3210         event_name = mono_string_to_utf8 (name);
3211         if (type->type->byref)
3212                 return NULL;
3213         klass = startklass = mono_class_from_mono_type (type->type);
3214         domain = mono_object_domain (type);
3215
3216 handle_parent:  
3217         iter = NULL;
3218         while ((event = mono_class_get_events (klass, &iter))) {
3219                 if (strcmp (event->name, event_name))
3220                         continue;
3221
3222                 method = event->add;
3223                 if (!method)
3224                         method = event->remove;
3225                 if (!method)
3226                         method = event->raise;
3227                 if (method) {
3228                         if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3229                                 if (!(bflags & BFLAGS_Public))
3230                                         continue;
3231                         } else {
3232                                 if (!(bflags & BFLAGS_NonPublic))
3233                                         continue;
3234                         }
3235                 }
3236                 else
3237                         if (!(bflags & BFLAGS_NonPublic))
3238                                 continue;
3239
3240                 g_free (event_name);
3241                 return mono_event_get_object (domain, startklass, event);
3242         }
3243
3244         if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3245                 goto handle_parent;
3246
3247         g_free (event_name);
3248         return NULL;
3249 }
3250
3251 static MonoArray*
3252 ves_icall_Type_GetEvents_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3253 {
3254         MonoDomain *domain; 
3255         GSList *l = NULL, *tmp;
3256         static MonoClass *System_Reflection_EventInfo;
3257         MonoClass *startklass, *klass;
3258         MonoArray *res;
3259         MonoMethod *method;
3260         MonoEvent *event;
3261         int i, len, match;
3262         gpointer iter;
3263
3264         MONO_ARCH_SAVE_REGS;
3265
3266         if (!System_Reflection_EventInfo)
3267                 System_Reflection_EventInfo = mono_class_from_name (
3268                         mono_defaults.corlib, "System.Reflection", "EventInfo");
3269
3270         domain = mono_object_domain (type);
3271         if (type->type->byref)
3272                 return mono_array_new (domain, System_Reflection_EventInfo, 0);
3273         klass = startklass = mono_class_from_mono_type (type->type);
3274
3275 handle_parent:  
3276         iter = NULL;
3277         while ((event = mono_class_get_events (klass, &iter))) {
3278                 match = 0;
3279                 method = event->add;
3280                 if (!method)
3281                         method = event->remove;
3282                 if (!method)
3283                         method = event->raise;
3284                 if (method) {
3285                         if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3286                                 if (bflags & BFLAGS_Public)
3287                                         match++;
3288                         } else {
3289                                 if (bflags & BFLAGS_NonPublic)
3290                                         match++;
3291                         }
3292                 }
3293                 else
3294                         if (bflags & BFLAGS_NonPublic)
3295                                 match ++;
3296                 if (!match)
3297                         continue;
3298                 match = 0;
3299                 if (method) {
3300                         if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3301                                 if (bflags & BFLAGS_Static)
3302                                         if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3303                                                 match++;
3304                         } else {
3305                                 if (bflags & BFLAGS_Instance)
3306                                         match++;
3307                         }
3308                 }
3309                 else
3310                         if (bflags & BFLAGS_Instance)
3311                                 match ++;
3312                 if (!match)
3313                         continue;
3314                 match = 0;
3315                 l = g_slist_prepend (l, mono_event_get_object (domain, klass, event));
3316         }
3317         if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3318                 goto handle_parent;
3319         len = g_slist_length (l);
3320         res = mono_array_new (domain, System_Reflection_EventInfo, len);
3321         i = 0;
3322
3323         tmp = l = g_slist_reverse (l);
3324
3325         for (; tmp; tmp = tmp->next, ++i)
3326                 mono_array_set (res, gpointer, i, tmp->data);
3327         g_slist_free (l);
3328         return res;
3329 }
3330
3331 static MonoReflectionType *
3332 ves_icall_Type_GetNestedType (MonoReflectionType *type, MonoString *name, guint32 bflags)
3333 {
3334         MonoDomain *domain; 
3335         MonoClass *startklass, *klass;
3336         MonoClass *nested;
3337         GList *tmpn;
3338         char *str;
3339         
3340         MONO_ARCH_SAVE_REGS;
3341
3342         domain = ((MonoObject *)type)->vtable->domain;
3343         if (type->type->byref)
3344                 return NULL;
3345         klass = startklass = mono_class_from_mono_type (type->type);
3346         str = mono_string_to_utf8 (name);
3347
3348  handle_parent:
3349         for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
3350                 int match = 0;
3351                 nested = tmpn->data;
3352                 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
3353                         if (bflags & BFLAGS_Public)
3354                                 match++;
3355                 } else {
3356                         if (bflags & BFLAGS_NonPublic)
3357                                 match++;
3358                 }
3359                 if (!match)
3360                         continue;
3361                 if (strcmp (nested->name, str) == 0){
3362                         g_free (str);
3363                         return mono_type_get_object (domain, &nested->byval_arg);
3364                 }
3365         }
3366         if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3367                 goto handle_parent;
3368         g_free (str);
3369         return NULL;
3370 }
3371
3372 static MonoArray*
3373 ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags)
3374 {
3375         MonoDomain *domain; 
3376         GSList *l = NULL, *tmp;
3377         GList *tmpn;
3378         MonoClass *startklass, *klass;
3379         MonoArray *res;
3380         MonoObject *member;
3381         int i, len, match;
3382         MonoClass *nested;
3383
3384         MONO_ARCH_SAVE_REGS;
3385
3386         domain = ((MonoObject *)type)->vtable->domain;
3387         if (type->type->byref)
3388                 return mono_array_new (domain, mono_defaults.monotype_class, 0);
3389         klass = startklass = mono_class_from_mono_type (type->type);
3390
3391         for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
3392                 match = 0;
3393                 nested = tmpn->data;
3394                 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
3395                         if (bflags & BFLAGS_Public)
3396                                 match++;
3397                 } else {
3398                         if (bflags & BFLAGS_NonPublic)
3399                                 match++;
3400                 }
3401                 if (!match)
3402                         continue;
3403                 member = (MonoObject*)mono_type_get_object (domain, &nested->byval_arg);
3404                 l = g_slist_prepend (l, member);
3405         }
3406         len = g_slist_length (l);
3407         res = mono_array_new (domain, mono_defaults.monotype_class, len);
3408         i = 0;
3409         tmp = l = g_slist_reverse (l);
3410         for (; tmp; tmp = tmp->next, ++i)
3411                 mono_array_set (res, gpointer, i, tmp->data);
3412         g_slist_free (l);
3413         return res;
3414 }
3415
3416 static MonoReflectionType*
3417 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *assembly, MonoReflectionModule *module, MonoString *name, MonoBoolean throwOnError, MonoBoolean ignoreCase)
3418 {
3419         gchar *str;
3420         MonoType *type = NULL;
3421         MonoTypeNameParse info;
3422         gboolean type_resolve = FALSE;
3423
3424         MONO_ARCH_SAVE_REGS;
3425
3426         str = mono_string_to_utf8 (name);
3427         /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
3428         if (!mono_reflection_parse_type (str, &info)) {
3429                 g_free (str);
3430                 g_list_free (info.modifiers);
3431                 g_list_free (info.nested);
3432                 if (throwOnError) /* uhm: this is a parse error, though... */
3433                         mono_raise_exception (mono_get_exception_type_load (name));
3434                 /*g_print ("failed parse\n");*/
3435                 return NULL;
3436         }
3437
3438         if (module != NULL) {
3439                 if (module->image)
3440                         type = mono_reflection_get_type (module->image, &info, ignoreCase, &type_resolve);
3441                 else
3442                         type = NULL;
3443         }
3444         else
3445                 if (assembly->assembly->dynamic) {
3446                         /* Enumerate all modules */
3447                         MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
3448                         int i;
3449
3450                         type = NULL;
3451                         if (abuilder->modules) {
3452                                 for (i = 0; i < mono_array_length (abuilder->modules); ++i) {
3453                                         MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
3454                                         type = mono_reflection_get_type (&mb->dynamic_image->image, &info, ignoreCase, &type_resolve);
3455                                         if (type)
3456                                                 break;
3457                                 }
3458                         }
3459
3460                         if (!type && abuilder->loaded_modules) {
3461                                 for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) {
3462                                         MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
3463                                         type = mono_reflection_get_type (mod->image, &info, ignoreCase, &type_resolve);
3464                                         if (type)
3465                                                 break;
3466                                 }
3467                         }
3468                 }
3469                 else
3470                         type = mono_reflection_get_type (assembly->assembly->image, &info, ignoreCase, &type_resolve);
3471         g_free (str);
3472         g_list_free (info.modifiers);
3473         g_list_free (info.nested);
3474         if (!type) {
3475                 if (throwOnError)
3476                         mono_raise_exception (mono_get_exception_type_load (name));
3477                 /* g_print ("failed find\n"); */
3478                 return NULL;
3479         }
3480
3481         if (type->type == MONO_TYPE_CLASS) {
3482                 MonoClass *klass = mono_type_get_class (type);
3483                 /* need to report exceptions ? */
3484                 if (throwOnError && klass->exception_type) {
3485                         /* report SecurityException (or others) that occured when loading the assembly */
3486                         MonoException *exc = mono_class_get_exception_for_failure (klass);
3487                         mono_raise_exception (exc);
3488                 } else if (klass->exception_type == MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND) {
3489                         return NULL;
3490                 }
3491         }
3492
3493         /* g_print ("got it\n"); */
3494         return mono_type_get_object (mono_object_domain (assembly), type);
3495 }
3496
3497 static MonoString *
3498 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *assembly)
3499 {
3500         MonoDomain *domain = mono_object_domain (assembly); 
3501         MonoAssembly *mass = assembly->assembly;
3502         MonoString *res;
3503         gchar *uri;
3504         gchar *absolute;
3505         
3506         MONO_ARCH_SAVE_REGS;
3507
3508         absolute = g_build_filename (mass->basedir, mass->image->module_name, NULL);
3509         uri = g_filename_to_uri (absolute, NULL, NULL);
3510         res = mono_string_new (domain, uri);
3511         g_free (uri);
3512         g_free (absolute);
3513         return res;
3514 }
3515
3516 static MonoBoolean
3517 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssembly *assembly)
3518 {
3519         MonoAssembly *mass = assembly->assembly;
3520
3521         MONO_ARCH_SAVE_REGS;
3522
3523         return mass->in_gac;
3524 }
3525
3526 static MonoReflectionAssembly*
3527 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoString *mname, MonoObject *evidence)
3528 {
3529         gchar *name;
3530         MonoAssembly *res;
3531         MonoImageOpenStatus status;
3532         
3533         MONO_ARCH_SAVE_REGS;
3534
3535         name = mono_string_to_utf8 (mname);
3536         res = mono_assembly_load_with_partial_name (name, &status);
3537
3538         g_free (name);
3539
3540         if (res == NULL)
3541                 return NULL;
3542         return mono_assembly_get_object (mono_domain_get (), res);
3543 }
3544
3545 static MonoString *
3546 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssembly *assembly)
3547 {
3548         MonoDomain *domain = mono_object_domain (assembly); 
3549         MonoString *res;
3550
3551         MONO_ARCH_SAVE_REGS;
3552
3553         res = mono_string_new (domain, mono_image_get_filename (assembly->assembly->image));
3554
3555         return res;
3556 }
3557
3558 static MonoBoolean
3559 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssembly *assembly)
3560 {
3561         MONO_ARCH_SAVE_REGS;
3562
3563         return assembly->assembly->ref_only;
3564 }
3565
3566 static MonoString *
3567 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssembly *assembly)
3568 {
3569         MonoDomain *domain = mono_object_domain (assembly); 
3570
3571         MONO_ARCH_SAVE_REGS;
3572
3573         return mono_string_new (domain, assembly->assembly->image->version);
3574 }
3575
3576 static MonoReflectionMethod*
3577 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssembly *assembly) 
3578 {
3579         guint32 token = mono_image_get_entry_point (assembly->assembly->image);
3580
3581         MONO_ARCH_SAVE_REGS;
3582
3583         if (!token)
3584                 return NULL;
3585         return mono_method_get_object (mono_object_domain (assembly), mono_get_method (assembly->assembly->image, token, NULL), NULL);
3586 }
3587
3588 static MonoReflectionModule*
3589 ves_icall_System_Reflection_Assembly_get_ManifestModule (MonoReflectionAssembly *assembly) 
3590 {
3591         return mono_module_get_object (mono_object_domain (assembly), assembly->assembly->image);
3592 }
3593
3594 static MonoArray*
3595 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssembly *assembly) 
3596 {
3597         MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
3598         MonoArray *result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, table->rows);
3599         int i;
3600         const char *val;
3601
3602         MONO_ARCH_SAVE_REGS;
3603
3604         for (i = 0; i < table->rows; ++i) {
3605                 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_MANIFEST_NAME));
3606                 mono_array_set (result, gpointer, i, mono_string_new (mono_object_domain (assembly), val));
3607         }
3608         return result;
3609 }
3610
3611 static MonoObject*
3612 create_version (MonoDomain *domain, MonoAssemblyName *aname)
3613 {
3614         static MonoClass *System_Version = NULL;
3615         static MonoMethod *create_version = NULL;
3616         MonoObject *result;
3617         int major, minor, build, revision;
3618         gpointer args [4];
3619         
3620         if (!System_Version) {
3621                 System_Version = mono_class_from_name (mono_defaults.corlib, "System", "Version");
3622                 g_assert (System_Version);
3623         }
3624
3625         if (!create_version) {
3626                 MonoMethodDesc *desc = mono_method_desc_new (":.ctor(int,int,int,int)", FALSE);
3627                 create_version = mono_method_desc_search_in_class (desc, System_Version);
3628                 g_assert (create_version);
3629                 mono_method_desc_free (desc);
3630         }
3631
3632         major = aname->major;
3633         minor = aname->minor;
3634         build = aname->build;
3635         revision = aname->revision;
3636         args [0] = &major;
3637         args [1] = &minor;
3638         args [2] = &build;
3639         args [3] = &revision;
3640         result = mono_object_new (domain, System_Version);
3641         mono_runtime_invoke (create_version, result, args, NULL);
3642
3643         return result;
3644 }
3645
3646 static MonoArray*
3647 ves_icall_System_Reflection_Assembly_GetReferencedAssemblies (MonoReflectionAssembly *assembly) 
3648 {
3649         static MonoClass *System_Reflection_AssemblyName;
3650         MonoArray *result;
3651         MonoDomain *domain = mono_object_domain (assembly);
3652         int i, count = 0;
3653         static MonoMethod *create_culture = NULL;
3654         MonoTableInfo *t;
3655
3656         MONO_ARCH_SAVE_REGS;
3657
3658         if (!System_Reflection_AssemblyName)
3659                 System_Reflection_AssemblyName = mono_class_from_name (
3660                         mono_defaults.corlib, "System.Reflection", "AssemblyName");
3661
3662         t = &assembly->assembly->image->tables [MONO_TABLE_ASSEMBLYREF];
3663         count = t->rows;
3664
3665         result = mono_array_new (domain, System_Reflection_AssemblyName, count);
3666
3667         if (count > 0) {
3668                 MonoMethodDesc *desc = mono_method_desc_new (
3669                         "System.Globalization.CultureInfo:CreateSpecificCulture(string)", TRUE);
3670                 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
3671                 g_assert (create_culture);
3672                 mono_method_desc_free (desc);
3673         }
3674
3675         for (i = 0; i < count; i++) {
3676                 MonoAssembly *assem;
3677                 MonoReflectionAssemblyName *aname;
3678
3679                 /* FIXME: There is no need to load the assemblies themselves */
3680                 mono_assembly_load_reference (assembly->assembly->image, i);
3681
3682                 assem = assembly->assembly->image->references [i];
3683                 if (assem == (gpointer)-1) {
3684                         char *msg = g_strdup_printf ("Assembly %d referenced from assembly %s not found ", i, assembly->assembly->image->name);
3685                         MonoException *ex = mono_get_exception_file_not_found2 (msg, NULL);
3686                         g_free (msg);
3687                         mono_raise_exception (ex);
3688                 }
3689
3690                 aname = (MonoReflectionAssemblyName *) mono_object_new (
3691                         domain, System_Reflection_AssemblyName);
3692
3693                 aname->name = mono_string_new (domain, assem->aname.name);
3694
3695                 aname->major = assem->aname.major;
3696                 aname->minor = assem->aname.minor;
3697                 aname->build = assem->aname.build;
3698                 aname->revision = assem->aname.revision;
3699                 aname->hashalg = assem->aname.hash_alg;
3700                 aname->flags = assem->aname.flags;
3701                 aname->versioncompat = 1; /* SameMachine (default) */
3702                 aname->version = create_version (domain, &assem->aname);
3703
3704                 if (create_culture) {
3705                         gpointer args [1];
3706                         args [0] = mono_string_new (domain, assem->aname.culture);
3707                         aname->cultureInfo = mono_runtime_invoke (create_culture, NULL, args, NULL);
3708                 }
3709
3710                 if (assem->aname.public_key) {
3711                         guint32 pkey_len;
3712                         const char *pkey_ptr = (char*)assem->aname.public_key;
3713                         pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
3714
3715                         aname->publicKey = mono_array_new (domain, mono_defaults.byte_class, pkey_len);
3716                         memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
3717                 }
3718
3719                 /* public key token isn't copied - the class library will 
3720                    automatically generate it from the public key if required */
3721
3722                 /* note: this function doesn't return the codebase on purpose (i.e. it can
3723                          be used under partial trust as path information isn't present). */
3724
3725                 mono_array_set (result, gpointer, i, aname);
3726         }
3727         return result;
3728 }
3729
3730 typedef struct {
3731         MonoArray *res;
3732         int idx;
3733 } NameSpaceInfo;
3734
3735 static void
3736 foreach_namespace (const char* key, gconstpointer val, NameSpaceInfo *info)
3737 {
3738         MonoString *name = mono_string_new (mono_object_domain (info->res), key);
3739
3740         mono_array_set (info->res, gpointer, info->idx, name);
3741         info->idx++;
3742 }
3743
3744 static MonoArray*
3745 ves_icall_System_Reflection_Assembly_GetNamespaces (MonoReflectionAssembly *assembly) 
3746 {
3747         MonoImage *img = assembly->assembly->image;
3748         MonoArray *res;
3749         NameSpaceInfo info;
3750
3751         MONO_ARCH_SAVE_REGS;
3752         
3753         res = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, g_hash_table_size (img->name_cache));
3754         info.res = res;
3755         info.idx = 0;
3756         g_hash_table_foreach (img->name_cache, (GHFunc)foreach_namespace, &info);
3757
3758         return res;
3759 }
3760
3761 /* move this in some file in mono/util/ */
3762 static char *
3763 g_concat_dir_and_file (const char *dir, const char *file)
3764 {
3765         g_return_val_if_fail (dir != NULL, NULL);
3766         g_return_val_if_fail (file != NULL, NULL);
3767
3768         /*
3769          * If the directory name doesn't have a / on the end, we need
3770          * to add one so we get a proper path to the file
3771          */
3772         if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
3773                 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
3774         else
3775                 return g_strconcat (dir, file, NULL);
3776 }
3777
3778 static void *
3779 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssembly *assembly, MonoString *name, gint32 *size, MonoReflectionModule **ref_module) 
3780 {
3781         char *n = mono_string_to_utf8 (name);
3782         MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
3783         guint32 i;
3784         guint32 cols [MONO_MANIFEST_SIZE];
3785         guint32 impl, file_idx;
3786         const char *val;
3787         MonoImage *module;
3788
3789         MONO_ARCH_SAVE_REGS;
3790
3791         for (i = 0; i < table->rows; ++i) {
3792                 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
3793                 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
3794                 if (strcmp (val, n) == 0)
3795                         break;
3796         }
3797         g_free (n);
3798         if (i == table->rows)
3799                 return NULL;
3800         /* FIXME */
3801         impl = cols [MONO_MANIFEST_IMPLEMENTATION];
3802         if (impl) {
3803                 /*
3804                  * this code should only be called after obtaining the 
3805                  * ResourceInfo and handling the other cases.
3806                  */
3807                 g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
3808                 file_idx = impl >> MONO_IMPLEMENTATION_BITS;
3809
3810                 module = mono_image_load_file_for_image (assembly->assembly->image, file_idx);
3811                 if (!module)
3812                         return NULL;
3813         }
3814         else
3815                 module = assembly->assembly->image;
3816
3817         *ref_module = mono_module_get_object (mono_domain_get (), module);
3818
3819         return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
3820 }
3821
3822 static gboolean
3823 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoManifestResourceInfo *info)
3824 {
3825         MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
3826         int i;
3827         guint32 cols [MONO_MANIFEST_SIZE];
3828         guint32 file_cols [MONO_FILE_SIZE];
3829         const char *val;
3830         char *n;
3831
3832         MONO_ARCH_SAVE_REGS;
3833
3834         n = mono_string_to_utf8 (name);
3835         for (i = 0; i < table->rows; ++i) {
3836                 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
3837                 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
3838                 if (strcmp (val, n) == 0)
3839                         break;
3840         }
3841         g_free (n);
3842         if (i == table->rows)
3843                 return FALSE;
3844
3845         if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
3846                 info->location = RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST;
3847         }
3848         else {
3849                 switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
3850                 case MONO_IMPLEMENTATION_FILE:
3851                         i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
3852                         table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
3853                         mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
3854                         val = mono_metadata_string_heap (assembly->assembly->image, file_cols [MONO_FILE_NAME]);
3855                         info->filename = mono_string_new (mono_object_domain (assembly), val);
3856                         if (file_cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA)
3857                                 info->location = 0;
3858                         else
3859                                 info->location = RESOURCE_LOCATION_EMBEDDED;
3860                         break;
3861
3862                 case MONO_IMPLEMENTATION_ASSEMBLYREF:
3863                         i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
3864                         mono_assembly_load_reference (assembly->assembly->image, i - 1);
3865                         if (assembly->assembly->image->references [i - 1] == (gpointer)-1) {
3866                                 char *msg = g_strdup_printf ("Assembly %d referenced from assembly %s not found ", i - 1, assembly->assembly->image->name);
3867                                 MonoException *ex = mono_get_exception_file_not_found2 (msg, NULL);
3868                                 g_free (msg);
3869                                 mono_raise_exception (ex);
3870                         }
3871                         info->assembly = mono_assembly_get_object (mono_domain_get (), assembly->assembly->image->references [i - 1]);
3872
3873                         /* Obtain info recursively */
3874                         ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (info->assembly, name, info);
3875                         info->location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
3876                         break;
3877
3878                 case MONO_IMPLEMENTATION_EXP_TYPE:
3879                         g_assert_not_reached ();
3880                         break;
3881                 }
3882         }
3883
3884         return TRUE;
3885 }
3886
3887 static MonoObject*
3888 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoBoolean resource_modules) 
3889 {
3890         MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
3891         MonoArray *result = NULL;
3892         int i, count;
3893         const char *val;
3894         char *n;
3895
3896         MONO_ARCH_SAVE_REGS;
3897
3898         /* check hash if needed */
3899         if (name) {
3900                 n = mono_string_to_utf8 (name);
3901                 for (i = 0; i < table->rows; ++i) {
3902                         val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
3903                         if (strcmp (val, n) == 0) {
3904                                 MonoString *fn;
3905                                 g_free (n);
3906                                 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
3907                                 fn = mono_string_new (mono_object_domain (assembly), n);
3908                                 g_free (n);
3909                                 return (MonoObject*)fn;
3910                         }
3911                 }
3912                 g_free (n);
3913                 return NULL;
3914         }
3915
3916         count = 0;
3917         for (i = 0; i < table->rows; ++i) {
3918                 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA))
3919                         count ++;
3920         }
3921
3922         result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, count);
3923
3924         count = 0;
3925         for (i = 0; i < table->rows; ++i) {
3926                 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
3927                         val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
3928                         n = g_concat_dir_and_file (assembly->assembly->basedir, val);
3929                         mono_array_set (result, gpointer, count, mono_string_new (mono_object_domain (assembly), n));
3930                         g_free (n);
3931                         count ++;
3932                 }
3933         }
3934         return (MonoObject*)result;
3935 }
3936
3937 static MonoArray*
3938 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly *assembly)
3939 {
3940         MonoDomain *domain = mono_domain_get();
3941         MonoArray *res;
3942         MonoClass *klass;
3943         int i, j, file_count = 0;
3944         MonoImage **modules;
3945         guint32 module_count, real_module_count;
3946         MonoTableInfo *table;
3947
3948         g_assert (assembly->assembly->image != NULL);
3949
3950         if (assembly->assembly->dynamic) {
3951                 MonoReflectionAssemblyBuilder *assemblyb = (MonoReflectionAssemblyBuilder*)assembly;
3952
3953                 if (assemblyb->modules)
3954                         module_count = mono_array_length (assemblyb->modules);
3955                 else
3956                         module_count = 0;
3957                 real_module_count = module_count;
3958
3959                 modules = g_new0 (MonoImage*, module_count);
3960                 if (assemblyb->modules) {
3961                         for (i = 0; i < mono_array_length (assemblyb->modules); ++i) {
3962                                 modules [i] = 
3963                                         mono_array_get (assemblyb->modules, MonoReflectionModuleBuilder*, i)->module.image;
3964                         }
3965                 }
3966         }
3967         else {
3968                 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
3969                 file_count = table->rows;
3970
3971                 modules = assembly->assembly->image->modules;
3972                 module_count = assembly->assembly->image->module_count;
3973
3974                 real_module_count = 0;
3975                 for (i = 0; i < module_count; ++i)
3976                         if (modules [i])
3977                                 real_module_count ++;
3978         }
3979
3980         klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "Module");
3981         res = mono_array_new (domain, klass, 1 + real_module_count + file_count);
3982
3983         mono_array_set (res, gpointer, 0, mono_module_get_object (domain, assembly->assembly->image));
3984         j = 1;
3985         for (i = 0; i < module_count; ++i)
3986                 if (modules [i]) {
3987                         mono_array_set (res, gpointer, j, mono_module_get_object (domain, modules[i]));
3988                         ++j;
3989                 }
3990
3991         for (i = 0; i < file_count; ++i, ++j)
3992                 mono_array_set (res, gpointer, j, mono_module_file_get_object (domain, assembly->assembly->image, i));
3993
3994         if (assembly->assembly->dynamic)
3995                 g_free (modules);
3996
3997         return res;
3998 }
3999
4000 static MonoReflectionMethod*
4001 ves_icall_GetCurrentMethod (void) 
4002 {
4003         MonoMethod *m = mono_method_get_last_managed ();
4004
4005         MONO_ARCH_SAVE_REGS;
4006
4007         return mono_method_get_object (mono_domain_get (), m, NULL);
4008 }
4009
4010 static MonoReflectionMethod*
4011 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternal (MonoMethod *method)
4012 {
4013         return mono_method_get_object (mono_domain_get (), method, NULL);
4014 }
4015
4016 static MonoReflectionMethodBody*
4017 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod *method)
4018 {
4019         return mono_method_body_get_object (mono_domain_get (), method);
4020 }
4021
4022 static MonoReflectionAssembly*
4023 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (void)
4024 {
4025         MonoMethod *m = mono_method_get_last_managed ();
4026
4027         MONO_ARCH_SAVE_REGS;
4028
4029         return mono_assembly_get_object (mono_domain_get (), m->klass->image->assembly);
4030 }
4031
4032
4033 static gboolean
4034 get_caller (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
4035 {
4036         MonoMethod **dest = data;
4037
4038         /* skip unmanaged frames */
4039         if (!managed)
4040                 return FALSE;
4041
4042         if (m == *dest) {
4043                 *dest = NULL;
4044                 return FALSE;
4045         }
4046         if (!(*dest)) {
4047                 *dest = m;
4048                 return TRUE;
4049         }
4050         return FALSE;
4051 }
4052
4053 static MonoReflectionAssembly*
4054 ves_icall_System_Reflection_Assembly_GetEntryAssembly (void)
4055 {
4056         MonoDomain* domain = mono_domain_get ();
4057
4058         MONO_ARCH_SAVE_REGS;
4059
4060         if (!domain->entry_assembly)
4061                 return NULL;
4062
4063         return mono_assembly_get_object (domain, domain->entry_assembly);
4064 }
4065
4066
4067 static MonoReflectionAssembly*
4068 ves_icall_System_Reflection_Assembly_GetCallingAssembly (void)
4069 {
4070         MonoMethod *m = mono_method_get_last_managed ();
4071         MonoMethod *dest = m;
4072
4073         MONO_ARCH_SAVE_REGS;
4074
4075         mono_stack_walk_no_il (get_caller, &dest);
4076         if (!dest)
4077                 dest = m;
4078         return mono_assembly_get_object (mono_domain_get (), dest->klass->image->assembly);
4079 }
4080
4081 static MonoString *
4082 ves_icall_System_MonoType_getFullName (MonoReflectionType *object, gboolean full_name,
4083                                        gboolean assembly_qualified)
4084 {
4085         MonoDomain *domain = mono_object_domain (object); 
4086         MonoTypeNameFormat format;
4087         MonoString *res;
4088         gchar *name;
4089
4090         MONO_ARCH_SAVE_REGS;
4091         if (full_name)
4092                 format = assembly_qualified ?
4093                         MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
4094                         MONO_TYPE_NAME_FORMAT_FULL_NAME;
4095         else
4096                 format = MONO_TYPE_NAME_FORMAT_REFLECTION;
4097  
4098         name = mono_type_get_name_full (object->type, format);
4099         res = mono_string_new (domain, name);
4100         g_free (name);
4101
4102         return res;
4103 }
4104
4105 static void
4106 fill_reflection_assembly_name (MonoDomain *domain, MonoReflectionAssemblyName *aname, MonoAssemblyName *name, const char *absolute)
4107 {
4108         static MonoMethod *create_culture = NULL;
4109         gpointer args [1];
4110         guint32 pkey_len;
4111         const char *pkey_ptr;
4112         gchar *codebase;
4113
4114         MONO_ARCH_SAVE_REGS;
4115
4116         aname->name = mono_string_new (domain, name->name);
4117         aname->major = name->major;
4118         aname->minor = name->minor;
4119         aname->build = name->build;
4120         aname->revision = name->revision;
4121         aname->hashalg = name->hash_alg;
4122         aname->version = create_version (domain, name);
4123         
4124         codebase = g_filename_to_uri (absolute, NULL, NULL);
4125         if (codebase) {
4126                 aname->codebase = mono_string_new (domain, codebase);
4127                 g_free (codebase);
4128         }
4129
4130         if (!create_culture) {
4131                 MonoMethodDesc *desc = mono_method_desc_new ("System.Globalization.CultureInfo:CreateSpecificCulture(string)", TRUE);
4132                 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4133                 g_assert (create_culture);
4134                 mono_method_desc_free (desc);
4135         }
4136
4137         args [0] = mono_string_new (domain, name->culture);
4138         aname->cultureInfo = 
4139                 mono_runtime_invoke (create_culture, NULL, args, NULL);
4140
4141         if (name->public_key) {
4142                 pkey_ptr = (char*)name->public_key;
4143                 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
4144
4145                 aname->publicKey = mono_array_new (domain, mono_defaults.byte_class, pkey_len);
4146                 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
4147         }
4148
4149         /* MonoAssemblyName keeps the public key token as an hexadecimal string */
4150         if (name->public_key_token [0]) {
4151                 int i, j;
4152                 char *p;
4153
4154                 aname->keyToken = mono_array_new (domain, mono_defaults.byte_class, 8);
4155                 p = mono_array_addr (aname->keyToken, char, 0);
4156
4157                 for (i = 0, j = 0; i < 8; i++) {
4158                         *p = g_ascii_xdigit_value (name->public_key_token [j++]) << 4;
4159                         *p |= g_ascii_xdigit_value (name->public_key_token [j++]);
4160                         p++;
4161                 }
4162         }
4163 }
4164
4165 static void
4166 ves_icall_System_Reflection_Assembly_FillName (MonoReflectionAssembly *assembly, MonoReflectionAssemblyName *aname)
4167 {
4168         gchar *absolute;
4169
4170         MONO_ARCH_SAVE_REGS;
4171
4172         absolute = g_build_filename (assembly->assembly->basedir, assembly->assembly->image->module_name, NULL);
4173
4174         fill_reflection_assembly_name (mono_object_domain (assembly), aname, 
4175                                                                    &assembly->assembly->aname, absolute);
4176
4177         g_free (absolute);
4178 }
4179
4180 static void
4181 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoString *fname, MonoReflectionAssemblyName *aname)
4182 {
4183         char *filename;
4184         MonoImageOpenStatus status = MONO_IMAGE_OK;
4185         gboolean res;
4186         MonoImage *image;
4187         MonoAssemblyName name;
4188
4189         MONO_ARCH_SAVE_REGS;
4190
4191         filename = mono_string_to_utf8 (fname);
4192
4193         image = mono_image_open (filename, &status);
4194         
4195         if (!image){
4196                 MonoException *exc;
4197
4198                 g_free (filename);
4199                 exc = mono_get_exception_file_not_found (fname);
4200                 mono_raise_exception (exc);
4201         }
4202
4203         res = mono_assembly_fill_assembly_name (image, &name);
4204         if (!res) {
4205                 mono_image_close (image);
4206                 g_free (filename);
4207                 mono_raise_exception (mono_get_exception_argument ("assemblyFile", "The file does not contain a manifest"));
4208         }
4209
4210         fill_reflection_assembly_name (mono_domain_get (), aname, &name, filename);
4211
4212         g_free (filename);
4213         mono_image_close (image);
4214 }
4215
4216 static MonoBoolean
4217 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssembly *assembly,
4218         char **minimum, guint32 *minLength, char **optional, guint32 *optLength, char **refused, guint32 *refLength)
4219 {
4220         MonoBoolean result = FALSE;
4221         MonoDeclSecurityEntry entry;
4222
4223         /* SecurityAction.RequestMinimum */
4224         if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQMIN, &entry)) {
4225                 *minimum = entry.blob;
4226                 *minLength = entry.size;
4227                 result = TRUE;
4228         }
4229         /* SecurityAction.RequestOptional */
4230         if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQOPT, &entry)) {
4231                 *optional = entry.blob;
4232                 *optLength = entry.size;
4233                 result = TRUE;
4234         }
4235         /* SecurityAction.RequestRefuse */
4236         if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQREFUSE, &entry)) {
4237                 *refused = entry.blob;
4238                 *refLength = entry.size;
4239                 result = TRUE;
4240         }
4241
4242         return result;  
4243 }
4244
4245 static MonoArray*
4246 mono_module_get_types (MonoDomain *domain, MonoImage *image, 
4247                                            MonoBoolean exportedOnly)
4248 {
4249         MonoArray *res;
4250         MonoClass *klass;
4251         MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
4252         int i, count;
4253         guint32 attrs, visibility;
4254
4255         /* we start the count from 1 because we skip the special type <Module> */
4256         if (exportedOnly) {
4257                 count = 0;
4258                 for (i = 1; i < tdef->rows; ++i) {
4259                         attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
4260                         visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
4261                         if (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)
4262                                 count++;
4263                 }
4264         } else {
4265                 count = tdef->rows - 1;
4266         }
4267         res = mono_array_new (domain, mono_defaults.monotype_class, count);
4268         count = 0;
4269         for (i = 1; i < tdef->rows; ++i) {
4270                 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
4271                 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
4272                 if (!exportedOnly || (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)) {
4273                         klass = mono_class_get (image, (i + 1) | MONO_TOKEN_TYPE_DEF);
4274                         mono_array_set (res, gpointer, count, mono_type_get_object (domain, &klass->byval_arg));
4275                         count++;
4276                 }
4277         }
4278         
4279         return res;
4280 }
4281
4282 static MonoArray*
4283 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly, MonoBoolean exportedOnly)
4284 {
4285         MonoArray *res = NULL;
4286         MonoImage *image = NULL;
4287         MonoTableInfo *table = NULL;
4288         MonoDomain *domain;
4289         int i;
4290
4291         MONO_ARCH_SAVE_REGS;
4292
4293         domain = mono_object_domain (assembly);
4294
4295         if (assembly->assembly->dynamic) {
4296                 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
4297                 if (abuilder->modules) {
4298                         for (i = 0; i < mono_array_length(abuilder->modules); i++) {
4299                                 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
4300                                 if (res == NULL)
4301                                         res = mb->types;
4302                                 else {
4303                                         MonoArray *append = mb->types;
4304                                         if (mono_array_length (append) > 0) {
4305                                                 guint32 len1, len2;
4306                                                 MonoArray *new;
4307                                                 len1 = mono_array_length (res);
4308                                                 len2 = mono_array_length (append);
4309                                                 new = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4310                                                 memcpy (mono_array_addr (new, MonoReflectionType*, 0),
4311                                                         mono_array_addr (res, MonoReflectionType*, 0),
4312                                                         len1 * sizeof (MonoReflectionType*));
4313                                                 memcpy (mono_array_addr (new, MonoReflectionType*, len1),
4314                                                         mono_array_addr (append, MonoReflectionType*, 0),
4315                                                         len2 * sizeof (MonoReflectionType*));
4316                                                 res = new;
4317                                         }
4318                                 }
4319                         }
4320
4321                         /* 
4322                          * Replace TypeBuilders with the created types to be compatible
4323                          * with MS.NET.
4324                          */
4325                         if (res) {
4326                                 for (i = 0; i < mono_array_length (res); ++i) {
4327                                         MonoReflectionTypeBuilder *tb = mono_array_get (res, MonoReflectionTypeBuilder*, i);
4328                                         if (tb->created)
4329                                                 mono_array_set (res, MonoReflectionType*, i, tb->created);
4330                                 }
4331                         }
4332                 }
4333
4334                 if (abuilder->loaded_modules)
4335                         for (i = 0; i < mono_array_length(abuilder->loaded_modules); i++) {
4336                                 MonoReflectionModule *rm = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
4337                                 if (res == NULL)
4338                                         res = mono_module_get_types (domain, rm->image, exportedOnly);
4339                                 else {
4340                                         MonoArray *append = mono_module_get_types (domain, rm->image, exportedOnly);
4341                                         if (mono_array_length (append) > 0) {
4342                                                 guint32 len1, len2;
4343                                                 MonoArray *new;
4344                                                 len1 = mono_array_length (res);
4345                                                 len2 = mono_array_length (append);
4346                                                 new = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4347                                                 memcpy (mono_array_addr (new, MonoReflectionType*, 0),
4348                                                         mono_array_addr (res, MonoReflectionType*, 0),
4349                                                         len1 * sizeof (MonoReflectionType*));
4350                                                 memcpy (mono_array_addr (new, MonoReflectionType*, len1),
4351                                                         mono_array_addr (append, MonoReflectionType*, 0),
4352                                                         len2 * sizeof (MonoReflectionType*));
4353                                                 res = new;
4354                                         }
4355                                 }
4356                         }
4357                 return res;
4358         }
4359         image = assembly->assembly->image;
4360         table = &image->tables [MONO_TABLE_FILE];
4361         res = mono_module_get_types (domain, image, exportedOnly);
4362
4363         /* Append data from all modules in the assembly */
4364         for (i = 0; i < table->rows; ++i) {
4365                 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4366                         MonoImage *loaded_image = mono_assembly_load_module (image->assembly, i + 1);
4367                         if (loaded_image) {
4368                                 MonoArray *res2 = mono_module_get_types (domain, loaded_image, exportedOnly);
4369                                 /* Append the new types to the end of the array */
4370                                 if (mono_array_length (res2) > 0) {
4371                                         guint32 len1, len2;
4372                                         MonoArray *res3;
4373
4374                                         len1 = mono_array_length (res);
4375                                         len2 = mono_array_length (res2);
4376                                         res3 = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4377                                         memcpy (mono_array_addr (res3, MonoReflectionType*, 0),
4378                                                         mono_array_addr (res, MonoReflectionType*, 0),
4379                                                         len1 * sizeof (MonoReflectionType*));
4380                                         memcpy (mono_array_addr (res3, MonoReflectionType*, len1),
4381                                                         mono_array_addr (res2, MonoReflectionType*, 0),
4382                                                         len2 * sizeof (MonoReflectionType*));
4383                                         res = res3;
4384                                 }
4385                         }
4386                 }
4387         }
4388
4389         if (mono_is_security_manager_active ()) {
4390                 /* the ReflectionTypeLoadException must have all the types (Types property), 
4391                  * NULL replacing types which throws an exception. The LoaderException must
4392                  * contains all exceptions for NULL items.
4393                  */
4394
4395                 guint32 len = mono_array_length (res);
4396                 GList *list = NULL;
4397
4398                 for (i = 0; i < len; i++) {
4399                         MonoReflectionType *t = mono_array_get (res, gpointer, i);
4400                         MonoClass *klass = mono_type_get_class (t->type);
4401                         if ((klass != NULL) && klass->exception_type) {
4402                                 /* keep the class in the list */
4403                                 list = g_list_append (list, klass);
4404                                 /* and replace Type with NULL */
4405                                 mono_array_set (res, gpointer, i, NULL);
4406                         }
4407                 }
4408
4409                 if (list) {
4410                         GList *tmp = NULL;
4411                         MonoException *exc = NULL;
4412                         int length = g_list_length (list);
4413
4414                         MonoArray *exl = mono_array_new (domain, mono_defaults.exception_class, length);
4415                         for (i = 0, tmp = list; i < length; i++, tmp = tmp->next) {
4416                                 MonoException *exc = mono_class_get_exception_for_failure (tmp->data);
4417                                 mono_array_set (exl, gpointer, i, exc);
4418                         }
4419                         g_list_free (list);
4420                         list = NULL;
4421
4422                         exc = mono_get_exception_reflection_type_load (res, exl);
4423                         mono_raise_exception (exc);
4424                 }
4425         }
4426                 
4427         return res;
4428 }
4429
4430 static MonoReflectionType*
4431 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModule *module)
4432 {
4433         MonoDomain *domain = mono_object_domain (module); 
4434         MonoClass *klass;
4435
4436         MONO_ARCH_SAVE_REGS;
4437
4438         g_assert (module->image);
4439
4440         if (module->image->dynamic && ((MonoDynamicImage*)(module->image))->initial_image)
4441                 /* These images do not have a global type */
4442                 return NULL;
4443
4444         klass = mono_class_get (module->image, 1 | MONO_TOKEN_TYPE_DEF);
4445         return mono_type_get_object (domain, &klass->byval_arg);
4446 }
4447
4448 static void
4449 ves_icall_System_Reflection_Module_Close (MonoReflectionModule *module)
4450 {
4451         /*if (module->image)
4452                 mono_image_close (module->image);*/
4453 }
4454
4455 static MonoString*
4456 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModule *module)
4457 {
4458         MonoDomain *domain = mono_object_domain (module); 
4459
4460         MONO_ARCH_SAVE_REGS;
4461
4462         g_assert (module->image);
4463         return mono_string_new (domain, module->image->guid);
4464 }
4465
4466 static void
4467 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine)
4468 {
4469         if (image->dynamic) {
4470                 MonoDynamicImage *dyn = (MonoDynamicImage*)image;
4471                 *pe_kind = dyn->pe_kind;
4472                 *machine = dyn->machine;
4473         }
4474         else {
4475                 *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
4476                 *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
4477         }
4478 }
4479
4480 static MonoArray*
4481 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModule *module)
4482 {
4483         MONO_ARCH_SAVE_REGS;
4484
4485         if (!module->image)
4486                 return mono_array_new (mono_object_domain (module), mono_defaults.monotype_class, 0);
4487         else
4488                 return mono_module_get_types (mono_object_domain (module), module->image, FALSE);
4489 }
4490
4491 static gboolean
4492 mono_metadata_memberref_is_method (MonoImage *image, guint32 token)
4493 {
4494         guint32 cols [MONO_MEMBERREF_SIZE];
4495         const char *sig;
4496         mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
4497         sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
4498         mono_metadata_decode_blob_size (sig, &sig);
4499         return (*sig != 0x6);
4500 }
4501
4502 static MonoType*
4503 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
4504 {
4505         MonoClass *klass;
4506         int table = mono_metadata_token_table (token);
4507         int index = mono_metadata_token_index (token);
4508
4509         *error = ResolveTokenError_Other;
4510
4511         /* Validate token */
4512         if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) && 
4513                 (table != MONO_TABLE_TYPESPEC)) {
4514                 *error = ResolveTokenError_BadTable;
4515                 return NULL;
4516         }
4517
4518         if (image->dynamic)
4519                 return mono_lookup_dynamic_token (image, token);
4520
4521         if ((index <= 0) || (index > image->tables [table].rows)) {
4522                 *error = ResolveTokenError_OutOfRange;
4523                 return NULL;
4524         }
4525
4526         klass = mono_class_get (image, token);
4527         if (klass)
4528                 return &klass->byval_arg;
4529         else
4530                 return NULL;
4531 }
4532
4533 static MonoMethod*
4534 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
4535 {
4536         int table = mono_metadata_token_table (token);
4537         int index = mono_metadata_token_index (token);
4538
4539         *error = ResolveTokenError_Other;
4540
4541         /* Validate token */
4542         if ((table != MONO_TABLE_METHOD) && (table != MONO_TABLE_METHODSPEC) && 
4543                 (table != MONO_TABLE_MEMBERREF)) {
4544                 *error = ResolveTokenError_BadTable;
4545                 return NULL;
4546         }
4547
4548         if (image->dynamic)
4549                 /* FIXME: validate memberref token type */
4550                 return mono_lookup_dynamic_token (image, token);
4551
4552         if ((index <= 0) || (index > image->tables [table].rows)) {
4553                 *error = ResolveTokenError_OutOfRange;
4554                 return NULL;
4555         }
4556         if ((table == MONO_TABLE_MEMBERREF) && (!mono_metadata_memberref_is_method (image, token))) {
4557                 *error = ResolveTokenError_BadTable;
4558                 return NULL;
4559         }
4560
4561         return mono_get_method (image, token, NULL);
4562 }
4563
4564 static MonoString*
4565 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
4566 {
4567         int index = mono_metadata_token_index (token);
4568
4569         *error = ResolveTokenError_Other;
4570
4571         /* Validate token */
4572         if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
4573                 *error = ResolveTokenError_BadTable;
4574                 return NULL;
4575         }
4576
4577         if (image->dynamic)
4578                 return mono_lookup_dynamic_token (image, token);
4579
4580         if ((index <= 0) || (index >= image->heap_us.size)) {
4581                 *error = ResolveTokenError_OutOfRange;
4582                 return NULL;
4583         }
4584
4585         /* FIXME: What to do if the index points into the middle of a string ? */
4586
4587         return mono_ldstr (mono_domain_get (), image, index);
4588 }
4589
4590 static MonoClassField*
4591 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
4592 {
4593         MonoClass *klass;
4594         int table = mono_metadata_token_table (token);
4595         int index = mono_metadata_token_index (token);
4596
4597         *error = ResolveTokenError_Other;
4598
4599         /* Validate token */
4600         if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
4601                 *error = ResolveTokenError_BadTable;
4602                 return NULL;
4603         }
4604
4605         if (image->dynamic)
4606                 /* FIXME: validate memberref token type */
4607                 return mono_lookup_dynamic_token (image, token);
4608
4609         if ((index <= 0) || (index > image->tables [table].rows)) {
4610                 *error = ResolveTokenError_OutOfRange;
4611                 return NULL;
4612         }
4613         if ((table == MONO_TABLE_MEMBERREF) && (mono_metadata_memberref_is_method (image, token))) {
4614                 *error = ResolveTokenError_BadTable;
4615                 return NULL;
4616         }
4617
4618         return mono_field_from_token (image, token, &klass, NULL);
4619 }
4620
4621
4622 static MonoObject*
4623 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
4624 {
4625         int table = mono_metadata_token_table (token);
4626
4627         *error = ResolveTokenError_Other;
4628
4629         switch (table) {
4630         case MONO_TABLE_TYPEDEF:
4631         case MONO_TABLE_TYPEREF:
4632         case MONO_TABLE_TYPESPEC: {
4633                 MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, error);
4634                 if (t)
4635                         return (MonoObject*)mono_type_get_object (mono_domain_get (), t);
4636                 else
4637                         return NULL;
4638         }
4639         case MONO_TABLE_METHOD:
4640         case MONO_TABLE_METHODSPEC: {
4641                 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, error);
4642                 if (m)
4643                         return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
4644                 else
4645                         return NULL;
4646         }               
4647         case MONO_TABLE_FIELD: {
4648                 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, error);
4649                 if (f)
4650                         return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
4651                 else
4652                         return NULL;
4653         }
4654         case MONO_TABLE_MEMBERREF:
4655                 if (mono_metadata_memberref_is_method (image, token)) {
4656                         MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, error);
4657                         if (m)
4658                                 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
4659                         else
4660                                 return NULL;
4661                 }
4662                 else {
4663                         MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, error);
4664                         if (f)
4665                                 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
4666                         else
4667                                 return NULL;
4668                 }
4669                 break;
4670
4671         default:
4672                 *error = ResolveTokenError_BadTable;
4673         }
4674
4675         return NULL;
4676 }
4677
4678 static MonoReflectionType*
4679 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
4680 {
4681         MonoClass *klass;
4682         int isbyref = 0, rank;
4683         char *str = mono_string_to_utf8 (smodifiers);
4684         char *p;
4685
4686         MONO_ARCH_SAVE_REGS;
4687
4688         klass = mono_class_from_mono_type (tb->type.type);
4689         p = str;
4690         /* logic taken from mono_reflection_parse_type(): keep in sync */
4691         while (*p) {
4692                 switch (*p) {
4693                 case '&':
4694                         if (isbyref) { /* only one level allowed by the spec */
4695                                 g_free (str);
4696                                 return NULL;
4697                         }
4698                         isbyref = 1;
4699                         p++;
4700                         g_free (str);
4701                         return mono_type_get_object (mono_object_domain (tb), &klass->this_arg);
4702                         break;
4703                 case '*':
4704                         klass = mono_ptr_class_get (&klass->byval_arg);
4705                         mono_class_init (klass);
4706                         p++;
4707                         break;
4708                 case '[':
4709                         rank = 1;
4710                         p++;
4711                         while (*p) {
4712                                 if (*p == ']')
4713                                         break;
4714                                 if (*p == ',')
4715                                         rank++;
4716                                 else if (*p != '*') { /* '*' means unknown lower bound */
4717                                         g_free (str);
4718                                         return NULL;
4719                                 }
4720                                 ++p;
4721                         }
4722                         if (*p != ']') {
4723                                 g_free (str);
4724                                 return NULL;
4725                         }
4726                         p++;
4727                         klass = mono_array_class_get (klass, rank);
4728                         mono_class_init (klass);
4729                         break;
4730                 default:
4731                         break;
4732                 }
4733         }
4734         g_free (str);
4735         return mono_type_get_object (mono_object_domain (tb), &klass->byval_arg);
4736 }
4737
4738 static MonoBoolean
4739 ves_icall_Type_IsArrayImpl (MonoReflectionType *t)
4740 {
4741         MonoType *type;
4742         MonoBoolean res;
4743
4744         MONO_ARCH_SAVE_REGS;
4745
4746         type = t->type;
4747         res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
4748
4749         return res;
4750 }
4751
4752 static MonoReflectionType *
4753 ves_icall_Type_make_array_type (MonoReflectionType *type, int rank)
4754 {
4755         MonoClass *klass, *aklass;
4756
4757         MONO_ARCH_SAVE_REGS;
4758
4759         klass = mono_class_from_mono_type (type->type);
4760         aklass = mono_array_class_get (klass, rank);
4761
4762         return mono_type_get_object (mono_object_domain (type), &aklass->byval_arg);
4763 }
4764
4765 static MonoReflectionType *
4766 ves_icall_Type_make_byref_type (MonoReflectionType *type)
4767 {
4768         MonoClass *klass;
4769
4770         MONO_ARCH_SAVE_REGS;
4771
4772         klass = mono_class_from_mono_type (type->type);
4773
4774         return mono_type_get_object (mono_object_domain (type), &klass->this_arg);
4775 }
4776
4777 static MonoReflectionType *
4778 ves_icall_Type_MakePointerType (MonoReflectionType *type)
4779 {
4780         MonoClass *pklass;
4781
4782         MONO_ARCH_SAVE_REGS;
4783
4784         pklass = mono_ptr_class_get (type->type);
4785
4786         return mono_type_get_object (mono_object_domain (type), &pklass->byval_arg);
4787 }
4788
4789 static MonoObject *
4790 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
4791                                                    MonoReflectionMethod *info)
4792 {
4793         MonoClass *delegate_class = mono_class_from_mono_type (type->type);
4794         MonoObject *delegate;
4795         gpointer func;
4796
4797         MONO_ARCH_SAVE_REGS;
4798
4799         mono_assert (delegate_class->parent == mono_defaults.multicastdelegate_class);
4800
4801         delegate = mono_object_new (mono_object_domain (type), delegate_class);
4802
4803         func = mono_compile_method (info->method);
4804
4805         mono_delegate_ctor (delegate, target, func);
4806
4807         return delegate;
4808 }
4809
4810 static void
4811 ves_icall_System_Delegate_FreeTrampoline (MonoDelegate *this)
4812 {
4813         /*
4814         Delegates have a finalizer only when needed, now.
4815         mono_delegate_free_ftnptr (this);*/
4816 }
4817
4818 /*
4819  * Magic number to convert a time which is relative to
4820  * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
4821  */
4822 #define EPOCH_ADJUST    ((guint64)62135596800LL)
4823
4824 /*
4825  * Magic number to convert FILETIME base Jan 1, 1601 to DateTime - base Jan, 1, 0001
4826  */
4827 #define FILETIME_ADJUST ((guint64)504911232000000000LL)
4828
4829 /*
4830  * This returns Now in UTC
4831  */
4832 static gint64
4833 ves_icall_System_DateTime_GetNow (void)
4834 {
4835 #ifdef PLATFORM_WIN32
4836         SYSTEMTIME st;
4837         FILETIME ft;
4838         
4839         GetSystemTime (&st);
4840         SystemTimeToFileTime (&st, &ft);
4841         return (gint64) FILETIME_ADJUST + ((((gint64)ft.dwHighDateTime)<<32) | ft.dwLowDateTime);
4842 #else
4843         /* FIXME: put this in io-layer and call it GetLocalTime */
4844         struct timeval tv;
4845         gint64 res;
4846
4847         MONO_ARCH_SAVE_REGS;
4848
4849         if (gettimeofday (&tv, NULL) == 0) {
4850                 res = (((gint64)tv.tv_sec + EPOCH_ADJUST)* 1000000 + tv.tv_usec)*10;
4851                 return res;
4852         }
4853         /* fixme: raise exception */
4854         return 0;
4855 #endif
4856 }
4857
4858 #ifdef PLATFORM_WIN32
4859 /* convert a SYSTEMTIME which is of the form "last thursday in october" to a real date */
4860 static void
4861 convert_to_absolute_date(SYSTEMTIME *date)
4862 {
4863 #define IS_LEAP(y) ((y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0))
4864         static int days_in_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
4865         static int leap_days_in_month[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
4866         /* from the calendar FAQ */
4867         int a = (14 - date->wMonth) / 12;
4868         int y = date->wYear - a;
4869         int m = date->wMonth + 12 * a - 2;
4870         int d = (1 + y + y/4 - y/100 + y/400 + (31*m)/12) % 7;
4871
4872         /* d is now the day of the week for the first of the month (0 == Sunday) */
4873
4874         int day_of_week = date->wDayOfWeek;
4875
4876         /* set day_in_month to the first day in the month which falls on day_of_week */    
4877         int day_in_month = 1 + (day_of_week - d);
4878         if (day_in_month <= 0)
4879                 day_in_month += 7;
4880
4881         /* wDay is 1 for first weekday in month, 2 for 2nd ... 5 means last - so work that out allowing for days in the month */
4882         date->wDay = day_in_month + (date->wDay - 1) * 7;
4883         if (date->wDay > (IS_LEAP(date->wYear) ? leap_days_in_month[date->wMonth - 1] : days_in_month[date->wMonth - 1]))
4884                 date->wDay -= 7;
4885 }
4886 #endif
4887
4888 #ifndef PLATFORM_WIN32
4889 /*
4890  * Return's the offset from GMT of a local time.
4891  * 
4892  *  tm is a local time
4893  *  t  is the same local time as seconds.
4894  */
4895 static int 
4896 gmt_offset(struct tm *tm, time_t t)
4897 {
4898 #if defined (HAVE_TM_GMTOFF)
4899         return tm->tm_gmtoff;
4900 #else
4901         struct tm g;
4902         time_t t2;
4903         g = *gmtime(&t);
4904         g.tm_isdst = tm->tm_isdst;
4905         t2 = mktime(&g);
4906         return (int)difftime(t, t2);
4907 #endif
4908 }
4909 #endif
4910 /*
4911  * This is heavily based on zdump.c from glibc 2.2.
4912  *
4913  *  * data[0]:  start of daylight saving time (in DateTime ticks).
4914  *  * data[1]:  end of daylight saving time (in DateTime ticks).
4915  *  * data[2]:  utcoffset (in TimeSpan ticks).
4916  *  * data[3]:  additional offset when daylight saving (in TimeSpan ticks).
4917  *  * name[0]:  name of this timezone when not daylight saving.
4918  *  * name[1]:  name of this timezone when daylight saving.
4919  *
4920  *  FIXME: This only works with "standard" Unix dates (years between 1900 and 2100) while
4921  *         the class library allows years between 1 and 9999.
4922  *
4923  *  Returns true on success and zero on failure.
4924  */
4925 static guint32
4926 ves_icall_System_CurrentTimeZone_GetTimeZoneData (guint32 year, MonoArray **data, MonoArray **names)
4927 {
4928 #ifndef PLATFORM_WIN32
4929         MonoDomain *domain = mono_domain_get ();
4930         struct tm start, tt;
4931         time_t t;
4932
4933         long int gmtoff;
4934         int is_daylight = 0, day;
4935         char tzone [64];
4936
4937         MONO_ARCH_SAVE_REGS;
4938
4939         MONO_CHECK_ARG_NULL (data);
4940         MONO_CHECK_ARG_NULL (names);
4941
4942         (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
4943         (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
4944
4945         /* 
4946          * no info is better than crashing: we'll need our own tz data
4947          * to make this work properly, anyway. The range is probably
4948          * reduced to 1970 .. 2037 because that is what mktime is
4949          * guaranteed to support (we get into an infinite loop
4950          * otherwise).
4951          */
4952
4953         memset (&start, 0, sizeof (start));
4954
4955         start.tm_mday = 1;
4956         start.tm_year = year-1900;
4957
4958         t = mktime (&start);
4959
4960         if ((year < 1970) || (year > 2037) || (t == -1)) {
4961                 t = time (NULL);
4962                 tt = *localtime (&t);
4963                 strftime (tzone, sizeof (tzone), "%Z", &tt);
4964                 mono_array_set ((*names), gpointer, 0, mono_string_new (domain, tzone));
4965                 mono_array_set ((*names), gpointer, 1, mono_string_new (domain, tzone));
4966                 return 1;
4967         }
4968
4969         gmtoff = gmt_offset (&start, t);
4970
4971         /* For each day of the year, calculate the tm_gmtoff. */
4972         for (day = 0; day < 365; day++) {
4973
4974                 t += 3600*24;
4975                 tt = *localtime (&t);
4976
4977                 /* Daylight saving starts or ends here. */
4978                 if (gmt_offset (&tt, t) != gmtoff) {
4979                         struct tm tt1;
4980                         time_t t1;
4981
4982                         /* Try to find the exact hour when daylight saving starts/ends. */
4983                         t1 = t;
4984                         do {
4985                                 t1 -= 3600;
4986                                 tt1 = *localtime (&t1);
4987                         } while (gmt_offset (&tt1, t1) != gmtoff);
4988
4989                         /* Try to find the exact minute when daylight saving starts/ends. */
4990                         do {
4991                                 t1 += 60;
4992                                 tt1 = *localtime (&t1);
4993                         } while (gmt_offset (&tt1, t1) == gmtoff);
4994                         t1+=gmtoff;
4995                         strftime (tzone, sizeof (tzone), "%Z", &tt);
4996                         
4997                         /* Write data, if we're already in daylight saving, we're done. */
4998                         if (is_daylight) {
4999                                 mono_array_set ((*names), gpointer, 0, mono_string_new (domain, tzone));
5000                                 mono_array_set ((*data), gint64, 1, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
5001                                 return 1;
5002                         } else {
5003                                 mono_array_set ((*names), gpointer, 1, mono_string_new (domain, tzone));
5004                                 mono_array_set ((*data), gint64, 0, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
5005                                 is_daylight = 1;
5006                         }
5007
5008                         /* This is only set once when we enter daylight saving. */
5009                         mono_array_set ((*data), gint64, 2, (gint64)gmtoff * 10000000L);
5010                         mono_array_set ((*data), gint64, 3, (gint64)(gmt_offset (&tt, t) - gmtoff) * 10000000L);
5011
5012                         gmtoff = gmt_offset (&tt, t);
5013                 }
5014         }
5015
5016         if (!is_daylight) {
5017                 strftime (tzone, sizeof (tzone), "%Z", &tt);
5018                 mono_array_set ((*names), gpointer, 0, mono_string_new (domain, tzone));
5019                 mono_array_set ((*names), gpointer, 1, mono_string_new (domain, tzone));
5020                 mono_array_set ((*data), gint64, 0, 0);
5021                 mono_array_set ((*data), gint64, 1, 0);
5022                 mono_array_set ((*data), gint64, 2, (gint64) gmtoff * 10000000L);
5023                 mono_array_set ((*data), gint64, 3, 0);
5024         }
5025
5026         return 1;
5027 #else
5028         MonoDomain *domain = mono_domain_get ();
5029         TIME_ZONE_INFORMATION tz_info;
5030         FILETIME ft;
5031         int i;
5032         int err, tz_id;
5033
5034         tz_id = GetTimeZoneInformation (&tz_info);
5035         if (tz_id == TIME_ZONE_ID_INVALID)
5036                 return 0;
5037
5038         MONO_CHECK_ARG_NULL (data);
5039         MONO_CHECK_ARG_NULL (names);
5040
5041         (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5042         (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5043
5044         for (i = 0; i < 32; ++i)
5045                 if (!tz_info.DaylightName [i])
5046                         break;
5047         mono_array_set ((*names), gpointer, 1, mono_string_new_utf16 (domain, tz_info.DaylightName, i));
5048         for (i = 0; i < 32; ++i)
5049                 if (!tz_info.StandardName [i])
5050                         break;
5051         mono_array_set ((*names), gpointer, 0, mono_string_new_utf16 (domain, tz_info.StandardName, i));
5052
5053         if ((year <= 1601) || (year > 30827)) {
5054                 /*
5055                  * According to MSDN, the MS time functions can't handle dates outside
5056                  * this interval.
5057                  */
5058                 return 1;
5059         }
5060
5061         /* even if the timezone has no daylight savings it may have Bias (e.g. GMT+13 it seems) */
5062         if (tz_id != TIME_ZONE_ID_UNKNOWN) {
5063                 tz_info.StandardDate.wYear = year;
5064                 convert_to_absolute_date(&tz_info.StandardDate);
5065                 err = SystemTimeToFileTime (&tz_info.StandardDate, &ft);
5066                 g_assert(err);
5067                 mono_array_set ((*data), gint64, 1, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
5068                 tz_info.DaylightDate.wYear = year;
5069                 convert_to_absolute_date(&tz_info.DaylightDate);
5070                 err = SystemTimeToFileTime (&tz_info.DaylightDate, &ft);
5071                 g_assert(err);
5072                 mono_array_set ((*data), gint64, 0, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
5073         }
5074         mono_array_set ((*data), gint64, 2, (tz_info.Bias + tz_info.StandardBias) * -600000000LL);
5075         mono_array_set ((*data), gint64, 3, (tz_info.DaylightBias - tz_info.StandardBias) * -600000000LL);
5076
5077         return 1;
5078 #endif
5079 }
5080
5081 static gpointer
5082 ves_icall_System_Object_obj_address (MonoObject *this) 
5083 {
5084         MONO_ARCH_SAVE_REGS;
5085
5086         return this;
5087 }
5088
5089 /* System.Buffer */
5090
5091 static inline gint32 
5092 mono_array_get_byte_length (MonoArray *array)
5093 {
5094         MonoClass *klass;
5095         int length;
5096         int i;
5097
5098         klass = array->obj.vtable->klass;
5099
5100         if (array->bounds == NULL)
5101                 length = array->max_length;
5102         else {
5103                 length = 1;
5104                 for (i = 0; i < klass->rank; ++ i)
5105                         length *= array->bounds [i].length;
5106         }
5107
5108         switch (klass->element_class->byval_arg.type) {
5109         case MONO_TYPE_I1:
5110         case MONO_TYPE_U1:
5111         case MONO_TYPE_BOOLEAN:
5112                 return length;
5113         case MONO_TYPE_I2:
5114         case MONO_TYPE_U2:
5115         case MONO_TYPE_CHAR:
5116                 return length << 1;
5117         case MONO_TYPE_I4:
5118         case MONO_TYPE_U4:
5119         case MONO_TYPE_R4:
5120                 return length << 2;
5121         case MONO_TYPE_I:
5122         case MONO_TYPE_U:
5123                 return length * sizeof (gpointer);
5124         case MONO_TYPE_I8:
5125         case MONO_TYPE_U8:
5126         case MONO_TYPE_R8:
5127                 return length << 3;
5128         default:
5129                 return -1;
5130         }
5131 }
5132
5133 static gint32 
5134 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array) 
5135 {
5136         MONO_ARCH_SAVE_REGS;
5137
5138         return mono_array_get_byte_length (array);
5139 }
5140
5141 static gint8 
5142 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx) 
5143 {
5144         MONO_ARCH_SAVE_REGS;
5145
5146         return mono_array_get (array, gint8, idx);
5147 }
5148
5149 static void 
5150 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value) 
5151 {
5152         MONO_ARCH_SAVE_REGS;
5153
5154         mono_array_set (array, gint8, idx, value);
5155 }
5156
5157 static MonoBoolean
5158 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count) 
5159 {
5160         guint8 *src_buf, *dest_buf;
5161
5162         MONO_ARCH_SAVE_REGS;
5163
5164         /* watch out for integer overflow */
5165         if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count))
5166                 return FALSE;
5167
5168         src_buf = (guint8 *)src->vector + src_offset;
5169         dest_buf = (guint8 *)dest->vector + dest_offset;
5170
5171         if (src != dest)
5172                 memcpy (dest_buf, src_buf, count);
5173         else
5174                 memmove (dest_buf, src_buf, count); /* Source and dest are the same array */
5175
5176         return TRUE;
5177 }
5178
5179 static MonoObject *
5180 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this, MonoString *class_name)
5181 {
5182         MonoDomain *domain = mono_object_domain (this); 
5183         MonoObject *res;
5184         MonoRealProxy *rp = ((MonoRealProxy *)this);
5185         MonoTransparentProxy *tp;
5186         MonoType *type;
5187         MonoClass *klass;
5188
5189         MONO_ARCH_SAVE_REGS;
5190
5191         res = mono_object_new (domain, mono_defaults.transparent_proxy_class);
5192         tp = (MonoTransparentProxy*) res;
5193         
5194         tp->rp = rp;
5195         type = ((MonoReflectionType *)rp->class_to_proxy)->type;
5196         klass = mono_class_from_mono_type (type);
5197
5198         tp->custom_type_info = (mono_object_isinst (this, mono_defaults.iremotingtypeinfo_class) != NULL);
5199         tp->remote_class = mono_remote_class (domain, class_name, klass);
5200
5201         res->vtable = mono_remote_class_vtable (domain, tp->remote_class, rp);
5202         return res;
5203 }
5204
5205 static MonoReflectionType *
5206 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
5207 {
5208         return mono_type_get_object (mono_object_domain (tp), &tp->remote_class->proxy_class->byval_arg);
5209 }
5210
5211 /* System.Environment */
5212
5213 static MonoString *
5214 ves_icall_System_Environment_get_MachineName (void)
5215 {
5216 #if defined (PLATFORM_WIN32)
5217         gunichar2 *buf;
5218         guint32 len;
5219         MonoString *result;
5220
5221         len = MAX_COMPUTERNAME_LENGTH + 1;
5222         buf = g_new (gunichar2, len);
5223
5224         result = NULL;
5225         if (GetComputerName (buf, (PDWORD) &len))
5226                 result = mono_string_new_utf16 (mono_domain_get (), buf, len);
5227
5228         g_free (buf);
5229         return result;
5230 #else
5231         gchar *buf;
5232         int len;
5233         MonoString *result;
5234
5235         MONO_ARCH_SAVE_REGS;
5236
5237         len = 256;
5238         buf = g_new (gchar, len);
5239
5240         result = NULL;
5241         if (gethostname (buf, len) == 0)
5242                 result = mono_string_new (mono_domain_get (), buf);
5243         
5244         g_free (buf);
5245         return result;
5246 #endif
5247 }
5248
5249 static int
5250 ves_icall_System_Environment_get_Platform (void)
5251 {
5252         MONO_ARCH_SAVE_REGS;
5253
5254 #if defined (PLATFORM_WIN32)
5255         /* Win32NT */
5256         return 2;
5257 #else
5258         /* Unix */
5259         return 128;
5260 #endif
5261 }
5262
5263 static MonoString *
5264 ves_icall_System_Environment_get_NewLine (void)
5265 {
5266         MONO_ARCH_SAVE_REGS;
5267
5268 #if defined (PLATFORM_WIN32)
5269         return mono_string_new (mono_domain_get (), "\r\n");
5270 #else
5271         return mono_string_new (mono_domain_get (), "\n");
5272 #endif
5273 }
5274
5275 static MonoString *
5276 ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name)
5277 {
5278         const gchar *value;
5279         gchar *utf8_name;
5280
5281         MONO_ARCH_SAVE_REGS;
5282
5283         if (name == NULL)
5284                 return NULL;
5285
5286         utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
5287         value = g_getenv (utf8_name);
5288         g_free (utf8_name);
5289
5290         if (value == 0)
5291                 return NULL;
5292         
5293         return mono_string_new (mono_domain_get (), value);
5294 }
5295
5296 /*
5297  * There is no standard way to get at environ.
5298  */
5299 #ifndef _MSC_VER
5300 extern
5301 #endif
5302 char **environ;
5303
5304 static MonoArray *
5305 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
5306 {
5307         MonoArray *names;
5308         MonoDomain *domain;
5309         MonoString *str;
5310         gchar **e, **parts;
5311         int n;
5312
5313         MONO_ARCH_SAVE_REGS;
5314
5315         n = 0;
5316         for (e = environ; *e != 0; ++ e)
5317                 ++ n;
5318
5319         domain = mono_domain_get ();
5320         names = mono_array_new (domain, mono_defaults.string_class, n);
5321
5322         n = 0;
5323         for (e = environ; *e != 0; ++ e) {
5324                 parts = g_strsplit (*e, "=", 2);
5325                 if (*parts != 0) {
5326                         str = mono_string_new (domain, *parts);
5327                         mono_array_set (names, MonoString *, n, str);
5328                 }
5329
5330                 g_strfreev (parts);
5331
5332                 ++ n;
5333         }
5334
5335         return names;
5336 }
5337
5338 /*
5339  * Returns: the number of milliseconds elapsed since the system started.
5340  */
5341 static gint32
5342 ves_icall_System_Environment_get_TickCount (void)
5343 {
5344         return GetTickCount ();
5345 }
5346
5347
5348 static void
5349 ves_icall_System_Environment_Exit (int result)
5350 {
5351         MONO_ARCH_SAVE_REGS;
5352
5353         mono_runtime_set_shutting_down ();
5354
5355         /* Suspend all managed threads since the runtime is going away */
5356         mono_thread_suspend_all_other_threads ();
5357
5358         mono_runtime_quit ();
5359
5360         /* we may need to do some cleanup here... */
5361         exit (result);
5362 }
5363
5364 static MonoString*
5365 ves_icall_System_Environment_GetGacPath (void)
5366 {
5367         return mono_string_new (mono_domain_get (), mono_assembly_getrootdir ());
5368 }
5369
5370 static MonoString*
5371 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
5372 {
5373 #if defined (PLATFORM_WIN32)
5374         #ifndef CSIDL_FLAG_CREATE
5375                 #define CSIDL_FLAG_CREATE       0x8000
5376         #endif
5377
5378         WCHAR path [MAX_PATH];
5379         /* Create directory if no existing */
5380         if (SUCCEEDED (SHGetFolderPathW (NULL, folder | CSIDL_FLAG_CREATE, NULL, 0, path))) {
5381                 int len = 0;
5382                 while (path [len])
5383                         ++ len;
5384                 return mono_string_new_utf16 (mono_domain_get (), path, len);
5385         }
5386 #else
5387         g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
5388 #endif
5389         return mono_string_new (mono_domain_get (), "");
5390 }
5391
5392 static MonoArray *
5393 ves_icall_System_Environment_GetLogicalDrives (void)
5394 {
5395         gunichar2 buf [128], *ptr, *dname;
5396         gunichar2 *u16;
5397         gint initial_size = 127, size = 128;
5398         gint ndrives;
5399         MonoArray *result;
5400         MonoString *drivestr;
5401         MonoDomain *domain = mono_domain_get ();
5402         gint len;
5403
5404         MONO_ARCH_SAVE_REGS;
5405
5406         buf [0] = '\0';
5407         ptr = buf;
5408
5409         while (size > initial_size) {
5410                 size = GetLogicalDriveStrings (initial_size, ptr);
5411                 if (size > initial_size) {
5412                         if (ptr != buf)
5413                                 g_free (ptr);
5414                         ptr = g_malloc0 ((size + 1) * sizeof (gunichar2));
5415                         initial_size = size;
5416                         size++;
5417                 }
5418         }
5419
5420         /* Count strings */
5421         dname = ptr;
5422         ndrives = 0;
5423         do {
5424                 while (*dname++);
5425                 ndrives++;
5426         } while (*dname);
5427
5428         dname = ptr;
5429         result = mono_array_new (domain, mono_defaults.string_class, ndrives);
5430         ndrives = 0;
5431         do {
5432                 len = 0;
5433                 u16 = dname;
5434                 while (*u16) { u16++; len ++; }
5435                 drivestr = mono_string_new_utf16 (domain, dname, len);
5436                 mono_array_set (result, gpointer, ndrives++, drivestr);
5437                 while (*dname++);
5438         } while (*dname);
5439
5440         if (ptr != buf)
5441                 g_free (ptr);
5442
5443         return result;
5444 }
5445
5446 static MonoString *
5447 ves_icall_System_Environment_InternalGetHome (void)
5448 {
5449         MONO_ARCH_SAVE_REGS;
5450
5451         return mono_string_new (mono_domain_get (), g_get_home_dir ());
5452 }
5453
5454 static const char *encodings [] = {
5455         (char *) 1,
5456                 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
5457                 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
5458                 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
5459         (char *) 2,
5460                 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
5461                 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
5462                 "x_unicode_2_0_utf_7",
5463         (char *) 3,
5464                 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
5465                 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
5466         (char *) 4,
5467                 "utf_16", "UTF_16LE", "ucs_2", "unicode",
5468                 "iso_10646_ucs2",
5469         (char *) 5,
5470                 "unicodefffe", "utf_16be",
5471         (char *) 6,
5472                 "iso_8859_1",
5473         (char *) 0
5474 };
5475
5476 /*
5477  * Returns the internal codepage, if the value of "int_code_page" is
5478  * 1 at entry, and we can not compute a suitable code page number,
5479  * returns the code page as a string
5480  */
5481 static MonoString*
5482 ves_icall_System_Text_Encoding_InternalCodePage (gint32 *int_code_page) 
5483 {
5484         const char *cset;
5485         const char *p;
5486         char *c;
5487         char *codepage = NULL;
5488         int code;
5489         int want_name = *int_code_page;
5490         int i;
5491         
5492         *int_code_page = -1;
5493         MONO_ARCH_SAVE_REGS;
5494
5495         g_get_charset (&cset);
5496         c = codepage = strdup (cset);
5497         for (c = codepage; *c; c++){
5498                 if (isascii (*c) && isalpha (*c))
5499                         *c = tolower (*c);
5500                 if (*c == '-')
5501                         *c = '_';
5502         }
5503         /* g_print ("charset: %s\n", cset); */
5504         
5505         /* handle some common aliases */
5506         p = encodings [0];
5507         code = 0;
5508         for (i = 0; p != 0; ){
5509                 if ((gssize) p < 7){
5510                         code = (gssize) p;
5511                         p = encodings [++i];
5512                         continue;
5513                 }
5514                 if (strcmp (p, codepage) == 0){
5515                         *int_code_page = code;
5516                         break;
5517                 }
5518                 p = encodings [++i];
5519         }
5520         
5521         if (strstr (codepage, "utf_8") != NULL)
5522                 *int_code_page |= 0x10000000;
5523         free (codepage);
5524         
5525         if (want_name && *int_code_page == -1)
5526                 return mono_string_new (mono_domain_get (), cset);
5527         else
5528                 return NULL;
5529 }
5530
5531 static MonoBoolean
5532 ves_icall_System_Environment_get_HasShutdownStarted (void)
5533 {
5534         if (mono_runtime_is_shutting_down ())
5535                 return TRUE;
5536
5537         if (mono_domain_is_unloading (mono_domain_get ()))
5538                 return TRUE;
5539
5540         return FALSE;
5541 }
5542
5543 static void
5544 ves_icall_MonoMethodMessage_InitMessage (MonoMethodMessage *this, 
5545                                          MonoReflectionMethod *method,
5546                                          MonoArray *out_args)
5547 {
5548         MONO_ARCH_SAVE_REGS;
5549
5550         mono_message_init (mono_object_domain (this), this, method, out_args);
5551 }
5552
5553 static MonoBoolean
5554 ves_icall_IsTransparentProxy (MonoObject *proxy)
5555 {
5556         MONO_ARCH_SAVE_REGS;
5557
5558         if (!proxy)
5559                 return 0;
5560
5561         if (proxy->vtable->klass == mono_defaults.transparent_proxy_class)
5562                 return 1;
5563
5564         return 0;
5565 }
5566
5567 static void
5568 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
5569 {
5570         MonoClass *klass;
5571         MonoVTable* vtable;
5572
5573         MONO_ARCH_SAVE_REGS;
5574
5575         klass = mono_class_from_mono_type (type->type);
5576         vtable = mono_class_vtable (mono_domain_get (), klass);
5577
5578         if (enable) vtable->remote = 1;
5579         else vtable->remote = 0;
5580 }
5581
5582 static MonoObject *
5583 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type)
5584 {
5585         MonoClass *klass;
5586         MonoDomain *domain;
5587         
5588         MONO_ARCH_SAVE_REGS;
5589
5590         domain = mono_object_domain (type);
5591         klass = mono_class_from_mono_type (type->type);
5592
5593         if (klass->rank >= 1) {
5594                 g_assert (klass->rank == 1);
5595                 return (MonoObject *) mono_array_new (domain, klass->element_class, 0);
5596         } else {
5597                 /* Bypass remoting object creation check */
5598                 return mono_object_new_alloc_specific (mono_class_vtable (domain, klass));
5599         }
5600 }
5601
5602 static MonoString *
5603 ves_icall_System_IO_get_temp_path (void)
5604 {
5605         MONO_ARCH_SAVE_REGS;
5606
5607         return mono_string_new (mono_domain_get (), g_get_tmp_dir ());
5608 }
5609
5610 static gpointer
5611 ves_icall_RuntimeMethod_GetFunctionPointer (MonoMethod *method)
5612 {
5613         MONO_ARCH_SAVE_REGS;
5614
5615         return mono_compile_method (method);
5616 }
5617
5618 static MonoString *
5619 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
5620 {
5621         MonoString *mcpath;
5622         gchar *path;
5623
5624         MONO_ARCH_SAVE_REGS;
5625
5626         path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
5627
5628 #if defined (PLATFORM_WIN32)
5629         /* Avoid mixing '/' and '\\' */
5630         {
5631                 gint i;
5632                 for (i = strlen (path) - 1; i >= 0; i--)
5633                         if (path [i] == '/')
5634                                 path [i] = '\\';
5635         }
5636 #endif
5637         mcpath = mono_string_new (mono_domain_get (), path);
5638         g_free (path);
5639
5640         return mcpath;
5641 }
5642
5643 static MonoString *
5644 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
5645 {
5646         MonoString *ipath;
5647         gchar *path;
5648
5649         MONO_ARCH_SAVE_REGS;
5650
5651         path = g_path_get_dirname (mono_get_config_dir ());
5652
5653 #if defined (PLATFORM_WIN32)
5654         /* Avoid mixing '/' and '\\' */
5655         {
5656                 gint i;
5657                 for (i = strlen (path) - 1; i >= 0; i--)
5658                         if (path [i] == '/')
5659                                 path [i] = '\\';
5660         }
5661 #endif
5662         ipath = mono_string_new (mono_domain_get (), path);
5663         g_free (path);
5664
5665         return ipath;
5666 }
5667
5668 static void
5669 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
5670 {
5671 #if defined (PLATFORM_WIN32)
5672         static void (*output_debug) (gunichar2 *);
5673         static gboolean tried_loading = FALSE;
5674
5675         MONO_ARCH_SAVE_REGS;
5676
5677         if (!tried_loading && output_debug == NULL) {
5678                 GModule *k32;
5679
5680                 tried_loading = TRUE;
5681                 k32 = g_module_open ("kernel32", G_MODULE_BIND_LAZY);
5682                 if (!k32) {
5683                         gchar *error = g_strdup (g_module_error ());
5684                         g_warning ("Failed to load kernel32.dll: %s\n", error);
5685                         g_free (error);
5686                         return;
5687                 }
5688
5689                 g_module_symbol (k32, "OutputDebugStringW", (gpointer *) &output_debug);
5690                 if (!output_debug) {
5691                         gchar *error = g_strdup (g_module_error ());
5692                         g_warning ("Failed to load OutputDebugStringW: %s\n", error);
5693                         g_free (error);
5694                         return;
5695                 }
5696         }
5697
5698         if (output_debug == NULL)
5699                 return;
5700         
5701         output_debug (mono_string_chars (message));
5702 #else
5703         g_warning ("WriteWindowsDebugString called and PLATFORM_WIN32 not defined!\n");
5704 #endif
5705 }
5706
5707 /* Only used for value types */
5708 static MonoObject *
5709 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
5710 {
5711         MonoClass *klass;
5712         MonoDomain *domain;
5713         
5714         MONO_ARCH_SAVE_REGS;
5715
5716         domain = mono_object_domain (type);
5717         klass = mono_class_from_mono_type (type->type);
5718
5719         return mono_object_new (domain, klass);
5720 }
5721
5722 static MonoReflectionMethod *
5723 ves_icall_MonoMethod_get_base_definition (MonoReflectionMethod *m)
5724 {
5725         MonoClass *klass;
5726         MonoMethod *method = m->method;
5727         MonoMethod *result = NULL;
5728
5729         MONO_ARCH_SAVE_REGS;
5730
5731         if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
5732             MONO_CLASS_IS_INTERFACE (method->klass) ||
5733             method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
5734                 return m;
5735
5736         if (method->klass == NULL || (klass = method->klass->parent) == NULL)
5737                 return m;
5738
5739         if (klass->generic_class)
5740                 klass = klass->generic_class->container_class;
5741
5742         mono_class_setup_vtable (klass);
5743         mono_class_setup_vtable (method->klass);
5744         while (result == NULL && klass != NULL && (klass->vtable_size > method->slot))
5745         {
5746                 mono_class_setup_vtable (klass);
5747
5748                 result = klass->vtable [method->slot];
5749                 if (result == NULL) {
5750                         MonoMethod* m;
5751                         gpointer iter = NULL;
5752                         /* It is an abstract method */
5753                         while ((m = mono_class_get_methods (klass, &iter))) {
5754                                 if (m->slot == method->slot) {
5755                                         result = m;
5756                                         break;
5757                                 }
5758                         }
5759                 }
5760                 klass = klass->parent;
5761         }
5762
5763         if (result == NULL)
5764                 return m;
5765
5766         return mono_method_get_object (mono_domain_get (), result, NULL);
5767 }
5768
5769 static void
5770 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
5771 {
5772         MONO_ARCH_SAVE_REGS;
5773
5774         iter->sig = *(MonoMethodSignature**)argsp;
5775         
5776         g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
5777         g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
5778
5779         iter->next_arg = 0;
5780         /* FIXME: it's not documented what start is exactly... */
5781         if (start) {
5782                 iter->args = start;
5783         } else {
5784                 int i, align, arg_size;
5785                 iter->args = argsp + sizeof (gpointer);
5786 #ifndef MONO_ARCH_REGPARMS
5787                 for (i = 0; i < iter->sig->sentinelpos; ++i) {
5788                         arg_size = mono_type_stack_size (iter->sig->params [i], &align);
5789                         iter->args = (char*)iter->args + arg_size;
5790                 }
5791 #endif
5792         }
5793         iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
5794
5795         /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
5796 }
5797
5798 static MonoTypedRef
5799 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
5800 {
5801         gint i, align, arg_size;
5802         MonoTypedRef res;
5803         MONO_ARCH_SAVE_REGS;
5804
5805         i = iter->sig->sentinelpos + iter->next_arg;
5806
5807         g_assert (i < iter->sig->param_count);
5808
5809         res.type = iter->sig->params [i];
5810         res.klass = mono_class_from_mono_type (res.type);
5811         /* FIXME: endianess issue... */
5812         res.value = iter->args;
5813         arg_size = mono_type_stack_size (res.type, &align);
5814         iter->args = (char*)iter->args + arg_size;
5815         iter->next_arg++;
5816
5817         /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
5818
5819         return res;
5820 }
5821
5822 static MonoTypedRef
5823 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
5824 {
5825         gint i, align, arg_size;
5826         MonoTypedRef res;
5827         MONO_ARCH_SAVE_REGS;
5828
5829         i = iter->sig->sentinelpos + iter->next_arg;
5830
5831         g_assert (i < iter->sig->param_count);
5832
5833         while (i < iter->sig->param_count) {
5834                 if (!mono_metadata_type_equal (type, iter->sig->params [i]))
5835                         continue;
5836                 res.type = iter->sig->params [i];
5837                 res.klass = mono_class_from_mono_type (res.type);
5838                 /* FIXME: endianess issue... */
5839                 res.value = iter->args;
5840                 arg_size = mono_type_stack_size (res.type, &align);
5841                 iter->args = (char*)iter->args + arg_size;
5842                 iter->next_arg++;
5843                 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
5844                 return res;
5845         }
5846         /* g_print ("arg type 0x%02x not found\n", res.type->type); */
5847
5848         res.type = NULL;
5849         res.value = NULL;
5850         res.klass = NULL;
5851         return res;
5852 }
5853
5854 static MonoType*
5855 mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
5856 {
5857         gint i;
5858         MONO_ARCH_SAVE_REGS;
5859         
5860         i = iter->sig->sentinelpos + iter->next_arg;
5861
5862         g_assert (i < iter->sig->param_count);
5863
5864         return iter->sig->params [i];
5865 }
5866
5867 static MonoObject*
5868 mono_TypedReference_ToObject (MonoTypedRef tref)
5869 {
5870         MONO_ARCH_SAVE_REGS;
5871
5872         if (MONO_TYPE_IS_REFERENCE (tref.type)) {
5873                 MonoObject** objp = tref.value;
5874                 return *objp;
5875         }
5876
5877         return mono_value_box (mono_domain_get (), tref.klass, tref.value);
5878 }
5879
5880 static MonoObject*
5881 mono_TypedReference_ToObjectInternal (MonoType *type, gpointer value, MonoClass *klass)
5882 {
5883         MONO_ARCH_SAVE_REGS;
5884
5885         if (MONO_TYPE_IS_REFERENCE (type)) {
5886                 MonoObject** objp = value;
5887                 return *objp;
5888         }
5889
5890         return mono_value_box (mono_domain_get (), klass, value);
5891 }
5892
5893 static void
5894 prelink_method (MonoMethod *method)
5895 {
5896         const char *exc_class, *exc_arg;
5897         if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
5898                 return;
5899         mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
5900         if (exc_class) {
5901                 mono_raise_exception( 
5902                         mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg ) );
5903         }
5904         /* create the wrapper, too? */
5905 }
5906
5907 static void
5908 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
5909 {
5910         MONO_ARCH_SAVE_REGS;
5911         prelink_method (method->method);
5912 }
5913
5914 static void
5915 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
5916 {
5917         MonoClass *klass = mono_class_from_mono_type (type->type);
5918         MonoMethod* m;
5919         gpointer iter = NULL;
5920         MONO_ARCH_SAVE_REGS;
5921
5922         while ((m = mono_class_get_methods (klass, &iter)))
5923                 prelink_method (m);
5924 }
5925
5926 /* These parameters are "readonly" in corlib/System/Char.cs */
5927 static void
5928 ves_icall_System_Char_GetDataTablePointers (guint8 const **category_data,
5929                                             guint8 const **numeric_data,
5930                                             gdouble const **numeric_data_values,
5931                                             guint16 const **to_lower_data_low,
5932                                             guint16 const **to_lower_data_high,
5933                                             guint16 const **to_upper_data_low,
5934                                             guint16 const **to_upper_data_high)
5935 {
5936         *category_data = CategoryData;
5937         *numeric_data = NumericData;
5938         *numeric_data_values = NumericDataValues;
5939         *to_lower_data_low = ToLowerDataLow;
5940         *to_lower_data_high = ToLowerDataHigh;
5941         *to_upper_data_low = ToUpperDataLow;
5942         *to_upper_data_high = ToUpperDataHigh;
5943 }
5944
5945 static MonoString *
5946 ves_icall_MonoDebugger_check_runtime_version (MonoString *fname)
5947 {
5948         gchar *filename, *error = NULL;
5949
5950         MONO_ARCH_SAVE_REGS;
5951
5952         filename = mono_string_to_utf8 (fname);
5953         error = mono_debugger_check_runtime_version (filename);
5954         g_free (filename);
5955
5956         if (error)
5957                 return mono_string_new (mono_domain_get (), error);
5958         else
5959                 return NULL;
5960 }
5961
5962 static gint32
5963 ves_icall_MonoDebugger_GetMethodIndex (MonoReflectionMethod *rmethod)
5964 {
5965         guint32 index;
5966
5967         MONO_ARCH_SAVE_REGS;
5968
5969         index = mono_method_get_index (rmethod->method);
5970         if (!index)
5971                 return -1;
5972
5973         return index - rmethod->method->klass->method.first;
5974 }
5975
5976 static MonoReflectionType*
5977 ves_icall_MonoDebugger_MakeArrayType (MonoReflectionType *type, int rank)
5978 {
5979         MonoClass *klass, *aklass;
5980
5981         MONO_ARCH_SAVE_REGS;
5982
5983         klass = mono_class_from_mono_type (type->type);
5984         aklass = mono_array_class_get (klass, rank);
5985
5986         return mono_type_get_object (mono_object_domain (type), &aklass->byval_arg);
5987 }
5988
5989 static int
5990 ves_icall_MonoDebugger_GetTypeToken (MonoObject *obj)
5991 {
5992         MONO_ARCH_SAVE_REGS;
5993
5994         return mono_reflection_get_token (obj);
5995 }
5996
5997 static MonoBoolean
5998 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
5999 {
6000         MonoCustomAttrInfo *cinfo;
6001         gboolean found;
6002
6003         cinfo = mono_reflection_get_custom_attrs_info (obj);
6004         if (!cinfo)
6005                 return FALSE;
6006         found = mono_custom_attrs_has_attr (cinfo, mono_class_from_mono_type (attr_type->type));
6007         if (!cinfo->cached)
6008                 mono_custom_attrs_free (cinfo);
6009         return found;
6010 }
6011
6012 static MonoBoolean
6013 GCHandle_CheckCurrentDomain (guint32 gchandle)
6014 {
6015         return mono_gchandle_is_in_domain (gchandle, mono_domain_get ());
6016 }
6017
6018 static MonoString*
6019 ves_icall_Mono_Runtime_GetDisplayName (void)
6020 {
6021         char *display_name_str = g_strdup_printf ("Mono %s", VERSION);
6022         MonoString *display_name = mono_string_new (mono_domain_get (), display_name_str);
6023         g_free (display_name_str);
6024         return display_name;
6025 }
6026
6027 static guchar dbase64 [] = {
6028         128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
6029         128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
6030         128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 62, 128, 128, 128, 63,
6031         52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 0, 128, 128,
6032         128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
6033         15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 128, 128, 128, 128, 128,
6034         128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
6035         41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
6036         };
6037
6038 static MonoArray *
6039 base64_to_byte_array (gunichar2 *start, gint ilength)
6040 {
6041         gint ignored;
6042         gint i;
6043         gunichar2 c;
6044         gint olength;
6045         MonoArray *result;
6046         guchar *res_ptr;
6047         gint a [4], b [4];
6048         MonoException *exc;
6049
6050         ignored = 0;
6051         for (i = 0; i < ilength; i++) {
6052                 c = start [i];
6053                 if (isspace (c)) {
6054                         ignored++;
6055                 } else if (c >= sizeof (dbase64)) {
6056                         exc = mono_exception_from_name_msg (mono_get_corlib (),
6057                                 "System", "FormatException",
6058                                 "Invalid character found.");
6059                         mono_raise_exception (exc);
6060                 }
6061         }
6062
6063         olength = ilength - ignored;
6064         if ((olength & 3) != 0 || olength <= 0) {
6065                 exc = mono_exception_from_name_msg (mono_get_corlib (), "System",
6066                                         "FormatException", "Invalid length.");
6067                 mono_raise_exception (exc);
6068         }
6069
6070         olength = (olength * 3) / 4;
6071         if (start [ilength - 1] == '=')
6072                 olength--;
6073
6074         if (start [ilength - 2] == '=')
6075                 olength--;
6076
6077         result = mono_array_new (mono_domain_get (), mono_defaults.byte_class, olength);
6078         res_ptr = mono_array_addr (result, guchar, 0);
6079         for (i = 0; i < ilength; ) {
6080                 int k;
6081
6082                 for (k = 0; k < 4 && i < ilength;) {
6083                         c = start [i++];
6084                         if (isspace (c))
6085                                 continue;
6086
6087                         a [k] = (guchar) c;
6088                         if (((b [k] = dbase64 [c]) & 0x80) != 0) {
6089                                 exc = mono_exception_from_name_msg (mono_get_corlib (),
6090                                         "System", "FormatException",
6091                                         "Invalid character found.");
6092                                 mono_raise_exception (exc);
6093                         }
6094                         k++;
6095                 }
6096
6097                 *res_ptr++ = (b [0] << 2) | (b [1] >> 4);
6098                 if (a [2] != '=')
6099                         *res_ptr++ = (b [1] << 4) | (b [2] >> 2);
6100                 if (a [3] != '=')
6101                         *res_ptr++ = (b [2] << 6) | b [3];
6102
6103                 while (i < ilength && isspace (start [i]))
6104                         i++;
6105         }
6106
6107         return result;
6108 }
6109
6110 static MonoArray *
6111 InternalFromBase64String (MonoString *str)
6112 {
6113         MONO_ARCH_SAVE_REGS;
6114
6115         return base64_to_byte_array (mono_string_chars (str), mono_string_length (str));
6116 }
6117
6118 static MonoArray *
6119 InternalFromBase64CharArray (MonoArray *input, gint offset, gint length)
6120 {
6121         MONO_ARCH_SAVE_REGS;
6122
6123         return base64_to_byte_array (mono_array_addr (input, gunichar2, offset), length);
6124 }
6125
6126 /* icall map */
6127 typedef struct {
6128         const char *method;
6129         gconstpointer func;
6130 } IcallEntry;
6131
6132 typedef struct {
6133         const char *klass;
6134         const IcallEntry *icalls;
6135         const int size;
6136 } IcallMap;
6137
6138 static const IcallEntry runtime_icalls [] = {
6139         {"GetDisplayName", ves_icall_Mono_Runtime_GetDisplayName}
6140 };
6141
6142 static const IcallEntry activator_icalls [] = {
6143         {"CreateInstanceInternal", ves_icall_System_Activator_CreateInstanceInternal}
6144 };
6145 static const IcallEntry appdomain_icalls [] = {
6146         {"ExecuteAssembly", ves_icall_System_AppDomain_ExecuteAssembly},
6147         {"GetAssemblies", ves_icall_System_AppDomain_GetAssemblies},
6148         {"GetData", ves_icall_System_AppDomain_GetData},
6149         {"InternalGetContext", ves_icall_System_AppDomain_InternalGetContext},
6150         {"InternalGetDefaultContext", ves_icall_System_AppDomain_InternalGetDefaultContext},
6151         {"InternalGetProcessGuid", ves_icall_System_AppDomain_InternalGetProcessGuid},
6152         {"InternalIsFinalizingForUnload", ves_icall_System_AppDomain_InternalIsFinalizingForUnload},
6153         {"InternalPopDomainRef", ves_icall_System_AppDomain_InternalPopDomainRef},
6154         {"InternalPushDomainRef", ves_icall_System_AppDomain_InternalPushDomainRef},
6155         {"InternalPushDomainRefByID", ves_icall_System_AppDomain_InternalPushDomainRefByID},
6156         {"InternalSetContext", ves_icall_System_AppDomain_InternalSetContext},
6157         {"InternalSetDomain", ves_icall_System_AppDomain_InternalSetDomain},
6158         {"InternalSetDomainByID", ves_icall_System_AppDomain_InternalSetDomainByID},
6159         {"InternalUnload", ves_icall_System_AppDomain_InternalUnload},
6160         {"LoadAssembly", ves_icall_System_AppDomain_LoadAssembly},
6161         {"LoadAssemblyRaw", ves_icall_System_AppDomain_LoadAssemblyRaw},
6162         {"SetData", ves_icall_System_AppDomain_SetData},
6163         {"createDomain", ves_icall_System_AppDomain_createDomain},
6164         {"getCurDomain", ves_icall_System_AppDomain_getCurDomain},
6165         {"getFriendlyName", ves_icall_System_AppDomain_getFriendlyName},
6166         {"getRootDomain", ves_icall_System_AppDomain_getRootDomain},
6167         {"getSetup", ves_icall_System_AppDomain_getSetup}
6168 };
6169
6170 static const IcallEntry argiterator_icalls [] = {
6171         {"IntGetNextArg()",                  mono_ArgIterator_IntGetNextArg},
6172         {"IntGetNextArg(intptr)", mono_ArgIterator_IntGetNextArgT},
6173         {"IntGetNextArgType",                mono_ArgIterator_IntGetNextArgType},
6174         {"Setup",                            mono_ArgIterator_Setup}
6175 };
6176
6177 static const IcallEntry array_icalls [] = {
6178         {"ClearInternal",    ves_icall_System_Array_ClearInternal},
6179         {"Clone",            mono_array_clone},
6180         {"CreateInstanceImpl",   ves_icall_System_Array_CreateInstanceImpl},
6181         {"FastCopy",         ves_icall_System_Array_FastCopy},
6182         {"GetLength",        ves_icall_System_Array_GetLength},
6183         {"GetLowerBound",    ves_icall_System_Array_GetLowerBound},
6184         {"GetRank",          ves_icall_System_Array_GetRank},
6185         {"GetValue",         ves_icall_System_Array_GetValue},
6186         {"GetValueImpl",     ves_icall_System_Array_GetValueImpl},
6187         {"SetValue",         ves_icall_System_Array_SetValue},
6188         {"SetValueImpl",     ves_icall_System_Array_SetValueImpl}
6189 };
6190
6191 static const IcallEntry buffer_icalls [] = {
6192         {"BlockCopyInternal", ves_icall_System_Buffer_BlockCopyInternal},
6193         {"ByteLengthInternal", ves_icall_System_Buffer_ByteLengthInternal},
6194         {"GetByteInternal", ves_icall_System_Buffer_GetByteInternal},
6195         {"SetByteInternal", ves_icall_System_Buffer_SetByteInternal}
6196 };
6197
6198 static const IcallEntry char_icalls [] = {
6199         {"GetDataTablePointers", ves_icall_System_Char_GetDataTablePointers}
6200 };
6201
6202 static const IcallEntry defaultconf_icalls [] = {
6203         {"get_machine_config_path", ves_icall_System_Configuration_DefaultConfig_get_machine_config_path}
6204 };
6205
6206 static const IcallEntry consoledriver_icalls [] = {
6207         {"InternalKeyAvailable", ves_icall_System_ConsoleDriver_InternalKeyAvailable },
6208         {"Isatty", ves_icall_System_ConsoleDriver_Isatty },
6209         {"SetBreak", ves_icall_System_ConsoleDriver_SetBreak },
6210         {"SetEcho", ves_icall_System_ConsoleDriver_SetEcho },
6211         {"TtySetup", ves_icall_System_ConsoleDriver_TtySetup }
6212 };
6213
6214 static const IcallEntry convert_icalls [] = {
6215         {"InternalFromBase64CharArray", InternalFromBase64CharArray },
6216         {"InternalFromBase64String", InternalFromBase64String }
6217 };
6218
6219 static const IcallEntry timezone_icalls [] = {
6220         {"GetTimeZoneData", ves_icall_System_CurrentTimeZone_GetTimeZoneData}
6221 };
6222
6223 static const IcallEntry datetime_icalls [] = {
6224         {"GetNow", ves_icall_System_DateTime_GetNow}
6225 };
6226
6227 #ifndef DISABLE_DECIMAL
6228 static const IcallEntry decimal_icalls [] = {
6229         {"decimal2Int64", mono_decimal2Int64},
6230         {"decimal2UInt64", mono_decimal2UInt64},
6231         {"decimal2double", mono_decimal2double},
6232         {"decimal2string", mono_decimal2string},
6233         {"decimalCompare", mono_decimalCompare},
6234         {"decimalDiv", mono_decimalDiv},
6235         {"decimalFloorAndTrunc", mono_decimalFloorAndTrunc},
6236         {"decimalIncr", mono_decimalIncr},
6237         {"decimalIntDiv", mono_decimalIntDiv},
6238         {"decimalMult", mono_decimalMult},
6239         {"decimalRound", mono_decimalRound},
6240         {"decimalSetExponent", mono_decimalSetExponent},
6241         {"double2decimal", mono_double2decimal}, /* FIXME: wrong signature. */
6242         {"string2decimal", mono_string2decimal}
6243 };
6244 #endif
6245
6246 static const IcallEntry delegate_icalls [] = {
6247         {"CreateDelegate_internal", ves_icall_System_Delegate_CreateDelegate_internal},
6248         {"FreeTrampoline", ves_icall_System_Delegate_FreeTrampoline}
6249 };
6250
6251 static const IcallEntry tracelist_icalls [] = {
6252         {"WriteWindowsDebugString", ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString}
6253 };
6254
6255 static const IcallEntry fileversion_icalls [] = {
6256         {"GetVersionInfo_internal(string)", ves_icall_System_Diagnostics_FileVersionInfo_GetVersionInfo_internal}
6257 };
6258
6259 static const IcallEntry process_icalls [] = {
6260         {"ExitCode_internal(intptr)", ves_icall_System_Diagnostics_Process_ExitCode_internal},
6261         {"ExitTime_internal(intptr)", ves_icall_System_Diagnostics_Process_ExitTime_internal},
6262         {"GetModules_internal()", ves_icall_System_Diagnostics_Process_GetModules_internal},
6263         {"GetPid_internal()", ves_icall_System_Diagnostics_Process_GetPid_internal},
6264         {"GetProcess_internal(int)", ves_icall_System_Diagnostics_Process_GetProcess_internal},
6265         {"GetProcesses_internal()", ves_icall_System_Diagnostics_Process_GetProcesses_internal},
6266         {"GetWorkingSet_internal(intptr,int&,int&)", ves_icall_System_Diagnostics_Process_GetWorkingSet_internal},
6267         {"Kill_internal", ves_icall_System_Diagnostics_Process_Kill_internal},
6268         {"ProcessName_internal(intptr)", ves_icall_System_Diagnostics_Process_ProcessName_internal},
6269         {"Process_free_internal(intptr)", ves_icall_System_Diagnostics_Process_Process_free_internal},
6270         {"SetWorkingSet_internal(intptr,int,int,bool)", ves_icall_System_Diagnostics_Process_SetWorkingSet_internal},
6271         {"StartTime_internal(intptr)", ves_icall_System_Diagnostics_Process_StartTime_internal},
6272         {"Start_internal(string,string,string,intptr,intptr,intptr,System.Diagnostics.Process/ProcInfo&)", ves_icall_System_Diagnostics_Process_Start_internal},
6273         {"WaitForExit_internal(intptr,int)", ves_icall_System_Diagnostics_Process_WaitForExit_internal}
6274 };
6275
6276 static const IcallEntry double_icalls [] = {
6277         {"AssertEndianity", ves_icall_System_Double_AssertEndianity},
6278         {"ParseImpl",    mono_double_ParseImpl}
6279 };
6280
6281 static const IcallEntry enum_icalls [] = {
6282         {"ToObject", ves_icall_System_Enum_ToObject},
6283         {"get_value", ves_icall_System_Enum_get_value}
6284 };
6285
6286 static const IcallEntry environment_icalls [] = {
6287         {"Exit", ves_icall_System_Environment_Exit},
6288         {"GetCommandLineArgs", mono_runtime_get_main_args},
6289         {"GetEnvironmentVariableNames", ves_icall_System_Environment_GetEnvironmentVariableNames},
6290         {"GetLogicalDrivesInternal", ves_icall_System_Environment_GetLogicalDrives },
6291         {"GetMachineConfigPath", ves_icall_System_Configuration_DefaultConfig_get_machine_config_path},
6292         {"GetOSVersionString", ves_icall_System_Environment_GetOSVersionString},
6293         {"GetWindowsFolderPath", ves_icall_System_Environment_GetWindowsFolderPath},
6294         {"get_ExitCode", mono_environment_exitcode_get},
6295         {"get_HasShutdownStarted", ves_icall_System_Environment_get_HasShutdownStarted},
6296         {"get_MachineName", ves_icall_System_Environment_get_MachineName},
6297         {"get_NewLine", ves_icall_System_Environment_get_NewLine},
6298         {"get_Platform", ves_icall_System_Environment_get_Platform},
6299         {"get_TickCount", ves_icall_System_Environment_get_TickCount},
6300         {"get_UserName", ves_icall_System_Environment_get_UserName},
6301         {"internalGetEnvironmentVariable", ves_icall_System_Environment_GetEnvironmentVariable},
6302         {"internalGetGacPath", ves_icall_System_Environment_GetGacPath},
6303         {"internalGetHome", ves_icall_System_Environment_InternalGetHome},
6304         {"set_ExitCode", mono_environment_exitcode_set}
6305 };
6306
6307 static const IcallEntry cultureinfo_icalls [] = {
6308         {"construct_compareinfo(object,string)", ves_icall_System_Globalization_CompareInfo_construct_compareinfo},
6309         {"construct_datetime_format", ves_icall_System_Globalization_CultureInfo_construct_datetime_format},
6310         {"construct_internal_locale(string)", ves_icall_System_Globalization_CultureInfo_construct_internal_locale},
6311         {"construct_internal_locale_from_current_locale", ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_current_locale},
6312         {"construct_internal_locale_from_lcid", ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_lcid},
6313         {"construct_internal_locale_from_name", ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_name},
6314         {"construct_internal_locale_from_specific_name", ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_specific_name},
6315         {"construct_number_format", ves_icall_System_Globalization_CultureInfo_construct_number_format},
6316         {"internal_get_cultures", ves_icall_System_Globalization_CultureInfo_internal_get_cultures},
6317         {"internal_is_lcid_neutral", ves_icall_System_Globalization_CultureInfo_internal_is_lcid_neutral}
6318 };
6319
6320 static const IcallEntry compareinfo_icalls [] = {
6321         {"assign_sortkey(object,string,System.Globalization.CompareOptions)", ves_icall_System_Globalization_CompareInfo_assign_sortkey},
6322         {"construct_compareinfo(string)", ves_icall_System_Globalization_CompareInfo_construct_compareinfo},
6323         {"free_internal_collator()", ves_icall_System_Globalization_CompareInfo_free_internal_collator},
6324         {"internal_compare(string,int,int,string,int,int,System.Globalization.CompareOptions)", ves_icall_System_Globalization_CompareInfo_internal_compare},
6325         {"internal_index(string,int,int,char,System.Globalization.CompareOptions,bool)", ves_icall_System_Globalization_CompareInfo_internal_index_char},
6326         {"internal_index(string,int,int,string,System.Globalization.CompareOptions,bool)", ves_icall_System_Globalization_CompareInfo_internal_index}
6327 };
6328
6329 static const IcallEntry gc_icalls [] = {
6330         {"GetTotalMemory", ves_icall_System_GC_GetTotalMemory},
6331         {"InternalCollect", ves_icall_System_GC_InternalCollect},
6332         {"KeepAlive", ves_icall_System_GC_KeepAlive},
6333         {"ReRegisterForFinalize", ves_icall_System_GC_ReRegisterForFinalize},
6334         {"SuppressFinalize", ves_icall_System_GC_SuppressFinalize},
6335         {"WaitForPendingFinalizers", ves_icall_System_GC_WaitForPendingFinalizers}
6336 };
6337
6338 static const IcallEntry famwatcher_icalls [] = {
6339         {"InternalFAMNextEvent", ves_icall_System_IO_FAMW_InternalFAMNextEvent}
6340 };
6341
6342 static const IcallEntry filewatcher_icalls [] = {
6343         {"InternalCloseDirectory", ves_icall_System_IO_FSW_CloseDirectory},
6344         {"InternalOpenDirectory", ves_icall_System_IO_FSW_OpenDirectory},
6345         {"InternalReadDirectoryChanges", ves_icall_System_IO_FSW_ReadDirectoryChanges},
6346         {"InternalSupportsFSW", ves_icall_System_IO_FSW_SupportsFSW}
6347 };
6348
6349 static const IcallEntry path_icalls [] = {
6350         {"get_temp_path", ves_icall_System_IO_get_temp_path}
6351 };
6352
6353 static const IcallEntry monoio_icalls [] = {
6354         {"Close(intptr,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_Close},
6355         {"CopyFile(string,string,bool,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_CopyFile},
6356         {"CreateDirectory(string,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_CreateDirectory},
6357         {"CreatePipe(intptr&,intptr&)", ves_icall_System_IO_MonoIO_CreatePipe},
6358         {"DeleteFile(string,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_DeleteFile},
6359         {"FindClose(intptr,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_FindClose},
6360         {"FindFirstFile(string,System.IO.MonoIOStat&,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_FindFirstFile},
6361         {"FindNextFile(intptr,System.IO.MonoIOStat&,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_FindNextFile},
6362         {"Flush(intptr,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_Flush},
6363         {"GetCurrentDirectory(System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_GetCurrentDirectory},
6364         {"GetFileAttributes(string,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_GetFileAttributes},
6365         {"GetFileStat(string,System.IO.MonoIOStat&,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_GetFileStat},
6366         {"GetFileType(intptr,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_GetFileType},
6367         {"GetLength(intptr,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_GetLength},
6368         {"GetTempPath(string&)", ves_icall_System_IO_MonoIO_GetTempPath},
6369         {"Lock(intptr,long,long,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_Lock},
6370         {"MoveFile(string,string,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_MoveFile},
6371         {"Open(string,System.IO.FileMode,System.IO.FileAccess,System.IO.FileShare,bool,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_Open},
6372         {"Read(intptr,byte[],int,int,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_Read},
6373         {"RemoveDirectory(string,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_RemoveDirectory},
6374         {"Seek(intptr,long,System.IO.SeekOrigin,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_Seek},
6375         {"SetCurrentDirectory(string,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_SetCurrentDirectory},
6376         {"SetFileAttributes(string,System.IO.FileAttributes,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_SetFileAttributes},
6377         {"SetFileTime(intptr,long,long,long,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_SetFileTime},
6378         {"SetLength(intptr,long,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_SetLength},
6379         {"Unlock(intptr,long,long,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_Unlock},
6380         {"Write(intptr,byte[],int,int,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_Write},
6381         {"get_AltDirectorySeparatorChar", ves_icall_System_IO_MonoIO_get_AltDirectorySeparatorChar},
6382         {"get_ConsoleError", ves_icall_System_IO_MonoIO_get_ConsoleError},
6383         {"get_ConsoleInput", ves_icall_System_IO_MonoIO_get_ConsoleInput},
6384         {"get_ConsoleOutput", ves_icall_System_IO_MonoIO_get_ConsoleOutput},
6385         {"get_DirectorySeparatorChar", ves_icall_System_IO_MonoIO_get_DirectorySeparatorChar},
6386         {"get_InvalidPathChars", ves_icall_System_IO_MonoIO_get_InvalidPathChars},
6387         {"get_PathSeparator", ves_icall_System_IO_MonoIO_get_PathSeparator},
6388         {"get_VolumeSeparatorChar", ves_icall_System_IO_MonoIO_get_VolumeSeparatorChar}
6389 };
6390
6391 static const IcallEntry math_icalls [] = {
6392         {"Acos", ves_icall_System_Math_Acos},
6393         {"Asin", ves_icall_System_Math_Asin},
6394         {"Atan", ves_icall_System_Math_Atan},
6395         {"Atan2", ves_icall_System_Math_Atan2},
6396         {"Cos", ves_icall_System_Math_Cos},
6397         {"Cosh", ves_icall_System_Math_Cosh},
6398         {"Exp", ves_icall_System_Math_Exp},
6399         {"Floor", ves_icall_System_Math_Floor},
6400         {"Log", ves_icall_System_Math_Log},
6401         {"Log10", ves_icall_System_Math_Log10},
6402         {"Pow", ves_icall_System_Math_Pow},
6403         {"Round", ves_icall_System_Math_Round},
6404         {"Round2", ves_icall_System_Math_Round2},
6405         {"Sin", ves_icall_System_Math_Sin},
6406         {"Sinh", ves_icall_System_Math_Sinh},
6407         {"Sqrt", ves_icall_System_Math_Sqrt},
6408         {"Tan", ves_icall_System_Math_Tan},
6409         {"Tanh", ves_icall_System_Math_Tanh}
6410 };
6411
6412 static const IcallEntry customattrs_icalls [] = {
6413         {"GetCustomAttributesDataInternal", mono_reflection_get_custom_attrs_data},
6414         {"GetCustomAttributesInternal", mono_reflection_get_custom_attrs},
6415         {"IsDefinedInternal", custom_attrs_defined_internal}
6416 };
6417
6418 static const IcallEntry enuminfo_icalls [] = {
6419         {"get_enum_info", ves_icall_get_enum_info}
6420 };
6421
6422 static const IcallEntry fieldinfo_icalls [] = {
6423         {"GetUnmanagedMarshal", ves_icall_System_Reflection_FieldInfo_GetUnmanagedMarshal},
6424         {"internal_from_handle", ves_icall_System_Reflection_FieldInfo_internal_from_handle}
6425 };
6426
6427 static const IcallEntry memberinfo_icalls [] = {
6428         {"get_MetadataToken", mono_reflection_get_token}
6429 };
6430
6431 static const IcallEntry monotype_icalls [] = {
6432         {"GetArrayRank", ves_icall_MonoType_GetArrayRank},
6433         {"GetConstructors", ves_icall_Type_GetConstructors_internal},
6434         {"GetConstructors_internal", ves_icall_Type_GetConstructors_internal},
6435         {"GetCorrespondingInflatedConstructor", ves_icall_MonoType_GetCorrespondingInflatedMethod},
6436         {"GetCorrespondingInflatedMethod", ves_icall_MonoType_GetCorrespondingInflatedMethod},
6437         {"GetElementType", ves_icall_MonoType_GetElementType},
6438         {"GetEvents_internal", ves_icall_Type_GetEvents_internal},
6439         {"GetField", ves_icall_Type_GetField},
6440         {"GetFields_internal", ves_icall_Type_GetFields_internal},
6441         {"GetGenericArguments", ves_icall_MonoType_GetGenericArguments},
6442         {"GetInterfaces", ves_icall_Type_GetInterfaces},
6443         {"GetMethodsByName", ves_icall_Type_GetMethodsByName},
6444         {"GetNestedType", ves_icall_Type_GetNestedType},
6445         {"GetNestedTypes", ves_icall_Type_GetNestedTypes},
6446         {"GetPropertiesByName", ves_icall_Type_GetPropertiesByName},
6447         {"InternalGetEvent", ves_icall_MonoType_GetEvent},
6448         {"IsByRefImpl", ves_icall_type_isbyref},
6449         {"IsPointerImpl", ves_icall_type_ispointer},
6450         {"IsPrimitiveImpl", ves_icall_type_isprimitive},
6451         {"getFullName", ves_icall_System_MonoType_getFullName},
6452         {"get_Assembly", ves_icall_MonoType_get_Assembly},
6453         {"get_BaseType", ves_icall_get_type_parent},
6454         {"get_DeclaringMethod", ves_icall_MonoType_get_DeclaringMethod},
6455         {"get_DeclaringType", ves_icall_MonoType_get_DeclaringType},
6456         {"get_HasGenericArguments", ves_icall_MonoType_get_HasGenericArguments},
6457         {"get_IsGenericParameter", ves_icall_MonoType_get_IsGenericParameter},
6458         {"get_Module", ves_icall_MonoType_get_Module},
6459         {"get_Name", ves_icall_MonoType_get_Name},
6460         {"get_Namespace", ves_icall_MonoType_get_Namespace},
6461         {"get_UnderlyingSystemType", ves_icall_MonoType_get_UnderlyingSystemType},
6462         {"get_attributes", ves_icall_get_attributes},
6463         {"type_from_obj", mono_type_type_from_obj}
6464 };
6465
6466 static const IcallEntry assembly_icalls [] = {
6467         {"FillName", ves_icall_System_Reflection_Assembly_FillName},
6468         {"GetCallingAssembly", ves_icall_System_Reflection_Assembly_GetCallingAssembly},
6469         {"GetEntryAssembly", ves_icall_System_Reflection_Assembly_GetEntryAssembly},
6470         {"GetExecutingAssembly", ves_icall_System_Reflection_Assembly_GetExecutingAssembly},
6471         {"GetFilesInternal", ves_icall_System_Reflection_Assembly_GetFilesInternal},
6472         {"GetManifestResourceInfoInternal", ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal},
6473         {"GetManifestResourceInternal", ves_icall_System_Reflection_Assembly_GetManifestResourceInternal},
6474         {"GetManifestResourceNames", ves_icall_System_Reflection_Assembly_GetManifestResourceNames},
6475         {"GetModulesInternal", ves_icall_System_Reflection_Assembly_GetModulesInternal},
6476         {"GetNamespaces", ves_icall_System_Reflection_Assembly_GetNamespaces},
6477         {"GetReferencedAssemblies", ves_icall_System_Reflection_Assembly_GetReferencedAssemblies},
6478         {"GetTypes", ves_icall_System_Reflection_Assembly_GetTypes},
6479         {"InternalGetAssemblyName", ves_icall_System_Reflection_Assembly_InternalGetAssemblyName},
6480         {"InternalGetType", ves_icall_System_Reflection_Assembly_InternalGetType},
6481         {"InternalImageRuntimeVersion", ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion},
6482         {"LoadFrom", ves_icall_System_Reflection_Assembly_LoadFrom},
6483         {"LoadPermissions", ves_icall_System_Reflection_Assembly_LoadPermissions},
6484         /*
6485          * Private icalls for the Mono Debugger
6486          */
6487         {"MonoDebugger_CheckRuntimeVersion", ves_icall_MonoDebugger_check_runtime_version},
6488         {"MonoDebugger_GetLocalTypeFromSignature", ves_icall_MonoDebugger_GetLocalTypeFromSignature},
6489         {"MonoDebugger_GetMethod", ves_icall_MonoDebugger_GetMethod},
6490         {"MonoDebugger_GetMethodIndex", ves_icall_MonoDebugger_GetMethodIndex},
6491         {"MonoDebugger_GetMethodToken", ves_icall_MonoDebugger_GetMethodToken},
6492         {"MonoDebugger_GetType", ves_icall_MonoDebugger_GetType},
6493         {"MonoDebugger_GetTypeToken", ves_icall_MonoDebugger_GetTypeToken},
6494         {"MonoDebugger_MakeArrayType", ves_icall_MonoDebugger_MakeArrayType},
6495
6496         /* normal icalls again */
6497         {"get_EntryPoint", ves_icall_System_Reflection_Assembly_get_EntryPoint},
6498         {"get_ManifestModule", ves_icall_System_Reflection_Assembly_get_ManifestModule},
6499         {"get_MetadataToken", mono_reflection_get_token},
6500         {"get_ReflectionOnly", ves_icall_System_Reflection_Assembly_get_ReflectionOnly},
6501         {"get_code_base", ves_icall_System_Reflection_Assembly_get_code_base},
6502         {"get_global_assembly_cache", ves_icall_System_Reflection_Assembly_get_global_assembly_cache},
6503         {"get_location", ves_icall_System_Reflection_Assembly_get_location},
6504         {"load_with_partial_name", ves_icall_System_Reflection_Assembly_load_with_partial_name}
6505 };
6506
6507 static const IcallEntry methodbase_icalls [] = {
6508         {"GetCurrentMethod", ves_icall_GetCurrentMethod},
6509         {"GetMethodBodyInternal", ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal},
6510         {"GetMethodFromHandleInternal", ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternal}
6511 };
6512
6513 static const IcallEntry module_icalls [] = {
6514         {"Close", ves_icall_System_Reflection_Module_Close},
6515         {"GetGlobalType", ves_icall_System_Reflection_Module_GetGlobalType},
6516         {"GetGuidInternal", ves_icall_System_Reflection_Module_GetGuidInternal},
6517         {"GetPEKind", ves_icall_System_Reflection_Module_GetPEKind},
6518         {"InternalGetTypes", ves_icall_System_Reflection_Module_InternalGetTypes},
6519         {"ResolveFieldToken", ves_icall_System_Reflection_Module_ResolveFieldToken},
6520         {"ResolveMemberToken", ves_icall_System_Reflection_Module_ResolveMemberToken},
6521         {"ResolveMethodToken", ves_icall_System_Reflection_Module_ResolveMethodToken},
6522         {"ResolveStringToken", ves_icall_System_Reflection_Module_ResolveStringToken},
6523         {"ResolveTypeToken", ves_icall_System_Reflection_Module_ResolveTypeToken},
6524         {"get_MetadataToken", mono_reflection_get_token}
6525 };
6526
6527 static const IcallEntry monocmethod_icalls [] = {
6528         {"GetGenericMethodDefinition_impl", ves_icall_MonoMethod_GetGenericMethodDefinition},
6529         {"InternalInvoke", ves_icall_InternalInvoke},
6530         {"get_Mono_IsInflatedMethod", ves_icall_MonoMethod_get_Mono_IsInflatedMethod}
6531 };
6532
6533 static const IcallEntry monoeventinfo_icalls [] = {
6534         {"get_event_info", ves_icall_get_event_info}
6535 };
6536
6537 static const IcallEntry monofield_icalls [] = {
6538         {"GetFieldOffset", ves_icall_MonoField_GetFieldOffset},
6539         {"GetParentType", ves_icall_MonoField_GetParentType},
6540         {"GetValueInternal", ves_icall_MonoField_GetValueInternal},
6541         {"Mono_GetGenericFieldDefinition", ves_icall_MonoField_Mono_GetGenericFieldDefinition},
6542         {"SetValueInternal", ves_icall_FieldInfo_SetValueInternal}
6543 };
6544
6545 static const IcallEntry monogenericclass_icalls [] = {
6546         {"GetConstructors_internal", ves_icall_MonoGenericClass_GetConstructors},
6547         {"GetCorrespondingInflatedConstructor", ves_icall_MonoGenericClass_GetCorrespondingInflatedConstructor},
6548         {"GetCorrespondingInflatedField", ves_icall_MonoGenericClass_GetCorrespondingInflatedField},
6549         {"GetCorrespondingInflatedMethod", ves_icall_MonoGenericClass_GetCorrespondingInflatedMethod},
6550         {"GetEvents_internal", ves_icall_MonoGenericClass_GetEvents},
6551         {"GetFields_internal", ves_icall_MonoGenericClass_GetFields},
6552         {"GetInterfaces_internal", ves_icall_MonoGenericClass_GetInterfaces},
6553         {"GetMethods_internal", ves_icall_MonoGenericClass_GetMethods},
6554         {"GetParentType", ves_icall_MonoGenericClass_GetParentType},
6555         {"GetProperties_internal", ves_icall_MonoGenericClass_GetProperties},
6556         {"initialize", mono_reflection_generic_class_initialize}
6557 };
6558
6559 static const IcallEntry monogenericmethod_icalls [] = {
6560         {"get_ReflectedType", ves_icall_MonoGenericMethod_get_ReflectedType}
6561 };
6562
6563 static const IcallEntry generictypeparambuilder_icalls [] = {
6564         {"initialize", mono_reflection_initialize_generic_parameter}
6565 };
6566
6567 static const IcallEntry monomethod_icalls [] = {
6568         {"BindGenericParameters", mono_reflection_bind_generic_method_parameters},
6569         {"GetDllImportAttribute", ves_icall_MonoMethod_GetDllImportAttribute},
6570         {"GetGenericArguments", ves_icall_MonoMethod_GetGenericArguments},
6571         {"GetGenericMethodDefinition_impl", ves_icall_MonoMethod_GetGenericMethodDefinition},
6572         {"InternalInvoke", ves_icall_InternalInvoke},
6573         {"get_HasGenericParameters", ves_icall_MonoMethod_get_HasGenericParameters},
6574         {"get_IsGenericMethodDefinition", ves_icall_MonoMethod_get_IsGenericMethodDefinition},
6575         {"get_Mono_IsInflatedMethod", ves_icall_MonoMethod_get_Mono_IsInflatedMethod},
6576         {"get_base_definition", ves_icall_MonoMethod_get_base_definition}
6577 };
6578
6579 static const IcallEntry monomethodinfo_icalls [] = {
6580         {"get_method_info", ves_icall_get_method_info},
6581         {"get_parameter_info", ves_icall_get_parameter_info}
6582 };
6583
6584 static const IcallEntry monopropertyinfo_icalls [] = {
6585         {"get_property_info", ves_icall_get_property_info}
6586 };
6587
6588 static const IcallEntry parameterinfo_icalls [] = {
6589         {"get_MetadataToken", mono_reflection_get_token}
6590 };
6591
6592 static const IcallEntry dns_icalls [] = {
6593         {"GetHostByAddr_internal(string,string&,string[]&,string[]&)", ves_icall_System_Net_Dns_GetHostByAddr_internal},
6594         {"GetHostByName_internal(string,string&,string[]&,string[]&)", ves_icall_System_Net_Dns_GetHostByName_internal},
6595         {"GetHostName_internal(string&)", ves_icall_System_Net_Dns_GetHostName_internal}
6596 };
6597
6598 static const IcallEntry socket_icalls [] = {
6599         {"Accept_internal(intptr,int&)", ves_icall_System_Net_Sockets_Socket_Accept_internal},
6600         {"Available_internal(intptr,int&)", ves_icall_System_Net_Sockets_Socket_Available_internal},
6601         {"Bind_internal(intptr,System.Net.SocketAddress,int&)", ves_icall_System_Net_Sockets_Socket_Bind_internal},
6602         {"Blocking_internal(intptr,bool,int&)", ves_icall_System_Net_Sockets_Socket_Blocking_internal},
6603         {"Close_internal(intptr,int&)", ves_icall_System_Net_Sockets_Socket_Close_internal},
6604         {"Connect_internal(intptr,System.Net.SocketAddress,int&)", ves_icall_System_Net_Sockets_Socket_Connect_internal},
6605         {"GetSocketOption_arr_internal(intptr,System.Net.Sockets.SocketOptionLevel,System.Net.Sockets.SocketOptionName,byte[]&,int&)", ves_icall_System_Net_Sockets_Socket_GetSocketOption_arr_internal},
6606         {"GetSocketOption_obj_internal(intptr,System.Net.Sockets.SocketOptionLevel,System.Net.Sockets.SocketOptionName,object&,int&)", ves_icall_System_Net_Sockets_Socket_GetSocketOption_obj_internal},
6607         {"Listen_internal(intptr,int,int&)", ves_icall_System_Net_Sockets_Socket_Listen_internal},
6608         {"LocalEndPoint_internal(intptr,int&)", ves_icall_System_Net_Sockets_Socket_LocalEndPoint_internal},
6609         {"Poll_internal", ves_icall_System_Net_Sockets_Socket_Poll_internal},
6610         {"Receive_internal(intptr,byte[],int,int,System.Net.Sockets.SocketFlags,int&)", ves_icall_System_Net_Sockets_Socket_Receive_internal},
6611         {"RecvFrom_internal(intptr,byte[],int,int,System.Net.Sockets.SocketFlags,System.Net.SocketAddress&,int&)", ves_icall_System_Net_Sockets_Socket_RecvFrom_internal},
6612         {"RemoteEndPoint_internal(intptr,int&)", ves_icall_System_Net_Sockets_Socket_RemoteEndPoint_internal},
6613         {"Select_internal(System.Net.Sockets.Socket[]&,int,int&)", ves_icall_System_Net_Sockets_Socket_Select_internal},
6614         {"SendTo_internal(intptr,byte[],int,int,System.Net.Sockets.SocketFlags,System.Net.SocketAddress,int&)", ves_icall_System_Net_Sockets_Socket_SendTo_internal},
6615         {"Send_internal(intptr,byte[],int,int,System.Net.Sockets.SocketFlags,int&)", ves_icall_System_Net_Sockets_Socket_Send_internal},
6616         {"SetSocketOption_internal(intptr,System.Net.Sockets.SocketOptionLevel,System.Net.Sockets.SocketOptionName,object,byte[],int,int&)", ves_icall_System_Net_Sockets_Socket_SetSocketOption_internal},
6617         {"Shutdown_internal(intptr,System.Net.Sockets.SocketShutdown,int&)", ves_icall_System_Net_Sockets_Socket_Shutdown_internal},
6618         {"Socket_internal(System.Net.Sockets.AddressFamily,System.Net.Sockets.SocketType,System.Net.Sockets.ProtocolType,int&)", ves_icall_System_Net_Sockets_Socket_Socket_internal},
6619         {"WSAIoctl(intptr,int,byte[],byte[],int&)", ves_icall_System_Net_Sockets_Socket_WSAIoctl}
6620 };
6621
6622 static const IcallEntry socketex_icalls [] = {
6623         {"WSAGetLastError_internal", ves_icall_System_Net_Sockets_SocketException_WSAGetLastError_internal}
6624 };
6625
6626 static const IcallEntry object_icalls [] = {
6627         {"GetType", ves_icall_System_Object_GetType},
6628         {"InternalGetHashCode", ves_icall_System_Object_GetHashCode},
6629         {"MemberwiseClone", ves_icall_System_Object_MemberwiseClone},
6630         {"obj_address", ves_icall_System_Object_obj_address}
6631 };
6632
6633 static const IcallEntry assemblybuilder_icalls[] = {
6634         {"InternalAddModule", mono_image_load_module},
6635         {"basic_init", mono_image_basic_init}
6636 };
6637
6638 static const IcallEntry customattrbuilder_icalls [] = {
6639         {"GetBlob", mono_reflection_get_custom_attrs_blob}
6640 };
6641
6642 static const IcallEntry dynamicmethod_icalls [] = {
6643         {"create_dynamic_method", mono_reflection_create_dynamic_method}
6644 };
6645
6646 static const IcallEntry methodbuilder_icalls [] = {
6647         {"BindGenericParameters", mono_reflection_bind_generic_method_parameters}
6648 };
6649
6650 static const IcallEntry modulebuilder_icalls [] = {
6651         {"WriteToFile", ves_icall_ModuleBuilder_WriteToFile},
6652         {"basic_init", mono_image_module_basic_init},
6653         {"build_metadata", ves_icall_ModuleBuilder_build_metadata},
6654         {"create_modified_type", ves_icall_ModuleBuilder_create_modified_type},
6655         {"getMethodToken", ves_icall_ModuleBuilder_getMethodToken},
6656         {"getToken", ves_icall_ModuleBuilder_getToken},
6657         {"getUSIndex", mono_image_insert_string}
6658 };
6659
6660 static const IcallEntry signaturehelper_icalls [] = {
6661         {"get_signature_field", mono_reflection_sighelper_get_signature_field},
6662         {"get_signature_local", mono_reflection_sighelper_get_signature_local}
6663 };
6664
6665 static const IcallEntry typebuilder_icalls [] = {
6666         {"create_generic_class", mono_reflection_create_generic_class},
6667         {"create_internal_class", mono_reflection_create_internal_class},
6668         {"create_runtime_class", mono_reflection_create_runtime_class},
6669         {"get_IsGenericParameter", ves_icall_TypeBuilder_get_IsGenericParameter},
6670         {"get_event_info", mono_reflection_event_builder_get_event_info},
6671         {"setup_generic_class", mono_reflection_setup_generic_class},
6672         {"setup_internal_class", mono_reflection_setup_internal_class}
6673 };
6674
6675 static const IcallEntry enumbuilder_icalls [] = {
6676         {"setup_enum_type", ves_icall_EnumBuilder_setup_enum_type}
6677 };
6678
6679 static const IcallEntry runtimehelpers_icalls [] = {
6680         {"GetObjectValue", ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue},
6681          /* REMOVEME: no longer needed, just so we dont break things when not needed */
6682         {"GetOffsetToStringData", ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData},
6683         {"InitializeArray", ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray},
6684         {"RunClassConstructor", ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor},
6685         {"get_OffsetToStringData", ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData}
6686 };
6687
6688 static const IcallEntry gchandle_icalls [] = {
6689         {"CheckCurrentDomain", GCHandle_CheckCurrentDomain},
6690         {"FreeHandle", ves_icall_System_GCHandle_FreeHandle},
6691         {"GetAddrOfPinnedObject", ves_icall_System_GCHandle_GetAddrOfPinnedObject},
6692         {"GetTarget", ves_icall_System_GCHandle_GetTarget},
6693         {"GetTargetHandle", ves_icall_System_GCHandle_GetTargetHandle}
6694 };
6695
6696 static const IcallEntry marshal_icalls [] = {
6697         {"AllocCoTaskMem", ves_icall_System_Runtime_InteropServices_Marshal_AllocCoTaskMem},
6698         {"AllocHGlobal", ves_icall_System_Runtime_InteropServices_Marshal_AllocHGlobal},
6699         {"DestroyStructure", ves_icall_System_Runtime_InteropServices_Marshal_DestroyStructure},
6700         {"FreeCoTaskMem", ves_icall_System_Runtime_InteropServices_Marshal_FreeCoTaskMem},
6701         {"FreeHGlobal", ves_icall_System_Runtime_InteropServices_Marshal_FreeHGlobal},
6702         {"GetDelegateForFunctionPointerInternal", ves_icall_System_Runtime_InteropServices_Marshal_GetDelegateForFunctionPointerInternal},
6703         {"GetFunctionPointerForDelegateInternal", mono_delegate_to_ftnptr},
6704         {"GetLastWin32Error", ves_icall_System_Runtime_InteropServices_Marshal_GetLastWin32Error},
6705         {"OffsetOf", ves_icall_System_Runtime_InteropServices_Marshal_OffsetOf},
6706         {"Prelink", ves_icall_System_Runtime_InteropServices_Marshal_Prelink},
6707         {"PrelinkAll", ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll},
6708         {"PtrToStringAnsi(intptr)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringAnsi},
6709         {"PtrToStringAnsi(intptr,int)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringAnsi_len},
6710         {"PtrToStringAuto(intptr)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringAnsi},
6711         {"PtrToStringAuto(intptr,int)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringAnsi_len},
6712         {"PtrToStringBSTR", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringBSTR},
6713         {"PtrToStringUni(intptr)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringUni},
6714         {"PtrToStringUni(intptr,int)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringUni_len},
6715         {"PtrToStructure(intptr,System.Type)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStructure_type},
6716         {"PtrToStructure(intptr,object)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStructure},
6717         {"ReAllocHGlobal", mono_marshal_realloc},
6718         {"ReadByte", ves_icall_System_Runtime_InteropServices_Marshal_ReadByte},
6719         {"ReadInt16", ves_icall_System_Runtime_InteropServices_Marshal_ReadInt16},
6720         {"ReadInt32", ves_icall_System_Runtime_InteropServices_Marshal_ReadInt32},
6721         {"ReadInt64", ves_icall_System_Runtime_InteropServices_Marshal_ReadInt64},
6722         {"ReadIntPtr", ves_icall_System_Runtime_InteropServices_Marshal_ReadIntPtr},
6723         {"SizeOf", ves_icall_System_Runtime_InteropServices_Marshal_SizeOf},
6724         {"StringToHGlobalAnsi", ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalAnsi},
6725         {"StringToHGlobalAuto", ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalAnsi},
6726         {"StringToHGlobalUni", ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalUni},
6727         {"StructureToPtr", ves_icall_System_Runtime_InteropServices_Marshal_StructureToPtr},
6728         {"UnsafeAddrOfPinnedArrayElement", ves_icall_System_Runtime_InteropServices_Marshal_UnsafeAddrOfPinnedArrayElement},
6729         {"WriteByte", ves_icall_System_Runtime_InteropServices_Marshal_WriteByte},
6730         {"WriteInt16", ves_icall_System_Runtime_InteropServices_Marshal_WriteInt16},
6731         {"WriteInt32", ves_icall_System_Runtime_InteropServices_Marshal_WriteInt32},
6732         {"WriteInt64", ves_icall_System_Runtime_InteropServices_Marshal_WriteInt64},
6733         {"WriteIntPtr", ves_icall_System_Runtime_InteropServices_Marshal_WriteIntPtr},
6734         {"copy_from_unmanaged", ves_icall_System_Runtime_InteropServices_Marshal_copy_from_unmanaged},
6735         {"copy_to_unmanaged", ves_icall_System_Runtime_InteropServices_Marshal_copy_to_unmanaged}
6736 };
6737
6738 static const IcallEntry activationservices_icalls [] = {
6739         {"AllocateUninitializedClassInstance", ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance},
6740         {"EnableProxyActivation", ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation}
6741 };
6742
6743 static const IcallEntry monomethodmessage_icalls [] = {
6744         {"InitMessage", ves_icall_MonoMethodMessage_InitMessage}
6745 };
6746         
6747 static const IcallEntry realproxy_icalls [] = {
6748         {"InternalGetProxyType", ves_icall_Remoting_RealProxy_InternalGetProxyType},
6749         {"InternalGetTransparentProxy", ves_icall_Remoting_RealProxy_GetTransparentProxy}
6750 };
6751
6752 static const IcallEntry remotingservices_icalls [] = {
6753         {"InternalExecute", ves_icall_InternalExecute},
6754         {"IsTransparentProxy", ves_icall_IsTransparentProxy}
6755 };
6756
6757 static const IcallEntry rng_icalls [] = {
6758         {"RngClose", ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_RngClose},
6759         {"RngGetBytes", ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_RngGetBytes},
6760         {"RngInitialize", ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_RngInitialize},
6761         {"RngOpen", ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_RngOpen}
6762 };
6763
6764 static const IcallEntry methodhandle_icalls [] = {
6765         {"GetFunctionPointer", ves_icall_RuntimeMethod_GetFunctionPointer}
6766 };
6767
6768 static const IcallEntry string_icalls [] = {
6769         {".ctor(char*)", ves_icall_System_String_ctor_charp},
6770         {".ctor(char*,int,int)", ves_icall_System_String_ctor_charp_int_int},
6771         {".ctor(char,int)", ves_icall_System_String_ctor_char_int},
6772         {".ctor(char[])", ves_icall_System_String_ctor_chara},
6773         {".ctor(char[],int,int)", ves_icall_System_String_ctor_chara_int_int},
6774         {".ctor(sbyte*)", ves_icall_System_String_ctor_sbytep},
6775         {".ctor(sbyte*,int,int)", ves_icall_System_String_ctor_sbytep_int_int},
6776         {".ctor(sbyte*,int,int,System.Text.Encoding)", ves_icall_System_String_ctor_encoding},
6777         {"InternalAllocateStr", ves_icall_System_String_InternalAllocateStr},
6778         {"InternalCharCopy", ves_icall_System_String_InternalCharCopy},
6779         {"InternalCopyTo", ves_icall_System_String_InternalCopyTo},
6780         {"InternalIndexOfAny", ves_icall_System_String_InternalIndexOfAny},
6781         {"InternalInsert", ves_icall_System_String_InternalInsert},
6782         {"InternalIntern", ves_icall_System_String_InternalIntern},
6783         {"InternalIsInterned", ves_icall_System_String_InternalIsInterned},
6784         {"InternalJoin", ves_icall_System_String_InternalJoin},
6785         {"InternalLastIndexOfAny", ves_icall_System_String_InternalLastIndexOfAny},
6786         {"InternalPad", ves_icall_System_String_InternalPad},
6787         {"InternalRemove", ves_icall_System_String_InternalRemove},
6788         {"InternalReplace(char,char)", ves_icall_System_String_InternalReplace_Char},
6789         {"InternalReplace(string,string,System.Globalization.CompareInfo)", ves_icall_System_String_InternalReplace_Str_Comp},
6790         {"InternalSplit", ves_icall_System_String_InternalSplit},
6791         {"InternalStrcpy(string,int,char[])", ves_icall_System_String_InternalStrcpy_Chars},
6792         {"InternalStrcpy(string,int,char[],int,int)", ves_icall_System_String_InternalStrcpy_CharsN},
6793         {"InternalStrcpy(string,int,string)", ves_icall_System_String_InternalStrcpy_Str},
6794         {"InternalStrcpy(string,int,string,int,int)", ves_icall_System_String_InternalStrcpy_StrN},
6795         {"InternalTrim", ves_icall_System_String_InternalTrim},
6796         {"get_Chars", ves_icall_System_String_get_Chars}
6797 };
6798
6799 static const IcallEntry encoding_icalls [] = {
6800         {"InternalCodePage", ves_icall_System_Text_Encoding_InternalCodePage}
6801 };
6802
6803 static const IcallEntry monitor_icalls [] = {
6804         {"Monitor_exit", ves_icall_System_Threading_Monitor_Monitor_exit},
6805         {"Monitor_pulse", ves_icall_System_Threading_Monitor_Monitor_pulse},
6806         {"Monitor_pulse_all", ves_icall_System_Threading_Monitor_Monitor_pulse_all},
6807         {"Monitor_test_owner", ves_icall_System_Threading_Monitor_Monitor_test_owner},
6808         {"Monitor_test_synchronised", ves_icall_System_Threading_Monitor_Monitor_test_synchronised},
6809         {"Monitor_try_enter", ves_icall_System_Threading_Monitor_Monitor_try_enter},
6810         {"Monitor_wait", ves_icall_System_Threading_Monitor_Monitor_wait}
6811 };
6812
6813 static const IcallEntry interlocked_icalls [] = {
6814     {"Add(int&,int)", ves_icall_System_Threading_Interlocked_Add_Int},
6815         {"Add(long&,long)", ves_icall_System_Threading_Interlocked_Add_Long},
6816     {"CompareExchange(double&,double,double)", ves_icall_System_Threading_Interlocked_CompareExchange_Double},
6817         {"CompareExchange(int&,int,int)", ves_icall_System_Threading_Interlocked_CompareExchange_Int},
6818         {"CompareExchange(intptr&,intptr,intptr)", ves_icall_System_Threading_Interlocked_CompareExchange_Object},
6819         {"CompareExchange(long&,long,long)", ves_icall_System_Threading_Interlocked_CompareExchange_Long},
6820         {"CompareExchange(object&,object,object)", ves_icall_System_Threading_Interlocked_CompareExchange_Object},
6821         {"CompareExchange(single&,single,single)", ves_icall_System_Threading_Interlocked_CompareExchange_Single},
6822         {"Decrement(int&)", ves_icall_System_Threading_Interlocked_Decrement_Int},
6823         {"Decrement(long&)", ves_icall_System_Threading_Interlocked_Decrement_Long},
6824         {"Exchange(double&,double)", ves_icall_System_Threading_Interlocked_Exchange_Double},
6825         {"Exchange(int&,int)", ves_icall_System_Threading_Interlocked_Exchange_Int},
6826         {"Exchange(intptr&,intptr)", ves_icall_System_Threading_Interlocked_Exchange_Object},
6827         {"Exchange(long&,long)", ves_icall_System_Threading_Interlocked_Exchange_Long},
6828         {"Exchange(object&,object)", ves_icall_System_Threading_Interlocked_Exchange_Object},
6829         {"Exchange(single&,single)", ves_icall_System_Threading_Interlocked_Exchange_Single},
6830         {"Increment(int&)", ves_icall_System_Threading_Interlocked_Increment_Int},
6831         {"Increment(long&)", ves_icall_System_Threading_Interlocked_Increment_Long},
6832         {"Read(long&)", ves_icall_System_Threading_Interlocked_Read_Long}
6833 };
6834
6835 static const IcallEntry mutex_icalls [] = {
6836         {"CreateMutex_internal(bool,string,bool&)", ves_icall_System_Threading_Mutex_CreateMutex_internal},
6837         {"ReleaseMutex_internal(intptr)", ves_icall_System_Threading_Mutex_ReleaseMutex_internal}
6838 };
6839
6840 static const IcallEntry nativeevents_icalls [] = {
6841         {"CloseEvent_internal", ves_icall_System_Threading_Events_CloseEvent_internal},
6842         {"CreateEvent_internal", ves_icall_System_Threading_Events_CreateEvent_internal},
6843         {"ResetEvent_internal",  ves_icall_System_Threading_Events_ResetEvent_internal},
6844         {"SetEvent_internal",    ves_icall_System_Threading_Events_SetEvent_internal}
6845 };
6846
6847 static const IcallEntry thread_icalls [] = {
6848         {"Abort_internal(object)", ves_icall_System_Threading_Thread_Abort},
6849         {"ClrState", ves_icall_System_Threading_Thread_ClrState},
6850         {"CurrentThread_internal", mono_thread_current},
6851         {"GetCachedCurrentCulture", ves_icall_System_Threading_Thread_GetCachedCurrentCulture},
6852         {"GetCachedCurrentUICulture", ves_icall_System_Threading_Thread_GetCachedCurrentUICulture},
6853         {"GetDomainID", ves_icall_System_Threading_Thread_GetDomainID},
6854         {"GetName_internal", ves_icall_System_Threading_Thread_GetName_internal},
6855         {"GetSerializedCurrentCulture", ves_icall_System_Threading_Thread_GetSerializedCurrentCulture},
6856         {"GetSerializedCurrentUICulture", ves_icall_System_Threading_Thread_GetSerializedCurrentUICulture},
6857         {"GetState", ves_icall_System_Threading_Thread_GetState},
6858         {"Join_internal", ves_icall_System_Threading_Thread_Join_internal},
6859         {"ResetAbort_internal()", ves_icall_System_Threading_Thread_ResetAbort},
6860         {"Resume_internal()", ves_icall_System_Threading_Thread_Resume},
6861         {"SetCachedCurrentCulture", ves_icall_System_Threading_Thread_SetCachedCurrentCulture},
6862         {"SetCachedCurrentUICulture", ves_icall_System_Threading_Thread_SetCachedCurrentUICulture},
6863         {"SetName_internal", ves_icall_System_Threading_Thread_SetName_internal},
6864         {"SetSerializedCurrentCulture", ves_icall_System_Threading_Thread_SetSerializedCurrentCulture},
6865         {"SetSerializedCurrentUICulture", ves_icall_System_Threading_Thread_SetSerializedCurrentUICulture},
6866         {"SetState", ves_icall_System_Threading_Thread_SetState},
6867         {"Sleep_internal", ves_icall_System_Threading_Thread_Sleep_internal},
6868         {"Suspend_internal", ves_icall_System_Threading_Thread_Suspend},
6869         {"Thread_free_internal", ves_icall_System_Threading_Thread_Thread_free_internal},
6870         {"Thread_internal", ves_icall_System_Threading_Thread_Thread_internal},
6871         {"VolatileRead(byte&)", ves_icall_System_Threading_Thread_VolatileRead1},
6872         {"VolatileRead(double&)", ves_icall_System_Threading_Thread_VolatileRead8},
6873         {"VolatileRead(int&)", ves_icall_System_Threading_Thread_VolatileRead4},
6874         {"VolatileRead(int16&)", ves_icall_System_Threading_Thread_VolatileRead2},
6875         {"VolatileRead(intptr&)", ves_icall_System_Threading_Thread_VolatileReadIntPtr},
6876         {"VolatileRead(long&)", ves_icall_System_Threading_Thread_VolatileRead8},
6877         {"VolatileRead(object&)", ves_icall_System_Threading_Thread_VolatileReadIntPtr},
6878         {"VolatileRead(sbyte&)", ves_icall_System_Threading_Thread_VolatileRead1},
6879         {"VolatileRead(single&)", ves_icall_System_Threading_Thread_VolatileRead4},
6880         {"VolatileRead(uint&)", ves_icall_System_Threading_Thread_VolatileRead2},
6881         {"VolatileRead(uint16&)", ves_icall_System_Threading_Thread_VolatileRead2},
6882         {"VolatileRead(uintptr&)", ves_icall_System_Threading_Thread_VolatileReadIntPtr},
6883         {"VolatileRead(ulong&)", ves_icall_System_Threading_Thread_VolatileRead8},
6884         {"VolatileWrite(byte&,byte)", ves_icall_System_Threading_Thread_VolatileWrite1},
6885         {"VolatileWrite(double&,double)", ves_icall_System_Threading_Thread_VolatileWrite8},
6886         {"VolatileWrite(int&,int)", ves_icall_System_Threading_Thread_VolatileWrite4},
6887         {"VolatileWrite(int16&,int16)", ves_icall_System_Threading_Thread_VolatileWrite2},
6888         {"VolatileWrite(intptr&,intptr)", ves_icall_System_Threading_Thread_VolatileWriteIntPtr},
6889         {"VolatileWrite(long&,long)", ves_icall_System_Threading_Thread_VolatileWrite8},
6890         {"VolatileWrite(object&,object)", ves_icall_System_Threading_Thread_VolatileWriteIntPtr},
6891         {"VolatileWrite(sbyte&,sbyte)", ves_icall_System_Threading_Thread_VolatileWrite1},
6892         {"VolatileWrite(single&,single)", ves_icall_System_Threading_Thread_VolatileWrite4},
6893         {"VolatileWrite(uint&,uint)", ves_icall_System_Threading_Thread_VolatileWrite2},
6894         {"VolatileWrite(uint16&,uint16)", ves_icall_System_Threading_Thread_VolatileWrite2},
6895         {"VolatileWrite(uintptr&,uintptr)", ves_icall_System_Threading_Thread_VolatileWriteIntPtr},
6896         {"VolatileWrite(ulong&,ulong)", ves_icall_System_Threading_Thread_VolatileWrite8},
6897         {"current_lcid()", ves_icall_System_Threading_Thread_current_lcid}
6898 };
6899
6900 static const IcallEntry threadpool_icalls [] = {
6901         {"GetAvailableThreads", ves_icall_System_Threading_ThreadPool_GetAvailableThreads},
6902         {"GetMaxThreads", ves_icall_System_Threading_ThreadPool_GetMaxThreads},
6903         {"GetMinThreads", ves_icall_System_Threading_ThreadPool_GetMinThreads},
6904         {"SetMinThreads", ves_icall_System_Threading_ThreadPool_SetMinThreads}
6905 };
6906
6907 static const IcallEntry waithandle_icalls [] = {
6908         {"WaitAll_internal", ves_icall_System_Threading_WaitHandle_WaitAll_internal},
6909         {"WaitAny_internal", ves_icall_System_Threading_WaitHandle_WaitAny_internal},
6910         {"WaitOne_internal", ves_icall_System_Threading_WaitHandle_WaitOne_internal}
6911 };
6912
6913 static const IcallEntry type_icalls [] = {
6914         {"BindGenericParameters", ves_icall_Type_BindGenericParameters},
6915         {"Equals", ves_icall_type_Equals},
6916         {"GetGenericParameterAttributes", ves_icall_Type_GetGenericParameterAttributes},
6917         {"GetGenericParameterConstraints_impl", ves_icall_Type_GetGenericParameterConstraints},
6918         {"GetGenericParameterPosition", ves_icall_Type_GetGenericParameterPosition},
6919         {"GetGenericTypeDefinition_impl", ves_icall_Type_GetGenericTypeDefinition_impl},
6920         {"GetInterfaceMapData", ves_icall_Type_GetInterfaceMapData},
6921         {"GetPacking", ves_icall_Type_GetPacking},
6922         {"GetTypeCode", ves_icall_type_GetTypeCodeInternal},
6923         {"GetTypeCodeInternal", ves_icall_type_GetTypeCodeInternal},
6924         {"IsArrayImpl", ves_icall_Type_IsArrayImpl},
6925         {"IsInstanceOfType", ves_icall_type_IsInstanceOfType},
6926         {"MakePointerType", ves_icall_Type_MakePointerType},
6927         {"get_IsGenericInstance", ves_icall_Type_get_IsGenericInstance},
6928         {"get_IsGenericTypeDefinition", ves_icall_Type_get_IsGenericTypeDefinition},
6929         {"internal_from_handle", ves_icall_type_from_handle},
6930         {"internal_from_name", ves_icall_type_from_name},
6931         {"make_array_type", ves_icall_Type_make_array_type},
6932         {"make_byref_type", ves_icall_Type_make_byref_type},
6933         {"type_is_assignable_from", ves_icall_type_is_assignable_from},
6934         {"type_is_subtype_of", ves_icall_type_is_subtype_of}
6935 };
6936
6937 static const IcallEntry typedref_icalls [] = {
6938         {"ToObject",    mono_TypedReference_ToObject},
6939         {"ToObjectInternal",    mono_TypedReference_ToObjectInternal}
6940 };
6941
6942 static const IcallEntry valuetype_icalls [] = {
6943         {"InternalEquals", ves_icall_System_ValueType_Equals},
6944         {"InternalGetHashCode", ves_icall_System_ValueType_InternalGetHashCode}
6945 };
6946
6947 static const IcallEntry web_icalls [] = {
6948         {"GetMachineConfigPath", ves_icall_System_Configuration_DefaultConfig_get_machine_config_path},
6949         {"GetMachineInstallDirectory", ves_icall_System_Web_Util_ICalls_get_machine_install_dir}
6950 };
6951
6952 static const IcallEntry identity_icalls [] = {
6953         {"GetCurrentToken", ves_icall_System_Security_Principal_WindowsIdentity_GetCurrentToken},
6954         {"GetTokenName", ves_icall_System_Security_Principal_WindowsIdentity_GetTokenName},
6955         {"GetUserToken", ves_icall_System_Security_Principal_WindowsIdentity_GetUserToken},
6956         {"_GetRoles", ves_icall_System_Security_Principal_WindowsIdentity_GetRoles}
6957 };
6958
6959 static const IcallEntry impersonation_icalls [] = {
6960         {"CloseToken", ves_icall_System_Security_Principal_WindowsImpersonationContext_CloseToken},
6961         {"DuplicateToken", ves_icall_System_Security_Principal_WindowsImpersonationContext_DuplicateToken},
6962         {"RevertToSelf", ves_icall_System_Security_Principal_WindowsImpersonationContext_RevertToSelf},
6963         {"SetCurrentToken", ves_icall_System_Security_Principal_WindowsImpersonationContext_SetCurrentToken}
6964 };
6965
6966 static const IcallEntry principal_icalls [] = {
6967         {"IsMemberOfGroupId", ves_icall_System_Security_Principal_WindowsPrincipal_IsMemberOfGroupId},
6968         {"IsMemberOfGroupName", ves_icall_System_Security_Principal_WindowsPrincipal_IsMemberOfGroupName}
6969 };
6970
6971 static const IcallEntry keypair_icalls [] = {
6972         {"_CanSecure", ves_icall_Mono_Security_Cryptography_KeyPairPersistence_CanSecure},
6973         {"_IsMachineProtected", ves_icall_Mono_Security_Cryptography_KeyPairPersistence_IsMachineProtected},
6974         {"_IsUserProtected", ves_icall_Mono_Security_Cryptography_KeyPairPersistence_IsUserProtected},
6975         {"_ProtectMachine", ves_icall_Mono_Security_Cryptography_KeyPairPersistence_ProtectMachine},
6976         {"_ProtectUser", ves_icall_Mono_Security_Cryptography_KeyPairPersistence_ProtectUser}
6977 };
6978
6979 static const IcallEntry evidence_icalls [] = {
6980         {"IsAuthenticodePresent", ves_icall_System_Security_Policy_Evidence_IsAuthenticodePresent}
6981 };
6982
6983 static const IcallEntry securitymanager_icalls [] = {
6984         {"GetLinkDemandSecurity", ves_icall_System_Security_SecurityManager_GetLinkDemandSecurity},
6985         {"get_CheckExecutionRights", ves_icall_System_Security_SecurityManager_get_CheckExecutionRights},
6986         {"get_SecurityEnabled", ves_icall_System_Security_SecurityManager_get_SecurityEnabled},
6987         {"set_CheckExecutionRights", ves_icall_System_Security_SecurityManager_set_CheckExecutionRights},
6988         {"set_SecurityEnabled", ves_icall_System_Security_SecurityManager_set_SecurityEnabled}
6989 };
6990
6991 static const IcallEntry generic_array_icalls [] = {
6992         {"GetGenericValueImpl", ves_icall_System_Array_InternalArray_GetGenericValueImpl}
6993 };
6994
6995 /* proto
6996 static const IcallEntry array_icalls [] = {
6997 };
6998
6999 */
7000
7001 /* keep the entries all sorted */
7002 static const IcallMap icall_entries [] = {
7003         {"Mono.Runtime", runtime_icalls, G_N_ELEMENTS (runtime_icalls)},
7004         {"Mono.Security.Cryptography.KeyPairPersistence", keypair_icalls, G_N_ELEMENTS (keypair_icalls)},
7005         {"System.Activator", activator_icalls, G_N_ELEMENTS (activator_icalls)},
7006         {"System.AppDomain", appdomain_icalls, G_N_ELEMENTS (appdomain_icalls)},
7007         {"System.ArgIterator", argiterator_icalls, G_N_ELEMENTS (argiterator_icalls)},
7008         {"System.Array", array_icalls, G_N_ELEMENTS (array_icalls)},
7009         {"System.Array/InternalArray`1", generic_array_icalls, G_N_ELEMENTS (generic_array_icalls)},
7010         {"System.Buffer", buffer_icalls, G_N_ELEMENTS (buffer_icalls)},
7011         {"System.Char", char_icalls, G_N_ELEMENTS (char_icalls)},
7012         {"System.Configuration.DefaultConfig", defaultconf_icalls, G_N_ELEMENTS (defaultconf_icalls)},
7013         {"System.ConsoleDriver", consoledriver_icalls, G_N_ELEMENTS (consoledriver_icalls)},
7014         {"System.Convert", convert_icalls, G_N_ELEMENTS (convert_icalls)},
7015         {"System.CurrentTimeZone", timezone_icalls, G_N_ELEMENTS (timezone_icalls)},
7016         {"System.DateTime", datetime_icalls, G_N_ELEMENTS (datetime_icalls)},
7017 #ifndef DISABLE_DECIMAL
7018         {"System.Decimal", decimal_icalls, G_N_ELEMENTS (decimal_icalls)},
7019 #endif  
7020         {"System.Delegate", delegate_icalls, G_N_ELEMENTS (delegate_icalls)},
7021         {"System.Diagnostics.DefaultTraceListener", tracelist_icalls, G_N_ELEMENTS (tracelist_icalls)},
7022         {"System.Diagnostics.FileVersionInfo", fileversion_icalls, G_N_ELEMENTS (fileversion_icalls)},
7023         {"System.Diagnostics.Process", process_icalls, G_N_ELEMENTS (process_icalls)},
7024         {"System.Double", double_icalls, G_N_ELEMENTS (double_icalls)},
7025         {"System.Enum", enum_icalls, G_N_ELEMENTS (enum_icalls)},
7026         {"System.Environment", environment_icalls, G_N_ELEMENTS (environment_icalls)},
7027         {"System.GC", gc_icalls, G_N_ELEMENTS (gc_icalls)},
7028         {"System.Globalization.CompareInfo", compareinfo_icalls, G_N_ELEMENTS (compareinfo_icalls)},
7029         {"System.Globalization.CultureInfo", cultureinfo_icalls, G_N_ELEMENTS (cultureinfo_icalls)},
7030         {"System.IO.FAMWatcher", famwatcher_icalls, G_N_ELEMENTS (famwatcher_icalls)},
7031         {"System.IO.FileSystemWatcher", filewatcher_icalls, G_N_ELEMENTS (filewatcher_icalls)},
7032         {"System.IO.MonoIO", monoio_icalls, G_N_ELEMENTS (monoio_icalls)},
7033         {"System.IO.Path", path_icalls, G_N_ELEMENTS (path_icalls)},
7034         {"System.Math", math_icalls, G_N_ELEMENTS (math_icalls)},
7035         {"System.MonoCustomAttrs", customattrs_icalls, G_N_ELEMENTS (customattrs_icalls)},
7036         {"System.MonoEnumInfo", enuminfo_icalls, G_N_ELEMENTS (enuminfo_icalls)},
7037         {"System.MonoType", monotype_icalls, G_N_ELEMENTS (monotype_icalls)},
7038         {"System.Net.Dns", dns_icalls, G_N_ELEMENTS (dns_icalls)},
7039         {"System.Net.Sockets.Socket", socket_icalls, G_N_ELEMENTS (socket_icalls)},
7040         {"System.Net.Sockets.SocketException", socketex_icalls, G_N_ELEMENTS (socketex_icalls)},
7041         {"System.Object", object_icalls, G_N_ELEMENTS (object_icalls)},
7042         {"System.Reflection.Assembly", assembly_icalls, G_N_ELEMENTS (assembly_icalls)},
7043         {"System.Reflection.Emit.AssemblyBuilder", assemblybuilder_icalls, G_N_ELEMENTS (assemblybuilder_icalls)},
7044         {"System.Reflection.Emit.CustomAttributeBuilder", customattrbuilder_icalls, G_N_ELEMENTS (customattrbuilder_icalls)},
7045         {"System.Reflection.Emit.DynamicMethod", dynamicmethod_icalls, G_N_ELEMENTS (dynamicmethod_icalls)},
7046         {"System.Reflection.Emit.EnumBuilder", enumbuilder_icalls, G_N_ELEMENTS (enumbuilder_icalls)},
7047         {"System.Reflection.Emit.GenericTypeParameterBuilder", generictypeparambuilder_icalls, G_N_ELEMENTS (generictypeparambuilder_icalls)},
7048         {"System.Reflection.Emit.MethodBuilder", methodbuilder_icalls, G_N_ELEMENTS (methodbuilder_icalls)},
7049         {"System.Reflection.Emit.ModuleBuilder", modulebuilder_icalls, G_N_ELEMENTS (modulebuilder_icalls)},
7050         {"System.Reflection.Emit.SignatureHelper", signaturehelper_icalls, G_N_ELEMENTS (signaturehelper_icalls)},
7051         {"System.Reflection.Emit.TypeBuilder", typebuilder_icalls, G_N_ELEMENTS (typebuilder_icalls)},
7052         {"System.Reflection.FieldInfo", fieldinfo_icalls, G_N_ELEMENTS (fieldinfo_icalls)},
7053         {"System.Reflection.MemberInfo", memberinfo_icalls, G_N_ELEMENTS (memberinfo_icalls)},
7054         {"System.Reflection.MethodBase", methodbase_icalls, G_N_ELEMENTS (methodbase_icalls)},
7055         {"System.Reflection.Module", module_icalls, G_N_ELEMENTS (module_icalls)},
7056         {"System.Reflection.MonoCMethod", monocmethod_icalls, G_N_ELEMENTS (monocmethod_icalls)},
7057         {"System.Reflection.MonoEventInfo", monoeventinfo_icalls, G_N_ELEMENTS (monoeventinfo_icalls)},
7058         {"System.Reflection.MonoField", monofield_icalls, G_N_ELEMENTS (monofield_icalls)},
7059         {"System.Reflection.MonoGenericCMethod", monogenericmethod_icalls, G_N_ELEMENTS (monogenericmethod_icalls)},
7060         {"System.Reflection.MonoGenericClass", monogenericclass_icalls, G_N_ELEMENTS (monogenericclass_icalls)},
7061         {"System.Reflection.MonoGenericMethod", monogenericmethod_icalls, G_N_ELEMENTS (monogenericmethod_icalls)},
7062         {"System.Reflection.MonoMethod", monomethod_icalls, G_N_ELEMENTS (monomethod_icalls)},
7063         {"System.Reflection.MonoMethodInfo", monomethodinfo_icalls, G_N_ELEMENTS (monomethodinfo_icalls)},
7064         {"System.Reflection.MonoPropertyInfo", monopropertyinfo_icalls, G_N_ELEMENTS (monopropertyinfo_icalls)},
7065         {"System.Reflection.ParameterInfo", parameterinfo_icalls, G_N_ELEMENTS (parameterinfo_icalls)},
7066         {"System.Runtime.CompilerServices.RuntimeHelpers", runtimehelpers_icalls, G_N_ELEMENTS (runtimehelpers_icalls)},
7067         {"System.Runtime.InteropServices.GCHandle", gchandle_icalls, G_N_ELEMENTS (gchandle_icalls)},
7068         {"System.Runtime.InteropServices.Marshal", marshal_icalls, G_N_ELEMENTS (marshal_icalls)},
7069         {"System.Runtime.Remoting.Activation.ActivationServices", activationservices_icalls, G_N_ELEMENTS (activationservices_icalls)},
7070         {"System.Runtime.Remoting.Messaging.MonoMethodMessage", monomethodmessage_icalls, G_N_ELEMENTS (monomethodmessage_icalls)},
7071         {"System.Runtime.Remoting.Proxies.RealProxy", realproxy_icalls, G_N_ELEMENTS (realproxy_icalls)},
7072         {"System.Runtime.Remoting.RemotingServices", remotingservices_icalls, G_N_ELEMENTS (remotingservices_icalls)},
7073         {"System.RuntimeMethodHandle", methodhandle_icalls, G_N_ELEMENTS (methodhandle_icalls)},
7074         {"System.Security.Cryptography.RNGCryptoServiceProvider", rng_icalls, G_N_ELEMENTS (rng_icalls)},
7075         {"System.Security.Policy.Evidence", evidence_icalls, G_N_ELEMENTS (evidence_icalls)},
7076         {"System.Security.Principal.WindowsIdentity", identity_icalls, G_N_ELEMENTS (identity_icalls)},
7077         {"System.Security.Principal.WindowsImpersonationContext", impersonation_icalls, G_N_ELEMENTS (impersonation_icalls)},
7078         {"System.Security.Principal.WindowsPrincipal", principal_icalls, G_N_ELEMENTS (principal_icalls)},
7079         {"System.Security.SecurityManager", securitymanager_icalls, G_N_ELEMENTS (securitymanager_icalls)},
7080         {"System.String", string_icalls, G_N_ELEMENTS (string_icalls)},
7081         {"System.Text.Encoding", encoding_icalls, G_N_ELEMENTS (encoding_icalls)},
7082         {"System.Threading.Interlocked", interlocked_icalls, G_N_ELEMENTS (interlocked_icalls)},
7083         {"System.Threading.Monitor", monitor_icalls, G_N_ELEMENTS (monitor_icalls)},
7084         {"System.Threading.Mutex", mutex_icalls, G_N_ELEMENTS (mutex_icalls)},
7085         {"System.Threading.NativeEventCalls", nativeevents_icalls, G_N_ELEMENTS (nativeevents_icalls)},
7086         {"System.Threading.Thread", thread_icalls, G_N_ELEMENTS (thread_icalls)},
7087         {"System.Threading.ThreadPool", threadpool_icalls, G_N_ELEMENTS (threadpool_icalls)},
7088         {"System.Threading.WaitHandle", waithandle_icalls, G_N_ELEMENTS (waithandle_icalls)},
7089         {"System.Type", type_icalls, G_N_ELEMENTS (type_icalls)},
7090         {"System.TypedReference", typedref_icalls, G_N_ELEMENTS (typedref_icalls)},
7091         {"System.ValueType", valuetype_icalls, G_N_ELEMENTS (valuetype_icalls)},
7092         {"System.Web.Util.ICalls", web_icalls, G_N_ELEMENTS (web_icalls)}
7093 };
7094
7095 static GHashTable *icall_hash = NULL;
7096 static GHashTable *jit_icall_hash_name = NULL;
7097 static GHashTable *jit_icall_hash_addr = NULL;
7098
7099 void
7100 mono_icall_init (void)
7101 {
7102         int i = 0;
7103
7104         /* check that tables are sorted: disable in release */
7105         if (TRUE) {
7106                 int j;
7107                 const IcallMap *imap;
7108                 const IcallEntry *ientry;
7109                 const char *prev_class = NULL;
7110                 const char *prev_method;
7111                 
7112                 for (i = 0; i < G_N_ELEMENTS (icall_entries); ++i) {
7113                         imap = &icall_entries [i];
7114                         prev_method = NULL;
7115                         if (prev_class && strcmp (prev_class, imap->klass) >= 0)
7116                                 g_print ("class %s should come before class %s\n", imap->klass, prev_class);
7117                         prev_class = imap->klass;
7118                         for (j = 0; j < imap->size; ++j) {
7119                                 ientry = &imap->icalls [j];
7120                                 if (prev_method && strcmp (prev_method, ientry->method) >= 0)
7121                                         g_print ("method %s should come before method %s\n", ientry->method, prev_method);
7122                                 prev_method = ientry->method;
7123                         }
7124                 }
7125         }
7126
7127         icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
7128 }
7129
7130 void
7131 mono_icall_cleanup (void)
7132 {
7133         g_hash_table_destroy (icall_hash);
7134         g_hash_table_destroy (jit_icall_hash_name);
7135         g_hash_table_destroy (jit_icall_hash_addr);
7136 }
7137
7138 void
7139 mono_add_internal_call (const char *name, gconstpointer method)
7140 {
7141         mono_loader_lock ();
7142
7143         g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
7144
7145         mono_loader_unlock ();
7146 }
7147
7148 static int
7149 compare_class_imap (const void *key, const void *elem)
7150 {
7151         const IcallMap* imap = (const IcallMap*)elem;
7152         return strcmp (key, imap->klass);
7153 }
7154
7155 static const IcallMap*
7156 find_class_icalls (const char *name)
7157 {
7158         return (const IcallMap*) bsearch (name, icall_entries, G_N_ELEMENTS (icall_entries), sizeof (IcallMap), compare_class_imap);
7159 }
7160
7161 static int
7162 compare_method_imap (const void *key, const void *elem)
7163 {
7164         const IcallEntry* ientry = (const IcallEntry*)elem;
7165         return strcmp (key, ientry->method);
7166 }
7167
7168 static void*
7169 find_method_icall (const IcallMap *imap, const char *name)
7170 {
7171         const IcallEntry *ientry = (const IcallEntry*) bsearch (name, imap->icalls, imap->size, sizeof (IcallEntry), compare_method_imap);
7172         if (ientry)
7173                 return (void*)ientry->func;
7174         return NULL;
7175 }
7176
7177 /* 
7178  * we should probably export this as an helper (handle nested types).
7179  * Returns the number of chars written in buf.
7180  */
7181 static int
7182 concat_class_name (char *buf, int bufsize, MonoClass *klass)
7183 {
7184         int nspacelen, cnamelen;
7185         nspacelen = strlen (klass->name_space);
7186         cnamelen = strlen (klass->name);
7187         if (nspacelen + cnamelen + 2 > bufsize)
7188                 return 0;
7189         if (nspacelen) {
7190                 memcpy (buf, klass->name_space, nspacelen);
7191                 buf [nspacelen ++] = '.';
7192         }
7193         memcpy (buf + nspacelen, klass->name, cnamelen);
7194         buf [nspacelen + cnamelen] = 0;
7195         return nspacelen + cnamelen;
7196 }
7197
7198 gpointer
7199 mono_lookup_internal_call (MonoMethod *method)
7200 {
7201         char *sigstart;
7202         char *tmpsig;
7203         char mname [2048];
7204         int typelen = 0, mlen, siglen;
7205         gpointer res;
7206         const IcallMap *imap;
7207
7208         g_assert (method != NULL);
7209
7210         if (method->klass->nested_in) {
7211                 int pos = concat_class_name (mname, sizeof (mname)-2, method->klass->nested_in);
7212                 if (!pos)
7213                         return NULL;
7214
7215                 mname [pos++] = '/';
7216                 mname [pos] = 0;
7217
7218                 typelen = concat_class_name (mname+pos, sizeof (mname)-pos-1, method->klass);
7219                 if (!typelen)
7220                         return NULL;
7221
7222                 typelen += pos;
7223         } else {
7224                 typelen = concat_class_name (mname, sizeof (mname), method->klass);
7225                 if (!typelen)
7226                         return NULL;
7227         }
7228
7229         imap = find_class_icalls (mname);
7230
7231         mname [typelen] = ':';
7232         mname [typelen + 1] = ':';
7233
7234         mlen = strlen (method->name);
7235         memcpy (mname + typelen + 2, method->name, mlen);
7236         sigstart = mname + typelen + 2 + mlen;
7237         *sigstart = 0;
7238
7239         tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
7240         siglen = strlen (tmpsig);
7241         if (typelen + mlen + siglen + 6 > sizeof (mname))
7242                 return NULL;
7243         sigstart [0] = '(';
7244         memcpy (sigstart + 1, tmpsig, siglen);
7245         sigstart [siglen + 1] = ')';
7246         sigstart [siglen + 2] = 0;
7247         g_free (tmpsig);
7248         
7249         mono_loader_lock ();
7250
7251         res = g_hash_table_lookup (icall_hash, mname);
7252         if (res) {
7253                 mono_loader_unlock ();
7254                 return res;
7255         }
7256         /* try without signature */
7257         *sigstart = 0;
7258         res = g_hash_table_lookup (icall_hash, mname);
7259         if (res) {
7260                 mono_loader_unlock ();
7261                 return res;
7262         }
7263
7264         /* it wasn't found in the static call tables */
7265         if (!imap) {
7266                 mono_loader_unlock ();
7267                 return NULL;
7268         }
7269         res = find_method_icall (imap, sigstart - mlen);
7270         if (res) {
7271                 mono_loader_unlock ();
7272                 return res;
7273         }
7274         /* try _with_ signature */
7275         *sigstart = '(';
7276         res = find_method_icall (imap, sigstart - mlen);
7277         if (res) {
7278                 mono_loader_unlock ();
7279                 return res;
7280         }
7281         
7282         g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname);
7283         g_print ("\nYour mono runtime and class libraries are out of sync.\n");
7284         g_print ("The out of sync library is: %s\n", method->klass->image->name);
7285         g_print ("\nWhen you update one from cvs you need to update, compile and install\nthe other too.\n");
7286         g_print ("Do not report this as a bug unless you're sure you have updated correctly:\nyou probably have a broken mono install.\n");
7287         g_print ("If you see other errors or faults after this message they are probably related\n");
7288         g_print ("and you need to fix your mono install first.\n");
7289
7290         mono_loader_unlock ();
7291
7292         return NULL;
7293 }
7294
7295 static MonoType*
7296 type_from_typename (char *typename)
7297 {
7298         MonoClass *klass = NULL;        /* assignment to shut GCC warning up */
7299
7300         if (!strcmp (typename, "int"))
7301                 klass = mono_defaults.int_class;
7302         else if (!strcmp (typename, "ptr"))
7303                 klass = mono_defaults.int_class;
7304         else if (!strcmp (typename, "void"))
7305                 klass = mono_defaults.void_class;
7306         else if (!strcmp (typename, "int32"))
7307                 klass = mono_defaults.int32_class;
7308         else if (!strcmp (typename, "uint32"))
7309                 klass = mono_defaults.uint32_class;
7310         else if (!strcmp (typename, "long"))
7311                 klass = mono_defaults.int64_class;
7312         else if (!strcmp (typename, "ulong"))
7313                 klass = mono_defaults.uint64_class;
7314         else if (!strcmp (typename, "float"))
7315                 klass = mono_defaults.single_class;
7316         else if (!strcmp (typename, "double"))
7317                 klass = mono_defaults.double_class;
7318         else if (!strcmp (typename, "object"))
7319                 klass = mono_defaults.object_class;
7320         else if (!strcmp (typename, "obj"))
7321                 klass = mono_defaults.object_class;
7322         else {
7323                 g_error (typename);
7324                 g_assert_not_reached ();
7325         }
7326         return &klass->byval_arg;
7327 }
7328
7329 MonoMethodSignature*
7330 mono_create_icall_signature (const char *sigstr)
7331 {
7332         gchar **parts;
7333         int i, len;
7334         gchar **tmp;
7335         MonoMethodSignature *res;
7336
7337         mono_loader_lock ();
7338         res = g_hash_table_lookup (mono_defaults.corlib->helper_signatures, sigstr);
7339         if (res) {
7340                 mono_loader_unlock ();
7341                 return res;
7342         }
7343
7344         parts = g_strsplit (sigstr, " ", 256);
7345
7346         tmp = parts;
7347         len = 0;
7348         while (*tmp) {
7349                 len ++;
7350                 tmp ++;
7351         }
7352
7353         res = mono_metadata_signature_alloc (mono_defaults.corlib, len - 1);
7354         res->pinvoke = 1;
7355
7356 #ifdef PLATFORM_WIN32
7357         /* 
7358          * Under windows, the default pinvoke calling convention is STDCALL but
7359          * we need CDECL.
7360          */
7361         res->call_convention = MONO_CALL_C;
7362 #endif
7363
7364         res->ret = type_from_typename (parts [0]);
7365         for (i = 1; i < len; ++i) {
7366                 res->params [i - 1] = type_from_typename (parts [i]);
7367         }
7368
7369         g_strfreev (parts);
7370
7371         g_hash_table_insert (mono_defaults.corlib->helper_signatures, (gpointer)sigstr, res);
7372
7373         mono_loader_unlock ();
7374
7375         return res;
7376 }
7377
7378 MonoJitICallInfo *
7379 mono_find_jit_icall_by_name (const char *name)
7380 {
7381         MonoJitICallInfo *info;
7382         g_assert (jit_icall_hash_name);
7383
7384         mono_loader_lock ();
7385         info = g_hash_table_lookup (jit_icall_hash_name, name);
7386         mono_loader_unlock ();
7387         return info;
7388 }
7389
7390 MonoJitICallInfo *
7391 mono_find_jit_icall_by_addr (gconstpointer addr)
7392 {
7393         MonoJitICallInfo *info;
7394         g_assert (jit_icall_hash_addr);
7395
7396         mono_loader_lock ();
7397         info = g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
7398         mono_loader_unlock ();
7399
7400         return info;
7401 }
7402
7403 void
7404 mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
7405 {
7406         mono_loader_lock ();
7407         g_hash_table_insert (jit_icall_hash_addr, (gpointer)info->wrapper, info);       
7408         mono_loader_unlock ();
7409 }
7410
7411 MonoJitICallInfo *
7412 mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
7413 {
7414         MonoJitICallInfo *info;
7415         
7416         g_assert (func);
7417         g_assert (name);
7418
7419         mono_loader_lock ();
7420
7421         if (!jit_icall_hash_name) {
7422                 jit_icall_hash_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
7423                 jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
7424         }
7425
7426         if (g_hash_table_lookup (jit_icall_hash_name, name)) {
7427                 g_warning ("jit icall already defined \"%s\"\n", name);
7428                 g_assert_not_reached ();
7429         }
7430
7431         info = g_new (MonoJitICallInfo, 1);
7432         
7433         info->name = name;
7434         info->func = func;
7435         info->sig = sig;
7436
7437         if (is_save) {
7438                 info->wrapper = func;
7439         } else {
7440                 info->wrapper = NULL;
7441         }
7442
7443         g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
7444         g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
7445
7446         mono_loader_unlock ();
7447         return info;
7448 }