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