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