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