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