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