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