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