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