2006-05-31 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mono / metadata / icall.c
1 /*
2  * icall.c:
3  *
4  * Authors:
5  *   Dietmar Maurer (dietmar@ximian.com)
6  *   Paolo Molaro (lupus@ximian.com)
7  *       Patrik Torstensson (patrik.torstensson@labs2.com)
8  *
9  * (C) 2001 Ximian, Inc.
10  */
11
12 #include <config.h>
13 #include <glib.h>
14 #include <stdarg.h>
15 #include <string.h>
16 #include <ctype.h>
17 #include <sys/time.h>
18 #include <unistd.h>
19 #if defined (PLATFORM_WIN32)
20 #include <stdlib.h>
21 #endif
22
23 #include <mono/metadata/object.h>
24 #include <mono/metadata/threads.h>
25 #include <mono/metadata/threads-types.h>
26 #include <mono/metadata/threadpool.h>
27 #include <mono/metadata/monitor.h>
28 #include <mono/metadata/reflection.h>
29 #include <mono/metadata/assembly.h>
30 #include <mono/metadata/tabledefs.h>
31 #include <mono/metadata/exception.h>
32 #include <mono/metadata/file-io.h>
33 #include <mono/metadata/console-io.h>
34 #include <mono/metadata/socket-io.h>
35 #include <mono/metadata/mono-endian.h>
36 #include <mono/metadata/tokentype.h>
37 #include <mono/metadata/unicode.h>
38 #include <mono/metadata/domain-internals.h>
39 #include <mono/metadata/metadata-internals.h>
40 #include <mono/metadata/class-internals.h>
41 #include <mono/metadata/marshal.h>
42 #include <mono/metadata/gc-internal.h>
43 #include <mono/metadata/rand.h>
44 #include <mono/metadata/sysmath.h>
45 #include <mono/metadata/string-icalls.h>
46 #include <mono/metadata/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 != NULL){
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                         mono_array_setref (res, count, mono_type_get_object (domain, &klass->byval_arg));
4536                         count++;
4537                 }
4538         }
4539         
4540         return res;
4541 }
4542
4543 static MonoArray*
4544 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly, MonoBoolean exportedOnly)
4545 {
4546         MonoArray *res = NULL;
4547         MonoImage *image = NULL;
4548         MonoTableInfo *table = NULL;
4549         MonoDomain *domain;
4550         int i;
4551
4552         MONO_ARCH_SAVE_REGS;
4553
4554         domain = mono_object_domain (assembly);
4555
4556         if (assembly->assembly->dynamic) {
4557                 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
4558                 if (abuilder->modules) {
4559                         for (i = 0; i < mono_array_length(abuilder->modules); i++) {
4560                                 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
4561                                 MonoArray *append = mb->types;
4562                                 if (append && mono_array_length (append) > 0) {
4563                                         guint32 len1, len2;
4564                                         MonoArray *new;
4565                                         len1 = res ? mono_array_length (res) : 0;
4566                                         len2 = mono_array_length (append);
4567                                         new = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4568                                         if (res)
4569                                                 mono_array_memcpy_refs (new, 0, res, 0, len1);
4570                                         mono_array_memcpy_refs (new, len1, append, 0, len2);
4571                                         res = new;
4572                                 }
4573                         }
4574
4575                         /*
4576                          * Replace TypeBuilders with the created types to be compatible
4577                          * with MS.NET.
4578                          */
4579                         if (res) {
4580                                 for (i = 0; i < mono_array_length (res); ++i) {
4581                                         MonoReflectionTypeBuilder *tb = mono_array_get (res, MonoReflectionTypeBuilder*, i);
4582                                         if (tb->created)
4583                                                 mono_array_setref (res, i, tb->created);
4584                                 }
4585                         }
4586                 }
4587
4588                 if (abuilder->loaded_modules)
4589                         for (i = 0; i < mono_array_length(abuilder->loaded_modules); i++) {
4590                                 MonoReflectionModule *rm = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
4591                                 MonoArray *append = mono_module_get_types (domain, rm->image, exportedOnly);
4592                                 if (append && mono_array_length (append) > 0) {
4593                                         guint32 len1, len2;
4594                                         MonoArray *new;
4595                                         len1 = res ? mono_array_length (res) : 0;
4596                                         len2 = mono_array_length (append);
4597                                         new = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4598                                         if (res)
4599                                                 mono_array_memcpy_refs (new, 0, res, 0, len1);
4600                                         mono_array_memcpy_refs (new, len1, append, 0, len2);
4601                                         res = new;
4602                                 }
4603                         }
4604                 if (res)
4605                         return res;
4606                 else
4607                         return mono_array_new (domain, mono_defaults.monotype_class, 0);
4608         }
4609         image = assembly->assembly->image;
4610         table = &image->tables [MONO_TABLE_FILE];
4611         res = mono_module_get_types (domain, image, exportedOnly);
4612
4613         /* Append data from all modules in the assembly */
4614         for (i = 0; i < table->rows; ++i) {
4615                 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4616                         MonoImage *loaded_image = mono_assembly_load_module (image->assembly, i + 1);
4617                         if (loaded_image) {
4618                                 MonoArray *res2 = mono_module_get_types (domain, loaded_image, exportedOnly);
4619                                 /* Append the new types to the end of the array */
4620                                 if (mono_array_length (res2) > 0) {
4621                                         guint32 len1, len2;
4622                                         MonoArray *res3;
4623
4624                                         len1 = mono_array_length (res);
4625                                         len2 = mono_array_length (res2);
4626                                         res3 = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4627                                         mono_array_memcpy_refs (res3, 0, res, 0, len1);
4628                                         mono_array_memcpy_refs (res3, len1, res2, 0, len2);
4629                                         res = res3;
4630                                 }
4631                         }
4632                 }
4633         }
4634
4635         if (mono_is_security_manager_active ()) {
4636                 /* the ReflectionTypeLoadException must have all the types (Types property), 
4637                  * NULL replacing types which throws an exception. The LoaderException must
4638                  * contains all exceptions for NULL items.
4639                  */
4640
4641                 guint32 len = mono_array_length (res);
4642                 GList *list = NULL;
4643
4644                 for (i = 0; i < len; i++) {
4645                         MonoReflectionType *t = mono_array_get (res, gpointer, i);
4646                         MonoClass *klass = mono_type_get_class (t->type);
4647                         if ((klass != NULL) && klass->exception_type) {
4648                                 /* keep the class in the list */
4649                                 list = g_list_append (list, klass);
4650                                 /* and replace Type with NULL */
4651                                 mono_array_setref (res, i, NULL);
4652                         }
4653                 }
4654
4655                 if (list) {
4656                         GList *tmp = NULL;
4657                         MonoException *exc = NULL;
4658                         int length = g_list_length (list);
4659
4660                         MonoArray *exl = mono_array_new (domain, mono_defaults.exception_class, length);
4661                         for (i = 0, tmp = list; i < length; i++, tmp = tmp->next) {
4662                                 MonoException *exc = mono_class_get_exception_for_failure (tmp->data);
4663                                 mono_array_setref (exl, i, exc);
4664                         }
4665                         g_list_free (list);
4666                         list = NULL;
4667
4668                         exc = mono_get_exception_reflection_type_load (res, exl);
4669                         mono_raise_exception (exc);
4670                 }
4671         }
4672                 
4673         return res;
4674 }
4675
4676 static gboolean
4677 ves_icall_System_Reflection_AssemblyName_ParseName (MonoReflectionAssemblyName *name, MonoString *assname)
4678 {
4679         MonoAssemblyName aname;
4680         MonoDomain *domain = mono_object_domain (name);
4681         char *val;
4682         gboolean is_version_defined;
4683
4684         val = mono_string_to_utf8 (assname);
4685         if (!mono_assembly_name_parse_full (val, &aname, TRUE, &is_version_defined))
4686                 return FALSE;
4687         
4688         fill_reflection_assembly_name (domain, name, &aname, "", is_version_defined);
4689
4690         mono_assembly_name_free (&aname);
4691         g_free ((guint8*) aname.public_key);
4692         g_free (val);
4693
4694         return TRUE;
4695 }
4696
4697 static MonoReflectionType*
4698 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModule *module)
4699 {
4700         MonoDomain *domain = mono_object_domain (module); 
4701         MonoClass *klass;
4702
4703         MONO_ARCH_SAVE_REGS;
4704
4705         g_assert (module->image);
4706
4707         if (module->image->dynamic && ((MonoDynamicImage*)(module->image))->initial_image)
4708                 /* These images do not have a global type */
4709                 return NULL;
4710
4711         klass = mono_class_get (module->image, 1 | MONO_TOKEN_TYPE_DEF);
4712         return mono_type_get_object (domain, &klass->byval_arg);
4713 }
4714
4715 static void
4716 ves_icall_System_Reflection_Module_Close (MonoReflectionModule *module)
4717 {
4718         /*if (module->image)
4719                 mono_image_close (module->image);*/
4720 }
4721
4722 static MonoString*
4723 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModule *module)
4724 {
4725         MonoDomain *domain = mono_object_domain (module); 
4726
4727         MONO_ARCH_SAVE_REGS;
4728
4729         g_assert (module->image);
4730         return mono_string_new (domain, module->image->guid);
4731 }
4732
4733 static void
4734 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine)
4735 {
4736         if (image->dynamic) {
4737                 MonoDynamicImage *dyn = (MonoDynamicImage*)image;
4738                 *pe_kind = dyn->pe_kind;
4739                 *machine = dyn->machine;
4740         }
4741         else {
4742                 *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
4743                 *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
4744         }
4745 }
4746
4747 static gint32
4748 ves_icall_System_Reflection_Module_get_MDStreamVersion (MonoReflectionModule *module)
4749 {
4750         MonoImage *image = module->image;
4751
4752         if (!image)
4753                 mono_raise_exception (mono_get_exception_not_supported (""));
4754         
4755         return (image->md_version_major << 16) | (image->md_version_minor);
4756 }
4757
4758 static MonoArray*
4759 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModule *module)
4760 {
4761         MONO_ARCH_SAVE_REGS;
4762
4763         if (!module->image)
4764                 return mono_array_new (mono_object_domain (module), mono_defaults.monotype_class, 0);
4765         else
4766                 return mono_module_get_types (mono_object_domain (module), module->image, FALSE);
4767 }
4768
4769 static gboolean
4770 mono_metadata_memberref_is_method (MonoImage *image, guint32 token)
4771 {
4772         guint32 cols [MONO_MEMBERREF_SIZE];
4773         const char *sig;
4774         mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
4775         sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
4776         mono_metadata_decode_blob_size (sig, &sig);
4777         return (*sig != 0x6);
4778 }
4779
4780 static MonoType*
4781 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
4782 {
4783         MonoClass *klass;
4784         int table = mono_metadata_token_table (token);
4785         int index = mono_metadata_token_index (token);
4786
4787         *error = ResolveTokenError_Other;
4788
4789         /* Validate token */
4790         if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) && 
4791                 (table != MONO_TABLE_TYPESPEC)) {
4792                 *error = ResolveTokenError_BadTable;
4793                 return NULL;
4794         }
4795
4796         if (image->dynamic)
4797                 return mono_lookup_dynamic_token (image, token);
4798
4799         if ((index <= 0) || (index > image->tables [table].rows)) {
4800                 *error = ResolveTokenError_OutOfRange;
4801                 return NULL;
4802         }
4803
4804         klass = mono_class_get (image, token);
4805         if (klass)
4806                 return &klass->byval_arg;
4807         else
4808                 return NULL;
4809 }
4810
4811 static MonoMethod*
4812 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
4813 {
4814         int table = mono_metadata_token_table (token);
4815         int index = mono_metadata_token_index (token);
4816
4817         *error = ResolveTokenError_Other;
4818
4819         /* Validate token */
4820         if ((table != MONO_TABLE_METHOD) && (table != MONO_TABLE_METHODSPEC) && 
4821                 (table != MONO_TABLE_MEMBERREF)) {
4822                 *error = ResolveTokenError_BadTable;
4823                 return NULL;
4824         }
4825
4826         if (image->dynamic)
4827                 /* FIXME: validate memberref token type */
4828                 return mono_lookup_dynamic_token (image, token);
4829
4830         if ((index <= 0) || (index > image->tables [table].rows)) {
4831                 *error = ResolveTokenError_OutOfRange;
4832                 return NULL;
4833         }
4834         if ((table == MONO_TABLE_MEMBERREF) && (!mono_metadata_memberref_is_method (image, token))) {
4835                 *error = ResolveTokenError_BadTable;
4836                 return NULL;
4837         }
4838
4839         return mono_get_method (image, token, NULL);
4840 }
4841
4842 static MonoString*
4843 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
4844 {
4845         int index = mono_metadata_token_index (token);
4846
4847         *error = ResolveTokenError_Other;
4848
4849         /* Validate token */
4850         if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
4851                 *error = ResolveTokenError_BadTable;
4852                 return NULL;
4853         }
4854
4855         if (image->dynamic)
4856                 return mono_lookup_dynamic_token (image, token);
4857
4858         if ((index <= 0) || (index >= image->heap_us.size)) {
4859                 *error = ResolveTokenError_OutOfRange;
4860                 return NULL;
4861         }
4862
4863         /* FIXME: What to do if the index points into the middle of a string ? */
4864
4865         return mono_ldstr (mono_domain_get (), image, index);
4866 }
4867
4868 static MonoClassField*
4869 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
4870 {
4871         MonoClass *klass;
4872         int table = mono_metadata_token_table (token);
4873         int index = mono_metadata_token_index (token);
4874
4875         *error = ResolveTokenError_Other;
4876
4877         /* Validate token */
4878         if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
4879                 *error = ResolveTokenError_BadTable;
4880                 return NULL;
4881         }
4882
4883         if (image->dynamic)
4884                 /* FIXME: validate memberref token type */
4885                 return mono_lookup_dynamic_token (image, token);
4886
4887         if ((index <= 0) || (index > image->tables [table].rows)) {
4888                 *error = ResolveTokenError_OutOfRange;
4889                 return NULL;
4890         }
4891         if ((table == MONO_TABLE_MEMBERREF) && (mono_metadata_memberref_is_method (image, token))) {
4892                 *error = ResolveTokenError_BadTable;
4893                 return NULL;
4894         }
4895
4896         return mono_field_from_token (image, token, &klass, NULL);
4897 }
4898
4899
4900 static MonoObject*
4901 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
4902 {
4903         int table = mono_metadata_token_table (token);
4904
4905         *error = ResolveTokenError_Other;
4906
4907         switch (table) {
4908         case MONO_TABLE_TYPEDEF:
4909         case MONO_TABLE_TYPEREF:
4910         case MONO_TABLE_TYPESPEC: {
4911                 MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, error);
4912                 if (t)
4913                         return (MonoObject*)mono_type_get_object (mono_domain_get (), t);
4914                 else
4915                         return NULL;
4916         }
4917         case MONO_TABLE_METHOD:
4918         case MONO_TABLE_METHODSPEC: {
4919                 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, error);
4920                 if (m)
4921                         return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
4922                 else
4923                         return NULL;
4924         }               
4925         case MONO_TABLE_FIELD: {
4926                 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, error);
4927                 if (f)
4928                         return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
4929                 else
4930                         return NULL;
4931         }
4932         case MONO_TABLE_MEMBERREF:
4933                 if (mono_metadata_memberref_is_method (image, token)) {
4934                         MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, error);
4935                         if (m)
4936                                 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
4937                         else
4938                                 return NULL;
4939                 }
4940                 else {
4941                         MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, error);
4942                         if (f)
4943                                 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
4944                         else
4945                                 return NULL;
4946                 }
4947                 break;
4948
4949         default:
4950                 *error = ResolveTokenError_BadTable;
4951         }
4952
4953         return NULL;
4954 }
4955
4956 static MonoReflectionType*
4957 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
4958 {
4959         MonoClass *klass;
4960         int isbyref = 0, rank;
4961         char *str = mono_string_to_utf8 (smodifiers);
4962         char *p;
4963
4964         MONO_ARCH_SAVE_REGS;
4965
4966         klass = mono_class_from_mono_type (tb->type.type);
4967         p = str;
4968         /* logic taken from mono_reflection_parse_type(): keep in sync */
4969         while (*p) {
4970                 switch (*p) {
4971                 case '&':
4972                         if (isbyref) { /* only one level allowed by the spec */
4973                                 g_free (str);
4974                                 return NULL;
4975                         }
4976                         isbyref = 1;
4977                         p++;
4978                         g_free (str);
4979                         return mono_type_get_object (mono_object_domain (tb), &klass->this_arg);
4980                         break;
4981                 case '*':
4982                         klass = mono_ptr_class_get (&klass->byval_arg);
4983                         mono_class_init (klass);
4984                         p++;
4985                         break;
4986                 case '[':
4987                         rank = 1;
4988                         p++;
4989                         while (*p) {
4990                                 if (*p == ']')
4991                                         break;
4992                                 if (*p == ',')
4993                                         rank++;
4994                                 else if (*p != '*') { /* '*' means unknown lower bound */
4995                                         g_free (str);
4996                                         return NULL;
4997                                 }
4998                                 ++p;
4999                         }
5000                         if (*p != ']') {
5001                                 g_free (str);
5002                                 return NULL;
5003                         }
5004                         p++;
5005                         klass = mono_array_class_get (klass, rank);
5006                         mono_class_init (klass);
5007                         break;
5008                 default:
5009                         break;
5010                 }
5011         }
5012         g_free (str);
5013         return mono_type_get_object (mono_object_domain (tb), &klass->byval_arg);
5014 }
5015
5016 static MonoBoolean
5017 ves_icall_Type_IsArrayImpl (MonoReflectionType *t)
5018 {
5019         MonoType *type;
5020         MonoBoolean res;
5021
5022         MONO_ARCH_SAVE_REGS;
5023
5024         type = t->type;
5025         res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
5026
5027         return res;
5028 }
5029
5030 static MonoReflectionType *
5031 ves_icall_Type_make_array_type (MonoReflectionType *type, int rank)
5032 {
5033         MonoClass *klass, *aklass;
5034
5035         MONO_ARCH_SAVE_REGS;
5036
5037         klass = mono_class_from_mono_type (type->type);
5038         aklass = mono_array_class_get (klass, rank);
5039
5040         return mono_type_get_object (mono_object_domain (type), &aklass->byval_arg);
5041 }
5042
5043 static MonoReflectionType *
5044 ves_icall_Type_make_byref_type (MonoReflectionType *type)
5045 {
5046         MonoClass *klass;
5047
5048         MONO_ARCH_SAVE_REGS;
5049
5050         klass = mono_class_from_mono_type (type->type);
5051
5052         return mono_type_get_object (mono_object_domain (type), &klass->this_arg);
5053 }
5054
5055 static MonoReflectionType *
5056 ves_icall_Type_MakePointerType (MonoReflectionType *type)
5057 {
5058         MonoClass *pklass;
5059
5060         MONO_ARCH_SAVE_REGS;
5061
5062         pklass = mono_ptr_class_get (type->type);
5063
5064         return mono_type_get_object (mono_object_domain (type), &pklass->byval_arg);
5065 }
5066
5067 static MonoObject *
5068 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
5069                                                    MonoReflectionMethod *info)
5070 {
5071         MonoClass *delegate_class = mono_class_from_mono_type (type->type);
5072         MonoObject *delegate;
5073         gpointer func;
5074
5075         MONO_ARCH_SAVE_REGS;
5076
5077         mono_assert (delegate_class->parent == mono_defaults.multicastdelegate_class);
5078
5079         delegate = mono_object_new (mono_object_domain (type), delegate_class);
5080
5081         func = mono_compile_method (info->method);
5082
5083         mono_delegate_ctor (delegate, target, func);
5084
5085         return delegate;
5086 }
5087
5088 static void
5089 ves_icall_System_Delegate_FreeTrampoline (MonoDelegate *this)
5090 {
5091         /*
5092         Delegates have a finalizer only when needed, now.
5093         mono_delegate_free_ftnptr (this);*/
5094 }
5095
5096 /*
5097  * Magic number to convert a time which is relative to
5098  * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
5099  */
5100 #define EPOCH_ADJUST    ((guint64)62135596800LL)
5101
5102 /*
5103  * Magic number to convert FILETIME base Jan 1, 1601 to DateTime - base Jan, 1, 0001
5104  */
5105 #define FILETIME_ADJUST ((guint64)504911232000000000LL)
5106
5107 /*
5108  * This returns Now in UTC
5109  */
5110 static gint64
5111 ves_icall_System_DateTime_GetNow (void)
5112 {
5113 #ifdef PLATFORM_WIN32
5114         SYSTEMTIME st;
5115         FILETIME ft;
5116         
5117         GetSystemTime (&st);
5118         SystemTimeToFileTime (&st, &ft);
5119         return (gint64) FILETIME_ADJUST + ((((gint64)ft.dwHighDateTime)<<32) | ft.dwLowDateTime);
5120 #else
5121         /* FIXME: put this in io-layer and call it GetLocalTime */
5122         struct timeval tv;
5123         gint64 res;
5124
5125         MONO_ARCH_SAVE_REGS;
5126
5127         if (gettimeofday (&tv, NULL) == 0) {
5128                 res = (((gint64)tv.tv_sec + EPOCH_ADJUST)* 1000000 + tv.tv_usec)*10;
5129                 return res;
5130         }
5131         /* fixme: raise exception */
5132         return 0;
5133 #endif
5134 }
5135
5136 #ifdef PLATFORM_WIN32
5137 /* convert a SYSTEMTIME which is of the form "last thursday in october" to a real date */
5138 static void
5139 convert_to_absolute_date(SYSTEMTIME *date)
5140 {
5141 #define IS_LEAP(y) ((y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0))
5142         static int days_in_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5143         static int leap_days_in_month[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5144         /* from the calendar FAQ */
5145         int a = (14 - date->wMonth) / 12;
5146         int y = date->wYear - a;
5147         int m = date->wMonth + 12 * a - 2;
5148         int d = (1 + y + y/4 - y/100 + y/400 + (31*m)/12) % 7;
5149
5150         /* d is now the day of the week for the first of the month (0 == Sunday) */
5151
5152         int day_of_week = date->wDayOfWeek;
5153
5154         /* set day_in_month to the first day in the month which falls on day_of_week */    
5155         int day_in_month = 1 + (day_of_week - d);
5156         if (day_in_month <= 0)
5157                 day_in_month += 7;
5158
5159         /* wDay is 1 for first weekday in month, 2 for 2nd ... 5 means last - so work that out allowing for days in the month */
5160         date->wDay = day_in_month + (date->wDay - 1) * 7;
5161         if (date->wDay > (IS_LEAP(date->wYear) ? leap_days_in_month[date->wMonth - 1] : days_in_month[date->wMonth - 1]))
5162                 date->wDay -= 7;
5163 }
5164 #endif
5165
5166 #ifndef PLATFORM_WIN32
5167 /*
5168  * Return's the offset from GMT of a local time.
5169  * 
5170  *  tm is a local time
5171  *  t  is the same local time as seconds.
5172  */
5173 static int 
5174 gmt_offset(struct tm *tm, time_t t)
5175 {
5176 #if defined (HAVE_TM_GMTOFF)
5177         return tm->tm_gmtoff;
5178 #else
5179         struct tm g;
5180         time_t t2;
5181         g = *gmtime(&t);
5182         g.tm_isdst = tm->tm_isdst;
5183         t2 = mktime(&g);
5184         return (int)difftime(t, t2);
5185 #endif
5186 }
5187 #endif
5188 /*
5189  * This is heavily based on zdump.c from glibc 2.2.
5190  *
5191  *  * data[0]:  start of daylight saving time (in DateTime ticks).
5192  *  * data[1]:  end of daylight saving time (in DateTime ticks).
5193  *  * data[2]:  utcoffset (in TimeSpan ticks).
5194  *  * data[3]:  additional offset when daylight saving (in TimeSpan ticks).
5195  *  * name[0]:  name of this timezone when not daylight saving.
5196  *  * name[1]:  name of this timezone when daylight saving.
5197  *
5198  *  FIXME: This only works with "standard" Unix dates (years between 1900 and 2100) while
5199  *         the class library allows years between 1 and 9999.
5200  *
5201  *  Returns true on success and zero on failure.
5202  */
5203 static guint32
5204 ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year, MonoArray **data, MonoArray **names)
5205 {
5206 #ifndef PLATFORM_WIN32
5207         MonoDomain *domain = mono_domain_get ();
5208         struct tm start, tt;
5209         time_t t;
5210
5211         long int gmtoff;
5212         int is_daylight = 0, day;
5213         char tzone [64];
5214
5215         MONO_ARCH_SAVE_REGS;
5216
5217         MONO_CHECK_ARG_NULL (data);
5218         MONO_CHECK_ARG_NULL (names);
5219
5220         (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5221         (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5222
5223         /* 
5224          * no info is better than crashing: we'll need our own tz data
5225          * to make this work properly, anyway. The range is probably
5226          * reduced to 1970 .. 2037 because that is what mktime is
5227          * guaranteed to support (we get into an infinite loop
5228          * otherwise).
5229          */
5230
5231         memset (&start, 0, sizeof (start));
5232
5233         start.tm_mday = 1;
5234         start.tm_year = year-1900;
5235
5236         t = mktime (&start);
5237
5238         if ((year < 1970) || (year > 2037) || (t == -1)) {
5239                 t = time (NULL);
5240                 tt = *localtime (&t);
5241                 strftime (tzone, sizeof (tzone), "%Z", &tt);
5242                 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5243                 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5244                 return 1;
5245         }
5246
5247         gmtoff = gmt_offset (&start, t);
5248
5249         /* For each day of the year, calculate the tm_gmtoff. */
5250         for (day = 0; day < 365; day++) {
5251
5252                 t += 3600*24;
5253                 tt = *localtime (&t);
5254
5255                 /* Daylight saving starts or ends here. */
5256                 if (gmt_offset (&tt, t) != gmtoff) {
5257                         struct tm tt1;
5258                         time_t t1;
5259
5260                         /* Try to find the exact hour when daylight saving starts/ends. */
5261                         t1 = t;
5262                         do {
5263                                 t1 -= 3600;
5264                                 tt1 = *localtime (&t1);
5265                         } while (gmt_offset (&tt1, t1) != gmtoff);
5266
5267                         /* Try to find the exact minute when daylight saving starts/ends. */
5268                         do {
5269                                 t1 += 60;
5270                                 tt1 = *localtime (&t1);
5271                         } while (gmt_offset (&tt1, t1) == gmtoff);
5272                         t1+=gmtoff;
5273                         strftime (tzone, sizeof (tzone), "%Z", &tt);
5274                         
5275                         /* Write data, if we're already in daylight saving, we're done. */
5276                         if (is_daylight) {
5277                                 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5278                                 mono_array_set ((*data), gint64, 1, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
5279                                 return 1;
5280                         } else {
5281                                 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5282                                 mono_array_set ((*data), gint64, 0, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
5283                                 is_daylight = 1;
5284                         }
5285
5286                         /* This is only set once when we enter daylight saving. */
5287                         mono_array_set ((*data), gint64, 2, (gint64)gmtoff * 10000000L);
5288                         mono_array_set ((*data), gint64, 3, (gint64)(gmt_offset (&tt, t) - gmtoff) * 10000000L);
5289
5290                         gmtoff = gmt_offset (&tt, t);
5291                 }
5292         }
5293
5294         if (!is_daylight) {
5295                 strftime (tzone, sizeof (tzone), "%Z", &tt);
5296                 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5297                 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5298                 mono_array_set ((*data), gint64, 0, 0);
5299                 mono_array_set ((*data), gint64, 1, 0);
5300                 mono_array_set ((*data), gint64, 2, (gint64) gmtoff * 10000000L);
5301                 mono_array_set ((*data), gint64, 3, 0);
5302         }
5303
5304         return 1;
5305 #else
5306         MonoDomain *domain = mono_domain_get ();
5307         TIME_ZONE_INFORMATION tz_info;
5308         FILETIME ft;
5309         int i;
5310         int err, tz_id;
5311
5312         tz_id = GetTimeZoneInformation (&tz_info);
5313         if (tz_id == TIME_ZONE_ID_INVALID)
5314                 return 0;
5315
5316         MONO_CHECK_ARG_NULL (data);
5317         MONO_CHECK_ARG_NULL (names);
5318
5319         (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5320         (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5321
5322         for (i = 0; i < 32; ++i)
5323                 if (!tz_info.DaylightName [i])
5324                         break;
5325         mono_array_setref ((*names), 1, mono_string_new_utf16 (domain, tz_info.DaylightName, i));
5326         for (i = 0; i < 32; ++i)
5327                 if (!tz_info.StandardName [i])
5328                         break;
5329         mono_array_setref ((*names), 0, mono_string_new_utf16 (domain, tz_info.StandardName, i));
5330
5331         if ((year <= 1601) || (year > 30827)) {
5332                 /*
5333                  * According to MSDN, the MS time functions can't handle dates outside
5334                  * this interval.
5335                  */
5336                 return 1;
5337         }
5338
5339         /* even if the timezone has no daylight savings it may have Bias (e.g. GMT+13 it seems) */
5340         if (tz_id != TIME_ZONE_ID_UNKNOWN) {
5341                 tz_info.StandardDate.wYear = year;
5342                 convert_to_absolute_date(&tz_info.StandardDate);
5343                 err = SystemTimeToFileTime (&tz_info.StandardDate, &ft);
5344                 g_assert(err);
5345                 mono_array_set ((*data), gint64, 1, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
5346                 tz_info.DaylightDate.wYear = year;
5347                 convert_to_absolute_date(&tz_info.DaylightDate);
5348                 err = SystemTimeToFileTime (&tz_info.DaylightDate, &ft);
5349                 g_assert(err);
5350                 mono_array_set ((*data), gint64, 0, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
5351         }
5352         mono_array_set ((*data), gint64, 2, (tz_info.Bias + tz_info.StandardBias) * -600000000LL);
5353         mono_array_set ((*data), gint64, 3, (tz_info.DaylightBias - tz_info.StandardBias) * -600000000LL);
5354
5355         return 1;
5356 #endif
5357 }
5358
5359 static gpointer
5360 ves_icall_System_Object_obj_address (MonoObject *this) 
5361 {
5362         MONO_ARCH_SAVE_REGS;
5363
5364         return this;
5365 }
5366
5367 /* System.Buffer */
5368
5369 static inline gint32 
5370 mono_array_get_byte_length (MonoArray *array)
5371 {
5372         MonoClass *klass;
5373         int length;
5374         int i;
5375
5376         klass = array->obj.vtable->klass;
5377
5378         if (array->bounds == NULL)
5379                 length = array->max_length;
5380         else {
5381                 length = 1;
5382                 for (i = 0; i < klass->rank; ++ i)
5383                         length *= array->bounds [i].length;
5384         }
5385
5386         switch (klass->element_class->byval_arg.type) {
5387         case MONO_TYPE_I1:
5388         case MONO_TYPE_U1:
5389         case MONO_TYPE_BOOLEAN:
5390                 return length;
5391         case MONO_TYPE_I2:
5392         case MONO_TYPE_U2:
5393         case MONO_TYPE_CHAR:
5394                 return length << 1;
5395         case MONO_TYPE_I4:
5396         case MONO_TYPE_U4:
5397         case MONO_TYPE_R4:
5398                 return length << 2;
5399         case MONO_TYPE_I:
5400         case MONO_TYPE_U:
5401                 return length * sizeof (gpointer);
5402         case MONO_TYPE_I8:
5403         case MONO_TYPE_U8:
5404         case MONO_TYPE_R8:
5405                 return length << 3;
5406         default:
5407                 return -1;
5408         }
5409 }
5410
5411 static gint32 
5412 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array) 
5413 {
5414         MONO_ARCH_SAVE_REGS;
5415
5416         return mono_array_get_byte_length (array);
5417 }
5418
5419 static gint8 
5420 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx) 
5421 {
5422         MONO_ARCH_SAVE_REGS;
5423
5424         return mono_array_get (array, gint8, idx);
5425 }
5426
5427 static void 
5428 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value) 
5429 {
5430         MONO_ARCH_SAVE_REGS;
5431
5432         mono_array_set (array, gint8, idx, value);
5433 }
5434
5435 static MonoBoolean
5436 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count) 
5437 {
5438         guint8 *src_buf, *dest_buf;
5439
5440         MONO_ARCH_SAVE_REGS;
5441
5442         /* watch out for integer overflow */
5443         if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count))
5444                 return FALSE;
5445
5446         src_buf = (guint8 *)src->vector + src_offset;
5447         dest_buf = (guint8 *)dest->vector + dest_offset;
5448
5449         if (src != dest)
5450                 memcpy (dest_buf, src_buf, count);
5451         else
5452                 memmove (dest_buf, src_buf, count); /* Source and dest are the same array */
5453
5454         return TRUE;
5455 }
5456
5457 static MonoObject *
5458 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this, MonoString *class_name)
5459 {
5460         MonoDomain *domain = mono_object_domain (this); 
5461         MonoObject *res;
5462         MonoRealProxy *rp = ((MonoRealProxy *)this);
5463         MonoTransparentProxy *tp;
5464         MonoType *type;
5465         MonoClass *klass;
5466
5467         MONO_ARCH_SAVE_REGS;
5468
5469         res = mono_object_new (domain, mono_defaults.transparent_proxy_class);
5470         tp = (MonoTransparentProxy*) res;
5471         
5472         MONO_OBJECT_SETREF (tp, rp, rp);
5473         type = ((MonoReflectionType *)rp->class_to_proxy)->type;
5474         klass = mono_class_from_mono_type (type);
5475
5476         tp->custom_type_info = (mono_object_isinst (this, mono_defaults.iremotingtypeinfo_class) != NULL);
5477         tp->remote_class = mono_remote_class (domain, class_name, klass);
5478
5479         res->vtable = mono_remote_class_vtable (domain, tp->remote_class, rp);
5480         return res;
5481 }
5482
5483 static MonoReflectionType *
5484 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
5485 {
5486         return mono_type_get_object (mono_object_domain (tp), &tp->remote_class->proxy_class->byval_arg);
5487 }
5488
5489 /* System.Environment */
5490
5491 static MonoString *
5492 ves_icall_System_Environment_get_MachineName (void)
5493 {
5494 #if defined (PLATFORM_WIN32)
5495         gunichar2 *buf;
5496         guint32 len;
5497         MonoString *result;
5498
5499         len = MAX_COMPUTERNAME_LENGTH + 1;
5500         buf = g_new (gunichar2, len);
5501
5502         result = NULL;
5503         if (GetComputerName (buf, (PDWORD) &len))
5504                 result = mono_string_new_utf16 (mono_domain_get (), buf, len);
5505
5506         g_free (buf);
5507         return result;
5508 #else
5509         gchar buf [256];
5510         MonoString *result;
5511
5512         if (gethostname (buf, sizeof (buf)) == 0)
5513                 result = mono_string_new (mono_domain_get (), buf);
5514         else
5515                 result = NULL;
5516         
5517         return result;
5518 #endif
5519 }
5520
5521 static int
5522 ves_icall_System_Environment_get_Platform (void)
5523 {
5524         MONO_ARCH_SAVE_REGS;
5525
5526 #if defined (PLATFORM_WIN32)
5527         /* Win32NT */
5528         return 2;
5529 #else
5530         /* Unix */
5531         return 128;
5532 #endif
5533 }
5534
5535 static MonoString *
5536 ves_icall_System_Environment_get_NewLine (void)
5537 {
5538         MONO_ARCH_SAVE_REGS;
5539
5540 #if defined (PLATFORM_WIN32)
5541         return mono_string_new (mono_domain_get (), "\r\n");
5542 #else
5543         return mono_string_new (mono_domain_get (), "\n");
5544 #endif
5545 }
5546
5547 static MonoString *
5548 ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name)
5549 {
5550         const gchar *value;
5551         gchar *utf8_name;
5552
5553         MONO_ARCH_SAVE_REGS;
5554
5555         if (name == NULL)
5556                 return NULL;
5557
5558         utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
5559         value = g_getenv (utf8_name);
5560
5561         g_free (utf8_name);
5562
5563         if (value == 0)
5564                 return NULL;
5565         
5566         return mono_string_new (mono_domain_get (), value);
5567 }
5568
5569 /*
5570  * There is no standard way to get at environ.
5571  */
5572 #ifndef _MSC_VER
5573 extern
5574 #endif
5575 char **environ;
5576
5577 static MonoArray *
5578 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
5579 {
5580         MonoArray *names;
5581         MonoDomain *domain;
5582         MonoString *str;
5583         gchar **e, **parts;
5584         int n;
5585
5586         MONO_ARCH_SAVE_REGS;
5587
5588         n = 0;
5589         for (e = environ; *e != 0; ++ e)
5590                 ++ n;
5591
5592         domain = mono_domain_get ();
5593         names = mono_array_new (domain, mono_defaults.string_class, n);
5594
5595         n = 0;
5596         for (e = environ; *e != 0; ++ e) {
5597                 parts = g_strsplit (*e, "=", 2);
5598                 if (*parts != 0) {
5599                         str = mono_string_new (domain, *parts);
5600                         mono_array_setref (names, n, str);
5601                 }
5602
5603                 g_strfreev (parts);
5604
5605                 ++ n;
5606         }
5607
5608         return names;
5609 }
5610
5611 /*
5612  * If your platform lacks setenv/unsetenv, you must upgrade your glib.
5613  */
5614 #if !GLIB_CHECK_VERSION(2,4,0)
5615 #define g_setenv(a,b,c)   setenv(a,b,c)
5616 #define g_unsetenv(a) unsetenv(a)
5617 #endif
5618
5619 static void
5620 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
5621 {
5622         gchar *utf8_name, *utf8_value;
5623
5624         MONO_ARCH_SAVE_REGS;
5625
5626         utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
5627
5628         if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
5629                 g_unsetenv (utf8_name);
5630                 return;
5631         }
5632
5633         utf8_value = mono_string_to_utf8 (value);
5634
5635         g_setenv (utf8_name, utf8_value, TRUE);
5636
5637         g_free (utf8_name);
5638         g_free (utf8_value);
5639 }
5640
5641 /*
5642  * Returns: the number of milliseconds elapsed since the system started.
5643  */
5644 static gint32
5645 ves_icall_System_Environment_get_TickCount (void)
5646 {
5647         return GetTickCount ();
5648 }
5649
5650
5651 static void
5652 ves_icall_System_Environment_Exit (int result)
5653 {
5654         MONO_ARCH_SAVE_REGS;
5655
5656         mono_runtime_set_shutting_down ();
5657
5658         /* Suspend all managed threads since the runtime is going away */
5659         mono_thread_suspend_all_other_threads ();
5660
5661         mono_runtime_quit ();
5662
5663         /* we may need to do some cleanup here... */
5664         exit (result);
5665 }
5666
5667 static MonoString*
5668 ves_icall_System_Environment_GetGacPath (void)
5669 {
5670         return mono_string_new (mono_domain_get (), mono_assembly_getrootdir ());
5671 }
5672
5673 static MonoString*
5674 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
5675 {
5676 #if defined (PLATFORM_WIN32)
5677         #ifndef CSIDL_FLAG_CREATE
5678                 #define CSIDL_FLAG_CREATE       0x8000
5679         #endif
5680
5681         WCHAR path [MAX_PATH];
5682         /* Create directory if no existing */
5683         if (SUCCEEDED (SHGetFolderPathW (NULL, folder | CSIDL_FLAG_CREATE, NULL, 0, path))) {
5684                 int len = 0;
5685                 while (path [len])
5686                         ++ len;
5687                 return mono_string_new_utf16 (mono_domain_get (), path, len);
5688         }
5689 #else
5690         g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
5691 #endif
5692         return mono_string_new (mono_domain_get (), "");
5693 }
5694
5695 static MonoArray *
5696 ves_icall_System_Environment_GetLogicalDrives (void)
5697 {
5698         gunichar2 buf [128], *ptr, *dname;
5699         gunichar2 *u16;
5700         gint initial_size = 127, size = 128;
5701         gint ndrives;
5702         MonoArray *result;
5703         MonoString *drivestr;
5704         MonoDomain *domain = mono_domain_get ();
5705         gint len;
5706
5707         MONO_ARCH_SAVE_REGS;
5708
5709         buf [0] = '\0';
5710         ptr = buf;
5711
5712         while (size > initial_size) {
5713                 size = GetLogicalDriveStrings (initial_size, ptr);
5714                 if (size > initial_size) {
5715                         if (ptr != buf)
5716                                 g_free (ptr);
5717                         ptr = g_malloc0 ((size + 1) * sizeof (gunichar2));
5718                         initial_size = size;
5719                         size++;
5720                 }
5721         }
5722
5723         /* Count strings */
5724         dname = ptr;
5725         ndrives = 0;
5726         do {
5727                 while (*dname++);
5728                 ndrives++;
5729         } while (*dname);
5730
5731         dname = ptr;
5732         result = mono_array_new (domain, mono_defaults.string_class, ndrives);
5733         ndrives = 0;
5734         do {
5735                 len = 0;
5736                 u16 = dname;
5737                 while (*u16) { u16++; len ++; }
5738                 drivestr = mono_string_new_utf16 (domain, dname, len);
5739                 mono_array_setref (result, ndrives++, drivestr);
5740                 while (*dname++);
5741         } while (*dname);
5742
5743         if (ptr != buf)
5744                 g_free (ptr);
5745
5746         return result;
5747 }
5748
5749 static MonoString *
5750 ves_icall_System_Environment_InternalGetHome (void)
5751 {
5752         MONO_ARCH_SAVE_REGS;
5753
5754         return mono_string_new (mono_domain_get (), g_get_home_dir ());
5755 }
5756
5757 static const char *encodings [] = {
5758         (char *) 1,
5759                 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
5760                 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
5761                 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
5762         (char *) 2,
5763                 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
5764                 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
5765                 "x_unicode_2_0_utf_7",
5766         (char *) 3,
5767                 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
5768                 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
5769         (char *) 4,
5770                 "utf_16", "UTF_16LE", "ucs_2", "unicode",
5771                 "iso_10646_ucs2",
5772         (char *) 5,
5773                 "unicodefffe", "utf_16be",
5774         (char *) 6,
5775                 "iso_8859_1",
5776         (char *) 0
5777 };
5778
5779 /*
5780  * Returns the internal codepage, if the value of "int_code_page" is
5781  * 1 at entry, and we can not compute a suitable code page number,
5782  * returns the code page as a string
5783  */
5784 static MonoString*
5785 ves_icall_System_Text_Encoding_InternalCodePage (gint32 *int_code_page) 
5786 {
5787         const char *cset;
5788         const char *p;
5789         char *c;
5790         char *codepage = NULL;
5791         int code;
5792         int want_name = *int_code_page;
5793         int i;
5794         
5795         *int_code_page = -1;
5796         MONO_ARCH_SAVE_REGS;
5797
5798         g_get_charset (&cset);
5799         c = codepage = strdup (cset);
5800         for (c = codepage; *c; c++){
5801                 if (isascii (*c) && isalpha (*c))
5802                         *c = tolower (*c);
5803                 if (*c == '-')
5804                         *c = '_';
5805         }
5806         /* g_print ("charset: %s\n", cset); */
5807         
5808         /* handle some common aliases */
5809         p = encodings [0];
5810         code = 0;
5811         for (i = 0; p != 0; ){
5812                 if ((gssize) p < 7){
5813                         code = (gssize) p;
5814                         p = encodings [++i];
5815                         continue;
5816                 }
5817                 if (strcmp (p, codepage) == 0){
5818                         *int_code_page = code;
5819                         break;
5820                 }
5821                 p = encodings [++i];
5822         }
5823         
5824         if (strstr (codepage, "utf_8") != NULL)
5825                 *int_code_page |= 0x10000000;
5826         free (codepage);
5827         
5828         if (want_name && *int_code_page == -1)
5829                 return mono_string_new (mono_domain_get (), cset);
5830         else
5831                 return NULL;
5832 }
5833
5834 static MonoBoolean
5835 ves_icall_System_Environment_get_HasShutdownStarted (void)
5836 {
5837         if (mono_runtime_is_shutting_down ())
5838                 return TRUE;
5839
5840         if (mono_domain_is_unloading (mono_domain_get ()))
5841                 return TRUE;
5842
5843         return FALSE;
5844 }
5845
5846 static void
5847 ves_icall_MonoMethodMessage_InitMessage (MonoMethodMessage *this, 
5848                                          MonoReflectionMethod *method,
5849                                          MonoArray *out_args)
5850 {
5851         MONO_ARCH_SAVE_REGS;
5852
5853         mono_message_init (mono_object_domain (this), this, method, out_args);
5854 }
5855
5856 static MonoBoolean
5857 ves_icall_IsTransparentProxy (MonoObject *proxy)
5858 {
5859         MONO_ARCH_SAVE_REGS;
5860
5861         if (!proxy)
5862                 return 0;
5863
5864         if (proxy->vtable->klass == mono_defaults.transparent_proxy_class)
5865                 return 1;
5866
5867         return 0;
5868 }
5869
5870 static void
5871 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
5872 {
5873         MonoClass *klass;
5874         MonoVTable* vtable;
5875
5876         MONO_ARCH_SAVE_REGS;
5877
5878         klass = mono_class_from_mono_type (type->type);
5879         vtable = mono_class_vtable (mono_domain_get (), klass);
5880
5881         if (enable) vtable->remote = 1;
5882         else vtable->remote = 0;
5883 }
5884
5885 static MonoObject *
5886 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type)
5887 {
5888         MonoClass *klass;
5889         MonoDomain *domain;
5890         
5891         MONO_ARCH_SAVE_REGS;
5892
5893         domain = mono_object_domain (type);
5894         klass = mono_class_from_mono_type (type->type);
5895
5896         if (klass->rank >= 1) {
5897                 g_assert (klass->rank == 1);
5898                 return (MonoObject *) mono_array_new (domain, klass->element_class, 0);
5899         } else {
5900                 /* Bypass remoting object creation check */
5901                 return mono_object_new_alloc_specific (mono_class_vtable (domain, klass));
5902         }
5903 }
5904
5905 static MonoString *
5906 ves_icall_System_IO_get_temp_path (void)
5907 {
5908         MONO_ARCH_SAVE_REGS;
5909
5910         return mono_string_new (mono_domain_get (), g_get_tmp_dir ());
5911 }
5912
5913 static gpointer
5914 ves_icall_RuntimeMethod_GetFunctionPointer (MonoMethod *method)
5915 {
5916         MONO_ARCH_SAVE_REGS;
5917
5918         return mono_compile_method (method);
5919 }
5920
5921 static MonoString *
5922 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
5923 {
5924         MonoString *mcpath;
5925         gchar *path;
5926
5927         MONO_ARCH_SAVE_REGS;
5928
5929         path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
5930
5931 #if defined (PLATFORM_WIN32)
5932         /* Avoid mixing '/' and '\\' */
5933         {
5934                 gint i;
5935                 for (i = strlen (path) - 1; i >= 0; i--)
5936                         if (path [i] == '/')
5937                                 path [i] = '\\';
5938         }
5939 #endif
5940         mcpath = mono_string_new (mono_domain_get (), path);
5941         g_free (path);
5942
5943         return mcpath;
5944 }
5945
5946 static MonoString *
5947 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
5948 {
5949         MonoString *ipath;
5950         gchar *path;
5951
5952         MONO_ARCH_SAVE_REGS;
5953
5954         path = g_path_get_dirname (mono_get_config_dir ());
5955
5956 #if defined (PLATFORM_WIN32)
5957         /* Avoid mixing '/' and '\\' */
5958         {
5959                 gint i;
5960                 for (i = strlen (path) - 1; i >= 0; i--)
5961                         if (path [i] == '/')
5962                                 path [i] = '\\';
5963         }
5964 #endif
5965         ipath = mono_string_new (mono_domain_get (), path);
5966         g_free (path);
5967
5968         return ipath;
5969 }
5970
5971 static void
5972 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
5973 {
5974 #if defined (PLATFORM_WIN32)
5975         static void (*output_debug) (gunichar2 *);
5976         static gboolean tried_loading = FALSE;
5977
5978         MONO_ARCH_SAVE_REGS;
5979
5980         if (!tried_loading && output_debug == NULL) {
5981                 GModule *k32;
5982
5983                 tried_loading = TRUE;
5984                 k32 = g_module_open ("kernel32", G_MODULE_BIND_LAZY);
5985                 if (!k32) {
5986                         gchar *error = g_strdup (g_module_error ());
5987                         g_warning ("Failed to load kernel32.dll: %s\n", error);
5988                         g_free (error);
5989                         return;
5990                 }
5991
5992                 g_module_symbol (k32, "OutputDebugStringW", (gpointer *) &output_debug);
5993                 if (!output_debug) {
5994                         gchar *error = g_strdup (g_module_error ());
5995                         g_warning ("Failed to load OutputDebugStringW: %s\n", error);
5996                         g_free (error);
5997                         return;
5998                 }
5999         }
6000
6001         if (output_debug == NULL)
6002                 return;
6003         
6004         output_debug (mono_string_chars (message));
6005 #else
6006         g_warning ("WriteWindowsDebugString called and PLATFORM_WIN32 not defined!\n");
6007 #endif
6008 }
6009
6010 /* Only used for value types */
6011 static MonoObject *
6012 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
6013 {
6014         MonoClass *klass;
6015         MonoDomain *domain;
6016         
6017         MONO_ARCH_SAVE_REGS;
6018
6019         domain = mono_object_domain (type);
6020         klass = mono_class_from_mono_type (type->type);
6021
6022         if (mono_class_is_nullable (klass))
6023                 /* No arguments -> null */
6024                 return NULL;
6025
6026         return mono_object_new (domain, klass);
6027 }
6028
6029 static MonoReflectionMethod *
6030 ves_icall_MonoMethod_get_base_definition (MonoReflectionMethod *m)
6031 {
6032         MonoClass *klass;
6033         MonoMethod *method = m->method;
6034         MonoMethod *result = NULL;
6035
6036         MONO_ARCH_SAVE_REGS;
6037
6038         if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
6039             MONO_CLASS_IS_INTERFACE (method->klass) ||
6040             method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
6041                 return m;
6042
6043         if (method->klass == NULL || (klass = method->klass->parent) == NULL)
6044                 return m;
6045
6046         if (klass->generic_class)
6047                 klass = klass->generic_class->container_class;
6048
6049         mono_class_setup_vtable (klass);
6050         mono_class_setup_vtable (method->klass);
6051         while (result == NULL && klass != NULL && (klass->vtable_size > method->slot))
6052         {
6053                 mono_class_setup_vtable (klass);
6054
6055                 result = klass->vtable [method->slot];
6056                 if (result == NULL) {
6057                         MonoMethod* m;
6058                         gpointer iter = NULL;
6059                         /* It is an abstract method */
6060                         while ((m = mono_class_get_methods (klass, &iter))) {
6061                                 if (m->slot == method->slot) {
6062                                         result = m;
6063                                         break;
6064                                 }
6065                         }
6066                 }
6067                 klass = klass->parent;
6068         }
6069
6070         if (result == NULL)
6071                 return m;
6072
6073         return mono_method_get_object (mono_domain_get (), result, NULL);
6074 }
6075
6076 static void
6077 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
6078 {
6079         MONO_ARCH_SAVE_REGS;
6080
6081         iter->sig = *(MonoMethodSignature**)argsp;
6082         
6083         g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
6084         g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
6085
6086         iter->next_arg = 0;
6087         /* FIXME: it's not documented what start is exactly... */
6088         if (start) {
6089                 iter->args = start;
6090         } else {
6091                 int i, align, arg_size;
6092                 iter->args = argsp + sizeof (gpointer);
6093 #ifndef MONO_ARCH_REGPARMS
6094                 for (i = 0; i < iter->sig->sentinelpos; ++i) {
6095                         arg_size = mono_type_stack_size (iter->sig->params [i], &align);
6096                         iter->args = (char*)iter->args + arg_size;
6097                 }
6098 #endif
6099         }
6100         iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
6101
6102         /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
6103 }
6104
6105 static MonoTypedRef
6106 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
6107 {
6108         gint i, align, arg_size;
6109         MonoTypedRef res;
6110         MONO_ARCH_SAVE_REGS;
6111
6112         i = iter->sig->sentinelpos + iter->next_arg;
6113
6114         g_assert (i < iter->sig->param_count);
6115
6116         res.type = iter->sig->params [i];
6117         res.klass = mono_class_from_mono_type (res.type);
6118         /* FIXME: endianess issue... */
6119         res.value = iter->args;
6120         arg_size = mono_type_stack_size (res.type, &align);
6121         iter->args = (char*)iter->args + arg_size;
6122         iter->next_arg++;
6123
6124         /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6125
6126         return res;
6127 }
6128
6129 static MonoTypedRef
6130 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
6131 {
6132         gint i, align, arg_size;
6133         MonoTypedRef res;
6134         MONO_ARCH_SAVE_REGS;
6135
6136         i = iter->sig->sentinelpos + iter->next_arg;
6137
6138         g_assert (i < iter->sig->param_count);
6139
6140         while (i < iter->sig->param_count) {
6141                 if (!mono_metadata_type_equal (type, iter->sig->params [i]))
6142                         continue;
6143                 res.type = iter->sig->params [i];
6144                 res.klass = mono_class_from_mono_type (res.type);
6145                 /* FIXME: endianess issue... */
6146                 res.value = iter->args;
6147                 arg_size = mono_type_stack_size (res.type, &align);
6148                 iter->args = (char*)iter->args + arg_size;
6149                 iter->next_arg++;
6150                 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6151                 return res;
6152         }
6153         /* g_print ("arg type 0x%02x not found\n", res.type->type); */
6154
6155         res.type = NULL;
6156         res.value = NULL;
6157         res.klass = NULL;
6158         return res;
6159 }
6160
6161 static MonoType*
6162 mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
6163 {
6164         gint i;
6165         MONO_ARCH_SAVE_REGS;
6166         
6167         i = iter->sig->sentinelpos + iter->next_arg;
6168
6169         g_assert (i < iter->sig->param_count);
6170
6171         return iter->sig->params [i];
6172 }
6173
6174 static MonoObject*
6175 mono_TypedReference_ToObject (MonoTypedRef tref)
6176 {
6177         MONO_ARCH_SAVE_REGS;
6178
6179         if (MONO_TYPE_IS_REFERENCE (tref.type)) {
6180                 MonoObject** objp = tref.value;
6181                 return *objp;
6182         }
6183
6184         return mono_value_box (mono_domain_get (), tref.klass, tref.value);
6185 }
6186
6187 static MonoObject*
6188 mono_TypedReference_ToObjectInternal (MonoType *type, gpointer value, MonoClass *klass)
6189 {
6190         MONO_ARCH_SAVE_REGS;
6191
6192         if (MONO_TYPE_IS_REFERENCE (type)) {
6193                 MonoObject** objp = value;
6194                 return *objp;
6195         }
6196
6197         return mono_value_box (mono_domain_get (), klass, value);
6198 }
6199
6200 static void
6201 prelink_method (MonoMethod *method)
6202 {
6203         const char *exc_class, *exc_arg;
6204         if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
6205                 return;
6206         mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
6207         if (exc_class) {
6208                 mono_raise_exception( 
6209                         mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg ) );
6210         }
6211         /* create the wrapper, too? */
6212 }
6213
6214 static void
6215 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
6216 {
6217         MONO_ARCH_SAVE_REGS;
6218         prelink_method (method->method);
6219 }
6220
6221 static void
6222 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
6223 {
6224         MonoClass *klass = mono_class_from_mono_type (type->type);
6225         MonoMethod* m;
6226         gpointer iter = NULL;
6227         MONO_ARCH_SAVE_REGS;
6228
6229         while ((m = mono_class_get_methods (klass, &iter)))
6230                 prelink_method (m);
6231 }
6232
6233 /* These parameters are "readonly" in corlib/System/Char.cs */
6234 static void
6235 ves_icall_System_Char_GetDataTablePointers (guint8 const **category_data,
6236                                             guint8 const **numeric_data,
6237                                             gdouble const **numeric_data_values,
6238                                             guint16 const **to_lower_data_low,
6239                                             guint16 const **to_lower_data_high,
6240                                             guint16 const **to_upper_data_low,
6241                                             guint16 const **to_upper_data_high)
6242 {
6243         *category_data = CategoryData;
6244         *numeric_data = NumericData;
6245         *numeric_data_values = NumericDataValues;
6246         *to_lower_data_low = ToLowerDataLow;
6247         *to_lower_data_high = ToLowerDataHigh;
6248         *to_upper_data_low = ToUpperDataLow;
6249         *to_upper_data_high = ToUpperDataHigh;
6250 }
6251
6252 static gint32
6253 ves_icall_MonoDebugger_GetMethodToken (MonoReflectionMethod *method)
6254 {
6255         return method->method->token;
6256 }
6257
6258 static MonoBoolean
6259 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
6260 {
6261         MonoCustomAttrInfo *cinfo;
6262         gboolean found;
6263
6264         cinfo = mono_reflection_get_custom_attrs_info (obj);
6265         if (!cinfo)
6266                 return FALSE;
6267         found = mono_custom_attrs_has_attr (cinfo, mono_class_from_mono_type (attr_type->type));
6268         if (!cinfo->cached)
6269                 mono_custom_attrs_free (cinfo);
6270         return found;
6271 }
6272
6273 static MonoArray*
6274 custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
6275 {
6276         return mono_reflection_get_custom_attrs_by_type (obj, attr_type ? mono_class_from_mono_type (attr_type->type) : NULL);
6277 }
6278
6279 static MonoBoolean
6280 GCHandle_CheckCurrentDomain (guint32 gchandle)
6281 {
6282         return mono_gchandle_is_in_domain (gchandle, mono_domain_get ());
6283 }
6284
6285 static MonoString*
6286 ves_icall_Mono_Runtime_GetDisplayName (void)
6287 {
6288         static const char display_name_str [] = "Mono " VERSION;
6289         MonoString *display_name = mono_string_new (mono_domain_get (), display_name_str);
6290         return display_name;
6291 }
6292
6293 const static guchar
6294 dbase64 [] = {
6295         128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
6296         128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
6297         128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 62, 128, 128, 128, 63,
6298         52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 0, 128, 128,
6299         128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
6300         15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 128, 128, 128, 128, 128,
6301         128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
6302         41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
6303 };
6304
6305 static MonoArray *
6306 base64_to_byte_array (gunichar2 *start, gint ilength, MonoBoolean allowWhitespaceOnly)
6307 {
6308         gint ignored;
6309         gint i;
6310         gunichar2 c;
6311         gunichar2 last, prev_last;
6312         gint olength;
6313         MonoArray *result;
6314         guchar *res_ptr;
6315         gint a [4], b [4];
6316         MonoException *exc;
6317
6318         ignored = 0;
6319         last = prev_last = 0;
6320         for (i = 0; i < ilength; i++) {
6321                 c = start [i];
6322                 if (c >= sizeof (dbase64)) {
6323                         exc = mono_exception_from_name_msg (mono_get_corlib (),
6324                                 "System", "FormatException",
6325                                 "Invalid character found.");
6326                         mono_raise_exception (exc);
6327                 } else if (isspace (c)) {
6328                         ignored++;
6329                 } else {
6330                         prev_last = last;
6331                         last = c;
6332                 }
6333         }
6334
6335         olength = ilength - ignored;
6336
6337         if (allowWhitespaceOnly && olength == 0) {
6338                 return mono_array_new (mono_domain_get (), mono_defaults.byte_class, 0);
6339         }
6340
6341         if ((olength & 3) != 0 || olength <= 0) {
6342                 exc = mono_exception_from_name_msg (mono_get_corlib (), "System",
6343                                         "FormatException", "Invalid length.");
6344                 mono_raise_exception (exc);
6345         }
6346
6347         olength = (olength * 3) / 4;
6348         if (last == '=')
6349                 olength--;
6350
6351         if (prev_last == '=')
6352                 olength--;
6353
6354         result = mono_array_new (mono_domain_get (), mono_defaults.byte_class, olength);
6355         res_ptr = mono_array_addr (result, guchar, 0);
6356         for (i = 0; i < ilength; ) {
6357                 int k;
6358
6359                 for (k = 0; k < 4 && i < ilength;) {
6360                         c = start [i++];
6361                         if (isspace (c))
6362                                 continue;
6363
6364                         a [k] = (guchar) c;
6365                         if (((b [k] = dbase64 [c]) & 0x80) != 0) {
6366                                 exc = mono_exception_from_name_msg (mono_get_corlib (),
6367                                         "System", "FormatException",
6368                                         "Invalid character found.");
6369                                 mono_raise_exception (exc);
6370                         }
6371                         k++;
6372                 }
6373
6374                 *res_ptr++ = (b [0] << 2) | (b [1] >> 4);
6375                 if (a [2] != '=')
6376                         *res_ptr++ = (b [1] << 4) | (b [2] >> 2);
6377                 if (a [3] != '=')
6378                         *res_ptr++ = (b [2] << 6) | b [3];
6379
6380                 while (i < ilength && isspace (start [i]))
6381                         i++;
6382         }
6383
6384         return result;
6385 }
6386
6387 static MonoArray *
6388 InternalFromBase64String (MonoString *str, MonoBoolean allowWhitespaceOnly)
6389 {
6390         MONO_ARCH_SAVE_REGS;
6391
6392         return base64_to_byte_array (mono_string_chars (str), 
6393                 mono_string_length (str), allowWhitespaceOnly);
6394 }
6395
6396 static MonoArray *
6397 InternalFromBase64CharArray (MonoArray *input, gint offset, gint length)
6398 {
6399         MONO_ARCH_SAVE_REGS;
6400
6401         return base64_to_byte_array (mono_array_addr (input, gunichar2, offset),
6402                 length, FALSE);
6403 }
6404
6405 /* icall map */
6406 typedef struct {
6407         const char *method;
6408         gconstpointer func;
6409 } IcallEntry;
6410
6411 typedef struct {
6412         const char *klass;
6413         const IcallEntry *icalls;
6414         const int size;
6415 } IcallMap;
6416
6417 static const IcallEntry runtime_icalls [] = {
6418         {"GetDisplayName", ves_icall_Mono_Runtime_GetDisplayName}
6419 };
6420
6421 static const IcallEntry activator_icalls [] = {
6422         {"CreateInstanceInternal", ves_icall_System_Activator_CreateInstanceInternal}
6423 };
6424 static const IcallEntry appdomain_icalls [] = {
6425         {"ExecuteAssembly", ves_icall_System_AppDomain_ExecuteAssembly},
6426         {"GetAssemblies", ves_icall_System_AppDomain_GetAssemblies},
6427         {"GetData", ves_icall_System_AppDomain_GetData},
6428         {"InternalGetContext", ves_icall_System_AppDomain_InternalGetContext},
6429         {"InternalGetDefaultContext", ves_icall_System_AppDomain_InternalGetDefaultContext},
6430         {"InternalGetProcessGuid", ves_icall_System_AppDomain_InternalGetProcessGuid},
6431         {"InternalIsFinalizingForUnload", ves_icall_System_AppDomain_InternalIsFinalizingForUnload},
6432         {"InternalPopDomainRef", ves_icall_System_AppDomain_InternalPopDomainRef},
6433         {"InternalPushDomainRef", ves_icall_System_AppDomain_InternalPushDomainRef},
6434         {"InternalPushDomainRefByID", ves_icall_System_AppDomain_InternalPushDomainRefByID},
6435         {"InternalSetContext", ves_icall_System_AppDomain_InternalSetContext},
6436         {"InternalSetDomain", ves_icall_System_AppDomain_InternalSetDomain},
6437         {"InternalSetDomainByID", ves_icall_System_AppDomain_InternalSetDomainByID},
6438         {"InternalUnload", ves_icall_System_AppDomain_InternalUnload},
6439         {"LoadAssembly", ves_icall_System_AppDomain_LoadAssembly},
6440         {"LoadAssemblyRaw", ves_icall_System_AppDomain_LoadAssemblyRaw},
6441         {"SetData", ves_icall_System_AppDomain_SetData},
6442         {"createDomain", ves_icall_System_AppDomain_createDomain},
6443         {"getCurDomain", ves_icall_System_AppDomain_getCurDomain},
6444         {"getFriendlyName", ves_icall_System_AppDomain_getFriendlyName},
6445         {"getRootDomain", ves_icall_System_AppDomain_getRootDomain},
6446         {"getSetup", ves_icall_System_AppDomain_getSetup}
6447 };
6448
6449 static const IcallEntry argiterator_icalls [] = {
6450         {"IntGetNextArg()",                  mono_ArgIterator_IntGetNextArg},
6451         {"IntGetNextArg(intptr)", mono_ArgIterator_IntGetNextArgT},
6452         {"IntGetNextArgType",                mono_ArgIterator_IntGetNextArgType},
6453         {"Setup",                            mono_ArgIterator_Setup}
6454 };
6455
6456 static const IcallEntry array_icalls [] = {
6457         {"ClearInternal",    ves_icall_System_Array_ClearInternal},
6458         {"Clone",            mono_array_clone},
6459         {"CreateInstanceImpl",   ves_icall_System_Array_CreateInstanceImpl},
6460         {"FastCopy",         ves_icall_System_Array_FastCopy},
6461         {"GetLength",        ves_icall_System_Array_GetLength},
6462         {"GetLowerBound",    ves_icall_System_Array_GetLowerBound},
6463         {"GetRank",          ves_icall_System_Array_GetRank},
6464         {"GetValue",         ves_icall_System_Array_GetValue},
6465         {"GetValueImpl",     ves_icall_System_Array_GetValueImpl},
6466         {"SetValue",         ves_icall_System_Array_SetValue},
6467         {"SetValueImpl",     ves_icall_System_Array_SetValueImpl}
6468 };
6469
6470 static const IcallEntry buffer_icalls [] = {
6471         {"BlockCopyInternal", ves_icall_System_Buffer_BlockCopyInternal},
6472         {"ByteLengthInternal", ves_icall_System_Buffer_ByteLengthInternal},
6473         {"GetByteInternal", ves_icall_System_Buffer_GetByteInternal},
6474         {"SetByteInternal", ves_icall_System_Buffer_SetByteInternal}
6475 };
6476
6477 static const IcallEntry char_icalls [] = {
6478         {"GetDataTablePointers", ves_icall_System_Char_GetDataTablePointers}
6479 };
6480
6481 static const IcallEntry defaultconf_icalls [] = {
6482         {"get_machine_config_path", ves_icall_System_Configuration_DefaultConfig_get_machine_config_path}
6483 };
6484
6485 static const IcallEntry consoledriver_icalls [] = {
6486         {"GetTtySize", ves_icall_System_ConsoleDriver_GetTtySize },
6487         {"InternalKeyAvailable", ves_icall_System_ConsoleDriver_InternalKeyAvailable },
6488         {"Isatty", ves_icall_System_ConsoleDriver_Isatty },
6489         {"SetBreak", ves_icall_System_ConsoleDriver_SetBreak },
6490         {"SetEcho", ves_icall_System_ConsoleDriver_SetEcho },
6491         {"TtySetup", ves_icall_System_ConsoleDriver_TtySetup }
6492 };
6493
6494 static const IcallEntry convert_icalls [] = {
6495         {"InternalFromBase64CharArray", InternalFromBase64CharArray },
6496         {"InternalFromBase64String", InternalFromBase64String }
6497 };
6498
6499 static const IcallEntry timezone_icalls [] = {
6500         {"GetTimeZoneData", ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData}
6501 };
6502
6503 static const IcallEntry datetime_icalls [] = {
6504         {"GetNow", ves_icall_System_DateTime_GetNow}
6505 };
6506
6507 #ifndef DISABLE_DECIMAL
6508 static const IcallEntry decimal_icalls [] = {
6509         {"decimal2Int64", mono_decimal2Int64},
6510         {"decimal2UInt64", mono_decimal2UInt64},
6511         {"decimal2double", mono_decimal2double},
6512         {"decimal2string", mono_decimal2string},
6513         {"decimalCompare", mono_decimalCompare},
6514         {"decimalDiv", mono_decimalDiv},
6515         {"decimalFloorAndTrunc", mono_decimalFloorAndTrunc},
6516         {"decimalIncr", mono_decimalIncr},
6517         {"decimalIntDiv", mono_decimalIntDiv},
6518         {"decimalMult", mono_decimalMult},
6519         {"decimalRound", mono_decimalRound},
6520         {"decimalSetExponent", mono_decimalSetExponent},
6521         {"double2decimal", mono_double2decimal}, /* FIXME: wrong signature. */
6522         {"string2decimal", mono_string2decimal}
6523 };
6524 #endif
6525
6526 static const IcallEntry delegate_icalls [] = {
6527         {"CreateDelegate_internal", ves_icall_System_Delegate_CreateDelegate_internal},
6528         {"FreeTrampoline", ves_icall_System_Delegate_FreeTrampoline}
6529 };
6530
6531 static const IcallEntry tracelist_icalls [] = {
6532         {"WriteWindowsDebugString", ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString}
6533 };
6534
6535 static const IcallEntry fileversion_icalls [] = {
6536         {"GetVersionInfo_internal(string)", ves_icall_System_Diagnostics_FileVersionInfo_GetVersionInfo_internal}
6537 };
6538
6539 static const IcallEntry process_icalls [] = {
6540         {"CreateProcess_internal(System.Diagnostics.ProcessStartInfo,intptr,intptr,intptr,System.Diagnostics.Process/ProcInfo&)", ves_icall_System_Diagnostics_Process_CreateProcess_internal},
6541         {"ExitCode_internal(intptr)", ves_icall_System_Diagnostics_Process_ExitCode_internal},
6542         {"ExitTime_internal(intptr)", ves_icall_System_Diagnostics_Process_ExitTime_internal},
6543         {"GetModules_internal()", ves_icall_System_Diagnostics_Process_GetModules_internal},
6544         {"GetPid_internal()", ves_icall_System_Diagnostics_Process_GetPid_internal},
6545         {"GetProcess_internal(int)", ves_icall_System_Diagnostics_Process_GetProcess_internal},
6546         {"GetProcesses_internal()", ves_icall_System_Diagnostics_Process_GetProcesses_internal},
6547         {"GetWorkingSet_internal(intptr,int&,int&)", ves_icall_System_Diagnostics_Process_GetWorkingSet_internal},
6548         {"Kill_internal", ves_icall_System_Diagnostics_Process_Kill_internal},
6549         {"ProcessName_internal(intptr)", ves_icall_System_Diagnostics_Process_ProcessName_internal},
6550         {"Process_free_internal(intptr)", ves_icall_System_Diagnostics_Process_Process_free_internal},
6551         {"SetWorkingSet_internal(intptr,int,int,bool)", ves_icall_System_Diagnostics_Process_SetWorkingSet_internal},
6552         {"ShellExecuteEx_internal(System.Diagnostics.ProcessStartInfo,System.Diagnostics.Process/ProcInfo&)", ves_icall_System_Diagnostics_Process_ShellExecuteEx_internal},
6553         {"StartTime_internal(intptr)", ves_icall_System_Diagnostics_Process_StartTime_internal},
6554         {"WaitForExit_internal(intptr,int)", ves_icall_System_Diagnostics_Process_WaitForExit_internal}
6555 };
6556
6557 static const IcallEntry double_icalls [] = {
6558         {"AssertEndianity", ves_icall_System_Double_AssertEndianity},
6559         {"ParseImpl",    mono_double_ParseImpl}
6560 };
6561
6562 static const IcallEntry enum_icalls [] = {
6563         {"ToObject", ves_icall_System_Enum_ToObject},
6564         {"get_value", ves_icall_System_Enum_get_value}
6565 };
6566
6567 static const IcallEntry environment_icalls [] = {
6568         {"Exit", ves_icall_System_Environment_Exit},
6569         {"GetCommandLineArgs", mono_runtime_get_main_args},
6570         {"GetEnvironmentVariableNames", ves_icall_System_Environment_GetEnvironmentVariableNames},
6571         {"GetLogicalDrivesInternal", ves_icall_System_Environment_GetLogicalDrives },
6572         {"GetMachineConfigPath", ves_icall_System_Configuration_DefaultConfig_get_machine_config_path},
6573         {"GetOSVersionString", ves_icall_System_Environment_GetOSVersionString},
6574         {"GetWindowsFolderPath", ves_icall_System_Environment_GetWindowsFolderPath},
6575         {"InternalSetEnvironmentVariable", ves_icall_System_Environment_InternalSetEnvironmentVariable},
6576         {"get_ExitCode", mono_environment_exitcode_get},
6577         {"get_HasShutdownStarted", ves_icall_System_Environment_get_HasShutdownStarted},
6578         {"get_MachineName", ves_icall_System_Environment_get_MachineName},
6579         {"get_NewLine", ves_icall_System_Environment_get_NewLine},
6580         {"get_Platform", ves_icall_System_Environment_get_Platform},
6581         {"get_TickCount", ves_icall_System_Environment_get_TickCount},
6582         {"get_UserName", ves_icall_System_Environment_get_UserName},
6583         {"internalGetEnvironmentVariable", ves_icall_System_Environment_GetEnvironmentVariable},
6584         {"internalGetGacPath", ves_icall_System_Environment_GetGacPath},
6585         {"internalGetHome", ves_icall_System_Environment_InternalGetHome},
6586         {"set_ExitCode", mono_environment_exitcode_set}
6587 };
6588
6589 static const IcallEntry cultureinfo_icalls [] = {
6590         {"construct_compareinfo(object,string)", ves_icall_System_Globalization_CompareInfo_construct_compareinfo},
6591         {"construct_datetime_format", ves_icall_System_Globalization_CultureInfo_construct_datetime_format},
6592         {"construct_internal_locale(string)", ves_icall_System_Globalization_CultureInfo_construct_internal_locale},
6593         {"construct_internal_locale_from_current_locale", ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_current_locale},
6594         {"construct_internal_locale_from_lcid", ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_lcid},
6595         {"construct_internal_locale_from_name", ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_name},
6596         {"construct_internal_locale_from_specific_name", ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_specific_name},
6597         {"construct_number_format", ves_icall_System_Globalization_CultureInfo_construct_number_format},
6598         {"internal_get_cultures", ves_icall_System_Globalization_CultureInfo_internal_get_cultures},
6599         {"internal_is_lcid_neutral", ves_icall_System_Globalization_CultureInfo_internal_is_lcid_neutral}
6600 };
6601
6602 static const IcallEntry regioninfo_icalls [] = {
6603         {"construct_internal_region_from_lcid", ves_icall_System_Globalization_RegionInfo_construct_internal_region_from_lcid},
6604         {"construct_internal_region_from_name", ves_icall_System_Globalization_RegionInfo_construct_internal_region_from_name}
6605 };
6606
6607 static const IcallEntry compareinfo_icalls [] = {
6608         {"assign_sortkey(object,string,System.Globalization.CompareOptions)", ves_icall_System_Globalization_CompareInfo_assign_sortkey},
6609         {"construct_compareinfo(string)", ves_icall_System_Globalization_CompareInfo_construct_compareinfo},
6610         {"free_internal_collator()", ves_icall_System_Globalization_CompareInfo_free_internal_collator},
6611         {"internal_compare(string,int,int,string,int,int,System.Globalization.CompareOptions)", ves_icall_System_Globalization_CompareInfo_internal_compare},
6612         {"internal_index(string,int,int,char,System.Globalization.CompareOptions,bool)", ves_icall_System_Globalization_CompareInfo_internal_index_char},
6613         {"internal_index(string,int,int,string,System.Globalization.CompareOptions,bool)", ves_icall_System_Globalization_CompareInfo_internal_index}
6614 };
6615
6616 static const IcallEntry gc_icalls [] = {
6617         {"GetTotalMemory", ves_icall_System_GC_GetTotalMemory},
6618         {"InternalCollect", ves_icall_System_GC_InternalCollect},
6619         {"KeepAlive", ves_icall_System_GC_KeepAlive},
6620         {"ReRegisterForFinalize", ves_icall_System_GC_ReRegisterForFinalize},
6621         {"SuppressFinalize", ves_icall_System_GC_SuppressFinalize},
6622         {"WaitForPendingFinalizers", ves_icall_System_GC_WaitForPendingFinalizers}
6623 };
6624
6625 static const IcallEntry famwatcher_icalls [] = {
6626         {"InternalFAMNextEvent", ves_icall_System_IO_FAMW_InternalFAMNextEvent}
6627 };
6628
6629 static const IcallEntry filewatcher_icalls [] = {
6630         {"InternalCloseDirectory", ves_icall_System_IO_FSW_CloseDirectory},
6631         {"InternalOpenDirectory", ves_icall_System_IO_FSW_OpenDirectory},
6632         {"InternalReadDirectoryChanges", ves_icall_System_IO_FSW_ReadDirectoryChanges},
6633         {"InternalSupportsFSW", ves_icall_System_IO_FSW_SupportsFSW}
6634 };
6635
6636 static const IcallEntry path_icalls [] = {
6637         {"get_temp_path", ves_icall_System_IO_get_temp_path}
6638 };
6639
6640 static const IcallEntry monoio_icalls [] = {
6641         {"Close(intptr,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_Close},
6642         {"CopyFile(string,string,bool,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_CopyFile},
6643         {"CreateDirectory(string,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_CreateDirectory},
6644         {"CreatePipe(intptr&,intptr&)", ves_icall_System_IO_MonoIO_CreatePipe},
6645         {"DeleteFile(string,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_DeleteFile},
6646         {"Flush(intptr,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_Flush},
6647         {"GetCurrentDirectory(System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_GetCurrentDirectory},
6648         {"GetFileAttributes(string,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_GetFileAttributes},
6649         {"GetFileStat(string,System.IO.MonoIOStat&,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_GetFileStat},
6650         {"GetFileSystemEntries", ves_icall_System_IO_MonoIO_GetFileSystemEntries},
6651         {"GetFileType(intptr,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_GetFileType},
6652         {"GetLength(intptr,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_GetLength},
6653         {"GetTempPath(string&)", ves_icall_System_IO_MonoIO_GetTempPath},
6654         {"Lock(intptr,long,long,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_Lock},
6655         {"MoveFile(string,string,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_MoveFile},
6656         {"Open(string,System.IO.FileMode,System.IO.FileAccess,System.IO.FileShare,System.IO.FileOptions,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_Open},
6657         {"Read(intptr,byte[],int,int,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_Read},
6658         {"RemoveDirectory(string,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_RemoveDirectory},
6659         {"Seek(intptr,long,System.IO.SeekOrigin,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_Seek},
6660         {"SetCurrentDirectory(string,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_SetCurrentDirectory},
6661         {"SetFileAttributes(string,System.IO.FileAttributes,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_SetFileAttributes},
6662         {"SetFileTime(intptr,long,long,long,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_SetFileTime},
6663         {"SetLength(intptr,long,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_SetLength},
6664         {"Unlock(intptr,long,long,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_Unlock},
6665         {"Write(intptr,byte[],int,int,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_Write},
6666         {"get_AltDirectorySeparatorChar", ves_icall_System_IO_MonoIO_get_AltDirectorySeparatorChar},
6667         {"get_ConsoleError", ves_icall_System_IO_MonoIO_get_ConsoleError},
6668         {"get_ConsoleInput", ves_icall_System_IO_MonoIO_get_ConsoleInput},
6669         {"get_ConsoleOutput", ves_icall_System_IO_MonoIO_get_ConsoleOutput},
6670         {"get_DirectorySeparatorChar", ves_icall_System_IO_MonoIO_get_DirectorySeparatorChar},
6671         {"get_InvalidPathChars", ves_icall_System_IO_MonoIO_get_InvalidPathChars},
6672         {"get_PathSeparator", ves_icall_System_IO_MonoIO_get_PathSeparator},
6673         {"get_VolumeSeparatorChar", ves_icall_System_IO_MonoIO_get_VolumeSeparatorChar}
6674 };
6675
6676 static const IcallEntry math_icalls [] = {
6677         {"Acos", ves_icall_System_Math_Acos},
6678         {"Asin", ves_icall_System_Math_Asin},
6679         {"Atan", ves_icall_System_Math_Atan},
6680         {"Atan2", ves_icall_System_Math_Atan2},
6681         {"Cos", ves_icall_System_Math_Cos},
6682         {"Cosh", ves_icall_System_Math_Cosh},
6683         {"Exp", ves_icall_System_Math_Exp},
6684         {"Floor", ves_icall_System_Math_Floor},
6685         {"Log", ves_icall_System_Math_Log},
6686         {"Log10", ves_icall_System_Math_Log10},
6687         {"Pow", ves_icall_System_Math_Pow},
6688         {"Round", ves_icall_System_Math_Round},
6689         {"Round2", ves_icall_System_Math_Round2},
6690         {"Sin", ves_icall_System_Math_Sin},
6691         {"Sinh", ves_icall_System_Math_Sinh},
6692         {"Sqrt", ves_icall_System_Math_Sqrt},
6693         {"Tan", ves_icall_System_Math_Tan},
6694         {"Tanh", ves_icall_System_Math_Tanh}
6695 };
6696
6697 static const IcallEntry customattrs_icalls [] = {
6698         {"GetCustomAttributesDataInternal", mono_reflection_get_custom_attrs_data},
6699         {"GetCustomAttributesInternal", custom_attrs_get_by_type},
6700         {"IsDefinedInternal", custom_attrs_defined_internal}
6701 };
6702
6703 static const IcallEntry enuminfo_icalls [] = {
6704         {"get_enum_info", ves_icall_get_enum_info}
6705 };
6706
6707 static const IcallEntry fieldinfo_icalls [] = {
6708         {"GetUnmanagedMarshal", ves_icall_System_Reflection_FieldInfo_GetUnmanagedMarshal},
6709         {"internal_from_handle", ves_icall_System_Reflection_FieldInfo_internal_from_handle}
6710 };
6711
6712 static const IcallEntry memberinfo_icalls [] = {
6713         {"get_MetadataToken", mono_reflection_get_token}
6714 };
6715
6716 static const IcallEntry monotype_icalls [] = {
6717         {"GetArrayRank", ves_icall_MonoType_GetArrayRank},
6718         {"GetConstructors", ves_icall_Type_GetConstructors_internal},
6719         {"GetConstructors_internal", ves_icall_Type_GetConstructors_internal},
6720         {"GetCorrespondingInflatedConstructor", ves_icall_MonoType_GetCorrespondingInflatedMethod},
6721         {"GetCorrespondingInflatedMethod", ves_icall_MonoType_GetCorrespondingInflatedMethod},
6722         {"GetElementType", ves_icall_MonoType_GetElementType},
6723         {"GetEvents_internal", ves_icall_Type_GetEvents_internal},
6724         {"GetField", ves_icall_Type_GetField},
6725         {"GetFields_internal", ves_icall_Type_GetFields_internal},
6726         {"GetGenericArguments", ves_icall_MonoType_GetGenericArguments},
6727         {"GetInterfaces", ves_icall_Type_GetInterfaces},
6728         {"GetMethodsByName", ves_icall_Type_GetMethodsByName},
6729         {"GetNestedType", ves_icall_Type_GetNestedType},
6730         {"GetNestedTypes", ves_icall_Type_GetNestedTypes},
6731         {"GetPropertiesByName", ves_icall_Type_GetPropertiesByName},
6732         {"InternalGetEvent", ves_icall_MonoType_GetEvent},
6733         {"IsByRefImpl", ves_icall_type_isbyref},
6734         {"IsPointerImpl", ves_icall_type_ispointer},
6735         {"IsPrimitiveImpl", ves_icall_type_isprimitive},
6736         {"getFullName", ves_icall_System_MonoType_getFullName},
6737         {"get_Assembly", ves_icall_MonoType_get_Assembly},
6738         {"get_BaseType", ves_icall_get_type_parent},
6739         {"get_DeclaringMethod", ves_icall_MonoType_get_DeclaringMethod},
6740         {"get_DeclaringType", ves_icall_MonoType_get_DeclaringType},
6741         {"get_IsGenericParameter", ves_icall_MonoType_get_IsGenericParameter},
6742         {"get_Module", ves_icall_MonoType_get_Module},
6743         {"get_Name", ves_icall_MonoType_get_Name},
6744         {"get_Namespace", ves_icall_MonoType_get_Namespace},
6745         {"get_UnderlyingSystemType", ves_icall_MonoType_get_UnderlyingSystemType},
6746         {"get_attributes", ves_icall_get_attributes},
6747         {"type_from_obj", mono_type_type_from_obj}
6748 };
6749
6750 static const IcallEntry assembly_icalls [] = {
6751         {"FillName", ves_icall_System_Reflection_Assembly_FillName},
6752         {"GetCallingAssembly", ves_icall_System_Reflection_Assembly_GetCallingAssembly},
6753         {"GetEntryAssembly", ves_icall_System_Reflection_Assembly_GetEntryAssembly},
6754         {"GetExecutingAssembly", ves_icall_System_Reflection_Assembly_GetExecutingAssembly},
6755         {"GetFilesInternal", ves_icall_System_Reflection_Assembly_GetFilesInternal},
6756         {"GetManifestResourceInfoInternal", ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal},
6757         {"GetManifestResourceInternal", ves_icall_System_Reflection_Assembly_GetManifestResourceInternal},
6758         {"GetManifestResourceNames", ves_icall_System_Reflection_Assembly_GetManifestResourceNames},
6759         {"GetModulesInternal", ves_icall_System_Reflection_Assembly_GetModulesInternal},
6760         {"GetNamespaces", ves_icall_System_Reflection_Assembly_GetNamespaces},
6761         {"GetReferencedAssemblies", ves_icall_System_Reflection_Assembly_GetReferencedAssemblies},
6762         {"GetTypes", ves_icall_System_Reflection_Assembly_GetTypes},
6763         {"InternalGetAssemblyName", ves_icall_System_Reflection_Assembly_InternalGetAssemblyName},
6764         {"InternalGetType", ves_icall_System_Reflection_Assembly_InternalGetType},
6765         {"InternalImageRuntimeVersion", ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion},
6766         {"LoadFrom", ves_icall_System_Reflection_Assembly_LoadFrom},
6767         {"LoadPermissions", ves_icall_System_Reflection_Assembly_LoadPermissions},
6768         /*
6769          * Private icalls for the Mono Debugger
6770          */
6771         {"MonoDebugger_GetMethodToken", ves_icall_MonoDebugger_GetMethodToken},
6772
6773         /* normal icalls again */
6774         {"get_EntryPoint", ves_icall_System_Reflection_Assembly_get_EntryPoint},
6775         {"get_ManifestModule", ves_icall_System_Reflection_Assembly_get_ManifestModule},
6776         {"get_ReflectionOnly", ves_icall_System_Reflection_Assembly_get_ReflectionOnly},
6777         {"get_code_base", ves_icall_System_Reflection_Assembly_get_code_base},
6778         {"get_global_assembly_cache", ves_icall_System_Reflection_Assembly_get_global_assembly_cache},
6779         {"get_location", ves_icall_System_Reflection_Assembly_get_location},
6780         {"load_with_partial_name", ves_icall_System_Reflection_Assembly_load_with_partial_name}
6781 };
6782
6783 static const IcallEntry assembly_name_icalls [] = {
6784         {"ParseName", ves_icall_System_Reflection_AssemblyName_ParseName}
6785 };
6786
6787 static const IcallEntry methodbase_icalls [] = {
6788         {"GetCurrentMethod", ves_icall_GetCurrentMethod},
6789         {"GetMethodBodyInternal", ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal},
6790         {"GetMethodFromHandleInternal", ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternal}
6791 };
6792
6793 static const IcallEntry module_icalls [] = {
6794         {"Close", ves_icall_System_Reflection_Module_Close},
6795         {"GetGlobalType", ves_icall_System_Reflection_Module_GetGlobalType},
6796         {"GetGuidInternal", ves_icall_System_Reflection_Module_GetGuidInternal},
6797         {"GetPEKind", ves_icall_System_Reflection_Module_GetPEKind},
6798         {"InternalGetTypes", ves_icall_System_Reflection_Module_InternalGetTypes},
6799         {"ResolveFieldToken", ves_icall_System_Reflection_Module_ResolveFieldToken},
6800         {"ResolveMemberToken", ves_icall_System_Reflection_Module_ResolveMemberToken},
6801         {"ResolveMethodToken", ves_icall_System_Reflection_Module_ResolveMethodToken},
6802         {"ResolveStringToken", ves_icall_System_Reflection_Module_ResolveStringToken},
6803         {"ResolveTypeToken", ves_icall_System_Reflection_Module_ResolveTypeToken},
6804         {"get_MDStreamVersion", ves_icall_System_Reflection_Module_get_MDStreamVersion},
6805         {"get_MetadataToken", mono_reflection_get_token}
6806 };
6807
6808 static const IcallEntry monocmethod_icalls [] = {
6809         {"GetGenericMethodDefinition_impl", ves_icall_MonoMethod_GetGenericMethodDefinition},
6810         {"InternalInvoke", ves_icall_InternalInvoke},
6811 };
6812
6813 static const IcallEntry monoeventinfo_icalls [] = {
6814         {"get_event_info", ves_icall_get_event_info}
6815 };
6816
6817 static const IcallEntry monofield_icalls [] = {
6818         {"GetFieldOffset", ves_icall_MonoField_GetFieldOffset},
6819         {"GetParentType", ves_icall_MonoField_GetParentType},
6820         {"GetValueInternal", ves_icall_MonoField_GetValueInternal},
6821         {"SetValueInternal", ves_icall_FieldInfo_SetValueInternal}
6822 };
6823
6824 static const IcallEntry monogenericclass_icalls [] = {
6825         {"GetConstructors_internal", ves_icall_MonoGenericClass_GetConstructors},
6826         {"GetCorrespondingInflatedConstructor", ves_icall_MonoGenericClass_GetCorrespondingInflatedConstructor},
6827         {"GetCorrespondingInflatedField", ves_icall_MonoGenericClass_GetCorrespondingInflatedField},
6828         {"GetCorrespondingInflatedMethod", ves_icall_MonoGenericClass_GetCorrespondingInflatedMethod},
6829         {"GetEvents_internal", ves_icall_MonoGenericClass_GetEvents},
6830         {"GetFields_internal", ves_icall_MonoGenericClass_GetFields},
6831         {"GetInterfaces_internal", ves_icall_MonoGenericClass_GetInterfaces},
6832         {"GetMethods_internal", ves_icall_MonoGenericClass_GetMethods},
6833         {"GetParentType", ves_icall_MonoGenericClass_GetParentType},
6834         {"GetProperties_internal", ves_icall_MonoGenericClass_GetProperties},
6835         {"initialize", mono_reflection_generic_class_initialize}
6836 };
6837
6838 static const IcallEntry monogenericmethod_icalls [] = {
6839         {"get_ReflectedType", ves_icall_MonoGenericMethod_get_ReflectedType}
6840 };
6841
6842 static const IcallEntry generictypeparambuilder_icalls [] = {
6843         {"initialize", mono_reflection_initialize_generic_parameter}
6844 };
6845
6846 static const IcallEntry monomethod_icalls [] = {
6847         {"GetDllImportAttribute", ves_icall_MonoMethod_GetDllImportAttribute},
6848         {"GetGenericArguments", ves_icall_MonoMethod_GetGenericArguments},
6849         {"GetGenericMethodDefinition_impl", ves_icall_MonoMethod_GetGenericMethodDefinition},
6850         {"InternalInvoke", ves_icall_InternalInvoke},
6851         {"MakeGenericMethod_impl", mono_reflection_bind_generic_method_parameters},
6852         {"get_IsGenericMethod", ves_icall_MonoMethod_get_IsGenericMethod},
6853         {"get_IsGenericMethodDefinition", ves_icall_MonoMethod_get_IsGenericMethodDefinition},
6854         {"get_base_definition", ves_icall_MonoMethod_get_base_definition}
6855 };
6856
6857 static const IcallEntry monomethodinfo_icalls [] = {
6858         {"get_method_info", ves_icall_get_method_info},
6859         {"get_parameter_info", ves_icall_get_parameter_info},
6860         {"get_retval_marshal", ves_icall_System_MonoMethodInfo_get_retval_marshal}
6861 };
6862
6863 static const IcallEntry monopropertyinfo_icalls [] = {
6864         {"get_property_info", ves_icall_get_property_info}
6865 };
6866
6867 static const IcallEntry parameterinfo_icalls [] = {
6868         {"get_MetadataToken", mono_reflection_get_token}
6869 };
6870
6871 static const IcallEntry dns_icalls [] = {
6872         {"GetHostByAddr_internal(string,string&,string[]&,string[]&)", ves_icall_System_Net_Dns_GetHostByAddr_internal},
6873         {"GetHostByName_internal(string,string&,string[]&,string[]&)", ves_icall_System_Net_Dns_GetHostByName_internal},
6874         {"GetHostName_internal(string&)", ves_icall_System_Net_Dns_GetHostName_internal}
6875 };
6876
6877 static const IcallEntry socket_icalls [] = {
6878         {"Accept_internal(intptr,int&)", ves_icall_System_Net_Sockets_Socket_Accept_internal},
6879         {"Available_internal(intptr,int&)", ves_icall_System_Net_Sockets_Socket_Available_internal},
6880         {"Bind_internal(intptr,System.Net.SocketAddress,int&)", ves_icall_System_Net_Sockets_Socket_Bind_internal},
6881         {"Blocking_internal(intptr,bool,int&)", ves_icall_System_Net_Sockets_Socket_Blocking_internal},
6882         {"Close_internal(intptr,int&)", ves_icall_System_Net_Sockets_Socket_Close_internal},
6883         {"Connect_internal(intptr,System.Net.SocketAddress,int&)", ves_icall_System_Net_Sockets_Socket_Connect_internal},
6884         {"GetSocketOption_arr_internal(intptr,System.Net.Sockets.SocketOptionLevel,System.Net.Sockets.SocketOptionName,byte[]&,int&)", ves_icall_System_Net_Sockets_Socket_GetSocketOption_arr_internal},
6885         {"GetSocketOption_obj_internal(intptr,System.Net.Sockets.SocketOptionLevel,System.Net.Sockets.SocketOptionName,object&,int&)", ves_icall_System_Net_Sockets_Socket_GetSocketOption_obj_internal},
6886         {"Listen_internal(intptr,int,int&)", ves_icall_System_Net_Sockets_Socket_Listen_internal},
6887         {"LocalEndPoint_internal(intptr,int&)", ves_icall_System_Net_Sockets_Socket_LocalEndPoint_internal},
6888         {"Poll_internal", ves_icall_System_Net_Sockets_Socket_Poll_internal},
6889         {"Receive_internal(intptr,byte[],int,int,System.Net.Sockets.SocketFlags,int&)", ves_icall_System_Net_Sockets_Socket_Receive_internal},
6890         {"RecvFrom_internal(intptr,byte[],int,int,System.Net.Sockets.SocketFlags,System.Net.SocketAddress&,int&)", ves_icall_System_Net_Sockets_Socket_RecvFrom_internal},
6891         {"RemoteEndPoint_internal(intptr,int&)", ves_icall_System_Net_Sockets_Socket_RemoteEndPoint_internal},
6892         {"Select_internal(System.Net.Sockets.Socket[]&,int,int&)", ves_icall_System_Net_Sockets_Socket_Select_internal},
6893         {"SendTo_internal(intptr,byte[],int,int,System.Net.Sockets.SocketFlags,System.Net.SocketAddress,int&)", ves_icall_System_Net_Sockets_Socket_SendTo_internal},
6894         {"Send_internal(intptr,byte[],int,int,System.Net.Sockets.SocketFlags,int&)", ves_icall_System_Net_Sockets_Socket_Send_internal},
6895         {"SetSocketOption_internal(intptr,System.Net.Sockets.SocketOptionLevel,System.Net.Sockets.SocketOptionName,object,byte[],int,int&)", ves_icall_System_Net_Sockets_Socket_SetSocketOption_internal},
6896         {"Shutdown_internal(intptr,System.Net.Sockets.SocketShutdown,int&)", ves_icall_System_Net_Sockets_Socket_Shutdown_internal},
6897         {"Socket_internal(System.Net.Sockets.AddressFamily,System.Net.Sockets.SocketType,System.Net.Sockets.ProtocolType,int&)", ves_icall_System_Net_Sockets_Socket_Socket_internal},
6898         {"WSAIoctl(intptr,int,byte[],byte[],int&)", ves_icall_System_Net_Sockets_Socket_WSAIoctl}
6899 };
6900
6901 static const IcallEntry socketex_icalls [] = {
6902         {"WSAGetLastError_internal", ves_icall_System_Net_Sockets_SocketException_WSAGetLastError_internal}
6903 };
6904
6905 static const IcallEntry object_icalls [] = {
6906         {"GetType", ves_icall_System_Object_GetType},
6907         {"InternalGetHashCode", mono_object_hash},
6908         {"MemberwiseClone", ves_icall_System_Object_MemberwiseClone},
6909         {"obj_address", ves_icall_System_Object_obj_address}
6910 };
6911
6912 static const IcallEntry assemblybuilder_icalls[] = {
6913         {"InternalAddModule", mono_image_load_module},
6914         {"basic_init", mono_image_basic_init}
6915 };
6916
6917 static const IcallEntry customattrbuilder_icalls [] = {
6918         {"GetBlob", mono_reflection_get_custom_attrs_blob}
6919 };
6920
6921 static const IcallEntry dynamicmethod_icalls [] = {
6922         {"create_dynamic_method", mono_reflection_create_dynamic_method}
6923 };
6924
6925 static const IcallEntry methodbuilder_icalls [] = {
6926         {"MakeGenericMethod", mono_reflection_bind_generic_method_parameters}
6927 };
6928
6929 static const IcallEntry modulebuilder_icalls [] = {
6930         {"WriteToFile", ves_icall_ModuleBuilder_WriteToFile},
6931         {"basic_init", mono_image_module_basic_init},
6932         {"build_metadata", ves_icall_ModuleBuilder_build_metadata},
6933         {"create_modified_type", ves_icall_ModuleBuilder_create_modified_type},
6934         {"getMethodToken", ves_icall_ModuleBuilder_getMethodToken},
6935         {"getToken", ves_icall_ModuleBuilder_getToken},
6936         {"getUSIndex", mono_image_insert_string}
6937 };
6938
6939 static const IcallEntry signaturehelper_icalls [] = {
6940         {"get_signature_field", mono_reflection_sighelper_get_signature_field},
6941         {"get_signature_local", mono_reflection_sighelper_get_signature_local}
6942 };
6943
6944 static const IcallEntry typebuilder_icalls [] = {
6945         {"create_generic_class", mono_reflection_create_generic_class},
6946         {"create_internal_class", mono_reflection_create_internal_class},
6947         {"create_runtime_class", mono_reflection_create_runtime_class},
6948         {"get_IsGenericParameter", ves_icall_TypeBuilder_get_IsGenericParameter},
6949         {"get_event_info", mono_reflection_event_builder_get_event_info},
6950         {"setup_generic_class", mono_reflection_setup_generic_class},
6951         {"setup_internal_class", mono_reflection_setup_internal_class}
6952 };
6953
6954 static const IcallEntry enumbuilder_icalls [] = {
6955         {"setup_enum_type", ves_icall_EnumBuilder_setup_enum_type}
6956 };
6957
6958 static const IcallEntry runtimehelpers_icalls [] = {
6959         {"GetObjectValue", ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue},
6960          /* REMOVEME: no longer needed, just so we dont break things when not needed */
6961         {"GetOffsetToStringData", ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData},
6962         {"InitializeArray", ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray},
6963         {"RunClassConstructor", ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor},
6964         {"get_OffsetToStringData", ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData}
6965 };
6966
6967 static const IcallEntry gchandle_icalls [] = {
6968         {"CheckCurrentDomain", GCHandle_CheckCurrentDomain},
6969         {"FreeHandle", ves_icall_System_GCHandle_FreeHandle},
6970         {"GetAddrOfPinnedObject", ves_icall_System_GCHandle_GetAddrOfPinnedObject},
6971         {"GetTarget", ves_icall_System_GCHandle_GetTarget},
6972         {"GetTargetHandle", ves_icall_System_GCHandle_GetTargetHandle}
6973 };
6974
6975 static const IcallEntry marshal_icalls [] = {
6976         {"AllocCoTaskMem", ves_icall_System_Runtime_InteropServices_Marshal_AllocCoTaskMem},
6977         {"AllocHGlobal", ves_icall_System_Runtime_InteropServices_Marshal_AllocHGlobal},
6978         {"DestroyStructure", ves_icall_System_Runtime_InteropServices_Marshal_DestroyStructure},
6979         {"FreeBSTR", ves_icall_System_Runtime_InteropServices_Marshal_FreeBSTR},
6980         {"FreeCoTaskMem", ves_icall_System_Runtime_InteropServices_Marshal_FreeCoTaskMem},
6981         {"FreeHGlobal", ves_icall_System_Runtime_InteropServices_Marshal_FreeHGlobal},
6982         {"GetDelegateForFunctionPointerInternal", ves_icall_System_Runtime_InteropServices_Marshal_GetDelegateForFunctionPointerInternal},
6983         {"GetFunctionPointerForDelegateInternal", mono_delegate_to_ftnptr},
6984         {"GetLastWin32Error", ves_icall_System_Runtime_InteropServices_Marshal_GetLastWin32Error},
6985         {"OffsetOf", ves_icall_System_Runtime_InteropServices_Marshal_OffsetOf},
6986         {"Prelink", ves_icall_System_Runtime_InteropServices_Marshal_Prelink},
6987         {"PrelinkAll", ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll},
6988         {"PtrToStringAnsi(intptr)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringAnsi},
6989         {"PtrToStringAnsi(intptr,int)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringAnsi_len},
6990         {"PtrToStringAuto(intptr)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringAnsi},
6991         {"PtrToStringAuto(intptr,int)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringAnsi_len},
6992         {"PtrToStringBSTR", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringBSTR},
6993         {"PtrToStringUni(intptr)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringUni},
6994         {"PtrToStringUni(intptr,int)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringUni_len},
6995         {"PtrToStructure(intptr,System.Type)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStructure_type},
6996         {"PtrToStructure(intptr,object)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStructure},
6997         {"ReAllocHGlobal", mono_marshal_realloc},
6998         {"ReadByte", ves_icall_System_Runtime_InteropServices_Marshal_ReadByte},
6999         {"ReadInt16", ves_icall_System_Runtime_InteropServices_Marshal_ReadInt16},
7000         {"ReadInt32", ves_icall_System_Runtime_InteropServices_Marshal_ReadInt32},
7001         {"ReadInt64", ves_icall_System_Runtime_InteropServices_Marshal_ReadInt64},
7002         {"ReadIntPtr", ves_icall_System_Runtime_InteropServices_Marshal_ReadIntPtr},
7003         {"SizeOf", ves_icall_System_Runtime_InteropServices_Marshal_SizeOf},
7004         {"StringToBSTR", ves_icall_System_Runtime_InteropServices_Marshal_StringToBSTR},
7005         {"StringToHGlobalAnsi", ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalAnsi},
7006         {"StringToHGlobalAuto", ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalAnsi},
7007         {"StringToHGlobalUni", ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalUni},
7008         {"StructureToPtr", ves_icall_System_Runtime_InteropServices_Marshal_StructureToPtr},
7009         {"UnsafeAddrOfPinnedArrayElement", ves_icall_System_Runtime_InteropServices_Marshal_UnsafeAddrOfPinnedArrayElement},
7010         {"WriteByte", ves_icall_System_Runtime_InteropServices_Marshal_WriteByte},
7011         {"WriteInt16", ves_icall_System_Runtime_InteropServices_Marshal_WriteInt16},
7012         {"WriteInt32", ves_icall_System_Runtime_InteropServices_Marshal_WriteInt32},
7013         {"WriteInt64", ves_icall_System_Runtime_InteropServices_Marshal_WriteInt64},
7014         {"WriteIntPtr", ves_icall_System_Runtime_InteropServices_Marshal_WriteIntPtr},
7015         {"copy_from_unmanaged", ves_icall_System_Runtime_InteropServices_Marshal_copy_from_unmanaged},
7016         {"copy_to_unmanaged", ves_icall_System_Runtime_InteropServices_Marshal_copy_to_unmanaged}
7017 };
7018
7019 static const IcallEntry activationservices_icalls [] = {
7020         {"AllocateUninitializedClassInstance", ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance},
7021         {"EnableProxyActivation", ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation}
7022 };
7023
7024 static const IcallEntry monomethodmessage_icalls [] = {
7025         {"InitMessage", ves_icall_MonoMethodMessage_InitMessage}
7026 };
7027         
7028 static const IcallEntry realproxy_icalls [] = {
7029         {"InternalGetProxyType", ves_icall_Remoting_RealProxy_InternalGetProxyType},
7030         {"InternalGetTransparentProxy", ves_icall_Remoting_RealProxy_GetTransparentProxy}
7031 };
7032
7033 static const IcallEntry remotingservices_icalls [] = {
7034         {"InternalExecute", ves_icall_InternalExecute},
7035         {"IsTransparentProxy", ves_icall_IsTransparentProxy}
7036 };
7037
7038 static const IcallEntry rng_icalls [] = {
7039         {"RngClose", ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_RngClose},
7040         {"RngGetBytes", ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_RngGetBytes},
7041         {"RngInitialize", ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_RngInitialize},
7042         {"RngOpen", ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_RngOpen}
7043 };
7044
7045 static const IcallEntry methodhandle_icalls [] = {
7046         {"GetFunctionPointer", ves_icall_RuntimeMethod_GetFunctionPointer}
7047 };
7048
7049 static const IcallEntry string_icalls [] = {
7050         {".ctor(char*)", ves_icall_System_String_ctor_charp},
7051         {".ctor(char*,int,int)", ves_icall_System_String_ctor_charp_int_int},
7052         {".ctor(char,int)", ves_icall_System_String_ctor_char_int},
7053         {".ctor(char[])", ves_icall_System_String_ctor_chara},
7054         {".ctor(char[],int,int)", ves_icall_System_String_ctor_chara_int_int},
7055         {".ctor(sbyte*)", ves_icall_System_String_ctor_sbytep},
7056         {".ctor(sbyte*,int,int)", ves_icall_System_String_ctor_sbytep_int_int},
7057         {".ctor(sbyte*,int,int,System.Text.Encoding)", ves_icall_System_String_ctor_encoding},
7058         {"InternalAllocateStr", ves_icall_System_String_InternalAllocateStr},
7059         {"InternalCharCopy", ves_icall_System_String_InternalCharCopy},
7060         {"InternalCopyTo", ves_icall_System_String_InternalCopyTo},
7061         {"InternalIndexOfAny", ves_icall_System_String_InternalIndexOfAny},
7062         {"InternalInsert", ves_icall_System_String_InternalInsert},
7063         {"InternalIntern", ves_icall_System_String_InternalIntern},
7064         {"InternalIsInterned", ves_icall_System_String_InternalIsInterned},
7065         {"InternalJoin", ves_icall_System_String_InternalJoin},
7066         {"InternalLastIndexOfAny", ves_icall_System_String_InternalLastIndexOfAny},
7067         {"InternalPad", ves_icall_System_String_InternalPad},
7068         {"InternalRemove", ves_icall_System_String_InternalRemove},
7069         {"InternalReplace(char,char)", ves_icall_System_String_InternalReplace_Char},
7070         {"InternalReplace(string,string,System.Globalization.CompareInfo)", ves_icall_System_String_InternalReplace_Str_Comp},
7071         {"InternalSplit", ves_icall_System_String_InternalSplit},
7072         {"InternalStrcpy(string,int,char[])", ves_icall_System_String_InternalStrcpy_Chars},
7073         {"InternalStrcpy(string,int,char[],int,int)", ves_icall_System_String_InternalStrcpy_CharsN},
7074         {"InternalStrcpy(string,int,string)", ves_icall_System_String_InternalStrcpy_Str},
7075         {"InternalStrcpy(string,int,string,int,int)", ves_icall_System_String_InternalStrcpy_StrN},
7076         {"InternalTrim", ves_icall_System_String_InternalTrim},
7077         {"get_Chars", ves_icall_System_String_get_Chars}
7078 };
7079
7080 static const IcallEntry encoding_icalls [] = {
7081         {"InternalCodePage", ves_icall_System_Text_Encoding_InternalCodePage}
7082 };
7083
7084 static const IcallEntry monitor_icalls [] = {
7085         {"Monitor_exit", ves_icall_System_Threading_Monitor_Monitor_exit},
7086         {"Monitor_pulse", ves_icall_System_Threading_Monitor_Monitor_pulse},
7087         {"Monitor_pulse_all", ves_icall_System_Threading_Monitor_Monitor_pulse_all},
7088         {"Monitor_test_owner", ves_icall_System_Threading_Monitor_Monitor_test_owner},
7089         {"Monitor_test_synchronised", ves_icall_System_Threading_Monitor_Monitor_test_synchronised},
7090         {"Monitor_try_enter", ves_icall_System_Threading_Monitor_Monitor_try_enter},
7091         {"Monitor_wait", ves_icall_System_Threading_Monitor_Monitor_wait}
7092 };
7093
7094 static const IcallEntry interlocked_icalls [] = {
7095         {"Add(int&,int)", ves_icall_System_Threading_Interlocked_Add_Int},
7096         {"Add(long&,long)", ves_icall_System_Threading_Interlocked_Add_Long},
7097         {"CompareExchange(T&,T,T)", ves_icall_System_Threading_Interlocked_CompareExchange_T},
7098         {"CompareExchange(double&,double,double)", ves_icall_System_Threading_Interlocked_CompareExchange_Double},
7099         {"CompareExchange(int&,int,int)", ves_icall_System_Threading_Interlocked_CompareExchange_Int},
7100         {"CompareExchange(intptr&,intptr,intptr)", ves_icall_System_Threading_Interlocked_CompareExchange_Object},
7101         {"CompareExchange(long&,long,long)", ves_icall_System_Threading_Interlocked_CompareExchange_Long},
7102         {"CompareExchange(object&,object,object)", ves_icall_System_Threading_Interlocked_CompareExchange_Object},
7103         {"CompareExchange(single&,single,single)", ves_icall_System_Threading_Interlocked_CompareExchange_Single},
7104         {"Decrement(int&)", ves_icall_System_Threading_Interlocked_Decrement_Int},
7105         {"Decrement(long&)", ves_icall_System_Threading_Interlocked_Decrement_Long},
7106         {"Exchange(T&,T)", ves_icall_System_Threading_Interlocked_Exchange_T},
7107         {"Exchange(double&,double)", ves_icall_System_Threading_Interlocked_Exchange_Double},
7108         {"Exchange(int&,int)", ves_icall_System_Threading_Interlocked_Exchange_Int},
7109         {"Exchange(intptr&,intptr)", ves_icall_System_Threading_Interlocked_Exchange_Object},
7110         {"Exchange(long&,long)", ves_icall_System_Threading_Interlocked_Exchange_Long},
7111         {"Exchange(object&,object)", ves_icall_System_Threading_Interlocked_Exchange_Object},
7112         {"Exchange(single&,single)", ves_icall_System_Threading_Interlocked_Exchange_Single},
7113         {"Increment(int&)", ves_icall_System_Threading_Interlocked_Increment_Int},
7114         {"Increment(long&)", ves_icall_System_Threading_Interlocked_Increment_Long},
7115         {"Read(long&)", ves_icall_System_Threading_Interlocked_Read_Long}
7116 };
7117
7118 static const IcallEntry mutex_icalls [] = {
7119         {"CreateMutex_internal(bool,string,bool&)", ves_icall_System_Threading_Mutex_CreateMutex_internal},
7120         {"OpenMutex_internal(string,System.Security.AccessControl.MutexRights,System.IO.MonoIOError&)", ves_icall_System_Threading_Mutex_OpenMutex_internal},
7121         {"ReleaseMutex_internal(intptr)", ves_icall_System_Threading_Mutex_ReleaseMutex_internal}
7122 };
7123
7124 static const IcallEntry semaphore_icalls [] = {
7125         {"CreateSemaphore_internal(int,int,string,bool&)", ves_icall_System_Threading_Semaphore_CreateSemaphore_internal},
7126         {"OpenSemaphore_internal(string,System.Security.AccessControl.SemaphoreRights,System.IO.MonoIOError&)", ves_icall_System_Threading_Semaphore_OpenSemaphore_internal},
7127         {"ReleaseSemaphore_internal(intptr,int,bool&)", ves_icall_System_Threading_Semaphore_ReleaseSemaphore_internal}
7128 };
7129
7130 static const IcallEntry nativeevents_icalls [] = {
7131         {"CloseEvent_internal", ves_icall_System_Threading_Events_CloseEvent_internal},
7132         {"CreateEvent_internal(bool,bool,string,bool&)", ves_icall_System_Threading_Events_CreateEvent_internal},
7133         {"OpenEvent_internal(string,System.Security.AccessControl.EventWaitHandleRights,System.IO.MonoIOError&)", ves_icall_System_Threading_Events_OpenEvent_internal},
7134         {"ResetEvent_internal",  ves_icall_System_Threading_Events_ResetEvent_internal},
7135         {"SetEvent_internal",    ves_icall_System_Threading_Events_SetEvent_internal}
7136 };
7137
7138 static const IcallEntry thread_icalls [] = {
7139         {"Abort_internal(object)", ves_icall_System_Threading_Thread_Abort},
7140         {"ClrState", ves_icall_System_Threading_Thread_ClrState},
7141         {"CurrentThread_internal", mono_thread_current},
7142         {"FreeLocalSlotValues", mono_thread_free_local_slot_values},
7143         {"GetCachedCurrentCulture", ves_icall_System_Threading_Thread_GetCachedCurrentCulture},
7144         {"GetCachedCurrentUICulture", ves_icall_System_Threading_Thread_GetCachedCurrentUICulture},
7145         {"GetDomainID", ves_icall_System_Threading_Thread_GetDomainID},
7146         {"GetName_internal", ves_icall_System_Threading_Thread_GetName_internal},
7147         {"GetSerializedCurrentCulture", ves_icall_System_Threading_Thread_GetSerializedCurrentCulture},
7148         {"GetSerializedCurrentUICulture", ves_icall_System_Threading_Thread_GetSerializedCurrentUICulture},
7149         {"GetState", ves_icall_System_Threading_Thread_GetState},
7150         {"Join_internal", ves_icall_System_Threading_Thread_Join_internal},
7151         {"MemoryBarrier", ves_icall_System_Threading_Thread_MemoryBarrier},
7152         {"ResetAbort_internal()", ves_icall_System_Threading_Thread_ResetAbort},
7153         {"Resume_internal()", ves_icall_System_Threading_Thread_Resume},
7154         {"SetCachedCurrentCulture", ves_icall_System_Threading_Thread_SetCachedCurrentCulture},
7155         {"SetCachedCurrentUICulture", ves_icall_System_Threading_Thread_SetCachedCurrentUICulture},
7156         {"SetName_internal", ves_icall_System_Threading_Thread_SetName_internal},
7157         {"SetSerializedCurrentCulture", ves_icall_System_Threading_Thread_SetSerializedCurrentCulture},
7158         {"SetSerializedCurrentUICulture", ves_icall_System_Threading_Thread_SetSerializedCurrentUICulture},
7159         {"SetState", ves_icall_System_Threading_Thread_SetState},
7160         {"Sleep_internal", ves_icall_System_Threading_Thread_Sleep_internal},
7161         {"Suspend_internal", ves_icall_System_Threading_Thread_Suspend},
7162         {"Thread_free_internal", ves_icall_System_Threading_Thread_Thread_free_internal},
7163         {"Thread_internal", ves_icall_System_Threading_Thread_Thread_internal},
7164         {"VolatileRead(byte&)", ves_icall_System_Threading_Thread_VolatileRead1},
7165         {"VolatileRead(double&)", ves_icall_System_Threading_Thread_VolatileRead8},
7166         {"VolatileRead(int&)", ves_icall_System_Threading_Thread_VolatileRead4},
7167         {"VolatileRead(int16&)", ves_icall_System_Threading_Thread_VolatileRead2},
7168         {"VolatileRead(intptr&)", ves_icall_System_Threading_Thread_VolatileReadIntPtr},
7169         {"VolatileRead(long&)", ves_icall_System_Threading_Thread_VolatileRead8},
7170         {"VolatileRead(object&)", ves_icall_System_Threading_Thread_VolatileReadIntPtr},
7171         {"VolatileRead(sbyte&)", ves_icall_System_Threading_Thread_VolatileRead1},
7172         {"VolatileRead(single&)", ves_icall_System_Threading_Thread_VolatileRead4},
7173         {"VolatileRead(uint&)", ves_icall_System_Threading_Thread_VolatileRead2},
7174         {"VolatileRead(uint16&)", ves_icall_System_Threading_Thread_VolatileRead2},
7175         {"VolatileRead(uintptr&)", ves_icall_System_Threading_Thread_VolatileReadIntPtr},
7176         {"VolatileRead(ulong&)", ves_icall_System_Threading_Thread_VolatileRead8},
7177         {"VolatileWrite(byte&,byte)", ves_icall_System_Threading_Thread_VolatileWrite1},
7178         {"VolatileWrite(double&,double)", ves_icall_System_Threading_Thread_VolatileWrite8},
7179         {"VolatileWrite(int&,int)", ves_icall_System_Threading_Thread_VolatileWrite4},
7180         {"VolatileWrite(int16&,int16)", ves_icall_System_Threading_Thread_VolatileWrite2},
7181         {"VolatileWrite(intptr&,intptr)", ves_icall_System_Threading_Thread_VolatileWriteIntPtr},
7182         {"VolatileWrite(long&,long)", ves_icall_System_Threading_Thread_VolatileWrite8},
7183         {"VolatileWrite(object&,object)", ves_icall_System_Threading_Thread_VolatileWriteIntPtr},
7184         {"VolatileWrite(sbyte&,sbyte)", ves_icall_System_Threading_Thread_VolatileWrite1},
7185         {"VolatileWrite(single&,single)", ves_icall_System_Threading_Thread_VolatileWrite4},
7186         {"VolatileWrite(uint&,uint)", ves_icall_System_Threading_Thread_VolatileWrite2},
7187         {"VolatileWrite(uint16&,uint16)", ves_icall_System_Threading_Thread_VolatileWrite2},
7188         {"VolatileWrite(uintptr&,uintptr)", ves_icall_System_Threading_Thread_VolatileWriteIntPtr},
7189         {"VolatileWrite(ulong&,ulong)", ves_icall_System_Threading_Thread_VolatileWrite8},
7190         {"current_lcid()", ves_icall_System_Threading_Thread_current_lcid}
7191 };
7192
7193 static const IcallEntry threadpool_icalls [] = {
7194         {"GetAvailableThreads", ves_icall_System_Threading_ThreadPool_GetAvailableThreads},
7195         {"GetMaxThreads", ves_icall_System_Threading_ThreadPool_GetMaxThreads},
7196         {"GetMinThreads", ves_icall_System_Threading_ThreadPool_GetMinThreads},
7197         {"SetMinThreads", ves_icall_System_Threading_ThreadPool_SetMinThreads}
7198 };
7199
7200 static const IcallEntry waithandle_icalls [] = {
7201         {"WaitAll_internal", ves_icall_System_Threading_WaitHandle_WaitAll_internal},
7202         {"WaitAny_internal", ves_icall_System_Threading_WaitHandle_WaitAny_internal},
7203         {"WaitOne_internal", ves_icall_System_Threading_WaitHandle_WaitOne_internal}
7204 };
7205
7206 static const IcallEntry type_icalls [] = {
7207         {"Equals", ves_icall_type_Equals},
7208         {"GetGenericParameterAttributes", ves_icall_Type_GetGenericParameterAttributes},
7209         {"GetGenericParameterConstraints_impl", ves_icall_Type_GetGenericParameterConstraints},
7210         {"GetGenericParameterPosition", ves_icall_Type_GetGenericParameterPosition},
7211         {"GetGenericTypeDefinition_impl", ves_icall_Type_GetGenericTypeDefinition_impl},
7212         {"GetInterfaceMapData", ves_icall_Type_GetInterfaceMapData},
7213         {"GetPacking", ves_icall_Type_GetPacking},
7214         {"GetTypeCode", ves_icall_type_GetTypeCodeInternal},
7215         {"GetTypeCodeInternal", ves_icall_type_GetTypeCodeInternal},
7216         {"IsArrayImpl", ves_icall_Type_IsArrayImpl},
7217         {"IsInstanceOfType", ves_icall_type_IsInstanceOfType},
7218         {"MakeGenericType", ves_icall_Type_MakeGenericType},
7219         {"MakePointerType", ves_icall_Type_MakePointerType},
7220         {"get_IsGenericInstance", ves_icall_Type_get_IsGenericInstance},
7221         {"get_IsGenericType", ves_icall_Type_get_IsGenericType},
7222         {"get_IsGenericTypeDefinition", ves_icall_Type_get_IsGenericTypeDefinition},
7223         {"internal_from_handle", ves_icall_type_from_handle},
7224         {"internal_from_name", ves_icall_type_from_name},
7225         {"make_array_type", ves_icall_Type_make_array_type},
7226         {"make_byref_type", ves_icall_Type_make_byref_type},
7227         {"type_is_assignable_from", ves_icall_type_is_assignable_from},
7228         {"type_is_subtype_of", ves_icall_type_is_subtype_of}
7229 };
7230
7231 static const IcallEntry typedref_icalls [] = {
7232         {"ToObject",    mono_TypedReference_ToObject},
7233         {"ToObjectInternal",    mono_TypedReference_ToObjectInternal}
7234 };
7235
7236 static const IcallEntry valuetype_icalls [] = {
7237         {"InternalEquals", ves_icall_System_ValueType_Equals},
7238         {"InternalGetHashCode", ves_icall_System_ValueType_InternalGetHashCode}
7239 };
7240
7241 static const IcallEntry web_icalls [] = {
7242         {"GetMachineConfigPath", ves_icall_System_Configuration_DefaultConfig_get_machine_config_path},
7243         {"GetMachineInstallDirectory", ves_icall_System_Web_Util_ICalls_get_machine_install_dir}
7244 };
7245
7246 static const IcallEntry identity_icalls [] = {
7247         {"GetCurrentToken", ves_icall_System_Security_Principal_WindowsIdentity_GetCurrentToken},
7248         {"GetTokenName", ves_icall_System_Security_Principal_WindowsIdentity_GetTokenName},
7249         {"GetUserToken", ves_icall_System_Security_Principal_WindowsIdentity_GetUserToken},
7250         {"_GetRoles", ves_icall_System_Security_Principal_WindowsIdentity_GetRoles}
7251 };
7252
7253 static const IcallEntry impersonation_icalls [] = {
7254         {"CloseToken", ves_icall_System_Security_Principal_WindowsImpersonationContext_CloseToken},
7255         {"DuplicateToken", ves_icall_System_Security_Principal_WindowsImpersonationContext_DuplicateToken},
7256         {"RevertToSelf", ves_icall_System_Security_Principal_WindowsImpersonationContext_RevertToSelf},
7257         {"SetCurrentToken", ves_icall_System_Security_Principal_WindowsImpersonationContext_SetCurrentToken}
7258 };
7259
7260 static const IcallEntry principal_icalls [] = {
7261         {"IsMemberOfGroupId", ves_icall_System_Security_Principal_WindowsPrincipal_IsMemberOfGroupId},
7262         {"IsMemberOfGroupName", ves_icall_System_Security_Principal_WindowsPrincipal_IsMemberOfGroupName}
7263 };
7264
7265 static const IcallEntry keypair_icalls [] = {
7266         {"_CanSecure", ves_icall_Mono_Security_Cryptography_KeyPairPersistence_CanSecure},
7267         {"_IsMachineProtected", ves_icall_Mono_Security_Cryptography_KeyPairPersistence_IsMachineProtected},
7268         {"_IsUserProtected", ves_icall_Mono_Security_Cryptography_KeyPairPersistence_IsUserProtected},
7269         {"_ProtectMachine", ves_icall_Mono_Security_Cryptography_KeyPairPersistence_ProtectMachine},
7270         {"_ProtectUser", ves_icall_Mono_Security_Cryptography_KeyPairPersistence_ProtectUser}
7271 };
7272
7273 static const IcallEntry evidence_icalls [] = {
7274         {"IsAuthenticodePresent", ves_icall_System_Security_Policy_Evidence_IsAuthenticodePresent}
7275 };
7276
7277 static const IcallEntry securitymanager_icalls [] = {
7278         {"GetLinkDemandSecurity", ves_icall_System_Security_SecurityManager_GetLinkDemandSecurity},
7279         {"get_CheckExecutionRights", ves_icall_System_Security_SecurityManager_get_CheckExecutionRights},
7280         {"get_SecurityEnabled", ves_icall_System_Security_SecurityManager_get_SecurityEnabled},
7281         {"set_CheckExecutionRights", ves_icall_System_Security_SecurityManager_set_CheckExecutionRights},
7282         {"set_SecurityEnabled", ves_icall_System_Security_SecurityManager_set_SecurityEnabled}
7283 };
7284
7285 static const IcallEntry generic_array_icalls [] = {
7286         {"GetGenericValueImpl", ves_icall_System_Array_InternalArray_GetGenericValueImpl}
7287 };
7288
7289 /* proto
7290 static const IcallEntry array_icalls [] = {
7291 };
7292
7293 */
7294
7295 /* keep the entries all sorted */
7296 static const IcallMap icall_entries [] = {
7297         {"Mono.Runtime", runtime_icalls, G_N_ELEMENTS (runtime_icalls)},
7298         {"Mono.Security.Cryptography.KeyPairPersistence", keypair_icalls, G_N_ELEMENTS (keypair_icalls)},
7299         {"System.Activator", activator_icalls, G_N_ELEMENTS (activator_icalls)},
7300         {"System.AppDomain", appdomain_icalls, G_N_ELEMENTS (appdomain_icalls)},
7301         {"System.ArgIterator", argiterator_icalls, G_N_ELEMENTS (argiterator_icalls)},
7302         {"System.Array", array_icalls, G_N_ELEMENTS (array_icalls)},
7303         {"System.Array/InternalArray`1", generic_array_icalls, G_N_ELEMENTS (generic_array_icalls)},
7304         {"System.Buffer", buffer_icalls, G_N_ELEMENTS (buffer_icalls)},
7305         {"System.Char", char_icalls, G_N_ELEMENTS (char_icalls)},
7306         {"System.Configuration.DefaultConfig", defaultconf_icalls, G_N_ELEMENTS (defaultconf_icalls)},
7307         {"System.ConsoleDriver", consoledriver_icalls, G_N_ELEMENTS (consoledriver_icalls)},
7308         {"System.Convert", convert_icalls, G_N_ELEMENTS (convert_icalls)},
7309         {"System.CurrentSystemTimeZone", timezone_icalls, G_N_ELEMENTS (timezone_icalls)},
7310         {"System.DateTime", datetime_icalls, G_N_ELEMENTS (datetime_icalls)},
7311 #ifndef DISABLE_DECIMAL
7312         {"System.Decimal", decimal_icalls, G_N_ELEMENTS (decimal_icalls)},
7313 #endif  
7314         {"System.Delegate", delegate_icalls, G_N_ELEMENTS (delegate_icalls)},
7315         {"System.Diagnostics.DefaultTraceListener", tracelist_icalls, G_N_ELEMENTS (tracelist_icalls)},
7316         {"System.Diagnostics.FileVersionInfo", fileversion_icalls, G_N_ELEMENTS (fileversion_icalls)},
7317         {"System.Diagnostics.Process", process_icalls, G_N_ELEMENTS (process_icalls)},
7318         {"System.Double", double_icalls, G_N_ELEMENTS (double_icalls)},
7319         {"System.Enum", enum_icalls, G_N_ELEMENTS (enum_icalls)},
7320         {"System.Environment", environment_icalls, G_N_ELEMENTS (environment_icalls)},
7321         {"System.GC", gc_icalls, G_N_ELEMENTS (gc_icalls)},
7322         {"System.Globalization.CompareInfo", compareinfo_icalls, G_N_ELEMENTS (compareinfo_icalls)},
7323         {"System.Globalization.CultureInfo", cultureinfo_icalls, G_N_ELEMENTS (cultureinfo_icalls)},
7324         {"System.Globalization.RegionInfo", regioninfo_icalls, G_N_ELEMENTS (regioninfo_icalls)},
7325         {"System.IO.FAMWatcher", famwatcher_icalls, G_N_ELEMENTS (famwatcher_icalls)},
7326         {"System.IO.FileSystemWatcher", filewatcher_icalls, G_N_ELEMENTS (filewatcher_icalls)},
7327         {"System.IO.MonoIO", monoio_icalls, G_N_ELEMENTS (monoio_icalls)},
7328         {"System.IO.Path", path_icalls, G_N_ELEMENTS (path_icalls)},
7329         {"System.Math", math_icalls, G_N_ELEMENTS (math_icalls)},
7330         {"System.MonoCustomAttrs", customattrs_icalls, G_N_ELEMENTS (customattrs_icalls)},
7331         {"System.MonoEnumInfo", enuminfo_icalls, G_N_ELEMENTS (enuminfo_icalls)},
7332         {"System.MonoType", monotype_icalls, G_N_ELEMENTS (monotype_icalls)},
7333         {"System.Net.Dns", dns_icalls, G_N_ELEMENTS (dns_icalls)},
7334         {"System.Net.Sockets.Socket", socket_icalls, G_N_ELEMENTS (socket_icalls)},
7335         {"System.Net.Sockets.SocketException", socketex_icalls, G_N_ELEMENTS (socketex_icalls)},
7336         {"System.Object", object_icalls, G_N_ELEMENTS (object_icalls)},
7337         {"System.Reflection.Assembly", assembly_icalls, G_N_ELEMENTS (assembly_icalls)},
7338         {"System.Reflection.AssemblyName", assembly_name_icalls, G_N_ELEMENTS (assembly_name_icalls)},
7339         {"System.Reflection.Emit.AssemblyBuilder", assemblybuilder_icalls, G_N_ELEMENTS (assemblybuilder_icalls)},
7340         {"System.Reflection.Emit.CustomAttributeBuilder", customattrbuilder_icalls, G_N_ELEMENTS (customattrbuilder_icalls)},
7341         {"System.Reflection.Emit.DynamicMethod", dynamicmethod_icalls, G_N_ELEMENTS (dynamicmethod_icalls)},
7342         {"System.Reflection.Emit.EnumBuilder", enumbuilder_icalls, G_N_ELEMENTS (enumbuilder_icalls)},
7343         {"System.Reflection.Emit.GenericTypeParameterBuilder", generictypeparambuilder_icalls, G_N_ELEMENTS (generictypeparambuilder_icalls)},
7344         {"System.Reflection.Emit.MethodBuilder", methodbuilder_icalls, G_N_ELEMENTS (methodbuilder_icalls)},
7345         {"System.Reflection.Emit.ModuleBuilder", modulebuilder_icalls, G_N_ELEMENTS (modulebuilder_icalls)},
7346         {"System.Reflection.Emit.SignatureHelper", signaturehelper_icalls, G_N_ELEMENTS (signaturehelper_icalls)},
7347         {"System.Reflection.Emit.TypeBuilder", typebuilder_icalls, G_N_ELEMENTS (typebuilder_icalls)},
7348         {"System.Reflection.FieldInfo", fieldinfo_icalls, G_N_ELEMENTS (fieldinfo_icalls)},
7349         {"System.Reflection.MemberInfo", memberinfo_icalls, G_N_ELEMENTS (memberinfo_icalls)},
7350         {"System.Reflection.MethodBase", methodbase_icalls, G_N_ELEMENTS (methodbase_icalls)},
7351         {"System.Reflection.Module", module_icalls, G_N_ELEMENTS (module_icalls)},
7352         {"System.Reflection.MonoCMethod", monocmethod_icalls, G_N_ELEMENTS (monocmethod_icalls)},
7353         {"System.Reflection.MonoEventInfo", monoeventinfo_icalls, G_N_ELEMENTS (monoeventinfo_icalls)},
7354         {"System.Reflection.MonoField", monofield_icalls, G_N_ELEMENTS (monofield_icalls)},
7355         {"System.Reflection.MonoGenericCMethod", monogenericmethod_icalls, G_N_ELEMENTS (monogenericmethod_icalls)},
7356         {"System.Reflection.MonoGenericClass", monogenericclass_icalls, G_N_ELEMENTS (monogenericclass_icalls)},
7357         {"System.Reflection.MonoGenericMethod", monogenericmethod_icalls, G_N_ELEMENTS (monogenericmethod_icalls)},
7358         {"System.Reflection.MonoMethod", monomethod_icalls, G_N_ELEMENTS (monomethod_icalls)},
7359         {"System.Reflection.MonoMethodInfo", monomethodinfo_icalls, G_N_ELEMENTS (monomethodinfo_icalls)},
7360         {"System.Reflection.MonoPropertyInfo", monopropertyinfo_icalls, G_N_ELEMENTS (monopropertyinfo_icalls)},
7361         {"System.Reflection.ParameterInfo", parameterinfo_icalls, G_N_ELEMENTS (parameterinfo_icalls)},
7362         {"System.Runtime.CompilerServices.RuntimeHelpers", runtimehelpers_icalls, G_N_ELEMENTS (runtimehelpers_icalls)},
7363         {"System.Runtime.InteropServices.GCHandle", gchandle_icalls, G_N_ELEMENTS (gchandle_icalls)},
7364         {"System.Runtime.InteropServices.Marshal", marshal_icalls, G_N_ELEMENTS (marshal_icalls)},
7365         {"System.Runtime.Remoting.Activation.ActivationServices", activationservices_icalls, G_N_ELEMENTS (activationservices_icalls)},
7366         {"System.Runtime.Remoting.Messaging.MonoMethodMessage", monomethodmessage_icalls, G_N_ELEMENTS (monomethodmessage_icalls)},
7367         {"System.Runtime.Remoting.Proxies.RealProxy", realproxy_icalls, G_N_ELEMENTS (realproxy_icalls)},
7368         {"System.Runtime.Remoting.RemotingServices", remotingservices_icalls, G_N_ELEMENTS (remotingservices_icalls)},
7369         {"System.RuntimeMethodHandle", methodhandle_icalls, G_N_ELEMENTS (methodhandle_icalls)},
7370         {"System.Security.Cryptography.RNGCryptoServiceProvider", rng_icalls, G_N_ELEMENTS (rng_icalls)},
7371         {"System.Security.Policy.Evidence", evidence_icalls, G_N_ELEMENTS (evidence_icalls)},
7372         {"System.Security.Principal.WindowsIdentity", identity_icalls, G_N_ELEMENTS (identity_icalls)},
7373         {"System.Security.Principal.WindowsImpersonationContext", impersonation_icalls, G_N_ELEMENTS (impersonation_icalls)},
7374         {"System.Security.Principal.WindowsPrincipal", principal_icalls, G_N_ELEMENTS (principal_icalls)},
7375         {"System.Security.SecurityManager", securitymanager_icalls, G_N_ELEMENTS (securitymanager_icalls)},
7376         {"System.String", string_icalls, G_N_ELEMENTS (string_icalls)},
7377         {"System.Text.Encoding", encoding_icalls, G_N_ELEMENTS (encoding_icalls)},
7378         {"System.Threading.Interlocked", interlocked_icalls, G_N_ELEMENTS (interlocked_icalls)},
7379         {"System.Threading.Monitor", monitor_icalls, G_N_ELEMENTS (monitor_icalls)},
7380         {"System.Threading.Mutex", mutex_icalls, G_N_ELEMENTS (mutex_icalls)},
7381         {"System.Threading.NativeEventCalls", nativeevents_icalls, G_N_ELEMENTS (nativeevents_icalls)},
7382         {"System.Threading.Semaphore", semaphore_icalls, G_N_ELEMENTS (semaphore_icalls)},
7383         {"System.Threading.Thread", thread_icalls, G_N_ELEMENTS (thread_icalls)},
7384         {"System.Threading.ThreadPool", threadpool_icalls, G_N_ELEMENTS (threadpool_icalls)},
7385         {"System.Threading.WaitHandle", waithandle_icalls, G_N_ELEMENTS (waithandle_icalls)},
7386         {"System.Type", type_icalls, G_N_ELEMENTS (type_icalls)},
7387         {"System.TypedReference", typedref_icalls, G_N_ELEMENTS (typedref_icalls)},
7388         {"System.ValueType", valuetype_icalls, G_N_ELEMENTS (valuetype_icalls)},
7389         {"System.Web.Util.ICalls", web_icalls, G_N_ELEMENTS (web_icalls)}
7390 };
7391
7392 static GHashTable *icall_hash = NULL;
7393 static GHashTable *jit_icall_hash_name = NULL;
7394 static GHashTable *jit_icall_hash_addr = NULL;
7395
7396 void
7397 mono_icall_init (void)
7398 {
7399         int i = 0;
7400
7401         /* check that tables are sorted: disable in release */
7402         if (TRUE) {
7403                 int j;
7404                 const IcallMap *imap;
7405                 const IcallEntry *ientry;
7406                 const char *prev_class = NULL;
7407                 const char *prev_method;
7408                 
7409                 for (i = 0; i < G_N_ELEMENTS (icall_entries); ++i) {
7410                         imap = &icall_entries [i];
7411                         prev_method = NULL;
7412                         if (prev_class && strcmp (prev_class, imap->klass) >= 0)
7413                                 g_print ("class %s should come before class %s\n", imap->klass, prev_class);
7414                         prev_class = imap->klass;
7415                         for (j = 0; j < imap->size; ++j) {
7416                                 ientry = &imap->icalls [j];
7417                                 if (prev_method && strcmp (prev_method, ientry->method) >= 0)
7418                                         g_print ("method %s should come before method %s\n", ientry->method, prev_method);
7419                                 prev_method = ientry->method;
7420                         }
7421                 }
7422         }
7423
7424         icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
7425 }
7426
7427 void
7428 mono_icall_cleanup (void)
7429 {
7430         g_hash_table_destroy (icall_hash);
7431         g_hash_table_destroy (jit_icall_hash_name);
7432         g_hash_table_destroy (jit_icall_hash_addr);
7433 }
7434
7435 void
7436 mono_add_internal_call (const char *name, gconstpointer method)
7437 {
7438         mono_loader_lock ();
7439
7440         g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
7441
7442         mono_loader_unlock ();
7443 }
7444
7445 static int
7446 compare_class_imap (const void *key, const void *elem)
7447 {
7448         const IcallMap* imap = (const IcallMap*)elem;
7449         return strcmp (key, imap->klass);
7450 }
7451
7452 static const IcallMap*
7453 find_class_icalls (const char *name)
7454 {
7455         return (const IcallMap*) bsearch (name, icall_entries, G_N_ELEMENTS (icall_entries), sizeof (IcallMap), compare_class_imap);
7456 }
7457
7458 static int
7459 compare_method_imap (const void *key, const void *elem)
7460 {
7461         const IcallEntry* ientry = (const IcallEntry*)elem;
7462         return strcmp (key, ientry->method);
7463 }
7464
7465 static void*
7466 find_method_icall (const IcallMap *imap, const char *name)
7467 {
7468         const IcallEntry *ientry = (const IcallEntry*) bsearch (name, imap->icalls, imap->size, sizeof (IcallEntry), compare_method_imap);
7469         if (ientry)
7470                 return (void*)ientry->func;
7471         return NULL;
7472 }
7473
7474 /* 
7475  * we should probably export this as an helper (handle nested types).
7476  * Returns the number of chars written in buf.
7477  */
7478 static int
7479 concat_class_name (char *buf, int bufsize, MonoClass *klass)
7480 {
7481         int nspacelen, cnamelen;
7482         nspacelen = strlen (klass->name_space);
7483         cnamelen = strlen (klass->name);
7484         if (nspacelen + cnamelen + 2 > bufsize)
7485                 return 0;
7486         if (nspacelen) {
7487                 memcpy (buf, klass->name_space, nspacelen);
7488                 buf [nspacelen ++] = '.';
7489         }
7490         memcpy (buf + nspacelen, klass->name, cnamelen);
7491         buf [nspacelen + cnamelen] = 0;
7492         return nspacelen + cnamelen;
7493 }
7494
7495 gpointer
7496 mono_lookup_internal_call (MonoMethod *method)
7497 {
7498         char *sigstart;
7499         char *tmpsig;
7500         char mname [2048];
7501         int typelen = 0, mlen, siglen;
7502         gpointer res;
7503         const IcallMap *imap;
7504
7505         g_assert (method != NULL);
7506
7507         if (method->is_inflated)
7508                 method = ((MonoMethodInflated *) method)->declaring;
7509
7510         if (method->klass->nested_in) {
7511                 int pos = concat_class_name (mname, sizeof (mname)-2, method->klass->nested_in);
7512                 if (!pos)
7513                         return NULL;
7514
7515                 mname [pos++] = '/';
7516                 mname [pos] = 0;
7517
7518                 typelen = concat_class_name (mname+pos, sizeof (mname)-pos-1, method->klass);
7519                 if (!typelen)
7520                         return NULL;
7521
7522                 typelen += pos;
7523         } else {
7524                 typelen = concat_class_name (mname, sizeof (mname), method->klass);
7525                 if (!typelen)
7526                         return NULL;
7527         }
7528
7529         imap = find_class_icalls (mname);
7530
7531         mname [typelen] = ':';
7532         mname [typelen + 1] = ':';
7533
7534         mlen = strlen (method->name);
7535         memcpy (mname + typelen + 2, method->name, mlen);
7536         sigstart = mname + typelen + 2 + mlen;
7537         *sigstart = 0;
7538
7539         tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
7540         siglen = strlen (tmpsig);
7541         if (typelen + mlen + siglen + 6 > sizeof (mname))
7542                 return NULL;
7543         sigstart [0] = '(';
7544         memcpy (sigstart + 1, tmpsig, siglen);
7545         sigstart [siglen + 1] = ')';
7546         sigstart [siglen + 2] = 0;
7547         g_free (tmpsig);
7548         
7549         mono_loader_lock ();
7550
7551         res = g_hash_table_lookup (icall_hash, mname);
7552         if (res) {
7553                 mono_loader_unlock ();
7554                 return res;
7555         }
7556         /* try without signature */
7557         *sigstart = 0;
7558         res = g_hash_table_lookup (icall_hash, mname);
7559         if (res) {
7560                 mono_loader_unlock ();
7561                 return res;
7562         }
7563
7564         /* it wasn't found in the static call tables */
7565         if (!imap) {
7566                 mono_loader_unlock ();
7567                 return NULL;
7568         }
7569         res = find_method_icall (imap, sigstart - mlen);
7570         if (res) {
7571                 mono_loader_unlock ();
7572                 return res;
7573         }
7574         /* try _with_ signature */
7575         *sigstart = '(';
7576         res = find_method_icall (imap, sigstart - mlen);
7577         if (res) {
7578                 mono_loader_unlock ();
7579                 return res;
7580         }
7581         
7582         g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname);
7583         g_print ("\nYour mono runtime and class libraries are out of sync.\n");
7584         g_print ("The out of sync library is: %s\n", method->klass->image->name);
7585         g_print ("\nWhen you update one from cvs you need to update, compile and install\nthe other too.\n");
7586         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");
7587         g_print ("If you see other errors or faults after this message they are probably related\n");
7588         g_print ("and you need to fix your mono install first.\n");
7589
7590         mono_loader_unlock ();
7591
7592         return NULL;
7593 }
7594
7595 static MonoType*
7596 type_from_typename (char *typename)
7597 {
7598         MonoClass *klass = NULL;        /* assignment to shut GCC warning up */
7599
7600         if (!strcmp (typename, "int"))
7601                 klass = mono_defaults.int_class;
7602         else if (!strcmp (typename, "ptr"))
7603                 klass = mono_defaults.int_class;
7604         else if (!strcmp (typename, "void"))
7605                 klass = mono_defaults.void_class;
7606         else if (!strcmp (typename, "int32"))
7607                 klass = mono_defaults.int32_class;
7608         else if (!strcmp (typename, "uint32"))
7609                 klass = mono_defaults.uint32_class;
7610         else if (!strcmp (typename, "long"))
7611                 klass = mono_defaults.int64_class;
7612         else if (!strcmp (typename, "ulong"))
7613                 klass = mono_defaults.uint64_class;
7614         else if (!strcmp (typename, "float"))
7615                 klass = mono_defaults.single_class;
7616         else if (!strcmp (typename, "double"))
7617                 klass = mono_defaults.double_class;
7618         else if (!strcmp (typename, "object"))
7619                 klass = mono_defaults.object_class;
7620         else if (!strcmp (typename, "obj"))
7621                 klass = mono_defaults.object_class;
7622         else {
7623                 g_error (typename);
7624                 g_assert_not_reached ();
7625         }
7626         return &klass->byval_arg;
7627 }
7628
7629 MonoMethodSignature*
7630 mono_create_icall_signature (const char *sigstr)
7631 {
7632         gchar **parts;
7633         int i, len;
7634         gchar **tmp;
7635         MonoMethodSignature *res;
7636
7637         mono_loader_lock ();
7638         res = g_hash_table_lookup (mono_defaults.corlib->helper_signatures, sigstr);
7639         if (res) {
7640                 mono_loader_unlock ();
7641                 return res;
7642         }
7643
7644         parts = g_strsplit (sigstr, " ", 256);
7645
7646         tmp = parts;
7647         len = 0;
7648         while (*tmp) {
7649                 len ++;
7650                 tmp ++;
7651         }
7652
7653         res = mono_metadata_signature_alloc (mono_defaults.corlib, len - 1);
7654         res->pinvoke = 1;
7655
7656 #ifdef PLATFORM_WIN32
7657         /* 
7658          * Under windows, the default pinvoke calling convention is STDCALL but
7659          * we need CDECL.
7660          */
7661         res->call_convention = MONO_CALL_C;
7662 #endif
7663
7664         res->ret = type_from_typename (parts [0]);
7665         for (i = 1; i < len; ++i) {
7666                 res->params [i - 1] = type_from_typename (parts [i]);
7667         }
7668
7669         g_strfreev (parts);
7670
7671         g_hash_table_insert (mono_defaults.corlib->helper_signatures, (gpointer)sigstr, res);
7672
7673         mono_loader_unlock ();
7674
7675         return res;
7676 }
7677
7678 MonoJitICallInfo *
7679 mono_find_jit_icall_by_name (const char *name)
7680 {
7681         MonoJitICallInfo *info;
7682         g_assert (jit_icall_hash_name);
7683
7684         mono_loader_lock ();
7685         info = g_hash_table_lookup (jit_icall_hash_name, name);
7686         mono_loader_unlock ();
7687         return info;
7688 }
7689
7690 MonoJitICallInfo *
7691 mono_find_jit_icall_by_addr (gconstpointer addr)
7692 {
7693         MonoJitICallInfo *info;
7694         g_assert (jit_icall_hash_addr);
7695
7696         mono_loader_lock ();
7697         info = g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
7698         mono_loader_unlock ();
7699
7700         return info;
7701 }
7702
7703 void
7704 mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
7705 {
7706         mono_loader_lock ();
7707         g_hash_table_insert (jit_icall_hash_addr, (gpointer)wrapper, info);
7708         mono_loader_unlock ();
7709 }
7710
7711 MonoJitICallInfo *
7712 mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
7713 {
7714         MonoJitICallInfo *info;
7715         
7716         g_assert (func);
7717         g_assert (name);
7718
7719         mono_loader_lock ();
7720
7721         if (!jit_icall_hash_name) {
7722                 jit_icall_hash_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
7723                 jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
7724         }
7725
7726         if (g_hash_table_lookup (jit_icall_hash_name, name)) {
7727                 g_warning ("jit icall already defined \"%s\"\n", name);
7728                 g_assert_not_reached ();
7729         }
7730
7731         info = g_new0 (MonoJitICallInfo, 1);
7732         
7733         info->name = name;
7734         info->func = func;
7735         info->sig = sig;
7736
7737         if (is_save) {
7738                 info->wrapper = func;
7739         } else {
7740                 info->wrapper = NULL;
7741         }
7742
7743         g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
7744         g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
7745
7746         mono_loader_unlock ();
7747         return info;
7748 }