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