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