2004-04-07 Martin Baulig <martin@ximian.com>
[mono.git] / mono / metadata / icall.c
1 /*
2  * icall.c:
3  *
4  * Authors:
5  *   Dietmar Maurer (dietmar@ximian.com)
6  *   Paolo Molaro (lupus@ximian.com)
7  *       Patrik Torstensson (patrik.torstensson@labs2.com)
8  *
9  * (C) 2001 Ximian, Inc.
10  */
11
12 #include <config.h>
13 #include <glib.h>
14 #include <stdarg.h>
15 #include <string.h>
16 #include <sys/time.h>
17 #include <unistd.h>
18 #if defined (PLATFORM_WIN32)
19 #include <stdlib.h>
20 #endif
21
22 #include <mono/metadata/object.h>
23 #include <mono/metadata/threads.h>
24 #include <mono/metadata/threadpool.h>
25 #include <mono/metadata/monitor.h>
26 #include <mono/metadata/reflection.h>
27 #include <mono/metadata/assembly.h>
28 #include <mono/metadata/tabledefs.h>
29 #include <mono/metadata/exception.h>
30 #include <mono/metadata/file-io.h>
31 #include <mono/metadata/socket-io.h>
32 #include <mono/metadata/mono-endian.h>
33 #include <mono/metadata/tokentype.h>
34 #include <mono/metadata/unicode.h>
35 #include <mono/metadata/appdomain.h>
36 #include <mono/metadata/marshal.h>
37 #include <mono/metadata/gc-internal.h>
38 #include <mono/metadata/rand.h>
39 #include <mono/metadata/sysmath.h>
40 #include <mono/metadata/string-icalls.h>
41 #include <mono/metadata/mono-debug-debugger.h>
42 #include <mono/metadata/process.h>
43 #include <mono/metadata/environment.h>
44 #include <mono/metadata/profiler-private.h>
45 #include <mono/metadata/locales.h>
46 #include <mono/metadata/filewatcher.h>
47 #include <mono/metadata/char-conversions.h>
48 #include <mono/metadata/security.h>
49 #include <mono/io-layer/io-layer.h>
50 #include <mono/utils/strtod.h>
51 #include <mono/utils/monobitset.h>
52
53 #if defined (PLATFORM_WIN32)
54 #include <windows.h>
55 #endif
56 #include "decimal.h"
57
58 static MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void);
59
60
61 /*
62  * We expect a pointer to a char, not a string
63  */
64 static double
65 mono_double_ParseImpl (char *ptr)
66 {
67         gchar *endptr = NULL;
68         gdouble result = 0.0;
69
70         MONO_ARCH_SAVE_REGS;
71
72         if (*ptr)
73                 result = bsd_strtod (ptr, &endptr);
74
75         if (!*ptr || (endptr && *endptr))
76                 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib,
77                                                                 "System",
78                                                                 "FormatException"));
79         
80         return result;
81 }
82
83 static void
84 ves_icall_System_Double_AssertEndianity (double *value)
85 {
86         MONO_ARCH_SAVE_REGS;
87
88         MONO_DOUBLE_ASSERT_ENDIANITY (value);
89 }
90
91 static MonoObject *
92 ves_icall_System_Array_GetValueImpl (MonoObject *this, guint32 pos)
93 {
94         MonoClass *ac;
95         MonoArray *ao;
96         gint32 esize;
97         gpointer *ea;
98
99         MONO_ARCH_SAVE_REGS;
100
101         ao = (MonoArray *)this;
102         ac = (MonoClass *)ao->obj.vtable->klass;
103
104         esize = mono_array_element_size (ac);
105         ea = (gpointer*)((char*)ao->vector + (pos * esize));
106
107         if (ac->element_class->valuetype)
108                 return mono_value_box (this->vtable->domain, ac->element_class, ea);
109         else
110                 return *ea;
111 }
112
113 static MonoObject *
114 ves_icall_System_Array_GetValue (MonoObject *this, MonoObject *idxs)
115 {
116         MonoClass *ac, *ic;
117         MonoArray *ao, *io;
118         gint32 i, pos, *ind;
119
120         MONO_ARCH_SAVE_REGS;
121
122         MONO_CHECK_ARG_NULL (idxs);
123
124         io = (MonoArray *)idxs;
125         ic = (MonoClass *)io->obj.vtable->klass;
126         
127         ao = (MonoArray *)this;
128         ac = (MonoClass *)ao->obj.vtable->klass;
129
130         g_assert (ic->rank == 1);
131         if (io->bounds != NULL || io->max_length !=  ac->rank)
132                 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
133
134         ind = (guint32 *)io->vector;
135
136         if (ao->bounds == NULL) {
137                 if (*ind < 0 || *ind >= ao->max_length)
138                         mono_raise_exception (mono_get_exception_index_out_of_range ());
139
140                 return ves_icall_System_Array_GetValueImpl (this, *ind);
141         }
142         
143         for (i = 0; i < ac->rank; i++)
144                 if ((ind [i] < ao->bounds [i].lower_bound) ||
145                     (ind [i] >= ao->bounds [i].length + ao->bounds [i].lower_bound))
146                         mono_raise_exception (mono_get_exception_index_out_of_range ());
147
148         pos = ind [0] - ao->bounds [0].lower_bound;
149         for (i = 1; i < ac->rank; i++)
150                 pos = pos*ao->bounds [i].length + ind [i] - 
151                         ao->bounds [i].lower_bound;
152
153         return ves_icall_System_Array_GetValueImpl (this, pos);
154 }
155
156 static void
157 ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32 pos)
158 {
159         MonoClass *ac, *vc, *ec;
160         gint32 esize, vsize;
161         gpointer *ea, *va;
162
163         guint64 u64 = 0;
164         gint64 i64 = 0;
165         gdouble r64 = 0;
166
167         MONO_ARCH_SAVE_REGS;
168
169         if (value)
170                 vc = value->vtable->klass;
171         else
172                 vc = NULL;
173
174         ac = this->obj.vtable->klass;
175         ec = ac->element_class;
176
177         esize = mono_array_element_size (ac);
178         ea = (gpointer*)((char*)this->vector + (pos * esize));
179         va = (gpointer*)((char*)value + sizeof (MonoObject));
180
181         if (!value) {
182                 memset (ea, 0,  esize);
183                 return;
184         }
185
186 #define NO_WIDENING_CONVERSION G_STMT_START{\
187         mono_raise_exception (mono_get_exception_argument ( \
188                 "value", "not a widening conversion")); \
189 }G_STMT_END
190
191 #define CHECK_WIDENING_CONVERSION(extra) G_STMT_START{\
192         if (esize < vsize + (extra)) \
193                 mono_raise_exception (mono_get_exception_argument ( \
194                         "value", "not a widening conversion")); \
195 }G_STMT_END
196
197 #define INVALID_CAST G_STMT_START{\
198         mono_raise_exception (mono_get_exception_invalid_cast ()); \
199 }G_STMT_END
200
201         /* Check element (destination) type. */
202         switch (ec->byval_arg.type) {
203         case MONO_TYPE_STRING:
204                 switch (vc->byval_arg.type) {
205                 case MONO_TYPE_STRING:
206                         break;
207                 default:
208                         INVALID_CAST;
209                 }
210                 break;
211         case MONO_TYPE_BOOLEAN:
212                 switch (vc->byval_arg.type) {
213                 case MONO_TYPE_BOOLEAN:
214                         break;
215                 case MONO_TYPE_CHAR:
216                 case MONO_TYPE_U1:
217                 case MONO_TYPE_U2:
218                 case MONO_TYPE_U4:
219                 case MONO_TYPE_U8:
220                 case MONO_TYPE_I1:
221                 case MONO_TYPE_I2:
222                 case MONO_TYPE_I4:
223                 case MONO_TYPE_I8:
224                 case MONO_TYPE_R4:
225                 case MONO_TYPE_R8:
226                         NO_WIDENING_CONVERSION;
227                 default:
228                         INVALID_CAST;
229                 }
230                 break;
231         }
232
233         if (!ec->valuetype) {
234                 if (!mono_object_isinst (value, ec))
235                         INVALID_CAST;
236                 *ea = (gpointer)value;
237                 return;
238         }
239
240         if (mono_object_isinst (value, ec)) {
241                 memcpy (ea, (char *)value + sizeof (MonoObject), esize);
242                 return;
243         }
244
245         if (!vc->valuetype)
246                 INVALID_CAST;
247
248         vsize = mono_class_instance_size (vc) - sizeof (MonoObject);
249
250 #if 0
251         g_message (G_STRLOC ": %d (%d) <= %d (%d)",
252                    ec->byval_arg.type, esize,
253                    vc->byval_arg.type, vsize);
254 #endif
255
256 #define ASSIGN_UNSIGNED(etype) G_STMT_START{\
257         switch (vc->byval_arg.type) { \
258         case MONO_TYPE_U1: \
259         case MONO_TYPE_U2: \
260         case MONO_TYPE_U4: \
261         case MONO_TYPE_U8: \
262         case MONO_TYPE_CHAR: \
263                 CHECK_WIDENING_CONVERSION(0); \
264                 *(etype *) ea = (etype) u64; \
265                 return; \
266         /* You can't assign a signed value to an unsigned array. */ \
267         case MONO_TYPE_I1: \
268         case MONO_TYPE_I2: \
269         case MONO_TYPE_I4: \
270         case MONO_TYPE_I8: \
271         /* You can't assign a floating point number to an integer array. */ \
272         case MONO_TYPE_R4: \
273         case MONO_TYPE_R8: \
274                 NO_WIDENING_CONVERSION; \
275         } \
276 }G_STMT_END
277
278 #define ASSIGN_SIGNED(etype) G_STMT_START{\
279         switch (vc->byval_arg.type) { \
280         case MONO_TYPE_I1: \
281         case MONO_TYPE_I2: \
282         case MONO_TYPE_I4: \
283         case MONO_TYPE_I8: \
284                 CHECK_WIDENING_CONVERSION(0); \
285                 *(etype *) ea = (etype) i64; \
286                 return; \
287         /* You can assign an unsigned value to a signed array if the array's */ \
288         /* element size is larger than the value size. */ \
289         case MONO_TYPE_U1: \
290         case MONO_TYPE_U2: \
291         case MONO_TYPE_U4: \
292         case MONO_TYPE_U8: \
293         case MONO_TYPE_CHAR: \
294                 CHECK_WIDENING_CONVERSION(1); \
295                 *(etype *) ea = (etype) u64; \
296                 return; \
297         /* You can't assign a floating point number to an integer array. */ \
298         case MONO_TYPE_R4: \
299         case MONO_TYPE_R8: \
300                 NO_WIDENING_CONVERSION; \
301         } \
302 }G_STMT_END
303
304 #define ASSIGN_REAL(etype) G_STMT_START{\
305         switch (vc->byval_arg.type) { \
306         case MONO_TYPE_R4: \
307         case MONO_TYPE_R8: \
308                 CHECK_WIDENING_CONVERSION(0); \
309                 *(etype *) ea = (etype) r64; \
310                 return; \
311         /* All integer values fit into a floating point array, so we don't */ \
312         /* need to CHECK_WIDENING_CONVERSION here. */ \
313         case MONO_TYPE_I1: \
314         case MONO_TYPE_I2: \
315         case MONO_TYPE_I4: \
316         case MONO_TYPE_I8: \
317                 *(etype *) ea = (etype) i64; \
318                 return; \
319         case MONO_TYPE_U1: \
320         case MONO_TYPE_U2: \
321         case MONO_TYPE_U4: \
322         case MONO_TYPE_U8: \
323         case MONO_TYPE_CHAR: \
324                 *(etype *) ea = (etype) u64; \
325                 return; \
326         } \
327 }G_STMT_END
328
329         switch (vc->byval_arg.type) {
330         case MONO_TYPE_U1:
331                 u64 = *(guint8 *) va;
332                 break;
333         case MONO_TYPE_U2:
334                 u64 = *(guint16 *) va;
335                 break;
336         case MONO_TYPE_U4:
337                 u64 = *(guint32 *) va;
338                 break;
339         case MONO_TYPE_U8:
340                 u64 = *(guint64 *) va;
341                 break;
342         case MONO_TYPE_I1:
343                 i64 = *(gint8 *) va;
344                 break;
345         case MONO_TYPE_I2:
346                 i64 = *(gint16 *) va;
347                 break;
348         case MONO_TYPE_I4:
349                 i64 = *(gint32 *) va;
350                 break;
351         case MONO_TYPE_I8:
352                 i64 = *(gint64 *) va;
353                 break;
354         case MONO_TYPE_R4:
355                 r64 = *(gfloat *) va;
356                 break;
357         case MONO_TYPE_R8:
358                 r64 = *(gdouble *) va;
359                 break;
360         case MONO_TYPE_CHAR:
361                 u64 = *(guint16 *) va;
362                 break;
363         case MONO_TYPE_BOOLEAN:
364                 /* Boolean is only compatible with itself. */
365                 switch (ec->byval_arg.type) {
366                 case MONO_TYPE_CHAR:
367                 case MONO_TYPE_U1:
368                 case MONO_TYPE_U2:
369                 case MONO_TYPE_U4:
370                 case MONO_TYPE_U8:
371                 case MONO_TYPE_I1:
372                 case MONO_TYPE_I2:
373                 case MONO_TYPE_I4:
374                 case MONO_TYPE_I8:
375                 case MONO_TYPE_R4:
376                 case MONO_TYPE_R8:
377                         NO_WIDENING_CONVERSION;
378                 default:
379                         INVALID_CAST;
380                 }
381                 break;
382         }
383
384         /* If we can't do a direct copy, let's try a widening conversion. */
385         switch (ec->byval_arg.type) {
386         case MONO_TYPE_CHAR:
387                 ASSIGN_UNSIGNED (guint16);
388         case MONO_TYPE_U1:
389                 ASSIGN_UNSIGNED (guint8);
390         case MONO_TYPE_U2:
391                 ASSIGN_UNSIGNED (guint16);
392         case MONO_TYPE_U4:
393                 ASSIGN_UNSIGNED (guint32);
394         case MONO_TYPE_U8:
395                 ASSIGN_UNSIGNED (guint64);
396         case MONO_TYPE_I1:
397                 ASSIGN_SIGNED (gint8);
398         case MONO_TYPE_I2:
399                 ASSIGN_SIGNED (gint16);
400         case MONO_TYPE_I4:
401                 ASSIGN_SIGNED (gint32);
402         case MONO_TYPE_I8:
403                 ASSIGN_SIGNED (gint64);
404         case MONO_TYPE_R4:
405                 ASSIGN_REAL (gfloat);
406         case MONO_TYPE_R8:
407                 ASSIGN_REAL (gdouble);
408         }
409
410         INVALID_CAST;
411         /* Not reached, INVALID_CAST does not return. Just to avoid a compiler warning ... */
412         return;
413
414 #undef INVALID_CAST
415 #undef NO_WIDENING_CONVERSION
416 #undef CHECK_WIDENING_CONVERSION
417 #undef ASSIGN_UNSIGNED
418 #undef ASSIGN_SIGNED
419 #undef ASSIGN_REAL
420 }
421
422 static void 
423 ves_icall_System_Array_SetValue (MonoArray *this, MonoObject *value,
424                                  MonoArray *idxs)
425 {
426         MonoClass *ac, *ic;
427         gint32 i, pos, *ind;
428
429         MONO_ARCH_SAVE_REGS;
430
431         MONO_CHECK_ARG_NULL (idxs);
432
433         ic = idxs->obj.vtable->klass;
434         ac = this->obj.vtable->klass;
435
436         g_assert (ic->rank == 1);
437         if (idxs->bounds != NULL || idxs->max_length != ac->rank)
438                 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
439
440         ind = (guint32 *)idxs->vector;
441
442         if (this->bounds == NULL) {
443                 if (*ind < 0 || *ind >= this->max_length)
444                         mono_raise_exception (mono_get_exception_index_out_of_range ());
445
446                 ves_icall_System_Array_SetValueImpl (this, value, *ind);
447                 return;
448         }
449         
450         for (i = 0; i < ac->rank; i++)
451                 if ((ind [i] < this->bounds [i].lower_bound) ||
452                     (ind [i] >= this->bounds [i].length + this->bounds [i].lower_bound))
453                         mono_raise_exception (mono_get_exception_index_out_of_range ());
454
455         pos = ind [0] - this->bounds [0].lower_bound;
456         for (i = 1; i < ac->rank; i++)
457                 pos = pos * this->bounds [i].length + ind [i] - 
458                         this->bounds [i].lower_bound;
459
460         ves_icall_System_Array_SetValueImpl (this, value, pos);
461 }
462
463 static MonoArray *
464 ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
465 {
466         MonoClass *aklass;
467         MonoArray *array;
468         gint32 *sizes, i;
469         gboolean bounded = FALSE;
470
471         MONO_ARCH_SAVE_REGS;
472
473         MONO_CHECK_ARG_NULL (type);
474         MONO_CHECK_ARG_NULL (lengths);
475
476         MONO_CHECK_ARG (lengths, mono_array_length (lengths) > 0);
477         if (bounds)
478                 MONO_CHECK_ARG (bounds, mono_array_length (lengths) == mono_array_length (bounds));
479
480         for (i = 0; i < mono_array_length (lengths); i++)
481                 if (mono_array_get (lengths, gint32, i) < 0)
482                         mono_raise_exception (mono_get_exception_argument_out_of_range (NULL));
483
484         if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint32, 0) != 0))
485                 /* vectors are not the same as one dimensional arrays with no-zero bounds */
486                 bounded = TRUE;
487         else
488                 bounded = FALSE;
489
490         aklass = mono_bounded_array_class_get (mono_class_from_mono_type (type->type), mono_array_length (lengths), bounded);
491
492         sizes = alloca (aklass->rank * sizeof(guint32) * 2);
493         for (i = 0; i < aklass->rank; ++i) {
494                 sizes [i] = mono_array_get (lengths, gint32, i);
495                 if (bounds)
496                         sizes [i + aklass->rank] = mono_array_get (bounds, gint32, i);
497                 else
498                         sizes [i + aklass->rank] = 0;
499         }
500
501         array = mono_array_new_full (mono_object_domain (type), aklass, sizes, sizes + aklass->rank);
502
503         return array;
504 }
505
506 static gint32 
507 ves_icall_System_Array_GetRank (MonoObject *this)
508 {
509         MONO_ARCH_SAVE_REGS;
510
511         return this->vtable->klass->rank;
512 }
513
514 static gint32
515 ves_icall_System_Array_GetLength (MonoArray *this, gint32 dimension)
516 {
517         gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
518
519         MONO_ARCH_SAVE_REGS;
520
521         if ((dimension < 0) || (dimension >= rank))
522                 mono_raise_exception (mono_get_exception_index_out_of_range ());
523         
524         if (this->bounds == NULL)
525                 return this->max_length;
526         
527         return this->bounds [dimension].length;
528 }
529
530 static gint32
531 ves_icall_System_Array_GetLowerBound (MonoArray *this, gint32 dimension)
532 {
533         gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
534
535         MONO_ARCH_SAVE_REGS;
536
537         if ((dimension < 0) || (dimension >= rank))
538                 mono_raise_exception (mono_get_exception_index_out_of_range ());
539         
540         if (this->bounds == NULL)
541                 return 0;
542         
543         return this->bounds [dimension].lower_bound;
544 }
545
546 static gboolean
547 ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* dest, int dest_idx, int length)
548 {
549         int element_size;
550         void * dest_addr;
551         void * source_addr;
552         MonoClass *src_class;
553         MonoClass *dest_class;
554         int i;
555
556         MONO_ARCH_SAVE_REGS;
557
558         if (source->obj.vtable->klass->rank != dest->obj.vtable->klass->rank)
559                 return FALSE;
560
561         if (source->bounds || dest->bounds)
562                 return FALSE;
563
564         if ((dest_idx + length > mono_array_length (dest)) ||
565                 (source_idx + length > mono_array_length (source)))
566                 return FALSE;
567
568         element_size = mono_array_element_size (source->obj.vtable->klass);
569         dest_addr = mono_array_addr_with_size (dest, element_size, dest_idx);
570         source_addr = mono_array_addr_with_size (source, element_size, source_idx);
571
572         src_class = source->obj.vtable->klass->element_class;
573         dest_class = dest->obj.vtable->klass->element_class;
574
575         /*
576          * Handle common cases.
577          */
578
579         /* Case1: object[] -> valuetype[] (ArrayList::ToArray) */
580         if (src_class == mono_defaults.object_class && dest_class->valuetype) {
581                 for (i = source_idx; i < source_idx + length; ++i) {
582                         MonoObject *elem = mono_array_get (source, MonoObject*, i);
583                         if (elem && !mono_object_isinst (elem, dest_class))
584                                 return FALSE;
585                 }
586
587                 element_size = mono_array_element_size (dest->obj.vtable->klass);
588                 for (i = 0; i < length; ++i) {
589                         MonoObject *elem = mono_array_get (source, MonoObject*, source_idx + i);
590                         void *addr = mono_array_addr_with_size (dest, element_size, dest_idx + i);
591                         if (!elem)
592                                 memset (addr, 0, element_size);
593                         else
594                                 memcpy (addr, (char *)elem + sizeof (MonoObject), element_size);
595                 }
596                 return TRUE;
597         }
598
599         if (src_class != dest_class) {
600                 if (dest_class->valuetype || dest_class->enumtype || src_class->valuetype || src_class->enumtype)
601                         return FALSE;
602
603                 if (mono_class_is_subclass_of (src_class, dest_class, FALSE))
604                         ;
605                 /* Case2: object[] -> reftype[] (ArrayList::ToArray) */
606                 else if (mono_class_is_subclass_of (dest_class, src_class, FALSE))
607                         for (i = source_idx; i < source_idx + length; ++i) {
608                                 MonoObject *elem = mono_array_get (source, MonoObject*, i);
609                                 if (elem && !mono_object_isinst (elem, dest_class))
610                                         return FALSE;
611                         }
612                 else
613                         return FALSE;
614         }
615
616         memmove (dest_addr, source_addr, element_size * length);
617
618         return TRUE;
619 }
620
621 static void
622 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoArray *array, MonoClassField *field_handle)
623 {
624         MonoClass *klass = array->obj.vtable->klass;
625         guint32 size = mono_array_element_size (klass);
626         int i;
627
628         MONO_ARCH_SAVE_REGS;
629
630         if (array->bounds == NULL)
631                 size *= array->max_length;
632         else
633                 for (i = 0; i < klass->rank; ++i) 
634                         size *= array->bounds [i].length;
635
636         memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
637
638 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
639 #define SWAP(n) {\
640         gint i; \
641         guint ## n tmp; \
642         guint ## n *data = (guint ## n *) mono_array_addr (array, char, 0); \
643 \
644         for (i = 0; i < size; i += n/8, data++) { \
645                 tmp = read ## n (data); \
646                 *data = tmp; \
647         } \
648 }
649
650         /* printf ("Initialize array with elements of %s type\n", klass->element_class->name); */
651
652         switch (klass->element_class->byval_arg.type) {
653         case MONO_TYPE_CHAR:
654         case MONO_TYPE_I2:
655         case MONO_TYPE_U2:
656                 SWAP (16);
657                 break;
658         case MONO_TYPE_I4:
659         case MONO_TYPE_U4:
660                 SWAP (32);
661                 break;
662         case MONO_TYPE_I8:
663         case MONO_TYPE_U8:
664                 SWAP (64);
665                 break;
666         }
667                  
668 #endif
669 }
670
671 static gint
672 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData (void)
673 {
674         MONO_ARCH_SAVE_REGS;
675
676         return offsetof (MonoString, chars);
677 }
678
679 static MonoObject *
680 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue (MonoObject *obj)
681 {
682         MONO_ARCH_SAVE_REGS;
683
684         if ((obj == NULL) || (! (obj->vtable->klass->valuetype)))
685                 return obj;
686         else
687                 return mono_object_clone (obj);
688 }
689
690 static void
691 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (MonoType *handle)
692 {
693         MonoClass *klass;
694
695         MONO_ARCH_SAVE_REGS;
696
697         MONO_CHECK_ARG_NULL (handle);
698
699         klass = mono_class_from_mono_type (handle);
700         MONO_CHECK_ARG (handle, klass);
701
702         /* This will call the type constructor */
703         if (! (klass->flags & TYPE_ATTRIBUTE_INTERFACE))
704                 mono_runtime_class_init (mono_class_vtable (mono_domain_get (), klass));
705 }
706
707 static MonoObject *
708 ves_icall_System_Object_MemberwiseClone (MonoObject *this)
709 {
710         MONO_ARCH_SAVE_REGS;
711
712         return mono_object_clone (this);
713 }
714
715 #if HAVE_BOEHM_GC
716 #define MONO_OBJECT_ALIGNMENT_SHIFT     3
717 #else
718 #define MONO_OBJECT_ALIGNMENT_SHIFT     2
719 #endif
720
721 /*
722  * Return hashcode based on object address. This function will need to be
723  * smarter in the presence of a moving garbage collector, which will cache
724  * the address hash before relocating the object.
725  *
726  * Wang's address-based hash function:
727  *   http://www.concentric.net/~Ttwang/tech/addrhash.htm
728  */
729 static gint32
730 ves_icall_System_Object_GetHashCode (MonoObject *this)
731 {
732         register guint32 key;
733
734         MONO_ARCH_SAVE_REGS;
735
736         key = (GPOINTER_TO_UINT (this) >> MONO_OBJECT_ALIGNMENT_SHIFT) * 2654435761u;
737
738         return key & 0x7fffffff;
739 }
740
741 static gint32
742 ves_icall_System_ValueType_InternalGetHashCode (MonoObject *this, MonoArray **fields)
743 {
744         int i;
745         MonoClass *klass;
746         MonoObject **values = NULL;
747         MonoObject *o;
748         int count = 0;
749         gint32 result = 0;
750
751         MONO_ARCH_SAVE_REGS;
752
753         klass = this->vtable->klass;
754
755         if (klass->field.count == 0)
756                 return ves_icall_System_Object_GetHashCode (this);
757
758         /*
759          * Compute the starting value of the hashcode for fields of primitive
760          * types, and return the remaining fields in an array to the managed side.
761          * This way, we can avoid costly reflection operations in managed code.
762          */
763         for (i = 0; i < klass->field.count; ++i) {
764                 MonoClassField *field = &klass->fields [i];
765                 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
766                         continue;
767                 if (mono_field_is_deleted (field))
768                         continue;
769                 /* FIXME: Add more types */
770                 switch (field->type->type) {
771                 case MONO_TYPE_I4:
772                         result ^= *(gint32*)((guint8*)this + field->offset);
773                         break;
774                 case MONO_TYPE_STRING: {
775                         MonoString *s;
776                         s = *(MonoString**)((guint8*)this + field->offset);
777                         if (s != NULL)
778                                 result ^= ves_icall_System_String_GetHashCode (s);
779                         break;
780                 }
781                 default:
782                         if (!values)
783                                 values = alloca (klass->field.count * sizeof (MonoObject*));
784                         o = mono_field_get_value_object (mono_object_domain (this), field, this);
785                         values [count++] = o;
786                 }
787         }
788
789         if (values) {
790                 *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
791                 memcpy (mono_array_addr (*fields, MonoObject*, 0), values, count * sizeof (MonoObject*));
792         }
793         else
794                 *fields = NULL;
795         return result;
796 }
797
798 static MonoBoolean
799 ves_icall_System_ValueType_Equals (MonoObject *this, MonoObject *that, MonoArray **fields)
800 {
801         int i;
802         MonoClass *klass;
803         MonoObject **values = NULL;
804         MonoObject *o;
805         int count = 0;
806
807         MONO_ARCH_SAVE_REGS;
808
809         MONO_CHECK_ARG_NULL (that);
810
811         if (this->vtable != that->vtable)
812                 return FALSE;
813
814         klass = this->vtable->klass;
815
816         /*
817          * Do the comparison for fields of primitive type and return a result if
818          * possible. Otherwise, return the remaining fields in an array to the 
819          * managed side. This way, we can avoid costly reflection operations in 
820          * managed code.
821          */
822         *fields = NULL;
823         for (i = 0; i < klass->field.count; ++i) {
824                 MonoClassField *field = &klass->fields [i];
825                 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
826                         continue;
827                 if (mono_field_is_deleted (field))
828                         continue;
829                 /* FIXME: Add more types */
830                 switch (field->type->type) {
831                 case MONO_TYPE_I4:
832                         if (*(gint32*)((guint8*)this + field->offset) != *(gint32*)((guint8*)that + field->offset))
833                                 return FALSE;
834                         break;
835                 case MONO_TYPE_STRING: {
836                         MonoString *s1, *s2;
837                         guint32 s1len, s2len;
838                         s1 = *(MonoString**)((guint8*)this + field->offset);
839                         s2 = *(MonoString**)((guint8*)that + field->offset);
840                         if (s1 == s2)
841                                 break;
842                         if ((s1 == NULL) || (s2 == NULL))
843                                 return FALSE;
844                         s1len = mono_string_length (s1);
845                         s2len = mono_string_length (s2);
846                         if (s1len != s2len)
847                                 return FALSE;
848
849                         if (memcmp (mono_string_chars (s1), mono_string_chars (s2), s1len * sizeof (gunichar2)) != 0)
850                                 return FALSE;
851                         break;
852                 }
853                 default:
854                         if (!values)
855                                 values = alloca (klass->field.count * 2 * sizeof (MonoObject*));
856                         o = mono_field_get_value_object (mono_object_domain (this), field, this);
857                         values [count++] = o;
858                         o = mono_field_get_value_object (mono_object_domain (this), field, that);
859                         values [count++] = o;
860                 }
861         }
862
863         if (values) {
864                 *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
865                 memcpy (mono_array_addr (*fields, MonoObject*, 0), values, count * sizeof (MonoObject*));
866
867                 return FALSE;
868         }
869         else
870                 return TRUE;
871 }
872
873 static MonoReflectionType *
874 ves_icall_System_Object_GetType (MonoObject *obj)
875 {
876         MONO_ARCH_SAVE_REGS;
877
878         if (obj->vtable->klass != mono_defaults.transparent_proxy_class)
879                 return mono_type_get_object (mono_object_domain (obj), &obj->vtable->klass->byval_arg);
880         else
881                 return mono_type_get_object (mono_object_domain (obj), &((MonoTransparentProxy*)obj)->remote_class->proxy_class->byval_arg);
882 }
883
884 static void
885 mono_type_type_from_obj (MonoReflectionType *mtype, MonoObject *obj)
886 {
887         MONO_ARCH_SAVE_REGS;
888
889         mtype->type = &obj->vtable->klass->byval_arg;
890         g_assert (mtype->type->type);
891 }
892
893 static gint32
894 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj)
895 {
896         MONO_ARCH_SAVE_REGS;
897
898         return mono_image_create_token (mb->dynamic_image, obj);
899 }
900
901 static gint32
902 ves_icall_ModuleBuilder_getDataChunk (MonoReflectionModuleBuilder *mb, MonoArray *buf, gint32 offset)
903 {
904         int count;
905         MonoDynamicImage *image = mb->dynamic_image;
906         char *p = mono_array_addr (buf, char, 0);
907
908         MONO_ARCH_SAVE_REGS;
909
910         mono_image_create_pefile (mb);
911
912         if (offset >= image->pefile.index)
913                 return 0;
914         count = mono_array_length (buf);
915         count = MIN (count, image->pefile.index - offset);
916         
917         memcpy (p, image->pefile.data + offset, count);
918
919         return count;
920 }
921
922 static void
923 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
924 {
925         MONO_ARCH_SAVE_REGS;
926
927         mono_image_build_metadata (mb);
928 }
929
930 static MonoReflectionType*
931 ves_icall_type_from_name (MonoString *name,
932                           MonoBoolean throwOnError,
933                           MonoBoolean ignoreCase)
934 {
935         gchar *str;
936         MonoType *type = NULL;
937         MonoAssembly *assembly;
938         MonoTypeNameParse info;
939
940         MONO_ARCH_SAVE_REGS;
941
942         str = mono_string_to_utf8 (name);
943         if (!mono_reflection_parse_type (str, &info)) {
944                 g_free (str);
945                 g_list_free (info.modifiers);
946                 g_list_free (info.nested);
947                 if (throwOnError) /* uhm: this is a parse error, though... */
948                         mono_raise_exception (mono_get_exception_type_load (name));
949
950                 return NULL;
951         }
952
953         if (info.assembly.name) {
954                 assembly = mono_assembly_load (&info.assembly, NULL, NULL);
955         } else {
956                 MonoReflectionAssembly *refass;
957
958                 refass = ves_icall_System_Reflection_Assembly_GetCallingAssembly  ();
959                 assembly = refass->assembly;
960         }
961
962         if (assembly)
963                 type = mono_reflection_get_type (assembly->image, &info, ignoreCase);
964         
965         if (!info.assembly.name && !type) /* try mscorlib */
966                 type = mono_reflection_get_type (NULL, &info, ignoreCase);
967
968         g_free (str);
969         g_list_free (info.modifiers);
970         g_list_free (info.nested);
971         if (!type) {
972                 if (throwOnError)
973                         mono_raise_exception (mono_get_exception_type_load (name));
974
975                 return NULL;
976         }
977
978         return mono_type_get_object (mono_domain_get (), type);
979 }
980
981 static MonoReflectionType*
982 ves_icall_type_from_handle (MonoType *handle)
983 {
984         MonoDomain *domain = mono_domain_get (); 
985         MonoClass *klass = mono_class_from_mono_type (handle);
986
987         MONO_ARCH_SAVE_REGS;
988
989         mono_class_init (klass);
990         return mono_type_get_object (domain, handle);
991 }
992
993 static guint32
994 ves_icall_type_Equals (MonoReflectionType *type, MonoReflectionType *c)
995 {
996         MONO_ARCH_SAVE_REGS;
997
998         if (type->type && c->type)
999                 return mono_metadata_type_equal (type->type, c->type);
1000         g_print ("type equals\n");
1001         return 0;
1002 }
1003
1004 /* System.TypeCode */
1005 typedef enum {
1006         TYPECODE_EMPTY,
1007         TYPECODE_OBJECT,
1008         TYPECODE_DBNULL,
1009         TYPECODE_BOOLEAN,
1010         TYPECODE_CHAR,
1011         TYPECODE_SBYTE,
1012         TYPECODE_BYTE,
1013         TYPECODE_INT16,
1014         TYPECODE_UINT16,
1015         TYPECODE_INT32,
1016         TYPECODE_UINT32,
1017         TYPECODE_INT64,
1018         TYPECODE_UINT64,
1019         TYPECODE_SINGLE,
1020         TYPECODE_DOUBLE,
1021         TYPECODE_DECIMAL,
1022         TYPECODE_DATETIME,
1023         TYPECODE_STRING = 18
1024 } TypeCode;
1025
1026 static guint32
1027 ves_icall_type_GetTypeCode (MonoReflectionType *type)
1028 {
1029         int t = type->type->type;
1030
1031         MONO_ARCH_SAVE_REGS;
1032
1033 handle_enum:
1034         switch (t) {
1035         case MONO_TYPE_VOID:
1036                 return TYPECODE_OBJECT;
1037         case MONO_TYPE_BOOLEAN:
1038                 return TYPECODE_BOOLEAN;
1039         case MONO_TYPE_U1:
1040                 return TYPECODE_BYTE;
1041         case MONO_TYPE_I1:
1042                 return TYPECODE_SBYTE;
1043         case MONO_TYPE_U2:
1044                 return TYPECODE_UINT16;
1045         case MONO_TYPE_I2:
1046                 return TYPECODE_INT16;
1047         case MONO_TYPE_CHAR:
1048                 return TYPECODE_CHAR;
1049         case MONO_TYPE_PTR:
1050         case MONO_TYPE_U:
1051         case MONO_TYPE_I:
1052                 return TYPECODE_OBJECT;
1053         case MONO_TYPE_U4:
1054                 return TYPECODE_UINT32;
1055         case MONO_TYPE_I4:
1056                 return TYPECODE_INT32;
1057         case MONO_TYPE_U8:
1058                 return TYPECODE_UINT64;
1059         case MONO_TYPE_I8:
1060                 return TYPECODE_INT64;
1061         case MONO_TYPE_R4:
1062                 return TYPECODE_SINGLE;
1063         case MONO_TYPE_R8:
1064                 return TYPECODE_DOUBLE;
1065         case MONO_TYPE_VALUETYPE:
1066                 if (type->type->data.klass->enumtype) {
1067                         t = type->type->data.klass->enum_basetype->type;
1068                         goto handle_enum;
1069                 } else {
1070                         MonoClass *k =  type->type->data.klass;
1071                         if (strcmp (k->name_space, "System") == 0) {
1072                                 if (strcmp (k->name, "Decimal") == 0)
1073                                         return TYPECODE_DECIMAL;
1074                                 else if (strcmp (k->name, "DateTime") == 0)
1075                                         return TYPECODE_DATETIME;
1076                         }
1077                 }
1078                 return TYPECODE_OBJECT;
1079         case MONO_TYPE_STRING:
1080                 return TYPECODE_STRING;
1081         case MONO_TYPE_SZARRAY:
1082         case MONO_TYPE_ARRAY:
1083         case MONO_TYPE_OBJECT:
1084         case MONO_TYPE_VAR:
1085         case MONO_TYPE_MVAR:
1086                 return TYPECODE_OBJECT;
1087         case MONO_TYPE_CLASS:
1088                 {
1089                         MonoClass *k =  type->type->data.klass;
1090                         if (strcmp (k->name_space, "System") == 0) {
1091                                 if (strcmp (k->name, "DBNull") == 0)
1092                                         return TYPECODE_DBNULL;
1093                         }
1094                 }
1095                 return TYPECODE_OBJECT;
1096         case MONO_TYPE_GENERICINST:
1097                 return TYPECODE_OBJECT;
1098         default:
1099                 g_error ("type 0x%02x not handled in GetTypeCode()", t);
1100         }
1101         return 0;
1102 }
1103
1104 static guint32
1105 ves_icall_type_is_subtype_of (MonoReflectionType *type, MonoReflectionType *c, MonoBoolean check_interfaces)
1106 {
1107         MonoDomain *domain; 
1108         MonoClass *klass;
1109         MonoClass *klassc;
1110
1111         MONO_ARCH_SAVE_REGS;
1112
1113         g_assert (type != NULL);
1114         
1115         domain = ((MonoObject *)type)->vtable->domain;
1116
1117         if (!c) /* FIXME: dont know what do do here */
1118                 return 0;
1119
1120         klass = mono_class_from_mono_type (type->type);
1121         klassc = mono_class_from_mono_type (c->type);
1122
1123         return mono_class_is_subclass_of (klass, klassc, check_interfaces);
1124 }
1125
1126 static guint32
1127 ves_icall_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType *c)
1128 {
1129         MonoDomain *domain; 
1130         MonoClass *klass;
1131         MonoClass *klassc;
1132
1133         MONO_ARCH_SAVE_REGS;
1134
1135         g_assert (type != NULL);
1136         
1137         domain = ((MonoObject *)type)->vtable->domain;
1138
1139         klass = mono_class_from_mono_type (type->type);
1140         klassc = mono_class_from_mono_type (c->type);
1141
1142         return mono_class_is_assignable_from (klass, klassc);
1143 }
1144
1145 static guint32
1146 ves_icall_type_IsInstanceOfType (MonoReflectionType *type, MonoObject *obj)
1147 {
1148         MonoClass *klass = mono_class_from_mono_type (type->type);
1149         return mono_object_isinst (obj, klass) != NULL;
1150 }
1151
1152 static guint32
1153 ves_icall_get_attributes (MonoReflectionType *type)
1154 {
1155         MonoClass *klass = mono_class_from_mono_type (type->type);
1156
1157         MONO_ARCH_SAVE_REGS;
1158
1159         return klass->flags;
1160 }
1161
1162 static MonoReflectionField*
1163 ves_icall_System_Reflection_FieldInfo_internal_from_handle (MonoClassField *handle)
1164 {
1165         MONO_ARCH_SAVE_REGS;
1166
1167         g_assert (handle);
1168
1169         return mono_field_get_object (mono_domain_get (), handle->parent, handle);
1170 }
1171
1172 static void
1173 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
1174 {
1175         MonoDomain *domain = mono_domain_get ();
1176
1177         MONO_ARCH_SAVE_REGS;
1178
1179         info->parent = mono_type_get_object (domain, &method->klass->byval_arg);
1180         info->ret = mono_type_get_object (domain, method->signature->ret);
1181         info->attrs = method->flags;
1182         info->implattrs = method->iflags;
1183         if (method->signature->call_convention == MONO_CALL_DEFAULT)
1184                 info->callconv = 1;
1185         else
1186                 if (method->signature->call_convention == MONO_CALL_VARARG)
1187                         info->callconv = 2;
1188                 else
1189                         info->callconv = 0;
1190         info->callconv |= (method->signature->hasthis << 5) | (method->signature->explicit_this << 6); 
1191 }
1192
1193 static MonoArray*
1194 ves_icall_get_parameter_info (MonoMethod *method)
1195 {
1196         MonoDomain *domain = mono_domain_get (); 
1197
1198         MONO_ARCH_SAVE_REGS;
1199
1200         return mono_param_get_objects (domain, method);
1201 }
1202
1203 static MonoReflectionType*
1204 ves_icall_MonoField_GetParentType (MonoReflectionField *field, MonoBoolean declaring)
1205 {
1206         MonoClass *parent;
1207         MONO_ARCH_SAVE_REGS;
1208
1209         parent = declaring? field->field->parent: field->klass;
1210
1211         return mono_type_get_object (mono_object_domain (field), &parent->byval_arg);
1212 }
1213
1214 static MonoObject *
1215 ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj)
1216 {       
1217         MonoObject *o;
1218         MonoClassField *cf = field->field;
1219         MonoClass *klass;
1220         MonoVTable *vtable;
1221         MonoDomain *domain = mono_object_domain (field); 
1222         gchar *v;
1223         gboolean is_static = FALSE;
1224         gboolean is_ref = FALSE;
1225
1226         MONO_ARCH_SAVE_REGS;
1227
1228         mono_class_init (field->klass);
1229
1230         switch (cf->type->type) {
1231         case MONO_TYPE_STRING:
1232         case MONO_TYPE_OBJECT:
1233         case MONO_TYPE_CLASS:
1234         case MONO_TYPE_ARRAY:
1235         case MONO_TYPE_SZARRAY:
1236                 is_ref = TRUE;
1237                 break;
1238         case MONO_TYPE_U1:
1239         case MONO_TYPE_I1:
1240         case MONO_TYPE_BOOLEAN:
1241         case MONO_TYPE_U2:
1242         case MONO_TYPE_I2:
1243         case MONO_TYPE_CHAR:
1244         case MONO_TYPE_U:
1245         case MONO_TYPE_I:
1246         case MONO_TYPE_U4:
1247         case MONO_TYPE_I4:
1248         case MONO_TYPE_R4:
1249         case MONO_TYPE_U8:
1250         case MONO_TYPE_I8:
1251         case MONO_TYPE_R8:
1252         case MONO_TYPE_VALUETYPE:
1253                 is_ref = cf->type->byref;
1254                 break;
1255         default:
1256                 g_error ("type 0x%x not handled in "
1257                          "ves_icall_Monofield_GetValue", cf->type->type);
1258                 return NULL;
1259         }
1260
1261         vtable = NULL;
1262         if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) {
1263                 is_static = TRUE;
1264                 vtable = mono_class_vtable (domain, field->klass);
1265                 if (!vtable->initialized && !(cf->type->attrs & FIELD_ATTRIBUTE_LITERAL))
1266                         mono_runtime_class_init (vtable);
1267         }
1268         
1269         if (is_ref) {
1270                 if (is_static) {
1271                         mono_field_static_get_value (vtable, cf, &o);
1272                 } else {
1273                         mono_field_get_value (obj, cf, &o);
1274                 }
1275                 return o;
1276         }
1277
1278         /* boxed value type */
1279         klass = mono_class_from_mono_type (cf->type);
1280         o = mono_object_new (domain, klass);
1281         v = ((gchar *) o) + sizeof (MonoObject);
1282         if (is_static) {
1283                 mono_field_static_get_value (vtable, cf, v);
1284         } else {
1285                 mono_field_get_value (obj, cf, v);
1286         }
1287
1288         return o;
1289 }
1290
1291 static void
1292 ves_icall_FieldInfo_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value)
1293 {
1294         MonoClassField *cf = field->field;
1295         gchar *v;
1296
1297         MONO_ARCH_SAVE_REGS;
1298
1299         v = (gchar *) value;
1300         if (!cf->type->byref) {
1301                 switch (cf->type->type) {
1302                 case MONO_TYPE_U1:
1303                 case MONO_TYPE_I1:
1304                 case MONO_TYPE_BOOLEAN:
1305                 case MONO_TYPE_U2:
1306                 case MONO_TYPE_I2:
1307                 case MONO_TYPE_CHAR:
1308                 case MONO_TYPE_U:
1309                 case MONO_TYPE_I:
1310                 case MONO_TYPE_U4:
1311                 case MONO_TYPE_I4:
1312                 case MONO_TYPE_R4:
1313                 case MONO_TYPE_U8:
1314                 case MONO_TYPE_I8:
1315                 case MONO_TYPE_R8:
1316                 case MONO_TYPE_VALUETYPE:
1317                         v += sizeof (MonoObject);
1318                         break;
1319                 case MONO_TYPE_STRING:
1320                 case MONO_TYPE_OBJECT:
1321                 case MONO_TYPE_CLASS:
1322                 case MONO_TYPE_ARRAY:
1323                 case MONO_TYPE_SZARRAY:
1324                         /* Do nothing */
1325                         break;
1326                 default:
1327                         g_error ("type 0x%x not handled in "
1328                                  "ves_icall_FieldInfo_SetValueInternal", cf->type->type);
1329                         return;
1330                 }
1331         }
1332
1333         if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) {
1334                 MonoVTable *vtable = mono_class_vtable (mono_object_domain (field), field->klass);
1335                 if (!vtable->initialized)
1336                         mono_runtime_class_init (vtable);
1337                 mono_field_static_set_value (vtable, cf, v);
1338         } else {
1339                 mono_field_set_value (obj, cf, v);
1340         }
1341 }
1342
1343 /* From MonoProperty.cs */
1344 typedef enum {
1345         PInfo_Attributes = 1,
1346         PInfo_GetMethod  = 1 << 1,
1347         PInfo_SetMethod  = 1 << 2,
1348         PInfo_ReflectedType = 1 << 3,
1349         PInfo_DeclaringType = 1 << 4,
1350         PInfo_Name = 1 << 5
1351 } PInfo;
1352
1353 static void
1354 ves_icall_get_property_info (MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
1355 {
1356         MonoDomain *domain = mono_object_domain (property); 
1357
1358         MONO_ARCH_SAVE_REGS;
1359
1360         if ((req_info & PInfo_ReflectedType) != 0)
1361                 info->parent = mono_type_get_object (domain, &property->klass->byval_arg);
1362         else if ((req_info & PInfo_DeclaringType) != 0)
1363                 info->parent = mono_type_get_object (domain, &property->property->parent->byval_arg);
1364
1365         if ((req_info & PInfo_Name) != 0)
1366                 info->name = mono_string_new (domain, property->property->name);
1367
1368         if ((req_info & PInfo_Attributes) != 0)
1369                 info->attrs = property->property->attrs;
1370
1371         if ((req_info & PInfo_GetMethod) != 0)
1372                 info->get = property->property->get ?
1373                             mono_method_get_object (domain, property->property->get, NULL): NULL;
1374         
1375         if ((req_info & PInfo_SetMethod) != 0)
1376                 info->set = property->property->set ?
1377                             mono_method_get_object (domain, property->property->set, NULL): NULL;
1378         /* 
1379          * There may be other methods defined for properties, though, it seems they are not exposed 
1380          * in the reflection API 
1381          */
1382 }
1383
1384 static void
1385 ves_icall_get_event_info (MonoReflectionEvent *event, MonoEventInfo *info)
1386 {
1387         MonoDomain *domain = mono_object_domain (event); 
1388
1389         MONO_ARCH_SAVE_REGS;
1390
1391         info->declaring_type = mono_type_get_object (domain, &event->klass->byval_arg);
1392         info->reflected_type = mono_type_get_object (domain, &event->event->parent->byval_arg);
1393
1394         info->name = mono_string_new (domain, event->event->name);
1395         info->attrs = event->event->attrs;
1396         info->add_method = event->event->add ? mono_method_get_object (domain, event->event->add, NULL): NULL;
1397         info->remove_method = event->event->remove ? mono_method_get_object (domain, event->event->remove, NULL): NULL;
1398         info->raise_method = event->event->raise ? mono_method_get_object (domain, event->event->raise, NULL): NULL;
1399 }
1400
1401 static MonoArray*
1402 ves_icall_Type_GetInterfaces (MonoReflectionType* type)
1403 {
1404         MonoDomain *domain = mono_object_domain (type); 
1405         MonoArray *intf;
1406         int ninterf, i;
1407         MonoClass *class = mono_class_from_mono_type (type->type);
1408         MonoClass *parent;
1409         MonoBitSet *slots = mono_bitset_new (class->max_interface_id + 1, 0);
1410
1411         MONO_ARCH_SAVE_REGS;
1412
1413         if (class->rank) {
1414                 /* GetInterfaces() returns an empty array in MS.NET (this may be a bug) */
1415                 mono_bitset_free (slots);
1416                 return mono_array_new (domain, mono_defaults.monotype_class, 0);
1417         }
1418
1419         ninterf = 0;
1420         for (parent = class; parent; parent = parent->parent) {
1421                 for (i = 0; i < parent->interface_count; ++i) {
1422                         if (mono_bitset_test (slots, parent->interfaces [i]->interface_id))
1423                                 continue;
1424
1425                         mono_bitset_set (slots, parent->interfaces [i]->interface_id);
1426                         ++ninterf;
1427                 }
1428         }
1429
1430         intf = mono_array_new (domain, mono_defaults.monotype_class, ninterf);
1431         ninterf = 0;
1432         for (parent = class; parent; parent = parent->parent) {
1433                 for (i = 0; i < parent->interface_count; ++i) {
1434                         if (!mono_bitset_test (slots, parent->interfaces [i]->interface_id))
1435                                 continue;
1436
1437                         mono_bitset_clear (slots, parent->interfaces [i]->interface_id);
1438                         mono_array_set (intf, gpointer, ninterf,
1439                                         mono_type_get_object (domain, &parent->interfaces [i]->byval_arg));
1440                         ++ninterf;
1441                 }
1442         }
1443
1444         mono_bitset_free (slots);
1445         return intf;
1446 }
1447
1448 static void
1449 ves_icall_Type_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType *iface, MonoArray **targets, MonoArray **methods)
1450 {
1451         MonoClass *class = mono_class_from_mono_type (type->type);
1452         MonoClass *iclass = mono_class_from_mono_type (iface->type);
1453         MonoReflectionMethod *member;
1454         int i, len, ioffset;
1455         MonoDomain *domain;
1456
1457         MONO_ARCH_SAVE_REGS;
1458
1459         /* type doesn't implement iface: the exception is thrown in managed code */
1460         if ((iclass->interface_id > class->max_interface_id) || !class->interface_offsets [iclass->interface_id])
1461                         return;
1462
1463         len = iclass->method.count;
1464         ioffset = class->interface_offsets [iclass->interface_id];
1465         domain = mono_object_domain (type);
1466         *targets = mono_array_new (domain, mono_defaults.method_info_class, len);
1467         *methods = mono_array_new (domain, mono_defaults.method_info_class, len);
1468         for (i = 0; i < len; ++i) {
1469                 member = mono_method_get_object (domain, iclass->methods [i], iclass);
1470                 mono_array_set (*methods, gpointer, i, member);
1471                 member = mono_method_get_object (domain, class->vtable [i + ioffset], class);
1472                 mono_array_set (*targets, gpointer, i, member);
1473         }
1474 }
1475
1476 static MonoReflectionType*
1477 ves_icall_MonoType_GetElementType (MonoReflectionType *type)
1478 {
1479         MonoClass *class = mono_class_from_mono_type (type->type);
1480
1481         MONO_ARCH_SAVE_REGS;
1482
1483         if (type->type->byref)
1484                 return mono_type_get_object (mono_object_domain (type), &class->byval_arg);
1485         if (class->enumtype && class->enum_basetype) /* types that are modifierd typebuilkders may not have enum_basetype set */
1486                 return mono_type_get_object (mono_object_domain (type), class->enum_basetype);
1487         else if (class->element_class)
1488                 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
1489         else
1490                 return NULL;
1491 }
1492
1493 static MonoReflectionType*
1494 ves_icall_get_type_parent (MonoReflectionType *type)
1495 {
1496         MonoClass *class = mono_class_from_mono_type (type->type);
1497
1498         MONO_ARCH_SAVE_REGS;
1499
1500         return class->parent ? mono_type_get_object (mono_object_domain (type), &class->parent->byval_arg): NULL;
1501 }
1502
1503 static MonoBoolean
1504 ves_icall_type_ispointer (MonoReflectionType *type)
1505 {
1506         MONO_ARCH_SAVE_REGS;
1507
1508         return type->type->type == MONO_TYPE_PTR;
1509 }
1510
1511 static MonoBoolean
1512 ves_icall_type_isprimitive (MonoReflectionType *type)
1513 {
1514         MONO_ARCH_SAVE_REGS;
1515
1516         return (!type->type->byref && (type->type->type >= MONO_TYPE_BOOLEAN) && (type->type->type <= MONO_TYPE_R8));
1517 }
1518
1519 static MonoBoolean
1520 ves_icall_type_isbyref (MonoReflectionType *type)
1521 {
1522         MONO_ARCH_SAVE_REGS;
1523
1524         return type->type->byref;
1525 }
1526
1527 static MonoReflectionModule*
1528 ves_icall_MonoType_get_Module (MonoReflectionType *type)
1529 {
1530         MonoClass *class = mono_class_from_mono_type (type->type);
1531
1532         MONO_ARCH_SAVE_REGS;
1533
1534         return mono_module_get_object (mono_object_domain (type), class->image);
1535 }
1536
1537 static MonoReflectionAssembly*
1538 ves_icall_MonoType_get_Assembly (MonoReflectionType *type)
1539 {
1540         MonoDomain *domain = mono_domain_get (); 
1541         MonoClass *class = mono_class_from_mono_type (type->type);
1542
1543         MONO_ARCH_SAVE_REGS;
1544
1545         return mono_assembly_get_object (domain, class->image->assembly);
1546 }
1547
1548 static MonoReflectionType*
1549 ves_icall_MonoType_get_DeclaringType (MonoReflectionType *type)
1550 {
1551         MonoDomain *domain = mono_domain_get (); 
1552         MonoClass *class = mono_class_from_mono_type (type->type);
1553
1554         MONO_ARCH_SAVE_REGS;
1555
1556         return class->nested_in ? mono_type_get_object (domain, &class->nested_in->byval_arg) : NULL;
1557 }
1558
1559 static MonoReflectionType*
1560 ves_icall_MonoType_get_UnderlyingSystemType (MonoReflectionType *type)
1561 {
1562         MonoDomain *domain = mono_domain_get (); 
1563         MonoClass *class = mono_class_from_mono_type (type->type);
1564
1565         MONO_ARCH_SAVE_REGS;
1566
1567         if (class->enumtype && class->enum_basetype) /* types that are modified typebuilders may not have enum_basetype set */
1568                 return mono_type_get_object (domain, class->enum_basetype);
1569         else if (class->element_class)
1570                 return mono_type_get_object (domain, &class->element_class->byval_arg);
1571         else
1572                 return NULL;
1573 }
1574
1575 static MonoString*
1576 ves_icall_MonoType_get_Name (MonoReflectionType *type)
1577 {
1578         MonoDomain *domain = mono_domain_get (); 
1579         MonoClass *class = mono_class_from_mono_type (type->type);
1580
1581         MONO_ARCH_SAVE_REGS;
1582
1583         return mono_string_new (domain, class->name);
1584 }
1585
1586 static MonoString*
1587 ves_icall_MonoType_get_Namespace (MonoReflectionType *type)
1588 {
1589         MonoDomain *domain = mono_domain_get (); 
1590         MonoClass *class = mono_class_from_mono_type (type->type);
1591
1592         MONO_ARCH_SAVE_REGS;
1593
1594         while (class->nested_in)
1595                 class = class->nested_in;
1596
1597         return mono_string_new (domain, class->name_space);
1598 }
1599
1600 static gint32
1601 ves_icall_MonoType_GetArrayRank (MonoReflectionType *type)
1602 {
1603         MonoClass *class = mono_class_from_mono_type (type->type);
1604
1605         MONO_ARCH_SAVE_REGS;
1606
1607         return class->rank;
1608 }
1609
1610 static MonoArray*
1611 ves_icall_MonoType_GetGenericArguments (MonoReflectionType *type)
1612 {
1613         MonoArray *res;
1614         MonoClass *klass, *pklass;
1615         int i;
1616         MONO_ARCH_SAVE_REGS;
1617
1618         klass = mono_class_from_mono_type (type->type);
1619
1620         if (type->type->byref) {
1621                 res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, 0);
1622         } else if (klass->gen_params) {
1623                 res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, klass->num_gen_params);
1624                 for (i = 0; i < klass->num_gen_params; ++i) {
1625                         pklass = mono_class_from_generic_parameter (&klass->gen_params [i], klass->image, FALSE);
1626                         mono_array_set (res, gpointer, i, mono_type_get_object (mono_object_domain (type), &pklass->byval_arg));
1627                 }
1628         } else if (klass->generic_inst) {
1629                 MonoGenericInst *inst = klass->generic_inst;
1630                 res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, inst->type_argc);
1631                 for (i = 0; i < inst->type_argc; ++i) {
1632                         mono_array_set (res, gpointer, i, mono_type_get_object (mono_object_domain (type), inst->type_argv [i]));
1633                 }
1634         } else {
1635                 res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, 0);
1636         }
1637         return res;
1638 }
1639
1640 static gboolean
1641 ves_icall_Type_get_IsGenericTypeDefinition (MonoReflectionType *type)
1642 {
1643         MonoClass *klass;
1644         MONO_ARCH_SAVE_REGS;
1645
1646         if (type->type->byref)
1647                 return FALSE;
1648         klass = mono_class_from_mono_type (type->type);
1649
1650         return klass->gen_params != NULL;
1651 }
1652
1653 static MonoReflectionType*
1654 ves_icall_Type_GetGenericTypeDefinition_impl (MonoReflectionType *type)
1655 {
1656         MonoClass *klass;
1657         MONO_ARCH_SAVE_REGS;
1658
1659         if (type->type->byref)
1660                 return NULL;
1661         klass = mono_class_from_mono_type (type->type);
1662         if (klass->gen_params) {
1663                 return type; /* check this one */
1664         }
1665         if (klass->generic_inst) {
1666                 MonoType *generic_type = klass->generic_inst->generic_type;
1667                 MonoClass *generic_class = mono_class_from_mono_type (generic_type);
1668
1669                 if (generic_class->wastypebuilder && generic_class->reflection_info)
1670                         return generic_class->reflection_info;
1671                 else
1672                         return mono_type_get_object (mono_object_domain (type), generic_type);
1673         }
1674         return NULL;
1675 }
1676
1677 static MonoReflectionType*
1678 ves_icall_Type_BindGenericParameters (MonoReflectionType *type, MonoArray *type_array)
1679 {
1680         MonoType *geninst, **types;
1681         int i, count;
1682
1683         MONO_ARCH_SAVE_REGS;
1684
1685         if (type->type->byref)
1686                 return NULL;
1687
1688         count = mono_array_length (type_array);
1689         types = g_new0 (MonoType *, count);
1690
1691         for (i = 0; i < count; i++) {
1692                 MonoReflectionType *t = mono_array_get (type_array, gpointer, i);
1693                 types [i] = t->type;
1694         }
1695
1696         geninst = mono_reflection_bind_generic_parameters (type, count, types);
1697
1698         return mono_type_get_object (mono_object_domain (type), geninst);
1699 }
1700
1701 static gboolean
1702 ves_icall_Type_get_IsGenericInstance (MonoReflectionType *type)
1703 {
1704         MonoClass *klass;
1705         MONO_ARCH_SAVE_REGS;
1706
1707         if (type->type->byref)
1708                 return FALSE;
1709         klass = mono_class_from_mono_type (type->type);
1710         return klass->generic_inst != NULL;
1711 }
1712
1713 static gint32
1714 ves_icall_Type_GetGenericParameterPosition (MonoReflectionType *type)
1715 {
1716         MONO_ARCH_SAVE_REGS;
1717
1718         if (type->type->byref)
1719                 return -1;
1720         if (type->type->type == MONO_TYPE_VAR || type->type->type == MONO_TYPE_MVAR)
1721                 return type->type->data.generic_param->num;
1722         return -1;
1723 }
1724
1725 static MonoBoolean
1726 ves_icall_MonoType_get_HasGenericArguments (MonoReflectionType *type)
1727 {
1728         MonoClass *klass;
1729         MONO_ARCH_SAVE_REGS;
1730
1731         if (type->type->byref)
1732                 return FALSE;
1733         klass = mono_class_from_mono_type (type->type);
1734         if (klass->gen_params || klass->generic_inst)
1735                 return TRUE;
1736         return FALSE;
1737 }
1738
1739 static MonoBoolean
1740 ves_icall_MonoType_get_IsGenericParameter (MonoReflectionType *type)
1741 {
1742         MONO_ARCH_SAVE_REGS;
1743
1744         if (type->type->byref)
1745                 return FALSE;
1746         if (type->type->type == MONO_TYPE_VAR || type->type->type == MONO_TYPE_MVAR)
1747                 return TRUE;
1748         return FALSE;
1749 }
1750
1751 static MonoBoolean
1752 ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder *tb)
1753 {
1754         MONO_ARCH_SAVE_REGS;
1755
1756         if (tb->type.type->byref)
1757                 return FALSE;
1758         if (tb->type.type->type == MONO_TYPE_VAR || tb->type.type->type == MONO_TYPE_MVAR)
1759                 return TRUE;
1760         return FALSE;
1761 }
1762
1763 static MonoReflectionType*
1764 ves_icall_MonoGenericInst_GetParentType (MonoReflectionGenericInst *type)
1765 {
1766         MonoGenericInst *ginst;
1767         MonoClass *klass;
1768
1769         MONO_ARCH_SAVE_REGS;
1770
1771         ginst = type->type.type->data.generic_inst;
1772         if (!ginst || !ginst->parent || (ginst->parent->type != MONO_TYPE_GENERICINST))
1773                 return NULL;
1774
1775         klass = mono_class_from_mono_type (ginst->parent);
1776         if (!klass->generic_inst && !klass->gen_params)
1777                 return NULL;
1778
1779         return mono_type_get_object (mono_object_domain (type), ginst->parent);
1780 }
1781
1782 static MonoArray*
1783 ves_icall_MonoGenericInst_GetInterfaces (MonoReflectionGenericInst *type)
1784 {
1785         static MonoClass *System_Reflection_MonoGenericInst;
1786         MonoGenericInst *ginst;
1787         MonoDomain *domain;
1788         MonoClass *klass;
1789         MonoArray *res;
1790         int i;
1791
1792         MONO_ARCH_SAVE_REGS;
1793
1794         if (!System_Reflection_MonoGenericInst) {
1795                 System_Reflection_MonoGenericInst = mono_class_from_name (
1796                         mono_defaults.corlib, "System.Reflection", "MonoGenericInst");
1797                 g_assert (System_Reflection_MonoGenericInst);
1798         }
1799
1800         domain = mono_object_domain (type);
1801
1802         ginst = type->type.type->data.generic_inst;
1803         if (!ginst || !ginst->ifaces)
1804                 return mono_array_new (domain, System_Reflection_MonoGenericInst, 0);
1805
1806         klass = mono_class_from_mono_type (ginst->generic_type);
1807
1808         res = mono_array_new (domain, System_Reflection_MonoGenericInst, ginst->count_ifaces);
1809
1810         for (i = 0; i < ginst->count_ifaces; i++) {
1811                 MonoReflectionType *iface = mono_type_get_object (domain, ginst->ifaces [i]);
1812
1813                 mono_array_set (res, gpointer, i, iface);
1814         }
1815
1816         return res;
1817 }
1818
1819 static MonoArray*
1820 ves_icall_MonoGenericInst_GetMethods (MonoReflectionGenericInst *type,
1821                                       MonoReflectionType *reflected_type)
1822 {
1823         MonoGenericInst *ginst;
1824         MonoDynamicGenericInst *dginst;
1825         MonoDomain *domain;
1826         MonoClass *refclass;
1827         MonoArray *res;
1828         int i;
1829
1830         MONO_ARCH_SAVE_REGS;
1831
1832         ginst = type->type.type->data.generic_inst;
1833         g_assert ((dginst = ginst->dynamic_info) != NULL);
1834
1835         refclass = mono_class_from_mono_type (reflected_type->type);
1836
1837         domain = mono_object_domain (type);
1838         res = mono_array_new (domain, mono_defaults.method_info_class, dginst->count_methods);
1839
1840         for (i = 0; i < dginst->count_methods; i++)
1841                 mono_array_set (res, gpointer, i,
1842                                 mono_method_get_object (domain, dginst->methods [i], refclass));
1843
1844         return res;
1845 }
1846
1847 static MonoArray*
1848 ves_icall_MonoGenericInst_GetConstructors (MonoReflectionGenericInst *type,
1849                                            MonoReflectionType *reflected_type)
1850 {
1851         static MonoClass *System_Reflection_ConstructorInfo;
1852         MonoGenericInst *ginst;
1853         MonoDynamicGenericInst *dginst;
1854         MonoDomain *domain;
1855         MonoClass *refclass;
1856         MonoArray *res;
1857         int i;
1858
1859         MONO_ARCH_SAVE_REGS;
1860
1861         if (!System_Reflection_ConstructorInfo)
1862                 System_Reflection_ConstructorInfo = mono_class_from_name (
1863                         mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
1864
1865         ginst = type->type.type->data.generic_inst;
1866         g_assert ((dginst = ginst->dynamic_info) != NULL);
1867
1868         refclass = mono_class_from_mono_type (reflected_type->type);
1869
1870         domain = mono_object_domain (type);
1871         res = mono_array_new (domain, System_Reflection_ConstructorInfo, dginst->count_ctors);
1872
1873         for (i = 0; i < dginst->count_ctors; i++)
1874                 mono_array_set (res, gpointer, i,
1875                                 mono_method_get_object (domain, dginst->ctors [i], refclass));
1876
1877         return res;
1878 }
1879
1880 static MonoArray*
1881 ves_icall_MonoGenericInst_GetFields (MonoReflectionGenericInst *type,
1882                                      MonoReflectionType *reflected_type)
1883 {
1884         MonoGenericInst *ginst;
1885         MonoDynamicGenericInst *dginst;
1886         MonoDomain *domain;
1887         MonoClass *refclass;
1888         MonoArray *res;
1889         int i;
1890
1891         MONO_ARCH_SAVE_REGS;
1892
1893         ginst = type->type.type->data.generic_inst;
1894         g_assert ((dginst = ginst->dynamic_info) != NULL);
1895
1896         refclass = mono_class_from_mono_type (reflected_type->type);
1897
1898         domain = mono_object_domain (type);
1899         res = mono_array_new (domain, mono_defaults.field_info_class, dginst->count_fields);
1900
1901         for (i = 0; i < dginst->count_fields; i++)
1902                 mono_array_set (res, gpointer, i,
1903                                 mono_field_get_object (domain, refclass, &dginst->fields [i]));
1904
1905         return res;
1906 }
1907
1908 static MonoArray*
1909 ves_icall_MonoGenericInst_GetProperties (MonoReflectionGenericInst *type,
1910                                          MonoReflectionType *reflected_type)
1911 {
1912         static MonoClass *System_Reflection_PropertyInfo;
1913         MonoGenericInst *ginst;
1914         MonoDynamicGenericInst *dginst;
1915         MonoDomain *domain;
1916         MonoClass *refclass;
1917         MonoArray *res;
1918         int i;
1919
1920         MONO_ARCH_SAVE_REGS;
1921
1922         if (!System_Reflection_PropertyInfo)
1923                 System_Reflection_PropertyInfo = mono_class_from_name (
1924                         mono_defaults.corlib, "System.Reflection", "PropertyInfo");
1925
1926         ginst = type->type.type->data.generic_inst;
1927         g_assert ((dginst = ginst->dynamic_info) != NULL);
1928
1929         refclass = mono_class_from_mono_type (reflected_type->type);
1930
1931         domain = mono_object_domain (type);
1932         res = mono_array_new (domain, System_Reflection_PropertyInfo, dginst->count_properties);
1933
1934         for (i = 0; i < dginst->count_properties; i++)
1935                 mono_array_set (res, gpointer, i,
1936                                 mono_property_get_object (domain, refclass, &dginst->properties [i]));
1937
1938         return res;
1939 }
1940
1941 static MonoArray*
1942 ves_icall_MonoGenericInst_GetEvents (MonoReflectionGenericInst *type,
1943                                      MonoReflectionType *reflected_type)
1944 {
1945         static MonoClass *System_Reflection_EventInfo;
1946         MonoGenericInst *ginst;
1947         MonoDynamicGenericInst *dginst;
1948         MonoDomain *domain;
1949         MonoClass *refclass;
1950         MonoArray *res;
1951         int i;
1952
1953         MONO_ARCH_SAVE_REGS;
1954
1955         if (!System_Reflection_EventInfo)
1956                 System_Reflection_EventInfo = mono_class_from_name (
1957                         mono_defaults.corlib, "System.Reflection", "EventInfo");
1958
1959         ginst = type->type.type->data.generic_inst;
1960         g_assert ((dginst = ginst->dynamic_info) != NULL);
1961
1962         refclass = mono_class_from_mono_type (reflected_type->type);
1963
1964         domain = mono_object_domain (type);
1965         res = mono_array_new (domain, System_Reflection_EventInfo, dginst->count_events);
1966
1967         for (i = 0; i < dginst->count_events; i++)
1968                 mono_array_set (res, gpointer, i,
1969                                 mono_event_get_object (domain, refclass, &dginst->events [i]));
1970
1971         return res;
1972 }
1973
1974 static MonoReflectionMethod *
1975 ves_icall_MonoType_get_DeclaringMethod (MonoReflectionType *type)
1976 {
1977         MonoMethod *method;
1978         MonoClass *klass;
1979
1980         MONO_ARCH_SAVE_REGS;
1981
1982         if (type->type->byref)
1983                 return FALSE;
1984
1985         method = type->type->data.generic_param->method;
1986         if (!method)
1987                 return NULL;
1988
1989         klass = mono_class_from_mono_type (type->type);
1990         return mono_method_get_object (mono_object_domain (type), method, klass);
1991 }
1992
1993 static MonoReflectionMethod *
1994 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
1995 {
1996         MonoMethodInflated *imethod;
1997
1998         MONO_ARCH_SAVE_REGS;
1999
2000         if (!method->method->signature->is_inflated) {
2001                 if (method->method->signature->generic_param_count)
2002                         return method;
2003
2004                 return NULL;
2005         }
2006
2007         imethod = (MonoMethodInflated *) method->method;
2008         if (imethod->context->gmethod && imethod->context->gmethod->reflection_info)
2009                 return imethod->context->gmethod->reflection_info;
2010         else
2011                 return mono_method_get_object (
2012                         mono_object_domain (method), imethod->declaring, NULL);
2013 }
2014
2015 static gboolean
2016 ves_icall_MonoMethod_get_HasGenericParameters (MonoReflectionMethod *method)
2017 {
2018         MONO_ARCH_SAVE_REGS;
2019
2020         if ((method->method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
2021             (method->method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
2022                 return FALSE;
2023
2024         return method->method->signature->generic_param_count != 0;
2025 }
2026
2027 static gboolean
2028 ves_icall_MonoMethod_get_Mono_IsInflatedMethod (MonoReflectionMethod *method)
2029 {
2030         MONO_ARCH_SAVE_REGS;
2031
2032         if ((method->method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
2033             (method->method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
2034                 return FALSE;
2035
2036         return method->method->signature->is_inflated;
2037 }
2038
2039 static gboolean
2040 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method)
2041 {
2042         MONO_ARCH_SAVE_REGS;
2043
2044         if ((method->method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
2045             (method->method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
2046                 return FALSE;
2047
2048         return method->method->signature->generic_param_count != 0;
2049 }
2050
2051 static MonoArray*
2052 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
2053 {
2054         MonoArray *res;
2055         MonoDomain *domain;
2056         MonoMethodNormal *mn;
2057         int count, i;
2058         MONO_ARCH_SAVE_REGS;
2059
2060         domain = mono_object_domain (method);
2061
2062         if ((method->method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
2063             (method->method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
2064                 return mono_array_new (domain, mono_defaults.monotype_class, 0);
2065
2066         if (method->method->signature->is_inflated) {
2067                 MonoMethodInflated *imethod = (MonoMethodInflated *) method->method;
2068                 MonoGenericMethod *gmethod = imethod->context->gmethod;
2069
2070                 if (gmethod) {
2071                         count = gmethod->mtype_argc;
2072                         res = mono_array_new (domain, mono_defaults.monotype_class, count);
2073
2074                         for (i = 0; i < count; i++) {
2075                                 MonoType *t = gmethod->mtype_argv [i];
2076                                 mono_array_set (
2077                                         res, gpointer, i, mono_type_get_object (domain, t));
2078                         }
2079
2080                         return res;
2081                 }
2082         }
2083
2084         mn = (MonoMethodNormal *) method->method;
2085         count = method->method->signature->generic_param_count;
2086         res = mono_array_new (domain, mono_defaults.monotype_class, count);
2087
2088         for (i = 0; i < count; i++) {
2089                 MonoGenericParam *param = &mn->header->gen_params [i];
2090                 MonoClass *pklass = mono_class_from_generic_parameter (
2091                         param, method->method->klass->image, TRUE);
2092                 mono_array_set (res, gpointer, i,
2093                                 mono_type_get_object (domain, &pklass->byval_arg));
2094         }
2095
2096         return res;
2097 }
2098
2099 static MonoObject *
2100 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoArray *params) 
2101 {
2102         /* 
2103          * Invoke from reflection is supposed to always be a virtual call (the API
2104          * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
2105          * greater flexibility.
2106          */
2107         MonoMethod *m = method->method;
2108         int pcount;
2109
2110         MONO_ARCH_SAVE_REGS;
2111
2112         if (this) {
2113                 if (!mono_object_isinst (this, m->klass))
2114                         mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
2115                 m = mono_object_get_virtual_method (this, m);
2116         } else if (!(m->flags & METHOD_ATTRIBUTE_STATIC) && strcmp (m->name, ".ctor") && !m->wrapper_type)
2117                 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
2118
2119         pcount = params? mono_array_length (params): 0;
2120         if (pcount != m->signature->param_count)
2121                 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
2122
2123         if (m->klass->rank && !strcmp (m->name, ".ctor")) {
2124                 int i;
2125                 guint32 *lengths;
2126                 guint32 *lower_bounds;
2127                 pcount = mono_array_length (params);
2128                 lengths = alloca (sizeof (guint32) * pcount);
2129                 for (i = 0; i < pcount; ++i)
2130                         lengths [i] = *(gint32*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
2131
2132                 if (m->klass->rank == pcount) {
2133                         /* Only lengths provided. */
2134                         lower_bounds = NULL;
2135                 } else {
2136                         g_assert (pcount == (m->klass->rank * 2));
2137                         /* lower bounds are first. */
2138                         lower_bounds = lengths;
2139                         lengths += m->klass->rank;
2140                 }
2141
2142                 return (MonoObject*)mono_array_new_full (mono_object_domain (params), m->klass, lengths, lower_bounds);
2143         }
2144         return mono_runtime_invoke_array (m, this, params, NULL);
2145 }
2146
2147 static MonoObject *
2148 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this, MonoArray *params, MonoArray **outArgs) 
2149 {
2150         MonoDomain *domain = mono_object_domain (method); 
2151         MonoMethod *m = method->method;
2152         MonoMethodSignature *sig = m->signature;
2153         MonoArray *out_args;
2154         MonoObject *result;
2155         int i, j, outarg_count = 0;
2156
2157         MONO_ARCH_SAVE_REGS;
2158
2159         if (m->klass == mono_defaults.object_class) {
2160
2161                 if (!strcmp (m->name, "FieldGetter")) {
2162                         MonoClass *k = this->vtable->klass;
2163                         MonoString *name = mono_array_get (params, MonoString *, 1);
2164                         char *str;
2165
2166                         str = mono_string_to_utf8 (name);
2167                 
2168                         for (i = 0; i < k->field.count; i++) {
2169                                 if (!strcmp (k->fields [i].name, str)) {
2170                                         MonoClass *field_klass =  mono_class_from_mono_type (k->fields [i].type);
2171                                         if (field_klass->valuetype)
2172                                                 result = mono_value_box (domain, field_klass,
2173                                                                          (char *)this + k->fields [i].offset);
2174                                         else 
2175                                                 result = *((gpointer *)((char *)this + k->fields [i].offset));
2176                                 
2177                                         g_assert (result);
2178                                         out_args = mono_array_new (domain, mono_defaults.object_class, 1);
2179                                         *outArgs = out_args;
2180                                         mono_array_set (out_args, gpointer, 0, result);
2181                                         g_free (str);
2182                                         return NULL;
2183                                 }
2184                         }
2185
2186                         g_free (str);
2187                         g_assert_not_reached ();
2188
2189                 } else if (!strcmp (m->name, "FieldSetter")) {
2190                         MonoClass *k = this->vtable->klass;
2191                         MonoString *name = mono_array_get (params, MonoString *, 1);
2192                         int size, align;
2193                         char *str;
2194
2195                         str = mono_string_to_utf8 (name);
2196                 
2197                         for (i = 0; i < k->field.count; i++) {
2198                                 if (!strcmp (k->fields [i].name, str)) {
2199                                         MonoClass *field_klass =  mono_class_from_mono_type (k->fields [i].type);
2200                                         MonoObject *val = mono_array_get (params, gpointer, 2);
2201
2202                                         if (field_klass->valuetype) {
2203                                                 size = mono_type_size (k->fields [i].type, &align);
2204                                                 memcpy ((char *)this + k->fields [i].offset, 
2205                                                         ((char *)val) + sizeof (MonoObject), size);
2206                                         } else 
2207                                                 *(MonoObject**)((char *)this + k->fields [i].offset) = val;
2208                                 
2209                                         out_args = mono_array_new (domain, mono_defaults.object_class, 0);
2210                                         *outArgs = out_args;
2211
2212                                         g_free (str);
2213                                         return NULL;
2214                                 }
2215                         }
2216
2217                         g_free (str);
2218                         g_assert_not_reached ();
2219
2220                 }
2221         }
2222
2223         for (i = 0; i < mono_array_length (params); i++) {
2224                 if (sig->params [i]->byref) 
2225                         outarg_count++;
2226         }
2227
2228         out_args = mono_array_new (domain, mono_defaults.object_class, outarg_count);
2229         
2230         /* fixme: handle constructors? */
2231         if (!strcmp (method->method->name, ".ctor"))
2232                 g_assert_not_reached ();
2233
2234         result = mono_runtime_invoke_array (method->method, this, params, NULL);
2235
2236         for (i = 0, j = 0; i < mono_array_length (params); i++) {
2237                 if (sig->params [i]->byref) {
2238                         gpointer arg;
2239                         arg = mono_array_get (params, gpointer, i);
2240                         mono_array_set (out_args, gpointer, j, arg);
2241                         j++;
2242                 }
2243         }
2244
2245         *outArgs = out_args;
2246
2247         return result;
2248 }
2249
2250 static MonoObject *
2251 ves_icall_System_Enum_ToObject (MonoReflectionType *type, MonoObject *obj)
2252 {
2253         MonoDomain *domain; 
2254         MonoClass *enumc, *objc;
2255         gint32 s1, s2;
2256         MonoObject *res;
2257         
2258         MONO_ARCH_SAVE_REGS;
2259
2260         MONO_CHECK_ARG_NULL (type);
2261         MONO_CHECK_ARG_NULL (obj);
2262
2263         domain = mono_object_domain (type); 
2264         enumc = mono_class_from_mono_type (type->type);
2265         objc = obj->vtable->klass;
2266
2267         MONO_CHECK_ARG (obj, enumc->enumtype == TRUE);
2268         MONO_CHECK_ARG (obj, (objc->enumtype) || (objc->byval_arg.type >= MONO_TYPE_I1 &&
2269                                                   objc->byval_arg.type <= MONO_TYPE_U8));
2270         
2271         s1 = mono_class_value_size (enumc, NULL);
2272         s2 = mono_class_value_size (objc, NULL);
2273
2274         res = mono_object_new (domain, enumc);
2275
2276 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
2277         memcpy ((char *)res + sizeof (MonoObject), (char *)obj + sizeof (MonoObject), MIN (s1, s2));
2278 #else
2279         memcpy ((char *)res + sizeof (MonoObject) + (s1 > s2 ? s1 - s2 : 0),
2280                 (char *)obj + sizeof (MonoObject) + (s2 > s1 ? s2 - s1 : 0),
2281                 MIN (s1, s2));
2282 #endif
2283         return res;
2284 }
2285
2286 static MonoObject *
2287 ves_icall_System_Enum_get_value (MonoObject *this)
2288 {
2289         MonoObject *res;
2290         MonoClass *enumc;
2291         gpointer dst;
2292         gpointer src;
2293         int size;
2294
2295         MONO_ARCH_SAVE_REGS;
2296
2297         if (!this)
2298                 return NULL;
2299
2300         g_assert (this->vtable->klass->enumtype);
2301         
2302         enumc = mono_class_from_mono_type (this->vtable->klass->enum_basetype);
2303         res = mono_object_new (mono_object_domain (this), enumc);
2304         dst = (char *)res + sizeof (MonoObject);
2305         src = (char *)this + sizeof (MonoObject);
2306         size = mono_class_value_size (enumc, NULL);
2307
2308         memcpy (dst, src, size);
2309
2310         return res;
2311 }
2312
2313 static void
2314 ves_icall_get_enum_info (MonoReflectionType *type, MonoEnumInfo *info)
2315 {
2316         MonoDomain *domain = mono_object_domain (type); 
2317         MonoClass *enumc = mono_class_from_mono_type (type->type);
2318         guint i, j, nvalues, crow;
2319         MonoClassField *field;
2320
2321         MONO_ARCH_SAVE_REGS;
2322
2323         info->utype = mono_type_get_object (domain, enumc->enum_basetype);
2324         nvalues = enumc->field.count - 1;
2325         info->names = mono_array_new (domain, mono_defaults.string_class, nvalues);
2326         info->values = mono_array_new (domain, enumc, nvalues);
2327         
2328         crow = -1;
2329         for (i = 0, j = 0; i < enumc->field.count; ++i) {
2330                 const char *p;
2331                 int len;
2332
2333                 field = &enumc->fields [i];
2334                 if (strcmp ("value__", field->name) == 0)
2335                         continue;
2336                 if (mono_field_is_deleted (field))
2337                         continue;
2338                 mono_array_set (info->names, gpointer, j, mono_string_new (domain, field->name));
2339                 if (!field->def_value) {
2340                         field->def_value = g_new0 (MonoConstant, 1);
2341                         crow = mono_metadata_get_constant_index (enumc->image, MONO_TOKEN_FIELD_DEF | (i+enumc->field.first+1), crow + 1);
2342                         field->def_value->type = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_TYPE);
2343                         crow = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_VALUE);
2344                         field->def_value->value = (gpointer)mono_metadata_blob_heap (enumc->image, crow);
2345                 }
2346
2347                 p = field->def_value->value;
2348                 len = mono_metadata_decode_blob_size (p, &p);
2349                 switch (enumc->enum_basetype->type) {
2350                 case MONO_TYPE_U1:
2351                 case MONO_TYPE_I1:
2352                         mono_array_set (info->values, gchar, j, *p);
2353                         break;
2354                 case MONO_TYPE_CHAR:
2355                 case MONO_TYPE_U2:
2356                 case MONO_TYPE_I2:
2357                         mono_array_set (info->values, gint16, j, read16 (p));
2358                         break;
2359                 case MONO_TYPE_U4:
2360                 case MONO_TYPE_I4:
2361                         mono_array_set (info->values, gint32, j, read32 (p));
2362                         break;
2363                 case MONO_TYPE_U8:
2364                 case MONO_TYPE_I8:
2365                         mono_array_set (info->values, gint64, j, read64 (p));
2366                         break;
2367                 default:
2368                         g_error ("Implement type 0x%02x in get_enum_info", enumc->enum_basetype->type);
2369                 }
2370                 ++j;
2371         }
2372 }
2373
2374 enum {
2375         BFLAGS_IgnoreCase = 1,
2376         BFLAGS_DeclaredOnly = 2,
2377         BFLAGS_Instance = 4,
2378         BFLAGS_Static = 8,
2379         BFLAGS_Public = 0x10,
2380         BFLAGS_NonPublic = 0x20,
2381         BFLAGS_FlattenHierarchy = 0x40,
2382         BFLAGS_InvokeMethod = 0x100,
2383         BFLAGS_CreateInstance = 0x200,
2384         BFLAGS_GetField = 0x400,
2385         BFLAGS_SetField = 0x800,
2386         BFLAGS_GetProperty = 0x1000,
2387         BFLAGS_SetProperty = 0x2000,
2388         BFLAGS_ExactBinding = 0x10000,
2389         BFLAGS_SuppressChangeType = 0x20000,
2390         BFLAGS_OptionalParamBinding = 0x40000
2391 };
2392
2393 static MonoReflectionField *
2394 ves_icall_Type_GetField (MonoReflectionType *type, MonoString *name, guint32 bflags)
2395 {
2396         MonoDomain *domain; 
2397         MonoClass *startklass, *klass;
2398         int i, match;
2399         MonoClassField *field;
2400         char *utf8_name;
2401         domain = ((MonoObject *)type)->vtable->domain;
2402         klass = startklass = mono_class_from_mono_type (type->type);
2403
2404         MONO_ARCH_SAVE_REGS;
2405
2406         if (!name)
2407                 mono_raise_exception (mono_get_exception_argument_null ("name"));
2408
2409 handle_parent:  
2410         for (i = 0; i < klass->field.count; ++i) {
2411                 match = 0;
2412                 field = &klass->fields [i];
2413                 if (mono_field_is_deleted (field))
2414                         continue;
2415                 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
2416                         if (bflags & BFLAGS_Public)
2417                                 match++;
2418                 } else {
2419                         if (bflags & BFLAGS_NonPublic)
2420                                 match++;
2421                 }
2422                 if (!match)
2423                         continue;
2424                 match = 0;
2425                 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
2426                         if (bflags & BFLAGS_Static)
2427                                 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
2428                                         match++;
2429                 } else {
2430                         if (bflags & BFLAGS_Instance)
2431                                 match++;
2432                 }
2433
2434                 if (!match)
2435                         continue;
2436                 
2437                 utf8_name = mono_string_to_utf8 (name);
2438
2439                 if (strcmp (field->name, utf8_name)) {
2440                         g_free (utf8_name);
2441                         continue;
2442                 }
2443                 g_free (utf8_name);
2444                 
2445                 return mono_field_get_object (domain, startklass, field);
2446         }
2447         if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
2448                 goto handle_parent;
2449
2450         return NULL;
2451 }
2452
2453 static MonoArray*
2454 ves_icall_Type_GetFields_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
2455 {
2456         MonoDomain *domain; 
2457         GSList *l = NULL, *tmp;
2458         MonoClass *startklass, *klass, *refklass;
2459         MonoArray *res;
2460         MonoObject *member;
2461         int i, len, match;
2462         MonoClassField *field;
2463
2464         MONO_ARCH_SAVE_REGS;
2465
2466         domain = ((MonoObject *)type)->vtable->domain;
2467         klass = startklass = mono_class_from_mono_type (type->type);
2468         refklass = mono_class_from_mono_type (reftype->type);
2469
2470 handle_parent:  
2471         for (i = 0; i < klass->field.count; ++i) {
2472                 match = 0;
2473                 field = &klass->fields [i];
2474                 if (mono_field_is_deleted (field))
2475                         continue;
2476                 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
2477                         if (bflags & BFLAGS_Public)
2478                                 match++;
2479                 } else {
2480                         if (bflags & BFLAGS_NonPublic)
2481                                 match++;
2482                 }
2483                 if (!match)
2484                         continue;
2485                 match = 0;
2486                 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
2487                         if (bflags & BFLAGS_Static)
2488                                 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
2489                                         match++;
2490                 } else {
2491                         if (bflags & BFLAGS_Instance)
2492                                 match++;
2493                 }
2494
2495                 if (!match)
2496                         continue;
2497                 member = (MonoObject*)mono_field_get_object (domain, refklass, field);
2498                 l = g_slist_prepend (l, member);
2499         }
2500         if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
2501                 goto handle_parent;
2502         len = g_slist_length (l);
2503         res = mono_array_new (domain, mono_defaults.field_info_class, len);
2504         i = 0;
2505         tmp = l = g_slist_reverse (l);
2506         for (; tmp; tmp = tmp->next, ++i)
2507                 mono_array_set (res, gpointer, i, tmp->data);
2508         g_slist_free (l);
2509         return res;
2510 }
2511
2512 static MonoArray*
2513 ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
2514 {
2515         MonoDomain *domain; 
2516         GSList *l = NULL, *tmp;
2517         MonoClass *startklass, *klass, *refklass;
2518         MonoArray *res;
2519         MonoMethod *method;
2520         MonoObject *member;
2521         int i, len, match;
2522         GHashTable *method_slots = g_hash_table_new (NULL, NULL);
2523         gchar *mname = NULL;
2524         int (*compare_func) (const char *s1, const char *s2) = NULL;
2525                 
2526         MONO_ARCH_SAVE_REGS;
2527
2528         domain = ((MonoObject *)type)->vtable->domain;
2529         klass = startklass = mono_class_from_mono_type (type->type);
2530         refklass = mono_class_from_mono_type (reftype->type);
2531         len = 0;
2532         if (name != NULL) {
2533                 mname = mono_string_to_utf8 (name);
2534                 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
2535         }
2536
2537 handle_parent:
2538         for (i = 0; i < klass->method.count; ++i) {
2539                 match = 0;
2540                 method = klass->methods [i];
2541                 if (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0)
2542                         continue;
2543                 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
2544                         if (bflags & BFLAGS_Public)
2545                                 match++;
2546                 } else {
2547                         if (bflags & BFLAGS_NonPublic)
2548                                 match++;
2549                 }
2550                 if (!match)
2551                         continue;
2552                 match = 0;
2553                 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
2554                         if (bflags & BFLAGS_Static)
2555                                 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
2556                                         match++;
2557                 } else {
2558                         if (bflags & BFLAGS_Instance)
2559                                 match++;
2560                 }
2561
2562                 if (!match)
2563                         continue;
2564
2565                 if (name != NULL) {
2566                         if (compare_func (mname, method->name))
2567                                 continue;
2568                 }
2569                 
2570                 match = 0;
2571                 if (method->slot != -1) {
2572                         if (g_hash_table_lookup (method_slots, GUINT_TO_POINTER (method->slot)))
2573                                 continue;
2574                         g_hash_table_insert (method_slots, GUINT_TO_POINTER (method->slot), method);
2575                 }
2576                 
2577                 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
2578                 
2579                 l = g_slist_prepend (l, member);
2580                 len++;
2581         }
2582         if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
2583                 goto handle_parent;
2584
2585         g_free (mname);
2586         res = mono_array_new (domain, mono_defaults.method_info_class, len);
2587         i = 0;
2588
2589         tmp = l = g_slist_reverse (l);
2590
2591         for (; tmp; tmp = tmp->next, ++i)
2592                 mono_array_set (res, gpointer, i, tmp->data);
2593         g_slist_free (l);
2594         g_hash_table_destroy (method_slots);
2595         return res;
2596 }
2597
2598 static MonoArray*
2599 ves_icall_Type_GetConstructors_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
2600 {
2601         MonoDomain *domain; 
2602         GSList *l = NULL, *tmp;
2603         static MonoClass *System_Reflection_ConstructorInfo;
2604         MonoClass *startklass, *klass, *refklass;
2605         MonoArray *res;
2606         MonoMethod *method;
2607         MonoObject *member;
2608         int i, len, match;
2609
2610         MONO_ARCH_SAVE_REGS;
2611
2612         domain = ((MonoObject *)type)->vtable->domain;
2613         klass = startklass = mono_class_from_mono_type (type->type);
2614         refklass = mono_class_from_mono_type (reftype->type);
2615
2616         for (i = 0; i < klass->method.count; ++i) {
2617                 match = 0;
2618                 method = klass->methods [i];
2619                 if (strcmp (method->name, ".ctor") && strcmp (method->name, ".cctor"))
2620                         continue;
2621                 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
2622                         if (bflags & BFLAGS_Public)
2623                                 match++;
2624                 } else {
2625                         if (bflags & BFLAGS_NonPublic)
2626                                 match++;
2627                 }
2628                 if (!match)
2629                         continue;
2630                 match = 0;
2631                 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
2632                         if (bflags & BFLAGS_Static)
2633                                 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
2634                                         match++;
2635                 } else {
2636                         if (bflags & BFLAGS_Instance)
2637                                 match++;
2638                 }
2639
2640                 if (!match)
2641                         continue;
2642                 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
2643                         
2644                 l = g_slist_prepend (l, member);
2645         }
2646         len = g_slist_length (l);
2647         if (!System_Reflection_ConstructorInfo)
2648                 System_Reflection_ConstructorInfo = mono_class_from_name (
2649                         mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
2650         res = mono_array_new (domain, System_Reflection_ConstructorInfo, len);
2651         i = 0;
2652         tmp = l = g_slist_reverse (l);
2653         for (; tmp; tmp = tmp->next, ++i)
2654                 mono_array_set (res, gpointer, i, tmp->data);
2655         g_slist_free (l);
2656         return res;
2657 }
2658
2659 static MonoArray*
2660 ves_icall_Type_GetPropertiesByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
2661 {
2662         MonoDomain *domain; 
2663         GSList *l = NULL, *tmp;
2664         static MonoClass *System_Reflection_PropertyInfo;
2665         MonoClass *startklass, *klass;
2666         MonoArray *res;
2667         MonoMethod *method;
2668         MonoProperty *prop;
2669         int i, match;
2670         int len = 0;
2671         GHashTable *method_slots = g_hash_table_new (NULL, NULL);
2672         gchar *propname = NULL;
2673         int (*compare_func) (const char *s1, const char *s2) = NULL;
2674
2675         MONO_ARCH_SAVE_REGS;
2676
2677         domain = ((MonoObject *)type)->vtable->domain;
2678         klass = startklass = mono_class_from_mono_type (type->type);
2679         if (name != NULL) {
2680                 propname = mono_string_to_utf8 (name);
2681                 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
2682         }
2683
2684 handle_parent:
2685         for (i = 0; i < klass->property.count; ++i) {
2686                 prop = &klass->properties [i];
2687                 match = 0;
2688                 method = prop->get;
2689                 if (!method)
2690                         method = prop->set;
2691                 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
2692                         if (bflags & BFLAGS_Public)
2693                                 match++;
2694                 } else {
2695                         if (bflags & BFLAGS_NonPublic)
2696                                 match++;
2697                 }
2698                 if (!match)
2699                         continue;
2700                 match = 0;
2701                 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
2702                         if (bflags & BFLAGS_Static)
2703                                 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
2704                                         match++;
2705                 } else {
2706                         if (bflags & BFLAGS_Instance)
2707                                 match++;
2708                 }
2709
2710                 if (!match)
2711                         continue;
2712                 match = 0;
2713
2714                 if (name != NULL) {
2715                         if (compare_func (propname, prop->name))
2716                                 continue;
2717                 }
2718                 
2719                 if (method->slot != -1) {
2720                         if (g_hash_table_lookup (method_slots, GUINT_TO_POINTER (method->slot)))
2721                                 continue;
2722                         g_hash_table_insert (method_slots, GUINT_TO_POINTER (method->slot), prop);
2723                 }
2724
2725                 l = g_slist_prepend (l, mono_property_get_object (domain, startklass, prop));
2726                 len++;
2727         }
2728         if ((!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent)))
2729                 goto handle_parent;
2730
2731         g_free (propname);
2732         if (!System_Reflection_PropertyInfo)
2733                 System_Reflection_PropertyInfo = mono_class_from_name (
2734                         mono_defaults.corlib, "System.Reflection", "PropertyInfo");
2735         res = mono_array_new (domain, System_Reflection_PropertyInfo, len);
2736         i = 0;
2737
2738         tmp = l = g_slist_reverse (l);
2739
2740         for (; tmp; tmp = tmp->next, ++i)
2741                 mono_array_set (res, gpointer, i, tmp->data);
2742         g_slist_free (l);
2743         g_hash_table_destroy (method_slots);
2744         return res;
2745 }
2746
2747 static MonoReflectionEvent *
2748 ves_icall_MonoType_GetEvent (MonoReflectionType *type, MonoString *name, guint32 bflags)
2749 {
2750         MonoDomain *domain;
2751         MonoClass *klass, *startklass;
2752         gint i;
2753         MonoEvent *event;
2754         MonoMethod *method;
2755         gchar *event_name;
2756
2757         MONO_ARCH_SAVE_REGS;
2758
2759         event_name = mono_string_to_utf8 (name);
2760         klass = startklass = mono_class_from_mono_type (type->type);
2761         domain = mono_object_domain (type);
2762
2763 handle_parent:  
2764         for (i = 0; i < klass->event.count; i++) {
2765                 event = &klass->events [i];
2766                 if (strcmp (event->name, event_name))
2767                         continue;
2768
2769                 method = event->add;
2770                 if (!method)
2771                         method = event->remove;
2772
2773                 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
2774                         if (!(bflags & BFLAGS_Public))
2775                                 continue;
2776                 } else {
2777                         if (!(bflags & BFLAGS_NonPublic))
2778                                 continue;
2779                 }
2780
2781                 g_free (event_name);
2782                 return mono_event_get_object (domain, startklass, event);
2783         }
2784
2785         if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
2786                 goto handle_parent;
2787
2788         g_free (event_name);
2789         return NULL;
2790 }
2791
2792 static MonoArray*
2793 ves_icall_Type_GetEvents_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
2794 {
2795         MonoDomain *domain; 
2796         GSList *l = NULL, *tmp;
2797         static MonoClass *System_Reflection_EventInfo;
2798         MonoClass *startklass, *klass;
2799         MonoArray *res;
2800         MonoMethod *method;
2801         MonoEvent *event;
2802         int i, len, match;
2803
2804         MONO_ARCH_SAVE_REGS;
2805
2806         domain = ((MonoObject *)type)->vtable->domain;
2807         klass = startklass = mono_class_from_mono_type (type->type);
2808
2809 handle_parent:  
2810         for (i = 0; i < klass->event.count; ++i) {
2811                 event = &klass->events [i];
2812                 match = 0;
2813                 method = event->add;
2814                 if (!method)
2815                         method = event->remove;
2816                 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
2817                         if (bflags & BFLAGS_Public)
2818                                 match++;
2819                 } else {
2820                         if (bflags & BFLAGS_NonPublic)
2821                                 match++;
2822                 }
2823                 if (!match)
2824                         continue;
2825                 match = 0;
2826                 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
2827                         if (bflags & BFLAGS_Static)
2828                                 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
2829                                         match++;
2830                 } else {
2831                         if (bflags & BFLAGS_Instance)
2832                                 match++;
2833                 }
2834
2835                 if (!match)
2836                         continue;
2837                 match = 0;
2838                 l = g_slist_prepend (l, mono_event_get_object (domain, klass, event));
2839         }
2840         if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
2841                 goto handle_parent;
2842         len = g_slist_length (l);
2843         if (!System_Reflection_EventInfo)
2844                 System_Reflection_EventInfo = mono_class_from_name (
2845                         mono_defaults.corlib, "System.Reflection", "EventInfo");
2846         res = mono_array_new (domain, System_Reflection_EventInfo, len);
2847         i = 0;
2848
2849         tmp = l = g_slist_reverse (l);
2850
2851         for (; tmp; tmp = tmp->next, ++i)
2852                 mono_array_set (res, gpointer, i, tmp->data);
2853         g_slist_free (l);
2854         return res;
2855 }
2856
2857 static MonoReflectionType *
2858 ves_icall_Type_GetNestedType (MonoReflectionType *type, MonoString *name, guint32 bflags)
2859 {
2860         MonoDomain *domain; 
2861         MonoClass *startklass, *klass;
2862         MonoClass *nested;
2863         GList *tmpn;
2864         char *str;
2865         
2866         MONO_ARCH_SAVE_REGS;
2867
2868         domain = ((MonoObject *)type)->vtable->domain;
2869         klass = startklass = mono_class_from_mono_type (type->type);
2870         str = mono_string_to_utf8 (name);
2871
2872  handle_parent:
2873         for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
2874                 int match = 0;
2875                 nested = tmpn->data;
2876                 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
2877                         if (bflags & BFLAGS_Public)
2878                                 match++;
2879                 } else {
2880                         if (bflags & BFLAGS_NonPublic)
2881                                 match++;
2882                 }
2883                 if (!match)
2884                         continue;
2885                 if (strcmp (nested->name, str) == 0){
2886                         g_free (str);
2887                         return mono_type_get_object (domain, &nested->byval_arg);
2888                 }
2889         }
2890         if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
2891                 goto handle_parent;
2892         g_free (str);
2893         return NULL;
2894 }
2895
2896 static MonoArray*
2897 ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags)
2898 {
2899         MonoDomain *domain; 
2900         GSList *l = NULL, *tmp;
2901         GList *tmpn;
2902         MonoClass *startklass, *klass;
2903         MonoArray *res;
2904         MonoObject *member;
2905         int i, len, match;
2906         MonoClass *nested;
2907
2908         MONO_ARCH_SAVE_REGS;
2909
2910         domain = ((MonoObject *)type)->vtable->domain;
2911         klass = startklass = mono_class_from_mono_type (type->type);
2912
2913         for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
2914                 match = 0;
2915                 nested = tmpn->data;
2916                 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
2917                         if (bflags & BFLAGS_Public)
2918                                 match++;
2919                 } else {
2920                         if (bflags & BFLAGS_NonPublic)
2921                                 match++;
2922                 }
2923                 if (!match)
2924                         continue;
2925                 member = (MonoObject*)mono_type_get_object (domain, &nested->byval_arg);
2926                 l = g_slist_prepend (l, member);
2927         }
2928         len = g_slist_length (l);
2929         res = mono_array_new (domain, mono_defaults.monotype_class, len);
2930         i = 0;
2931         tmp = l = g_slist_reverse (l);
2932         for (; tmp; tmp = tmp->next, ++i)
2933                 mono_array_set (res, gpointer, i, tmp->data);
2934         g_slist_free (l);
2935         return res;
2936 }
2937
2938 static MonoReflectionType*
2939 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *assembly, MonoReflectionModule *module, MonoString *name, MonoBoolean throwOnError, MonoBoolean ignoreCase)
2940 {
2941         gchar *str;
2942         MonoType *type = NULL;
2943         MonoTypeNameParse info;
2944
2945         MONO_ARCH_SAVE_REGS;
2946
2947         str = mono_string_to_utf8 (name);
2948         /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
2949         if (!mono_reflection_parse_type (str, &info)) {
2950                 g_free (str);
2951                 g_list_free (info.modifiers);
2952                 g_list_free (info.nested);
2953                 if (throwOnError) /* uhm: this is a parse error, though... */
2954                         mono_raise_exception (mono_get_exception_type_load (name));
2955                 /*g_print ("failed parse\n");*/
2956                 return NULL;
2957         }
2958
2959         if (module != NULL) {
2960                 if (module->image)
2961                         type = mono_reflection_get_type (module->image, &info, ignoreCase);
2962                 else
2963                         type = NULL;
2964         }
2965         else
2966                 if (assembly->assembly->dynamic) {
2967                         /* Enumerate all modules */
2968                         MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
2969                         int i;
2970
2971                         type = NULL;
2972                         if (abuilder->modules) {
2973                                 for (i = 0; i < mono_array_length (abuilder->modules); ++i) {
2974                                         MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
2975                                         type = mono_reflection_get_type (&mb->dynamic_image->image, &info, ignoreCase);
2976                                         if (type)
2977                                                 break;
2978                                 }
2979                         }
2980
2981                         if (!type && abuilder->loaded_modules) {
2982                                 for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) {
2983                                         MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
2984                                         type = mono_reflection_get_type (mod->image, &info, ignoreCase);
2985                                         if (type)
2986                                                 break;
2987                                 }
2988                         }
2989                 }
2990                 else
2991                         type = mono_reflection_get_type (assembly->assembly->image, &info, ignoreCase);
2992         g_free (str);
2993         g_list_free (info.modifiers);
2994         g_list_free (info.nested);
2995         if (!type) {
2996                 if (throwOnError)
2997                         mono_raise_exception (mono_get_exception_type_load (name));
2998                 /* g_print ("failed find\n"); */
2999                 return NULL;
3000         }
3001         /* g_print ("got it\n"); */
3002         return mono_type_get_object (mono_object_domain (assembly), type);
3003
3004 }
3005
3006 static MonoString *
3007 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *assembly)
3008 {
3009         MonoDomain *domain = mono_object_domain (assembly); 
3010         MonoAssembly *mass = assembly->assembly;
3011         MonoString *res;
3012         gchar *uri;
3013         gchar *absolute;
3014         
3015         MONO_ARCH_SAVE_REGS;
3016
3017         absolute = g_build_filename (mass->basedir, mass->image->module_name, NULL);
3018         uri = g_filename_to_uri (absolute, NULL, NULL);
3019         res = mono_string_new (domain, uri);
3020         g_free (uri);
3021         g_free (absolute);
3022         return res;
3023 }
3024
3025 static MonoString *
3026 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssembly *assembly)
3027 {
3028         MonoDomain *domain = mono_object_domain (assembly); 
3029         MonoString *res;
3030         char *name = g_build_filename (
3031                 assembly->assembly->basedir,
3032                 assembly->assembly->image->module_name, NULL);
3033
3034         MONO_ARCH_SAVE_REGS;
3035
3036         res = mono_string_new (domain, name);
3037         g_free (name);
3038         return res;
3039 }
3040
3041 static MonoString *
3042 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssembly *assembly)
3043 {
3044         MonoDomain *domain = mono_object_domain (assembly); 
3045
3046         MONO_ARCH_SAVE_REGS;
3047
3048         return mono_string_new (domain, assembly->assembly->image->version);
3049 }
3050
3051 static MonoReflectionMethod*
3052 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssembly *assembly) 
3053 {
3054         guint32 token = mono_image_get_entry_point (assembly->assembly->image);
3055
3056         MONO_ARCH_SAVE_REGS;
3057
3058         if (!token)
3059                 return NULL;
3060         return mono_method_get_object (mono_object_domain (assembly), mono_get_method (assembly->assembly->image, token, NULL), NULL);
3061 }
3062
3063 static MonoArray*
3064 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssembly *assembly) 
3065 {
3066         MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
3067         MonoArray *result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, table->rows);
3068         int i;
3069         const char *val;
3070
3071         MONO_ARCH_SAVE_REGS;
3072
3073         for (i = 0; i < table->rows; ++i) {
3074                 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_MANIFEST_NAME));
3075                 mono_array_set (result, gpointer, i, mono_string_new (mono_object_domain (assembly), val));
3076         }
3077         return result;
3078 }
3079
3080 static MonoArray*
3081 ves_icall_System_Reflection_Assembly_GetReferencedAssemblies (MonoReflectionAssembly *assembly) 
3082 {
3083         static MonoClass *System_Reflection_AssemblyName;
3084         MonoArray *result;
3085         MonoAssembly **ptr;
3086         MonoDomain *domain = mono_object_domain (assembly);
3087         int i, count = 0;
3088
3089         MONO_ARCH_SAVE_REGS;
3090
3091         if (!System_Reflection_AssemblyName)
3092                 System_Reflection_AssemblyName = mono_class_from_name (
3093                         mono_defaults.corlib, "System.Reflection", "AssemblyName");
3094
3095         for (ptr = assembly->assembly->image->references; ptr && *ptr; ptr++)
3096                 count++;
3097
3098         result = mono_array_new (mono_object_domain (assembly), System_Reflection_AssemblyName, count);
3099
3100         for (i = 0; i < count; i++) {
3101                 MonoAssembly *assem = assembly->assembly->image->references [i];
3102                 MonoReflectionAssemblyName *aname;
3103                 char *codebase, *absolute;
3104
3105                 aname = (MonoReflectionAssemblyName *) mono_object_new (
3106                         domain, System_Reflection_AssemblyName);
3107
3108                 if (strcmp (assem->aname.name, "corlib") == 0)
3109                         aname->name = mono_string_new (domain, "mscorlib");
3110                 else
3111                         aname->name = mono_string_new (domain, assem->aname.name);
3112                 aname->major = assem->aname.major;
3113
3114                 absolute = g_build_filename (assem->basedir, assem->image->module_name, NULL);
3115                 codebase = g_filename_to_uri (absolute, NULL, NULL);
3116                 aname->codebase = mono_string_new (domain, codebase);
3117                 g_free (codebase);
3118                 g_free (absolute);
3119                 mono_array_set (result, gpointer, i, aname);
3120         }
3121         return result;
3122 }
3123
3124 typedef struct {
3125         MonoArray *res;
3126         int idx;
3127 } NameSpaceInfo;
3128
3129 static void
3130 foreach_namespace (const char* key, gconstpointer val, NameSpaceInfo *info)
3131 {
3132         MonoString *name = mono_string_new (mono_object_domain (info->res), key);
3133
3134         mono_array_set (info->res, gpointer, info->idx, name);
3135         info->idx++;
3136 }
3137
3138 static MonoArray*
3139 ves_icall_System_Reflection_Assembly_GetNamespaces (MonoReflectionAssembly *assembly) 
3140 {
3141         MonoImage *img = assembly->assembly->image;
3142         int n;
3143         MonoArray *res;
3144         NameSpaceInfo info;
3145         MonoTableInfo  *t = &img->tables [MONO_TABLE_EXPORTEDTYPE];
3146         int i;
3147
3148         MONO_ARCH_SAVE_REGS;
3149
3150         n = g_hash_table_size (img->name_cache);
3151         res = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, n);
3152         info.res = res;
3153         info.idx = 0;
3154         g_hash_table_foreach (img->name_cache, (GHFunc)foreach_namespace, &info);
3155
3156         /* Add namespaces from the EXPORTEDTYPES table as well */
3157         if (t->rows) {
3158                 MonoArray *res2;
3159                 GPtrArray *nspaces = g_ptr_array_new ();
3160                 for (i = 0; i < t->rows; ++i) {
3161                         const char *nspace = mono_metadata_string_heap (img, mono_metadata_decode_row_col (t, i, MONO_EXP_TYPE_NAMESPACE));
3162                         if (!g_hash_table_lookup (img->name_cache, nspace)) {
3163                                 g_ptr_array_add (nspaces, (char*)nspace);
3164                         }
3165                 }
3166                 if (nspaces->len > 0) {
3167                         res2 = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, n + nspaces->len);
3168                         memcpy (mono_array_addr (res2, MonoString*, 0),
3169                                         mono_array_addr (res, MonoString*, 0),
3170                                         n * sizeof (MonoString*));
3171                         for (i = 0; i < nspaces->len; ++i)
3172                                 mono_array_set (res2, MonoString*, n + i, 
3173                                                                 mono_string_new (mono_object_domain (assembly),
3174                                                                                                  g_ptr_array_index (nspaces, i)));
3175                         res = res2;
3176                 }
3177                 g_ptr_array_free (nspaces, TRUE);
3178         }
3179
3180         return res;
3181 }
3182
3183 /* move this in some file in mono/util/ */
3184 static char *
3185 g_concat_dir_and_file (const char *dir, const char *file)
3186 {
3187         g_return_val_if_fail (dir != NULL, NULL);
3188         g_return_val_if_fail (file != NULL, NULL);
3189
3190         /*
3191          * If the directory name doesn't have a / on the end, we need
3192          * to add one so we get a proper path to the file
3193          */
3194         if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
3195                 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
3196         else
3197                 return g_strconcat (dir, file, NULL);
3198 }
3199
3200 static void *
3201 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssembly *assembly, MonoString *name, gint32 *size, MonoReflectionModule **ref_module) 
3202 {
3203         char *n = mono_string_to_utf8 (name);
3204         MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
3205         guint32 i;
3206         guint32 cols [MONO_MANIFEST_SIZE];
3207         guint32 impl, file_idx;
3208         const char *val;
3209         MonoImage *module;
3210
3211         MONO_ARCH_SAVE_REGS;
3212
3213         for (i = 0; i < table->rows; ++i) {
3214                 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
3215                 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
3216                 if (strcmp (val, n) == 0)
3217                         break;
3218         }
3219         g_free (n);
3220         if (i == table->rows)
3221                 return NULL;
3222         /* FIXME */
3223         impl = cols [MONO_MANIFEST_IMPLEMENTATION];
3224         if (impl) {
3225                 /*
3226                  * this code should only be called after obtaining the 
3227                  * ResourceInfo and handling the other cases.
3228                  */
3229                 g_assert ((impl & IMPLEMENTATION_MASK) == IMPLEMENTATION_FILE);
3230                 file_idx = impl >> IMPLEMENTATION_BITS;
3231
3232                 module = mono_image_load_file_for_image (assembly->assembly->image, file_idx);
3233                 if (!module)
3234                         return NULL;
3235         }
3236         else
3237                 module = assembly->assembly->image;
3238
3239         *ref_module = mono_module_get_object (mono_domain_get (), module);
3240
3241         return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], size);
3242 }
3243
3244 static gboolean
3245 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoManifestResourceInfo *info)
3246 {
3247         MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
3248         int i;
3249         guint32 cols [MONO_MANIFEST_SIZE];
3250         guint32 file_cols [MONO_FILE_SIZE];
3251         const char *val;
3252         char *n;
3253
3254         MONO_ARCH_SAVE_REGS;
3255
3256         n = mono_string_to_utf8 (name);
3257         for (i = 0; i < table->rows; ++i) {
3258                 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
3259                 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
3260                 if (strcmp (val, n) == 0)
3261                         break;
3262         }
3263         g_free (n);
3264         if (i == table->rows)
3265                 return FALSE;
3266
3267         if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
3268                 info->location = RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST;
3269         }
3270         else {
3271                 switch (cols [MONO_MANIFEST_IMPLEMENTATION] & IMPLEMENTATION_MASK) {
3272                 case IMPLEMENTATION_FILE:
3273                         i = cols [MONO_MANIFEST_IMPLEMENTATION] >> IMPLEMENTATION_BITS;
3274                         table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
3275                         mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
3276                         val = mono_metadata_string_heap (assembly->assembly->image, file_cols [MONO_FILE_NAME]);
3277                         info->filename = mono_string_new (mono_object_domain (assembly), val);
3278                         if (file_cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA)
3279                                 info->location = 0;
3280                         else
3281                                 info->location = RESOURCE_LOCATION_EMBEDDED;
3282                         break;
3283
3284                 case IMPLEMENTATION_ASSEMBLYREF:
3285                         i = cols [MONO_MANIFEST_IMPLEMENTATION] >> IMPLEMENTATION_BITS;
3286                         info->assembly = mono_assembly_get_object (mono_domain_get (), assembly->assembly->image->references [i - 1]);
3287
3288                         // Obtain info recursively
3289                         ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (info->assembly, name, info);
3290                         info->location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
3291                         break;
3292
3293                 case IMPLEMENTATION_EXP_TYPE:
3294                         g_assert_not_reached ();
3295                         break;
3296                 }
3297         }
3298
3299         return TRUE;
3300 }
3301
3302 static MonoObject*
3303 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssembly *assembly, MonoString *name) 
3304 {
3305         MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
3306         MonoArray *result = NULL;
3307         int i;
3308         const char *val;
3309         char *n;
3310
3311         MONO_ARCH_SAVE_REGS;
3312
3313         /* check hash if needed */
3314         if (name) {
3315                 n = mono_string_to_utf8 (name);
3316                 for (i = 0; i < table->rows; ++i) {
3317                         val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
3318                         if (strcmp (val, n) == 0) {
3319                                 MonoString *fn;
3320                                 g_free (n);
3321                                 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
3322                                 fn = mono_string_new (mono_object_domain (assembly), n);
3323                                 g_free (n);
3324                                 return (MonoObject*)fn;
3325                         }
3326                 }
3327                 g_free (n);
3328                 return NULL;
3329         }
3330
3331         for (i = 0; i < table->rows; ++i) {
3332                 result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, table->rows);
3333                 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
3334                 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
3335                 mono_array_set (result, gpointer, i, mono_string_new (mono_object_domain (assembly), n));
3336                 g_free (n);
3337         }
3338         return (MonoObject*)result;
3339 }
3340
3341 static MonoArray*
3342 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly *assembly)
3343 {
3344         MonoDomain *domain = mono_domain_get();
3345         MonoArray *res;
3346         MonoClass *klass;
3347         int i, module_count = 0, file_count = 0;
3348         MonoImage **modules = assembly->assembly->image->modules;
3349         MonoTableInfo *table;
3350
3351         if (modules) {
3352                 while (modules[module_count])
3353                         ++module_count;
3354         }
3355
3356         table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
3357         file_count = table->rows;
3358
3359         g_assert( assembly->assembly->image != NULL);
3360         ++module_count;
3361
3362         klass = mono_class_from_name ( mono_defaults.corlib, "System.Reflection", "Module");
3363         res = mono_array_new (domain, klass, module_count + file_count);
3364
3365         mono_array_set (res, gpointer, 0, mono_module_get_object (domain, assembly->assembly->image));
3366         for ( i = 1; i < module_count; ++i )
3367                 mono_array_set (res, gpointer, i, mono_module_get_object (domain, modules[i]));
3368
3369         for (i = 0; i < table->rows; ++i)
3370                 mono_array_set (res, gpointer, module_count + i, mono_module_file_get_object (domain, assembly->assembly->image, i));
3371
3372         return res;
3373 }
3374
3375 static MonoReflectionMethod*
3376 ves_icall_GetCurrentMethod (void) 
3377 {
3378         MonoMethod *m = mono_method_get_last_managed ();
3379
3380         MONO_ARCH_SAVE_REGS;
3381
3382         return mono_method_get_object (mono_domain_get (), m, NULL);
3383 }
3384
3385 static MonoReflectionAssembly*
3386 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (void)
3387 {
3388         MonoMethod *m = mono_method_get_last_managed ();
3389
3390         MONO_ARCH_SAVE_REGS;
3391
3392         return mono_assembly_get_object (mono_domain_get (), m->klass->image->assembly);
3393 }
3394
3395
3396 static gboolean
3397 get_caller (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
3398 {
3399         MonoMethod **dest = data;
3400
3401         /* skip unmanaged frames */
3402         if (!managed)
3403                 return FALSE;
3404
3405         if (m == *dest) {
3406                 *dest = NULL;
3407                 return FALSE;
3408         }
3409         if (!(*dest)) {
3410                 *dest = m;
3411                 return TRUE;
3412         }
3413         return FALSE;
3414 }
3415
3416 static MonoReflectionAssembly*
3417 ves_icall_System_Reflection_Assembly_GetEntryAssembly (void)
3418 {
3419         MonoDomain* domain = mono_domain_get ();
3420
3421         MONO_ARCH_SAVE_REGS;
3422
3423         if (!domain->entry_assembly)
3424                 domain = mono_root_domain;
3425
3426         return mono_assembly_get_object (domain, domain->entry_assembly);
3427 }
3428
3429
3430 static MonoReflectionAssembly*
3431 ves_icall_System_Reflection_Assembly_GetCallingAssembly (void)
3432 {
3433         MonoMethod *m = mono_method_get_last_managed ();
3434         MonoMethod *dest = m;
3435
3436         MONO_ARCH_SAVE_REGS;
3437
3438         mono_stack_walk (get_caller, &dest);
3439         if (!dest)
3440                 dest = m;
3441         return mono_assembly_get_object (mono_domain_get (), dest->klass->image->assembly);
3442 }
3443
3444 static MonoString *
3445 ves_icall_System_MonoType_getFullName (MonoReflectionType *object)
3446 {
3447         MonoDomain *domain = mono_object_domain (object); 
3448         MonoString *res;
3449         gchar *name;
3450
3451         MONO_ARCH_SAVE_REGS;
3452
3453         name = mono_type_get_name (object->type);
3454         res = mono_string_new (domain, name);
3455         g_free (name);
3456
3457         return res;
3458 }
3459
3460 static void
3461 fill_reflection_assembly_name (MonoDomain *domain, MonoReflectionAssemblyName *aname, MonoAssemblyName *name, const char *absolute)
3462 {
3463         static MonoMethod *create_culture = NULL;
3464     gpointer args [1];
3465         guint32 pkey_len;
3466         const char *pkey_ptr;
3467         gchar *codebase;
3468
3469         MONO_ARCH_SAVE_REGS;
3470
3471         if (strcmp (name->name, "corlib") == 0)
3472                 aname->name = mono_string_new (domain, "mscorlib");
3473         else
3474                 aname->name = mono_string_new (domain, name->name);
3475
3476         aname->major = name->major;
3477         aname->minor = name->minor;
3478         aname->build = name->build;
3479         aname->revision = name->revision;
3480         aname->hashalg = name->hash_alg;
3481
3482         codebase = g_filename_to_uri (absolute, NULL, NULL);
3483         if (codebase) {
3484                 aname->codebase = mono_string_new (domain, codebase);
3485                 g_free (codebase);
3486         }
3487
3488         if (!create_culture) {
3489                 MonoMethodDesc *desc = mono_method_desc_new ("System.Globalization.CultureInfo:CreateSpecificCulture(string)", TRUE);
3490                 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
3491                 g_assert (create_culture);
3492                 mono_method_desc_free (desc);
3493         }
3494
3495         args [0] = mono_string_new (domain, name->culture);
3496         aname->cultureInfo = 
3497                 mono_runtime_invoke (create_culture, NULL, args, NULL);
3498
3499         if (name->public_key) {
3500                 pkey_ptr = name->public_key;
3501                 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
3502
3503                 aname->publicKey = mono_array_new (domain, mono_defaults.byte_class, pkey_len);
3504                 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
3505         }
3506 }
3507
3508 static void
3509 ves_icall_System_Reflection_Assembly_FillName (MonoReflectionAssembly *assembly, MonoReflectionAssemblyName *aname)
3510 {
3511         gchar *absolute;
3512
3513         MONO_ARCH_SAVE_REGS;
3514
3515         absolute = g_build_filename (assembly->assembly->basedir, assembly->assembly->image->module_name, NULL);
3516
3517         fill_reflection_assembly_name (mono_object_domain (assembly), aname, 
3518                                                                    &assembly->assembly->aname, absolute);
3519
3520         g_free (absolute);
3521 }
3522
3523 static void
3524 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoString *fname, MonoReflectionAssemblyName *aname)
3525 {
3526         char *filename;
3527         MonoImageOpenStatus status = MONO_IMAGE_OK;
3528         gboolean res;
3529         MonoImage *image;
3530         MonoAssemblyName name;
3531
3532         MONO_ARCH_SAVE_REGS;
3533
3534         filename = mono_string_to_utf8 (fname);
3535
3536         image = mono_image_open (filename, &status);
3537         
3538         if (!image){
3539                 MonoException *exc;
3540
3541                 g_free (filename);
3542                 exc = mono_get_exception_file_not_found (fname);
3543                 mono_raise_exception (exc);
3544         }
3545
3546         res = mono_assembly_fill_assembly_name (image, &name);
3547         if (!res) {
3548                 mono_image_close (image);
3549                 g_free (filename);
3550                 mono_raise_exception (mono_get_exception_argument ("assemblyFile", "The file does not contain a manifest"));
3551         }
3552
3553         fill_reflection_assembly_name (mono_domain_get (), aname, &name, filename);
3554
3555         g_free (filename);
3556         mono_image_close (image);
3557 }
3558
3559 static MonoArray*
3560 mono_module_get_types (MonoDomain *domain, MonoImage *image, 
3561                                            MonoBoolean exportedOnly)
3562 {
3563         MonoArray *res;
3564         MonoClass *klass;
3565         MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
3566         int i, count;
3567         guint32 attrs, visibility;
3568
3569         /* we start the count from 1 because we skip the special type <Module> */
3570         if (exportedOnly) {
3571                 count = 0;
3572                 for (i = 1; i < tdef->rows; ++i) {
3573                         attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
3574                         visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
3575                         if (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)
3576                                 count++;
3577                 }
3578         } else {
3579                 count = tdef->rows - 1;
3580         }
3581         res = mono_array_new (domain, mono_defaults.monotype_class, count);
3582         count = 0;
3583         for (i = 1; i < tdef->rows; ++i) {
3584                 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
3585                 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
3586                 if (!exportedOnly || (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)) {
3587                         klass = mono_class_get (image, (i + 1) | MONO_TOKEN_TYPE_DEF);
3588                         mono_array_set (res, gpointer, count, mono_type_get_object (domain, &klass->byval_arg));
3589                         count++;
3590                 }
3591         }
3592         
3593         return res;
3594 }
3595
3596 static MonoArray*
3597 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly, MonoBoolean exportedOnly)
3598 {
3599         MonoArray *res;
3600         MonoImage *image = assembly->assembly->image;
3601         MonoTableInfo *table = &image->tables [MONO_TABLE_FILE];
3602         MonoDomain *domain;
3603         int i;
3604
3605         MONO_ARCH_SAVE_REGS;
3606
3607         domain = mono_object_domain (assembly);
3608         res = mono_module_get_types (domain, image, exportedOnly);
3609
3610         /* Append data from all modules in the assembly */
3611         for (i = 0; i < table->rows; ++i) {
3612                 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
3613                         MonoImage *loaded_image = mono_assembly_load_module (image->assembly, i + 1);
3614                         if (loaded_image) {
3615                                 MonoArray *res2 = mono_module_get_types (domain, loaded_image, exportedOnly);
3616                                 /* Append the new types to the end of the array */
3617                                 if (mono_array_length (res2) > 0) {
3618                                         guint32 len1, len2;
3619                                         MonoArray *res3;
3620
3621                                         len1 = mono_array_length (res);
3622                                         len2 = mono_array_length (res2);
3623                                         res3 = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
3624                                         memcpy (mono_array_addr (res3, MonoReflectionType*, 0),
3625                                                         mono_array_addr (res, MonoReflectionType*, 0),
3626                                                         len1 * sizeof (MonoReflectionType*));
3627                                         memcpy (mono_array_addr (res3, MonoReflectionType*, len1),
3628                                                         mono_array_addr (res2, MonoReflectionType*, 0),
3629                                                         len2 * sizeof (MonoReflectionType*));
3630                                         res = res3;
3631                                 }
3632                         }
3633                 }
3634         }               
3635
3636         return res;
3637 }
3638
3639 static MonoReflectionType*
3640 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModule *module)
3641 {
3642         MonoDomain *domain = mono_object_domain (module); 
3643         MonoClass *klass;
3644
3645         MONO_ARCH_SAVE_REGS;
3646
3647         g_assert (module->image);
3648         klass = mono_class_get (module->image, 1 | MONO_TOKEN_TYPE_DEF);
3649         return mono_type_get_object (domain, &klass->byval_arg);
3650 }
3651
3652 static void
3653 ves_icall_System_Reflection_Module_Close (MonoReflectionModule *module)
3654 {
3655         if (module->image)
3656                 mono_image_close (module->image);
3657 }
3658
3659 static MonoString*
3660 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModule *module)
3661 {
3662         MonoDomain *domain = mono_object_domain (module); 
3663
3664         MONO_ARCH_SAVE_REGS;
3665
3666         g_assert (module->image);
3667         return mono_string_new (domain, module->image->guid);
3668 }
3669
3670 static MonoArray*
3671 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModule *module)
3672 {
3673         MONO_ARCH_SAVE_REGS;
3674
3675         if (!module->image)
3676                 return mono_array_new (mono_object_domain (module), mono_defaults.monotype_class, 0);
3677         else
3678                 return mono_module_get_types (mono_object_domain (module), module->image, FALSE);
3679 }
3680
3681 static MonoReflectionType*
3682 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
3683 {
3684         MonoClass *klass;
3685         int isbyref = 0, rank;
3686         char *str = mono_string_to_utf8 (smodifiers);
3687         char *p;
3688
3689         MONO_ARCH_SAVE_REGS;
3690
3691         klass = mono_class_from_mono_type (tb->type.type);
3692         p = str;
3693         /* logic taken from mono_reflection_parse_type(): keep in sync */
3694         while (*p) {
3695                 switch (*p) {
3696                 case '&':
3697                         if (isbyref) { /* only one level allowed by the spec */
3698                                 g_free (str);
3699                                 return NULL;
3700                         }
3701                         isbyref = 1;
3702                         p++;
3703                         g_free (str);
3704                         return mono_type_get_object (mono_object_domain (tb), &klass->this_arg);
3705                         break;
3706                 case '*':
3707                         klass = mono_ptr_class_get (&klass->byval_arg);
3708                         mono_class_init (klass);
3709                         p++;
3710                         break;
3711                 case '[':
3712                         rank = 1;
3713                         p++;
3714                         while (*p) {
3715                                 if (*p == ']')
3716                                         break;
3717                                 if (*p == ',')
3718                                         rank++;
3719                                 else if (*p != '*') { /* '*' means unknown lower bound */
3720                                         g_free (str);
3721                                         return NULL;
3722                                 }
3723                                 ++p;
3724                         }
3725                         if (*p != ']') {
3726                                 g_free (str);
3727                                 return NULL;
3728                         }
3729                         p++;
3730                         klass = mono_array_class_get (klass, rank);
3731                         mono_class_init (klass);
3732                         break;
3733                 default:
3734                         break;
3735                 }
3736         }
3737         g_free (str);
3738         return mono_type_get_object (mono_object_domain (tb), &klass->byval_arg);
3739 }
3740
3741 static MonoBoolean
3742 ves_icall_Type_IsArrayImpl (MonoReflectionType *t)
3743 {
3744         MonoType *type;
3745         MonoBoolean res;
3746
3747         MONO_ARCH_SAVE_REGS;
3748
3749         type = t->type;
3750         res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
3751
3752         return res;
3753 }
3754
3755 static MonoReflectionType *
3756 ves_icall_Type_make_array_type (MonoReflectionType *type, int rank)
3757 {
3758         MonoClass *klass, *aklass;
3759
3760         MONO_ARCH_SAVE_REGS;
3761
3762         klass = mono_class_from_mono_type (type->type);
3763         aklass = mono_array_class_get (klass, rank);
3764
3765         return mono_type_get_object (mono_object_domain (type), &aklass->byval_arg);
3766 }
3767
3768 static MonoReflectionType *
3769 ves_icall_Type_make_byref_type (MonoReflectionType *type)
3770 {
3771         MonoClass *klass;
3772
3773         MONO_ARCH_SAVE_REGS;
3774
3775         klass = mono_class_from_mono_type (type->type);
3776
3777         return mono_type_get_object (mono_object_domain (type), &klass->this_arg);
3778 }
3779
3780 static MonoObject *
3781 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
3782                                                    MonoReflectionMethod *info)
3783 {
3784         MonoClass *delegate_class = mono_class_from_mono_type (type->type);
3785         MonoObject *delegate;
3786         gpointer func;
3787
3788         MONO_ARCH_SAVE_REGS;
3789
3790         mono_assert (delegate_class->parent == mono_defaults.multicastdelegate_class);
3791
3792         delegate = mono_object_new (mono_object_domain (type), delegate_class);
3793
3794         func = mono_compile_method (info->method);
3795
3796         mono_delegate_ctor (delegate, target, func);
3797
3798         return delegate;
3799 }
3800
3801 /*
3802  * Magic number to convert a time which is relative to
3803  * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
3804  */
3805 #define EPOCH_ADJUST    ((guint64)62135596800LL)
3806
3807 /*
3808  * Magic number to convert FILETIME base Jan 1, 1601 to DateTime - base Jan, 1, 0001
3809  */
3810 #define FILETIME_ADJUST ((guint64)504911232000000000LL)
3811
3812 /*
3813  * This returns Now in UTC
3814  */
3815 static gint64
3816 ves_icall_System_DateTime_GetNow (void)
3817 {
3818 #ifdef PLATFORM_WIN32
3819         SYSTEMTIME st;
3820         FILETIME ft;
3821         
3822         GetLocalTime (&st);
3823         SystemTimeToFileTime (&st, &ft);
3824         return (gint64) FILETIME_ADJUST + ((((gint64)ft.dwHighDateTime)<<32) | ft.dwLowDateTime);
3825 #else
3826         /* FIXME: put this in io-layer and call it GetLocalTime */
3827         struct timeval tv;
3828         gint64 res;
3829
3830         MONO_ARCH_SAVE_REGS;
3831
3832         if (gettimeofday (&tv, NULL) == 0) {
3833                 res = (((gint64)tv.tv_sec + EPOCH_ADJUST)* 1000000 + tv.tv_usec)*10;
3834                 return res;
3835         }
3836         /* fixme: raise exception */
3837         return 0;
3838 #endif
3839 }
3840
3841 #ifdef PLATFORM_WIN32
3842 /* convert a SYSTEMTIME which is of the form "last thursday in october" to a real date */
3843 static void
3844 convert_to_absolute_date(SYSTEMTIME *date)
3845 {
3846 #define IS_LEAP(y) ((y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0))
3847         static int days_in_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
3848         static int leap_days_in_month[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
3849         /* from the calendar FAQ */
3850         int a = (14 - date->wMonth) / 12;
3851         int y = date->wYear - a;
3852         int m = date->wMonth + 12 * a - 2;
3853         int d = (1 + y + y/4 - y/100 + y/400 + (31*m)/12) % 7;
3854
3855         /* d is now the day of the week for the first of the month (0 == Sunday) */
3856
3857         int day_of_week = date->wDayOfWeek;
3858
3859         /* set day_in_month to the first day in the month which falls on day_of_week */    
3860         int day_in_month = 1 + (day_of_week - d);
3861         if (day_in_month <= 0)
3862                 day_in_month += 7;
3863
3864         /* wDay is 1 for first weekday in month, 2 for 2nd ... 5 means last - so work that out allowing for days in the month */
3865         date->wDay = day_in_month + (date->wDay - 1) * 7;
3866         if (date->wDay > (IS_LEAP(date->wYear) ? leap_days_in_month[date->wMonth - 1] : days_in_month[date->wMonth - 1]))
3867                 date->wDay -= 7;
3868 }
3869 #endif
3870
3871 #ifndef PLATFORM_WIN32
3872 /*
3873  * Return's the offset from GMT of a local time.
3874  * 
3875  *  tm is a local time
3876  *  t  is the same local time as seconds.
3877  */
3878 static int 
3879 gmt_offset(struct tm *tm, time_t t)
3880 {
3881 #if defined (HAVE_TM_GMTOFF)
3882         return tm->tm_gmtoff;
3883 #else
3884         struct tm g;
3885         time_t t2;
3886         g = *gmtime(&t);
3887         g.tm_isdst = tm->tm_isdst;
3888         t2 = mktime(&g);
3889         return (int)difftime(t, t2);
3890 #endif
3891 }
3892 #endif
3893 /*
3894  * This is heavily based on zdump.c from glibc 2.2.
3895  *
3896  *  * data[0]:  start of daylight saving time (in DateTime ticks).
3897  *  * data[1]:  end of daylight saving time (in DateTime ticks).
3898  *  * data[2]:  utcoffset (in TimeSpan ticks).
3899  *  * data[3]:  additional offset when daylight saving (in TimeSpan ticks).
3900  *  * name[0]:  name of this timezone when not daylight saving.
3901  *  * name[1]:  name of this timezone when daylight saving.
3902  *
3903  *  FIXME: This only works with "standard" Unix dates (years between 1900 and 2100) while
3904  *         the class library allows years between 1 and 9999.
3905  *
3906  *  Returns true on success and zero on failure.
3907  */
3908 static guint32
3909 ves_icall_System_CurrentTimeZone_GetTimeZoneData (guint32 year, MonoArray **data, MonoArray **names)
3910 {
3911 #ifndef PLATFORM_WIN32
3912         MonoDomain *domain = mono_domain_get ();
3913         struct tm start, tt;
3914         time_t t;
3915
3916         long int gmtoff;
3917         int is_daylight = 0, day;
3918         char tzone [64];
3919
3920         MONO_ARCH_SAVE_REGS;
3921
3922         MONO_CHECK_ARG_NULL (data);
3923         MONO_CHECK_ARG_NULL (names);
3924
3925         (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
3926         (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
3927
3928         /* 
3929          * no info is better than crashing: we'll need our own tz data to make 
3930          * this work properly, anyway. The range is reduced to 1970 .. 2037 because
3931          * that is what mktime is guaranteed to support (we get into an infinite loop 
3932          * otherwise).
3933          */
3934         if ((year < 1970) || (year > 2037)) {
3935                 t = time (NULL);
3936                 tt = *localtime (&t);
3937                 strftime (tzone, sizeof (tzone), "%Z", &tt);
3938                 mono_array_set ((*names), gpointer, 0, mono_string_new (domain, tzone));
3939                 mono_array_set ((*names), gpointer, 1, mono_string_new (domain, tzone));
3940                 return 1;
3941         }
3942
3943         memset (&start, 0, sizeof (start));
3944
3945         start.tm_mday = 1;
3946         start.tm_year = year-1900;
3947
3948         t = mktime (&start);
3949         gmtoff = gmt_offset (&start, t);
3950
3951         /* For each day of the year, calculate the tm_gmtoff. */
3952         for (day = 0; day < 365; day++) {
3953
3954                 t += 3600*24;
3955                 tt = *localtime (&t);
3956
3957                 /* Daylight saving starts or ends here. */
3958                 if (gmt_offset (&tt, t) != gmtoff) {
3959                         struct tm tt1;
3960                         time_t t1;
3961
3962                         /* Try to find the exact hour when daylight saving starts/ends. */
3963                         t1 = t;
3964                         do {
3965                                 t1 -= 3600;
3966                                 tt1 = *localtime (&t1);
3967                         } while (gmt_offset (&tt1, t1) != gmtoff);
3968
3969                         /* Try to find the exact minute when daylight saving starts/ends. */
3970                         do {
3971                                 t1 += 60;
3972                                 tt1 = *localtime (&t1);
3973                         } while (gmt_offset (&tt1, t1) == gmtoff);
3974                         
3975                         strftime (tzone, sizeof (tzone), "%Z", &tt);
3976                         
3977                         /* Write data, if we're already in daylight saving, we're done. */
3978                         if (is_daylight) {
3979                                 mono_array_set ((*names), gpointer, 0, mono_string_new (domain, tzone));
3980                                 mono_array_set ((*data), gint64, 1, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
3981                                 return 1;
3982                         } else {
3983                                 mono_array_set ((*names), gpointer, 1, mono_string_new (domain, tzone));
3984                                 mono_array_set ((*data), gint64, 0, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
3985                                 is_daylight = 1;
3986                         }
3987
3988                         /* This is only set once when we enter daylight saving. */
3989                         mono_array_set ((*data), gint64, 2, (gint64)gmtoff * 10000000L);
3990                         mono_array_set ((*data), gint64, 3, (gint64)(gmt_offset (&tt, t) - gmtoff) * 10000000L);
3991
3992                         gmtoff = gmt_offset (&tt, t);
3993                 }
3994         }
3995
3996         if (!is_daylight) {
3997                 strftime (tzone, sizeof (tzone), "%Z", &tt);
3998                 mono_array_set ((*names), gpointer, 0, mono_string_new (domain, tzone));
3999                 mono_array_set ((*names), gpointer, 1, mono_string_new (domain, tzone));
4000                 mono_array_set ((*data), gint64, 0, 0);
4001                 mono_array_set ((*data), gint64, 1, 0);
4002                 mono_array_set ((*data), gint64, 2, (gint64) gmtoff * 10000000L);
4003                 mono_array_set ((*data), gint64, 3, 0);
4004         }
4005
4006         return 1;
4007 #else
4008         MonoDomain *domain = mono_domain_get ();
4009         TIME_ZONE_INFORMATION tz_info;
4010         FILETIME ft;
4011         int i;
4012         int err, tz_id;
4013
4014         tz_id = GetTimeZoneInformation (&tz_info);
4015         if (tz_id == TIME_ZONE_ID_INVALID)
4016                 return 0;
4017
4018         MONO_CHECK_ARG_NULL (data);
4019         MONO_CHECK_ARG_NULL (names);
4020
4021         (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
4022         (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
4023
4024         for (i = 0; i < 32; ++i)
4025                 if (!tz_info.DaylightName [i])
4026                         break;
4027         mono_array_set ((*names), gpointer, 1, mono_string_new_utf16 (domain, tz_info.DaylightName, i));
4028         for (i = 0; i < 32; ++i)
4029                 if (!tz_info.StandardName [i])
4030                         break;
4031         mono_array_set ((*names), gpointer, 0, mono_string_new_utf16 (domain, tz_info.StandardName, i));
4032
4033         if ((year <= 1601) || (year > 30827)) {
4034                 /*
4035                  * According to MSDN, the MS time functions can't handle dates outside
4036                  * this interval.
4037                  */
4038                 return 1;
4039         }
4040
4041         /* even if the timezone has no daylight savings it may have Bias (e.g. GMT+13 it seems) */
4042         if (tz_id != TIME_ZONE_ID_UNKNOWN) {
4043                 tz_info.StandardDate.wYear = year;
4044                 convert_to_absolute_date(&tz_info.StandardDate);
4045                 err = SystemTimeToFileTime (&tz_info.StandardDate, &ft);
4046                 g_assert(err);
4047                 mono_array_set ((*data), gint64, 1, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
4048                 tz_info.DaylightDate.wYear = year;
4049                 convert_to_absolute_date(&tz_info.DaylightDate);
4050                 err = SystemTimeToFileTime (&tz_info.DaylightDate, &ft);
4051                 g_assert(err);
4052                 mono_array_set ((*data), gint64, 0, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
4053         }
4054         mono_array_set ((*data), gint64, 2, (tz_info.Bias + tz_info.StandardBias) * -600000000LL);
4055         mono_array_set ((*data), gint64, 3, (tz_info.DaylightBias - tz_info.StandardBias) * -600000000LL);
4056
4057         return 1;
4058 #endif
4059 }
4060
4061 static gpointer
4062 ves_icall_System_Object_obj_address (MonoObject *this) 
4063 {
4064         MONO_ARCH_SAVE_REGS;
4065
4066         return this;
4067 }
4068
4069 /* System.Buffer */
4070
4071 static gint32 
4072 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array) 
4073 {
4074         MonoClass *klass;
4075         MonoTypeEnum etype;
4076         int length, esize;
4077         int i;
4078
4079         MONO_ARCH_SAVE_REGS;
4080
4081         klass = array->obj.vtable->klass;
4082         etype = klass->element_class->byval_arg.type;
4083         if (etype < MONO_TYPE_BOOLEAN || etype > MONO_TYPE_R8)
4084                 return -1;
4085
4086         if (array->bounds == NULL)
4087                 length = array->max_length;
4088         else {
4089                 length = 1;
4090                 for (i = 0; i < klass->rank; ++ i)
4091                         length *= array->bounds [i].length;
4092         }
4093
4094         esize = mono_array_element_size (klass);
4095         return length * esize;
4096 }
4097
4098 static gint8 
4099 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx) 
4100 {
4101         MONO_ARCH_SAVE_REGS;
4102
4103         return mono_array_get (array, gint8, idx);
4104 }
4105
4106 static void 
4107 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value) 
4108 {
4109         MONO_ARCH_SAVE_REGS;
4110
4111         mono_array_set (array, gint8, idx, value);
4112 }
4113
4114 static void 
4115 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count) 
4116 {
4117         char *src_buf, *dest_buf;
4118
4119         MONO_ARCH_SAVE_REGS;
4120
4121         src_buf = (gint8 *)src->vector + src_offset;
4122         dest_buf = (gint8 *)dest->vector + dest_offset;
4123
4124         memcpy (dest_buf, src_buf, count);
4125 }
4126
4127 static MonoObject *
4128 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this, MonoString *class_name)
4129 {
4130         MonoDomain *domain = mono_object_domain (this); 
4131         MonoObject *res;
4132         MonoRealProxy *rp = ((MonoRealProxy *)this);
4133         MonoTransparentProxy *tp;
4134         MonoType *type;
4135         MonoClass *klass;
4136
4137         MONO_ARCH_SAVE_REGS;
4138
4139         res = mono_object_new (domain, mono_defaults.transparent_proxy_class);
4140         tp = (MonoTransparentProxy*) res;
4141         
4142         tp->rp = rp;
4143         type = ((MonoReflectionType *)rp->class_to_proxy)->type;
4144         klass = mono_class_from_mono_type (type);
4145
4146         tp->custom_type_info = (mono_object_isinst (this, mono_defaults.iremotingtypeinfo_class) != NULL);
4147         tp->remote_class = mono_remote_class (domain, class_name, klass);
4148         res->vtable = tp->remote_class->vtable;
4149
4150         return res;
4151 }
4152
4153 static MonoReflectionType *
4154 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
4155 {
4156         return mono_type_get_object (mono_object_domain (tp), &tp->remote_class->proxy_class->byval_arg);
4157 }
4158
4159 /* System.Environment */
4160
4161 static MonoString *
4162 ves_icall_System_Environment_get_MachineName (void)
4163 {
4164 #if defined (PLATFORM_WIN32)
4165         gunichar2 *buf;
4166         guint32 len;
4167         MonoString *result;
4168
4169         len = MAX_COMPUTERNAME_LENGTH + 1;
4170         buf = g_new (gunichar2, len);
4171
4172         result = NULL;
4173         if (GetComputerName (buf, (PDWORD) &len))
4174                 result = mono_string_new_utf16 (mono_domain_get (), buf, len);
4175
4176         g_free (buf);
4177         return result;
4178 #else
4179         gchar *buf;
4180         int len;
4181         MonoString *result;
4182
4183         MONO_ARCH_SAVE_REGS;
4184
4185         len = 256;
4186         buf = g_new (gchar, len);
4187
4188         result = NULL;
4189         if (gethostname (buf, len) == 0)
4190                 result = mono_string_new (mono_domain_get (), buf);
4191         
4192         g_free (buf);
4193         return result;
4194 #endif
4195 }
4196
4197 static int
4198 ves_icall_System_Environment_get_Platform (void)
4199 {
4200         MONO_ARCH_SAVE_REGS;
4201
4202 #if defined (PLATFORM_WIN32)
4203         /* Win32NT */
4204         return 2;
4205 #else
4206         /* Unix */
4207         return 128;
4208 #endif
4209 }
4210
4211 static MonoString *
4212 ves_icall_System_Environment_get_NewLine (void)
4213 {
4214         MONO_ARCH_SAVE_REGS;
4215
4216 #if defined (PLATFORM_WIN32)
4217         return mono_string_new (mono_domain_get (), "\r\n");
4218 #else
4219         return mono_string_new (mono_domain_get (), "\n");
4220 #endif
4221 }
4222
4223 static MonoString *
4224 ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name)
4225 {
4226         const gchar *value;
4227         gchar *utf8_name;
4228
4229         MONO_ARCH_SAVE_REGS;
4230
4231         if (name == NULL)
4232                 return NULL;
4233
4234         utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
4235         value = g_getenv (utf8_name);
4236         g_free (utf8_name);
4237
4238         if (value == 0)
4239                 return NULL;
4240         
4241         return mono_string_new (mono_domain_get (), value);
4242 }
4243
4244 /*
4245  * There is no standard way to get at environ.
4246  */
4247 #ifndef _MSC_VER
4248 extern
4249 #endif
4250 char **environ;
4251
4252 static MonoArray *
4253 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
4254 {
4255         MonoArray *names;
4256         MonoDomain *domain;
4257         MonoString *str;
4258         gchar **e, **parts;
4259         int n;
4260
4261         MONO_ARCH_SAVE_REGS;
4262
4263         n = 0;
4264         for (e = environ; *e != 0; ++ e)
4265                 ++ n;
4266
4267         domain = mono_domain_get ();
4268         names = mono_array_new (domain, mono_defaults.string_class, n);
4269
4270         n = 0;
4271         for (e = environ; *e != 0; ++ e) {
4272                 parts = g_strsplit (*e, "=", 2);
4273                 if (*parts != 0) {
4274                         str = mono_string_new (domain, *parts);
4275                         mono_array_set (names, MonoString *, n, str);
4276                 }
4277
4278                 g_strfreev (parts);
4279
4280                 ++ n;
4281         }
4282
4283         return names;
4284 }
4285
4286 /*
4287  * Returns the number of milliseconds elapsed since the system started.
4288  */
4289 static gint32
4290 ves_icall_System_Environment_get_TickCount (void)
4291 {
4292 #if defined (PLATFORM_WIN32)
4293         return GetTickCount();
4294 #else
4295         struct timeval tv;
4296         struct timezone tz;
4297         gint32 res;
4298
4299         MONO_ARCH_SAVE_REGS;
4300
4301         res = (gint32) gettimeofday (&tv, &tz);
4302
4303         if (res != -1)
4304                 res = (gint32) ((tv.tv_sec & 0xFFFFF) * 1000 + (tv.tv_usec / 1000));
4305         return res;
4306 #endif
4307 }
4308
4309
4310 static void
4311 ves_icall_System_Environment_Exit (int result)
4312 {
4313         MONO_ARCH_SAVE_REGS;
4314
4315         mono_runtime_quit ();
4316
4317         /* we may need to do some cleanup here... */
4318         exit (result);
4319 }
4320
4321 static MonoString*
4322 ves_icall_System_Environment_GetGacPath (void)
4323 {
4324         return mono_string_new (mono_domain_get (), MONO_ASSEMBLIES);
4325 }
4326
4327 static MonoString*
4328 ves_icall_System_Text_Encoding_InternalCodePage (void) 
4329 {
4330         const char *cset;
4331
4332         MONO_ARCH_SAVE_REGS;
4333
4334         g_get_charset (&cset);
4335         /* g_print ("charset: %s\n", cset); */
4336         /* handle some common aliases */
4337         switch (*cset) {
4338         case 'A':
4339                 if (strcmp (cset, "ANSI_X3.4-1968") == 0)
4340                         cset = "us-ascii";
4341                 break;
4342         }
4343         return mono_string_new (mono_domain_get (), cset);
4344 }
4345
4346 static MonoBoolean
4347 ves_icall_System_Environment_get_HasShutdownStarted (void)
4348 {
4349         if (mono_runtime_is_shutting_down ())
4350                 return TRUE;
4351
4352         if (mono_domain_is_unloading (mono_domain_get ()))
4353                 return TRUE;
4354
4355         return FALSE;
4356 }
4357
4358 static void
4359 ves_icall_MonoMethodMessage_InitMessage (MonoMethodMessage *this, 
4360                                          MonoReflectionMethod *method,
4361                                          MonoArray *out_args)
4362 {
4363         MONO_ARCH_SAVE_REGS;
4364
4365         mono_message_init (mono_object_domain (this), this, method, out_args);
4366 }
4367
4368 static MonoBoolean
4369 ves_icall_IsTransparentProxy (MonoObject *proxy)
4370 {
4371         MONO_ARCH_SAVE_REGS;
4372
4373         if (!proxy)
4374                 return 0;
4375
4376         if (proxy->vtable->klass == mono_defaults.transparent_proxy_class)
4377                 return 1;
4378
4379         return 0;
4380 }
4381
4382 static void
4383 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
4384 {
4385         MonoClass *klass;
4386         MonoVTable* vtable;
4387
4388         MONO_ARCH_SAVE_REGS;
4389
4390         klass = mono_class_from_mono_type (type->type);
4391         vtable = mono_class_vtable (mono_domain_get (), klass);
4392
4393         if (enable) vtable->remote = 1;
4394         else vtable->remote = 0;
4395 }
4396
4397 static MonoObject *
4398 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type)
4399 {
4400         MonoClass *klass;
4401         MonoDomain *domain;
4402         
4403         MONO_ARCH_SAVE_REGS;
4404
4405         domain = mono_object_domain (type);
4406         klass = mono_class_from_mono_type (type->type);
4407
4408         if (klass->rank >= 1) {
4409                 g_assert (klass->rank == 1);
4410                 return (MonoObject *) mono_array_new (domain, klass->element_class, 0);
4411         } else {
4412                 // Bypass remoting object creation check
4413                 return mono_object_new_alloc_specific (mono_class_vtable (domain, klass));
4414         }
4415 }
4416
4417 static MonoString *
4418 ves_icall_System_IO_get_temp_path (void)
4419 {
4420         MONO_ARCH_SAVE_REGS;
4421
4422         return mono_string_new (mono_domain_get (), g_get_tmp_dir ());
4423 }
4424
4425 static gpointer
4426 ves_icall_RuntimeMethod_GetFunctionPointer (MonoMethod *method)
4427 {
4428         MONO_ARCH_SAVE_REGS;
4429
4430         return mono_compile_method (method);
4431 }
4432
4433 char const * mono_cfg_dir = "";
4434
4435 void    
4436 mono_install_get_config_dir (void)
4437 {
4438 #ifdef PLATFORM_WIN32
4439   int i;
4440 #endif
4441
4442   mono_cfg_dir = getenv ("MONO_CFG_DIR");
4443
4444   if (!mono_cfg_dir) {
4445 #ifndef PLATFORM_WIN32
4446     mono_cfg_dir = MONO_CFG_DIR;
4447 #else
4448     mono_cfg_dir = g_strdup (MONO_CFG_DIR);
4449     for (i = strlen (mono_cfg_dir) - 1; i >= 0; i--) {
4450         if (mono_cfg_dir [i] == '/')
4451             ((char*) mono_cfg_dir) [i] = '\\';
4452     }
4453 #endif
4454   }
4455 }
4456
4457
4458 static MonoString *
4459 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
4460 {
4461         MonoString *mcpath;
4462         gchar *path;
4463
4464         MONO_ARCH_SAVE_REGS;
4465
4466         path = g_build_path (G_DIR_SEPARATOR_S, mono_cfg_dir, "mono", "machine.config", NULL);
4467
4468 #if defined (PLATFORM_WIN32)
4469         /* Avoid mixing '/' and '\\' */
4470         {
4471                 gint i;
4472                 for (i = strlen (path) - 1; i >= 0; i--)
4473                         if (path [i] == '/')
4474                                 path [i] = '\\';
4475         }
4476 #endif
4477         mcpath = mono_string_new (mono_domain_get (), path);
4478         g_free (path);
4479
4480         return mcpath;
4481 }
4482
4483 static MonoString *
4484 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
4485 {
4486         MonoString *ipath;
4487         gchar *path;
4488
4489         MONO_ARCH_SAVE_REGS;
4490
4491         path = g_path_get_dirname (mono_cfg_dir);
4492
4493 #if defined (PLATFORM_WIN32)
4494         /* Avoid mixing '/' and '\\' */
4495         {
4496                 gint i;
4497                 for (i = strlen (path) - 1; i >= 0; i--)
4498                         if (path [i] == '/')
4499                                 path [i] = '\\';
4500         }
4501 #endif
4502         ipath = mono_string_new (mono_domain_get (), path);
4503         g_free (path);
4504
4505         return ipath;
4506 }
4507
4508 static void
4509 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
4510 {
4511 #if defined (PLATFORM_WIN32)
4512         static void (*output_debug) (gchar *);
4513         static gboolean tried_loading = FALSE;
4514
4515         MONO_ARCH_SAVE_REGS;
4516
4517         if (!tried_loading && output_debug == NULL) {
4518                 GModule *k32;
4519
4520                 tried_loading = TRUE;
4521                 k32 = g_module_open ("kernel32", G_MODULE_BIND_LAZY);
4522                 if (!k32) {
4523                         gchar *error = g_strdup (g_module_error ());
4524                         g_warning ("Failed to load kernel32.dll: %s\n", error);
4525                         g_free (error);
4526                         return;
4527                 }
4528
4529                 g_module_symbol (k32, "OutputDebugStringW", (gpointer *) &output_debug);
4530                 if (!output_debug) {
4531                         gchar *error = g_strdup (g_module_error ());
4532                         g_warning ("Failed to load OutputDebugStringW: %s\n", error);
4533                         g_free (error);
4534                         return;
4535                 }
4536         }
4537
4538         if (output_debug == NULL)
4539                 return;
4540         
4541         output_debug (mono_string_chars (message));
4542 #else
4543         g_warning ("WriteWindowsDebugString called and PLATFORM_WIN32 not defined!\n");
4544 #endif
4545 }
4546
4547 /* Only used for value types */
4548 static MonoObject *
4549 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
4550 {
4551         MonoClass *klass;
4552         MonoDomain *domain;
4553         
4554         MONO_ARCH_SAVE_REGS;
4555
4556         domain = mono_object_domain (type);
4557         klass = mono_class_from_mono_type (type->type);
4558
4559         return mono_object_new (domain, klass);
4560 }
4561
4562 static MonoReflectionMethod *
4563 ves_icall_MonoMethod_get_base_definition (MonoReflectionMethod *m)
4564 {
4565         MonoClass *klass;
4566         MonoMethod *method = m->method;
4567         MonoMethod *result = NULL;
4568
4569         MONO_ARCH_SAVE_REGS;
4570
4571         if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
4572             MONO_CLASS_IS_INTERFACE (method->klass) ||
4573             method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
4574                 return m;
4575
4576         if (method->klass == NULL || (klass = method->klass->parent) == NULL)
4577                 return m;
4578
4579         if (klass->generic_inst)
4580                 klass = mono_class_from_mono_type (klass->generic_inst->generic_type);
4581
4582         while (result == NULL && klass != NULL && (klass->vtable_size > method->slot))
4583         {
4584                 result = klass->vtable [method->slot];
4585                 if (result == NULL) {
4586                         /* It is an abstract method */
4587                         int i;
4588                         for (i=0; i<klass->method.count; i++) {
4589                                 if (klass->methods [i]->slot == method->slot) {
4590                                         result = klass->methods [i];
4591                                         break;
4592                                 }
4593                         }
4594                 }
4595                 klass = klass->parent;
4596         }
4597
4598         if (result == NULL)
4599                 return m;
4600
4601         return mono_method_get_object (mono_domain_get (), result, NULL);
4602 }
4603
4604 static void
4605 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
4606 {
4607         MONO_ARCH_SAVE_REGS;
4608
4609         iter->sig = *(MonoMethodSignature**)argsp;
4610         
4611         g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
4612         g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
4613
4614         iter->next_arg = 0;
4615         /* FIXME: it's not documented what start is exactly... */
4616         iter->args = start? start: argsp + sizeof (gpointer);
4617         iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
4618
4619         // g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos);
4620 }
4621
4622 static MonoTypedRef
4623 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
4624 {
4625         gint i, align, arg_size;
4626         MonoTypedRef res;
4627         MONO_ARCH_SAVE_REGS;
4628
4629         i = iter->sig->sentinelpos + iter->next_arg;
4630
4631         g_assert (i < iter->sig->param_count);
4632
4633         res.type = iter->sig->params [i];
4634         res.klass = mono_class_from_mono_type (res.type);
4635         /* FIXME: endianess issue... */
4636         res.value = iter->args;
4637         arg_size = mono_type_stack_size (res.type, &align);
4638         iter->args = (char*)iter->args + arg_size;
4639         iter->next_arg++;
4640
4641         //g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value);
4642
4643         return res;
4644 }
4645
4646 static MonoTypedRef
4647 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
4648 {
4649         gint i, align, arg_size;
4650         MonoTypedRef res;
4651         MONO_ARCH_SAVE_REGS;
4652
4653         i = iter->sig->sentinelpos + iter->next_arg;
4654
4655         g_assert (i < iter->sig->param_count);
4656
4657         while (i < iter->sig->param_count) {
4658                 if (!mono_metadata_type_equal (type, iter->sig->params [i]))
4659                         continue;
4660                 res.type = iter->sig->params [i];
4661                 res.klass = mono_class_from_mono_type (res.type);
4662                 /* FIXME: endianess issue... */
4663                 res.value = iter->args;
4664                 arg_size = mono_type_stack_size (res.type, &align);
4665                 iter->args = (char*)iter->args + arg_size;
4666                 iter->next_arg++;
4667                 //g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value);
4668                 return res;
4669         }
4670         //g_print ("arg type 0x%02x not found\n", res.type->type);
4671
4672         res.type = NULL;
4673         res.value = NULL;
4674         res.klass = NULL;
4675         return res;
4676 }
4677
4678 static MonoType*
4679 mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
4680 {
4681         gint i;
4682         MONO_ARCH_SAVE_REGS;
4683         
4684         i = iter->sig->sentinelpos + iter->next_arg;
4685
4686         g_assert (i < iter->sig->param_count);
4687
4688         return iter->sig->params [i];
4689 }
4690
4691 static MonoObject*
4692 mono_TypedReference_ToObject (MonoTypedRef tref)
4693 {
4694         MONO_ARCH_SAVE_REGS;
4695
4696         if (MONO_TYPE_IS_REFERENCE (tref.type)) {
4697                 MonoObject** objp = tref.value;
4698                 return *objp;
4699         }
4700
4701         return mono_value_box (mono_domain_get (), tref.klass, tref.value);
4702 }
4703
4704 static void
4705 prelink_method (MonoMethod *method)
4706 {
4707         const char *exc_class, *exc_arg;
4708         if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
4709                 return;
4710         mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
4711         if (exc_class) {
4712                 mono_raise_exception( 
4713                         mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg ) );
4714         }
4715         /* create the wrapper, too? */
4716 }
4717
4718 static void
4719 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
4720 {
4721         MONO_ARCH_SAVE_REGS;
4722         prelink_method (method->method);
4723 }
4724
4725 static void
4726 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
4727 {
4728         MonoClass *klass = mono_class_from_mono_type (type->type);
4729         int i;
4730         MONO_ARCH_SAVE_REGS;
4731
4732         mono_class_init (klass);
4733         for (i = 0; i < klass->method.count; ++i)
4734                 prelink_method (klass->methods [i]);
4735 }
4736
4737 static void
4738 ves_icall_System_Char_GetDataTablePointers (guint8 **category_data, guint8 **numeric_data,
4739                 gdouble **numeric_data_values, guint16 **to_lower_data_low,
4740                 guint16 **to_lower_data_high, guint16 **to_upper_data_low,
4741                 guint16 **to_upper_data_high)
4742 {
4743         *category_data = CategoryData;
4744         *numeric_data = NumericData;
4745         *numeric_data_values = NumericDataValues;
4746         *to_lower_data_low = ToLowerDataLow;
4747         *to_lower_data_high = ToLowerDataHigh;
4748         *to_upper_data_low = ToUpperDataLow;
4749         *to_upper_data_high = ToUpperDataHigh;
4750 }
4751
4752 /* icall map */
4753 typedef struct {
4754         const char *method;
4755         gconstpointer func;
4756 } IcallEntry;
4757
4758 typedef struct {
4759         const char *klass;
4760         const IcallEntry *icalls;
4761         const int size;
4762 } IcallMap;
4763
4764 static const IcallEntry activator_icalls [] = {
4765         {"CreateInstanceInternal", ves_icall_System_Activator_CreateInstanceInternal}
4766 };
4767 static const IcallEntry appdomain_icalls [] = {
4768         {"ExecuteAssembly", ves_icall_System_AppDomain_ExecuteAssembly},
4769         {"GetAssemblies", ves_icall_System_AppDomain_GetAssemblies},
4770         {"GetData", ves_icall_System_AppDomain_GetData},
4771         {"InternalGetContext", ves_icall_System_AppDomain_InternalGetContext},
4772         {"InternalGetDefaultContext", ves_icall_System_AppDomain_InternalGetDefaultContext},
4773         {"InternalGetProcessGuid", ves_icall_System_AppDomain_InternalGetProcessGuid},
4774         {"InternalIsFinalizingForUnload", ves_icall_System_AppDomain_InternalIsFinalizingForUnload},
4775         {"InternalPopDomainRef", ves_icall_System_AppDomain_InternalPopDomainRef},
4776         {"InternalPushDomainRef", ves_icall_System_AppDomain_InternalPushDomainRef},
4777         {"InternalPushDomainRefByID", ves_icall_System_AppDomain_InternalPushDomainRefByID},
4778         {"InternalSetContext", ves_icall_System_AppDomain_InternalSetContext},
4779         {"InternalSetDomain", ves_icall_System_AppDomain_InternalSetDomain},
4780         {"InternalSetDomainByID", ves_icall_System_AppDomain_InternalSetDomainByID},
4781         {"InternalUnload", ves_icall_System_AppDomain_InternalUnload},
4782         {"LoadAssembly", ves_icall_System_AppDomain_LoadAssembly},
4783         {"LoadAssemblyRaw", ves_icall_System_AppDomain_LoadAssemblyRaw},
4784         {"SetData", ves_icall_System_AppDomain_SetData},
4785         {"createDomain", ves_icall_System_AppDomain_createDomain},
4786         {"getCurDomain", ves_icall_System_AppDomain_getCurDomain},
4787         {"getFriendlyName", ves_icall_System_AppDomain_getFriendlyName},
4788         {"getSetup", ves_icall_System_AppDomain_getSetup}
4789 };
4790
4791 static const IcallEntry appdomainsetup_icalls [] = {
4792         {"InitAppDomainSetup", ves_icall_System_AppDomainSetup_InitAppDomainSetup}
4793 };
4794
4795 static const IcallEntry argiterator_icalls [] = {
4796         {"IntGetNextArg()",                  mono_ArgIterator_IntGetNextArg},
4797         {"IntGetNextArg(intptr)", mono_ArgIterator_IntGetNextArgT},
4798         {"IntGetNextArgType",                mono_ArgIterator_IntGetNextArgType},
4799         {"Setup",                            mono_ArgIterator_Setup}
4800 };
4801
4802 static const IcallEntry array_icalls [] = {
4803         {"Clone",            mono_array_clone},
4804         {"CreateInstanceImpl",   ves_icall_System_Array_CreateInstanceImpl},
4805         {"FastCopy",         ves_icall_System_Array_FastCopy},
4806         {"GetLength",        ves_icall_System_Array_GetLength},
4807         {"GetLowerBound",    ves_icall_System_Array_GetLowerBound},
4808         {"GetRank",          ves_icall_System_Array_GetRank},
4809         {"GetValue",         ves_icall_System_Array_GetValue},
4810         {"GetValueImpl",     ves_icall_System_Array_GetValueImpl},
4811         {"SetValue",         ves_icall_System_Array_SetValue},
4812         {"SetValueImpl",     ves_icall_System_Array_SetValueImpl}
4813 };
4814
4815 static const IcallEntry buffer_icalls [] = {
4816         {"BlockCopyInternal", ves_icall_System_Buffer_BlockCopyInternal},
4817         {"ByteLengthInternal", ves_icall_System_Buffer_ByteLengthInternal},
4818         {"GetByteInternal", ves_icall_System_Buffer_GetByteInternal},
4819         {"SetByteInternal", ves_icall_System_Buffer_SetByteInternal}
4820 };
4821
4822 static const IcallEntry char_icalls [] = {
4823         {"GetDataTablePointers", ves_icall_System_Char_GetDataTablePointers},
4824 };
4825
4826 static const IcallEntry defaultconf_icalls [] = {
4827         {"get_machine_config_path", ves_icall_System_Configuration_DefaultConfig_get_machine_config_path}
4828 };
4829
4830 static const IcallEntry timezone_icalls [] = {
4831         {"GetTimeZoneData", ves_icall_System_CurrentTimeZone_GetTimeZoneData}
4832 };
4833
4834 static const IcallEntry datetime_icalls [] = {
4835         {"GetNow", ves_icall_System_DateTime_GetNow}
4836 };
4837
4838 static const IcallEntry decimal_icalls [] = {
4839         {"decimal2Int64", mono_decimal2Int64},
4840         {"decimal2UInt64", mono_decimal2UInt64},
4841         {"decimal2double", mono_decimal2double},
4842         {"decimal2string", mono_decimal2string},
4843         {"decimalCompare", mono_decimalCompare},
4844         {"decimalDiv", mono_decimalDiv},
4845         {"decimalFloorAndTrunc", mono_decimalFloorAndTrunc},
4846         {"decimalIncr", mono_decimalIncr},
4847         {"decimalIntDiv", mono_decimalIntDiv},
4848         {"decimalMult", mono_decimalMult},
4849         {"decimalRound", mono_decimalRound},
4850         {"decimalSetExponent", mono_decimalSetExponent},
4851         {"double2decimal", mono_double2decimal}, /* FIXME: wrong signature. */
4852         {"string2decimal", mono_string2decimal}
4853 };
4854
4855 static const IcallEntry delegate_icalls [] = {
4856         {"CreateDelegate_internal", ves_icall_System_Delegate_CreateDelegate_internal}
4857 };
4858
4859 static const IcallEntry tracelist_icalls [] = {
4860         {"WriteWindowsDebugString", ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString}
4861 };
4862
4863 static const IcallEntry fileversion_icalls [] = {
4864         {"GetVersionInfo_internal(string)", ves_icall_System_Diagnostics_FileVersionInfo_GetVersionInfo_internal}
4865 };
4866
4867 static const IcallEntry process_icalls [] = {
4868         {"ExitCode_internal(intptr)", ves_icall_System_Diagnostics_Process_ExitCode_internal},
4869         {"ExitTime_internal(intptr)", ves_icall_System_Diagnostics_Process_ExitTime_internal},
4870         {"GetModules_internal()", ves_icall_System_Diagnostics_Process_GetModules_internal},
4871         {"GetPid_internal()", ves_icall_System_Diagnostics_Process_GetPid_internal},
4872         {"GetProcess_internal(int)", ves_icall_System_Diagnostics_Process_GetProcess_internal},
4873         {"GetProcesses_internal()", ves_icall_System_Diagnostics_Process_GetProcesses_internal},
4874         {"GetWorkingSet_internal(intptr,int&,int&)", ves_icall_System_Diagnostics_Process_GetWorkingSet_internal},
4875         {"Kill_internal", ves_icall_System_Diagnostics_Process_Kill_internal},
4876         {"ProcessName_internal(intptr)", ves_icall_System_Diagnostics_Process_ProcessName_internal},
4877         {"Process_free_internal(intptr)", ves_icall_System_Diagnostics_Process_Process_free_internal},
4878         {"SetWorkingSet_internal(intptr,int,int,bool)", ves_icall_System_Diagnostics_Process_SetWorkingSet_internal},
4879         {"StartTime_internal(intptr)", ves_icall_System_Diagnostics_Process_StartTime_internal},
4880         {"Start_internal(string,string,intptr,intptr,intptr,System.Diagnostics.Process/ProcInfo&)", ves_icall_System_Diagnostics_Process_Start_internal},
4881         {"WaitForExit_internal(intptr,int)", ves_icall_System_Diagnostics_Process_WaitForExit_internal}
4882 };
4883
4884 static const IcallEntry double_icalls [] = {
4885         {"AssertEndianity", ves_icall_System_Double_AssertEndianity},
4886         {"ParseImpl",    mono_double_ParseImpl}
4887 };
4888
4889 static const IcallEntry enum_icalls [] = {
4890         {"ToObject", ves_icall_System_Enum_ToObject},
4891         {"get_value", ves_icall_System_Enum_get_value}
4892 };
4893
4894 static const IcallEntry environment_icalls [] = {
4895         {"Exit", ves_icall_System_Environment_Exit},
4896         {"GetCommandLineArgs", mono_runtime_get_main_args},
4897         {"GetEnvironmentVariable", ves_icall_System_Environment_GetEnvironmentVariable},
4898         {"GetEnvironmentVariableNames", ves_icall_System_Environment_GetEnvironmentVariableNames},
4899         {"GetMachineConfigPath",        ves_icall_System_Configuration_DefaultConfig_get_machine_config_path},
4900         {"get_ExitCode", mono_environment_exitcode_get},
4901         {"get_HasShutdownStarted", ves_icall_System_Environment_get_HasShutdownStarted},
4902         {"get_MachineName", ves_icall_System_Environment_get_MachineName},
4903         {"get_NewLine", ves_icall_System_Environment_get_NewLine},
4904         {"get_Platform", ves_icall_System_Environment_get_Platform},
4905         {"get_TickCount", ves_icall_System_Environment_get_TickCount},
4906         {"get_UserName", ves_icall_System_Environment_get_UserName},
4907         {"internalGetGacPath", ves_icall_System_Environment_GetGacPath},
4908         {"set_ExitCode", mono_environment_exitcode_set}
4909 };
4910
4911 static const IcallEntry cultureinfo_icalls [] = {
4912         {"construct_compareinfo(object,string)", ves_icall_System_Globalization_CompareInfo_construct_compareinfo},
4913         {"construct_datetime_format", ves_icall_System_Globalization_CultureInfo_construct_datetime_format},
4914         {"construct_internal_locale(string)", ves_icall_System_Globalization_CultureInfo_construct_internal_locale},
4915         {"construct_internal_locale_from_current_locale", ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_current_locale},
4916         {"construct_internal_locale_from_lcid", ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_lcid},
4917         {"construct_internal_locale_from_name", ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_name},
4918         {"construct_internal_locale_from_specific_name", ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_specific_name},
4919         {"construct_number_format", ves_icall_System_Globalization_CultureInfo_construct_number_format},
4920         {"internal_get_cultures", ves_icall_System_Globalization_CultureInfo_internal_get_cultures},
4921         {"internal_is_lcid_neutral", ves_icall_System_Globalization_CultureInfo_internal_is_lcid_neutral}
4922 };
4923
4924 static const IcallEntry compareinfo_icalls [] = {
4925         {"assign_sortkey(object,string,System.Globalization.CompareOptions)", ves_icall_System_Globalization_CompareInfo_assign_sortkey},
4926         {"construct_compareinfo(string)", ves_icall_System_Globalization_CompareInfo_construct_compareinfo},
4927         {"free_internal_collator()", ves_icall_System_Globalization_CompareInfo_free_internal_collator},
4928         {"internal_compare(string,int,int,string,int,int,System.Globalization.CompareOptions)", ves_icall_System_Globalization_CompareInfo_internal_compare},
4929         {"internal_index(string,int,int,char,System.Globalization.CompareOptions,bool)", ves_icall_System_Globalization_CompareInfo_internal_index_char},
4930         {"internal_index(string,int,int,string,System.Globalization.CompareOptions,bool)", ves_icall_System_Globalization_CompareInfo_internal_index}
4931 };
4932
4933 static const IcallEntry gc_icalls [] = {
4934         {"GetTotalMemory", ves_icall_System_GC_GetTotalMemory},
4935         {"InternalCollect", ves_icall_System_GC_InternalCollect},
4936         {"KeepAlive", ves_icall_System_GC_KeepAlive},
4937         {"ReRegisterForFinalize", ves_icall_System_GC_ReRegisterForFinalize},
4938         {"SuppressFinalize", ves_icall_System_GC_SuppressFinalize},
4939         {"WaitForPendingFinalizers", ves_icall_System_GC_WaitForPendingFinalizers}
4940 };
4941
4942 static const IcallEntry famwatcher_icalls [] = {
4943         {"InternalFAMNextEvent", ves_icall_System_IO_FAMW_InternalFAMNextEvent}
4944 };
4945
4946 static const IcallEntry filewatcher_icalls [] = {
4947         {"InternalCloseDirectory", ves_icall_System_IO_FSW_CloseDirectory},
4948         {"InternalOpenDirectory", ves_icall_System_IO_FSW_OpenDirectory},
4949         {"InternalReadDirectoryChanges", ves_icall_System_IO_FSW_ReadDirectoryChanges},
4950         {"InternalSupportsFSW", ves_icall_System_IO_FSW_SupportsFSW}
4951 };
4952
4953 static const IcallEntry path_icalls [] = {
4954         {"get_temp_path", ves_icall_System_IO_get_temp_path}
4955 };
4956
4957 static const IcallEntry monoio_icalls [] = {
4958         {"BeginRead", ves_icall_System_IO_MonoIO_BeginRead },
4959         {"BeginWrite", ves_icall_System_IO_MonoIO_BeginWrite },
4960         {"Close(intptr,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_Close},
4961         {"CopyFile(string,string,bool,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_CopyFile},
4962         {"CreateDirectory(string,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_CreateDirectory},
4963         {"CreatePipe(intptr&,intptr&)", ves_icall_System_IO_MonoIO_CreatePipe},
4964         {"DeleteFile(string,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_DeleteFile},
4965         {"FindClose(intptr,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_FindClose},
4966         {"FindFirstFile(string,System.IO.MonoIOStat&,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_FindFirstFile},
4967         {"FindNextFile(intptr,System.IO.MonoIOStat&,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_FindNextFile},
4968         {"Flush(intptr,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_Flush},
4969         {"GetCurrentDirectory(System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_GetCurrentDirectory},
4970         {"GetFileAttributes(string,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_GetFileAttributes},
4971         {"GetFileStat(string,System.IO.MonoIOStat&,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_GetFileStat},
4972         {"GetFileType(intptr,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_GetFileType},
4973         {"GetLength(intptr,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_GetLength},
4974         {"GetSupportsAsync", ves_icall_System_IO_MonoIO_GetSupportsAsync},
4975         {"GetTempPath(string&)", ves_icall_System_IO_MonoIO_GetTempPath},
4976         {"MoveFile(string,string,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_MoveFile},
4977         {"Open(string,System.IO.FileMode,System.IO.FileAccess,System.IO.FileShare,bool,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_Open},
4978         {"Read(intptr,byte[],int,int,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_Read},
4979         {"RemoveDirectory(string,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_RemoveDirectory},
4980         {"Seek(intptr,long,System.IO.SeekOrigin,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_Seek},
4981         {"SetCurrentDirectory(string,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_SetCurrentDirectory},
4982         {"SetFileAttributes(string,System.IO.FileAttributes,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_SetFileAttributes},
4983         {"SetFileTime(intptr,long,long,long,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_SetFileTime},
4984         {"SetLength(intptr,long,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_SetLength},
4985         {"Write(intptr,byte[],int,int,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_Write},
4986         {"get_AltDirectorySeparatorChar", ves_icall_System_IO_MonoIO_get_AltDirectorySeparatorChar},
4987         {"get_ConsoleError", ves_icall_System_IO_MonoIO_get_ConsoleError},
4988         {"get_ConsoleInput", ves_icall_System_IO_MonoIO_get_ConsoleInput},
4989         {"get_ConsoleOutput", ves_icall_System_IO_MonoIO_get_ConsoleOutput},
4990         {"get_DirectorySeparatorChar", ves_icall_System_IO_MonoIO_get_DirectorySeparatorChar},
4991         {"get_InvalidPathChars", ves_icall_System_IO_MonoIO_get_InvalidPathChars},
4992         {"get_PathSeparator", ves_icall_System_IO_MonoIO_get_PathSeparator},
4993         {"get_VolumeSeparatorChar", ves_icall_System_IO_MonoIO_get_VolumeSeparatorChar}
4994 };
4995
4996 static const IcallEntry math_icalls [] = {
4997         {"Acos", ves_icall_System_Math_Acos},
4998         {"Asin", ves_icall_System_Math_Asin},
4999         {"Atan", ves_icall_System_Math_Atan},
5000         {"Atan2", ves_icall_System_Math_Atan2},
5001         {"Cos", ves_icall_System_Math_Cos},
5002         {"Cosh", ves_icall_System_Math_Cosh},
5003         {"Exp", ves_icall_System_Math_Exp},
5004         {"Floor", ves_icall_System_Math_Floor},
5005         {"Log", ves_icall_System_Math_Log},
5006         {"Log10", ves_icall_System_Math_Log10},
5007         {"Pow", ves_icall_System_Math_Pow},
5008         {"Round", ves_icall_System_Math_Round},
5009         {"Round2", ves_icall_System_Math_Round2},
5010         {"Sin", ves_icall_System_Math_Sin},
5011         {"Sinh", ves_icall_System_Math_Sinh},
5012         {"Sqrt", ves_icall_System_Math_Sqrt},
5013         {"Tan", ves_icall_System_Math_Tan},
5014         {"Tanh", ves_icall_System_Math_Tanh}
5015 };
5016
5017 static const IcallEntry customattrs_icalls [] = {
5018         {"GetCustomAttributes", mono_reflection_get_custom_attrs}
5019 };
5020
5021 static const IcallEntry enuminfo_icalls [] = {
5022         {"get_enum_info", ves_icall_get_enum_info}
5023 };
5024
5025 static const IcallEntry fieldinfo_icalls [] = {
5026         {"internal_from_handle", ves_icall_System_Reflection_FieldInfo_internal_from_handle}
5027 };
5028
5029 static const IcallEntry monotype_icalls [] = {
5030         {"GetArrayRank", ves_icall_MonoType_GetArrayRank},
5031         {"GetConstructors", ves_icall_Type_GetConstructors_internal},
5032         {"GetConstructors_internal", ves_icall_Type_GetConstructors_internal},
5033         {"GetElementType", ves_icall_MonoType_GetElementType},
5034         {"GetEvents_internal", ves_icall_Type_GetEvents_internal},
5035         {"GetField", ves_icall_Type_GetField},
5036         {"GetFields_internal", ves_icall_Type_GetFields_internal},
5037         {"GetGenericArguments", ves_icall_MonoType_GetGenericArguments},
5038         {"GetInterfaces", ves_icall_Type_GetInterfaces},
5039         {"GetMethodsByName", ves_icall_Type_GetMethodsByName},
5040         {"GetNestedType", ves_icall_Type_GetNestedType},
5041         {"GetNestedTypes", ves_icall_Type_GetNestedTypes},
5042         {"GetPropertiesByName", ves_icall_Type_GetPropertiesByName},
5043         {"InternalGetEvent", ves_icall_MonoType_GetEvent},
5044         {"IsByRefImpl", ves_icall_type_isbyref},
5045         {"IsPointerImpl", ves_icall_type_ispointer},
5046         {"IsPrimitiveImpl", ves_icall_type_isprimitive},
5047         {"getFullName", ves_icall_System_MonoType_getFullName},
5048         {"get_Assembly", ves_icall_MonoType_get_Assembly},
5049         {"get_BaseType", ves_icall_get_type_parent},
5050         {"get_DeclaringMethod", ves_icall_MonoType_get_DeclaringMethod},
5051         {"get_DeclaringType", ves_icall_MonoType_get_DeclaringType},
5052         {"get_HasGenericArguments", ves_icall_MonoType_get_HasGenericArguments},
5053         {"get_IsGenericParameter", ves_icall_MonoType_get_IsGenericParameter},
5054         {"get_Module", ves_icall_MonoType_get_Module},
5055         {"get_Name", ves_icall_MonoType_get_Name},
5056         {"get_Namespace", ves_icall_MonoType_get_Namespace},
5057         {"get_UnderlyingSystemType", ves_icall_MonoType_get_UnderlyingSystemType},
5058         {"get_attributes", ves_icall_get_attributes},
5059         {"type_from_obj", mono_type_type_from_obj}
5060 };
5061
5062 static const IcallEntry assembly_icalls [] = {
5063         {"FillName", ves_icall_System_Reflection_Assembly_FillName},
5064         {"GetCallingAssembly", ves_icall_System_Reflection_Assembly_GetCallingAssembly},
5065         {"GetEntryAssembly", ves_icall_System_Reflection_Assembly_GetEntryAssembly},
5066         {"GetExecutingAssembly", ves_icall_System_Reflection_Assembly_GetExecutingAssembly},
5067         {"GetFilesInternal", ves_icall_System_Reflection_Assembly_GetFilesInternal},
5068         {"GetManifestResourceInfoInternal", ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal},
5069         {"GetManifestResourceInternal", ves_icall_System_Reflection_Assembly_GetManifestResourceInternal},
5070         {"GetManifestResourceNames", ves_icall_System_Reflection_Assembly_GetManifestResourceNames},
5071         {"GetModulesInternal", ves_icall_System_Reflection_Assembly_GetModulesInternal},
5072         {"GetNamespaces", ves_icall_System_Reflection_Assembly_GetNamespaces},
5073         {"GetReferencedAssemblies", ves_icall_System_Reflection_Assembly_GetReferencedAssemblies},
5074         {"GetTypes", ves_icall_System_Reflection_Assembly_GetTypes},
5075         {"InternalGetAssemblyName", ves_icall_System_Reflection_Assembly_InternalGetAssemblyName},
5076         {"InternalGetType", ves_icall_System_Reflection_Assembly_InternalGetType},
5077         {"InternalImageRuntimeVersion", ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion},
5078         {"LoadFrom", ves_icall_System_Reflection_Assembly_LoadFrom},
5079         /*
5080          * Private icalls for the Mono Debugger
5081          */
5082         {"MonoDebugger_GetLocalTypeFromSignature", ves_icall_MonoDebugger_GetLocalTypeFromSignature},
5083         {"MonoDebugger_GetMethod", ves_icall_MonoDebugger_GetMethod},
5084         {"MonoDebugger_GetMethodToken", ves_icall_MonoDebugger_GetMethodToken},
5085         {"MonoDebugger_GetType", ves_icall_MonoDebugger_GetType},
5086         /* normal icalls again */
5087         {"get_EntryPoint", ves_icall_System_Reflection_Assembly_get_EntryPoint},
5088         {"get_code_base", ves_icall_System_Reflection_Assembly_get_code_base},
5089         {"get_location", ves_icall_System_Reflection_Assembly_get_location}
5090 };
5091
5092 static const IcallEntry methodbase_icalls [] = {
5093         {"GetCurrentMethod", ves_icall_GetCurrentMethod}
5094 };
5095
5096 static const IcallEntry module_icalls [] = {
5097         {"Close", ves_icall_System_Reflection_Module_Close},
5098         {"GetGlobalType", ves_icall_System_Reflection_Module_GetGlobalType},
5099         {"GetGuidInternal", ves_icall_System_Reflection_Module_GetGuidInternal},
5100         {"InternalGetTypes", ves_icall_System_Reflection_Module_InternalGetTypes}
5101 };
5102
5103 static const IcallEntry monocmethod_icalls [] = {
5104         {"GetGenericMethodDefinition_impl", ves_icall_MonoMethod_GetGenericMethodDefinition},
5105         {"InternalInvoke", ves_icall_InternalInvoke},
5106         {"get_Mono_IsInflatedMethod", ves_icall_MonoMethod_get_Mono_IsInflatedMethod}
5107 };
5108
5109 static const IcallEntry monoeventinfo_icalls [] = {
5110         {"get_event_info", ves_icall_get_event_info}
5111 };
5112
5113 static const IcallEntry monofield_icalls [] = {
5114         {"GetParentType", ves_icall_MonoField_GetParentType},
5115         {"GetValueInternal", ves_icall_MonoField_GetValueInternal},
5116         {"SetValueInternal", ves_icall_FieldInfo_SetValueInternal}
5117 };
5118
5119 static const IcallEntry monogenericinst_icalls [] = {
5120         {"GetConstructors_internal", ves_icall_MonoGenericInst_GetConstructors},
5121         {"GetEvents_internal", ves_icall_MonoGenericInst_GetEvents},
5122         {"GetFields_internal", ves_icall_MonoGenericInst_GetFields},
5123         {"GetInterfaces_internal", ves_icall_MonoGenericInst_GetInterfaces},
5124         {"GetMethods_internal", ves_icall_MonoGenericInst_GetMethods},
5125         {"GetParentType", ves_icall_MonoGenericInst_GetParentType},
5126         {"GetProperties_internal", ves_icall_MonoGenericInst_GetProperties},
5127         {"initialize", mono_reflection_generic_inst_initialize}
5128 };
5129
5130 static const IcallEntry generictypeparambuilder_icalls [] = {
5131         {"initialize", mono_reflection_initialize_generic_parameter}
5132 };
5133
5134 static const IcallEntry monomethod_icalls [] = {
5135         {"BindGenericParameters", mono_reflection_bind_generic_method_parameters},
5136         {"GetGenericArguments", ves_icall_MonoMethod_GetGenericArguments},
5137         {"GetGenericMethodDefinition_impl", ves_icall_MonoMethod_GetGenericMethodDefinition},
5138         {"InternalInvoke", ves_icall_InternalInvoke},
5139         {"get_HasGenericParameters", ves_icall_MonoMethod_get_HasGenericParameters},
5140         {"get_IsGenericMethodDefinition", ves_icall_MonoMethod_get_IsGenericMethodDefinition},
5141         {"get_Mono_IsInflatedMethod", ves_icall_MonoMethod_get_Mono_IsInflatedMethod},
5142         {"get_base_definition", ves_icall_MonoMethod_get_base_definition}
5143 };
5144
5145 static const IcallEntry monomethodinfo_icalls [] = {
5146         {"get_method_info", ves_icall_get_method_info},
5147         {"get_parameter_info", ves_icall_get_parameter_info}
5148 };
5149
5150 static const IcallEntry monopropertyinfo_icalls [] = {
5151         {"get_property_info", ves_icall_get_property_info}
5152 };
5153
5154 static const IcallEntry dns_icalls [] = {
5155         {"GetHostByAddr_internal(string,string&,string[]&,string[]&)", ves_icall_System_Net_Dns_GetHostByAddr_internal},
5156         {"GetHostByName_internal(string,string&,string[]&,string[]&)", ves_icall_System_Net_Dns_GetHostByName_internal},
5157         {"GetHostName_internal(string&)", ves_icall_System_Net_Dns_GetHostName_internal}
5158 };
5159
5160 static const IcallEntry socket_icalls [] = {
5161         {"Accept_internal", ves_icall_System_Net_Sockets_Socket_Accept_internal},
5162         {"Available_internal", ves_icall_System_Net_Sockets_Socket_Available_internal},
5163         {"Bind_internal", ves_icall_System_Net_Sockets_Socket_Bind_internal},
5164         {"Blocking_internal", ves_icall_System_Net_Sockets_Socket_Blocking_internal},
5165         {"Close_internal", ves_icall_System_Net_Sockets_Socket_Close_internal},
5166         {"Connect_internal", ves_icall_System_Net_Sockets_Socket_Connect_internal},
5167         {"GetSocketOption_arr_internal", ves_icall_System_Net_Sockets_Socket_GetSocketOption_arr_internal},
5168         {"GetSocketOption_obj_internal", ves_icall_System_Net_Sockets_Socket_GetSocketOption_obj_internal},
5169         {"Listen_internal", ves_icall_System_Net_Sockets_Socket_Listen_internal},
5170         {"LocalEndPoint_internal", ves_icall_System_Net_Sockets_Socket_LocalEndPoint_internal},
5171         {"Receive_internal", ves_icall_System_Net_Sockets_Socket_Receive_internal},
5172         {"RecvFrom_internal", ves_icall_System_Net_Sockets_Socket_RecvFrom_internal},
5173         {"RemoteEndPoint_internal", ves_icall_System_Net_Sockets_Socket_RemoteEndPoint_internal},
5174         {"Select_internal", ves_icall_System_Net_Sockets_Socket_Select_internal},
5175         {"SendTo_internal", ves_icall_System_Net_Sockets_Socket_SendTo_internal},
5176         {"Send_internal", ves_icall_System_Net_Sockets_Socket_Send_internal},
5177         {"SetSocketOption_internal", ves_icall_System_Net_Sockets_Socket_SetSocketOption_internal},
5178         {"Shutdown_internal", ves_icall_System_Net_Sockets_Socket_Shutdown_internal},
5179         {"Socket_internal", ves_icall_System_Net_Sockets_Socket_Socket_internal},
5180         {"WSAIoctl", ves_icall_System_Net_Sockets_Socket_WSAIoctl}
5181 };
5182
5183 static const IcallEntry socketex_icalls [] = {
5184         {"WSAGetLastError_internal", ves_icall_System_Net_Sockets_SocketException_WSAGetLastError_internal}
5185 };
5186
5187 static const IcallEntry object_icalls [] = {
5188         {"GetType", ves_icall_System_Object_GetType},
5189         {"InternalGetHashCode", ves_icall_System_Object_GetHashCode},
5190         {"MemberwiseClone", ves_icall_System_Object_MemberwiseClone},
5191         {"obj_address", ves_icall_System_Object_obj_address}
5192 };
5193
5194 static const IcallEntry assemblybuilder_icalls[] = {
5195         {"InternalAddModule", mono_image_load_module},
5196         {"basic_init", mono_image_basic_init}
5197 };
5198
5199 static const IcallEntry customattrbuilder_icalls [] = {
5200         {"GetBlob", mono_reflection_get_custom_attrs_blob}
5201 };
5202
5203 static const IcallEntry dynamicmethod_icalls [] = {
5204         {"create_dynamic_method", mono_reflection_create_dynamic_method}
5205 };
5206
5207 static const IcallEntry methodbuilder_icalls [] = {
5208         {"BindGenericParameters", mono_reflection_bind_generic_method_parameters}
5209 };
5210
5211 static const IcallEntry modulebuilder_icalls [] = {
5212         {"basic_init", mono_image_module_basic_init},
5213         {"build_metadata", ves_icall_ModuleBuilder_build_metadata},
5214         {"create_modified_type", ves_icall_ModuleBuilder_create_modified_type},
5215         {"getDataChunk", ves_icall_ModuleBuilder_getDataChunk},
5216         {"getToken", ves_icall_ModuleBuilder_getToken},
5217         {"getUSIndex", mono_image_insert_string}
5218 };
5219
5220 static const IcallEntry signaturehelper_icalls [] = {
5221         {"get_signature_field", mono_reflection_sighelper_get_signature_field},
5222         {"get_signature_local", mono_reflection_sighelper_get_signature_local}
5223 };
5224
5225 static const IcallEntry typebuilder_icalls [] = {
5226         {"create_internal_class", mono_reflection_create_internal_class},
5227         {"create_runtime_class", mono_reflection_create_runtime_class},
5228         {"get_IsGenericParameter", ves_icall_TypeBuilder_get_IsGenericParameter},
5229         {"get_event_info", mono_reflection_event_builder_get_event_info},
5230         {"setup_generic_class", mono_reflection_setup_generic_class},
5231         {"setup_internal_class", mono_reflection_setup_internal_class}
5232 };
5233
5234 static const IcallEntry runtimehelpers_icalls [] = {
5235         {"GetObjectValue", ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue},
5236         {"GetOffsetToStringData", ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData},
5237         {"InitializeArray", ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray},
5238         {"RunClassConstructor", ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor}
5239 };
5240
5241 static const IcallEntry gchandle_icalls [] = {
5242         {"FreeHandle", ves_icall_System_GCHandle_FreeHandle},
5243         {"GetAddrOfPinnedObject", ves_icall_System_GCHandle_GetAddrOfPinnedObject},
5244         {"GetTarget", ves_icall_System_GCHandle_GetTarget},
5245         {"GetTargetHandle", ves_icall_System_GCHandle_GetTargetHandle}
5246 };
5247
5248 static const IcallEntry marshal_icalls [] = {
5249         {"AllocCoTaskMem", ves_icall_System_Runtime_InteropServices_Marshal_AllocCoTaskMem},
5250         {"AllocHGlobal", mono_marshal_alloc},
5251         {"DestroyStructure", ves_icall_System_Runtime_InteropServices_Marshal_DestroyStructure},
5252         {"FreeCoTaskMem", ves_icall_System_Runtime_InteropServices_Marshal_FreeCoTaskMem},
5253         {"FreeHGlobal", mono_marshal_free},
5254         {"GetLastWin32Error", ves_icall_System_Runtime_InteropServices_Marshal_GetLastWin32Error},
5255         {"OffsetOf", ves_icall_System_Runtime_InteropServices_Marshal_OffsetOf},
5256         {"Prelink", ves_icall_System_Runtime_InteropServices_Marshal_Prelink},
5257         {"PrelinkAll", ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll},
5258         {"PtrToStringAnsi(intptr)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringAnsi},
5259         {"PtrToStringAnsi(intptr,int)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringAnsi_len},
5260         {"PtrToStringAuto(intptr)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringAnsi},
5261         {"PtrToStringAuto(intptr,int)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringAnsi_len},
5262         {"PtrToStringBSTR", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringBSTR},
5263         {"PtrToStringUni(intptr)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringUni},
5264         {"PtrToStringUni(intptr,int)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringUni_len},
5265         {"PtrToStructure(intptr,System.Type)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStructure_type},
5266         {"PtrToStructure(intptr,object)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStructure},
5267         {"ReAllocHGlobal", mono_marshal_realloc},
5268         {"ReadByte", ves_icall_System_Runtime_InteropServices_Marshal_ReadByte},
5269         {"ReadInt16", ves_icall_System_Runtime_InteropServices_Marshal_ReadInt16},
5270         {"ReadInt32", ves_icall_System_Runtime_InteropServices_Marshal_ReadInt32},
5271         {"ReadInt64", ves_icall_System_Runtime_InteropServices_Marshal_ReadInt64},
5272         {"ReadIntPtr", ves_icall_System_Runtime_InteropServices_Marshal_ReadIntPtr},
5273         {"SizeOf", ves_icall_System_Runtime_InteropServices_Marshal_SizeOf},
5274         {"StringToHGlobalAnsi", ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalAnsi},
5275         {"StringToHGlobalAuto", ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalAnsi},
5276         {"StringToHGlobalUni", ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalUni},
5277         {"StructureToPtr", ves_icall_System_Runtime_InteropServices_Marshal_StructureToPtr},
5278         {"WriteByte", ves_icall_System_Runtime_InteropServices_Marshal_WriteByte},
5279         {"WriteInt16", ves_icall_System_Runtime_InteropServices_Marshal_WriteInt16},
5280         {"WriteInt32", ves_icall_System_Runtime_InteropServices_Marshal_WriteInt32},
5281         {"WriteInt64", ves_icall_System_Runtime_InteropServices_Marshal_WriteInt64},
5282         {"WriteIntPtr", ves_icall_System_Runtime_InteropServices_Marshal_WriteIntPtr},
5283         {"copy_from_unmanaged", ves_icall_System_Runtime_InteropServices_Marshal_copy_from_unmanaged},
5284         {"copy_to_unmanaged", ves_icall_System_Runtime_InteropServices_Marshal_copy_to_unmanaged}
5285 };
5286
5287 static const IcallEntry activationservices_icalls [] = {
5288         {"AllocateUninitializedClassInstance", ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance},
5289         {"EnableProxyActivation", ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation}
5290 };
5291
5292 static const IcallEntry monomethodmessage_icalls [] = {
5293         {"InitMessage", ves_icall_MonoMethodMessage_InitMessage}
5294 };
5295         
5296 static const IcallEntry realproxy_icalls [] = {
5297         {"InternalGetProxyType", ves_icall_Remoting_RealProxy_InternalGetProxyType},
5298         {"InternalGetTransparentProxy", ves_icall_Remoting_RealProxy_GetTransparentProxy}
5299 };
5300
5301 static const IcallEntry remotingservices_icalls [] = {
5302         {"InternalExecute", ves_icall_InternalExecute},
5303         {"IsTransparentProxy", ves_icall_IsTransparentProxy}
5304 };
5305
5306 static const IcallEntry rng_icalls [] = {
5307         {"InternalGetBytes", ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_InternalGetBytes}
5308 };
5309
5310 static const IcallEntry methodhandle_icalls [] = {
5311         {"GetFunctionPointer", ves_icall_RuntimeMethod_GetFunctionPointer}
5312 };
5313
5314 static const IcallEntry string_icalls [] = {
5315         {".ctor(char*)", ves_icall_System_String_ctor_charp},
5316         {".ctor(char*,int,int)", ves_icall_System_String_ctor_charp_int_int},
5317         {".ctor(char,int)", ves_icall_System_String_ctor_char_int},
5318         {".ctor(char[])", ves_icall_System_String_ctor_chara},
5319         {".ctor(char[],int,int)", ves_icall_System_String_ctor_chara_int_int},
5320         {".ctor(sbyte*)", ves_icall_System_String_ctor_sbytep},
5321         {".ctor(sbyte*,int,int)", ves_icall_System_String_ctor_sbytep_int_int},
5322         {".ctor(sbyte*,int,int,System.Text.Encoding)", ves_icall_System_String_ctor_encoding},
5323         {"GetHashCode", ves_icall_System_String_GetHashCode},
5324         {"InternalAllocateStr", ves_icall_System_String_InternalAllocateStr},
5325         {"InternalCopyTo", ves_icall_System_String_InternalCopyTo},
5326         {"InternalIndexOfAny", ves_icall_System_String_InternalIndexOfAny},
5327         {"InternalInsert", ves_icall_System_String_InternalInsert},
5328         {"InternalIntern", ves_icall_System_String_InternalIntern},
5329         {"InternalIsInterned", ves_icall_System_String_InternalIsInterned},
5330         {"InternalJoin", ves_icall_System_String_InternalJoin},
5331         {"InternalLastIndexOfAny", ves_icall_System_String_InternalLastIndexOfAny},
5332         {"InternalPad", ves_icall_System_String_InternalPad},
5333         {"InternalRemove", ves_icall_System_String_InternalRemove},
5334         {"InternalReplace(char,char)", ves_icall_System_String_InternalReplace_Char},
5335         {"InternalReplace(string,string,System.Globalization.CompareInfo)", ves_icall_System_String_InternalReplace_Str_Comp},
5336         {"InternalSplit", ves_icall_System_String_InternalSplit},
5337         {"InternalStrcpy(string,int,string)", ves_icall_System_String_InternalStrcpy_Str},
5338         {"InternalStrcpy(string,int,string,int,int)", ves_icall_System_String_InternalStrcpy_StrN},
5339         {"InternalToLower(System.Globalization.CultureInfo)", ves_icall_System_String_InternalToLower_Comp},
5340         {"InternalToUpper(System.Globalization.CultureInfo)", ves_icall_System_String_InternalToUpper_Comp},
5341         {"InternalTrim", ves_icall_System_String_InternalTrim},
5342         {"get_Chars", ves_icall_System_String_get_Chars}
5343 };
5344
5345 static const IcallEntry encoding_icalls [] = {
5346         {"InternalCodePage", ves_icall_System_Text_Encoding_InternalCodePage}
5347 };
5348
5349 static const IcallEntry monitor_icalls [] = {
5350         {"Monitor_exit", ves_icall_System_Threading_Monitor_Monitor_exit},
5351         {"Monitor_pulse", ves_icall_System_Threading_Monitor_Monitor_pulse},
5352         {"Monitor_pulse_all", ves_icall_System_Threading_Monitor_Monitor_pulse_all},
5353         {"Monitor_test_owner", ves_icall_System_Threading_Monitor_Monitor_test_owner},
5354         {"Monitor_test_synchronised", ves_icall_System_Threading_Monitor_Monitor_test_synchronised},
5355         {"Monitor_try_enter", ves_icall_System_Threading_Monitor_Monitor_try_enter},
5356         {"Monitor_wait", ves_icall_System_Threading_Monitor_Monitor_wait}
5357 };
5358
5359 static const IcallEntry interlocked_icalls [] = {
5360         {"CompareExchange(int&,int,int)", ves_icall_System_Threading_Interlocked_CompareExchange_Int},
5361         {"CompareExchange(object&,object,object)", ves_icall_System_Threading_Interlocked_CompareExchange_Object},
5362         {"CompareExchange(single&,single,single)", ves_icall_System_Threading_Interlocked_CompareExchange_Single},
5363         {"Decrement(int&)", ves_icall_System_Threading_Interlocked_Decrement_Int},
5364         {"Decrement(long&)", ves_icall_System_Threading_Interlocked_Decrement_Long},
5365         {"Exchange(int&,int)", ves_icall_System_Threading_Interlocked_Exchange_Int},
5366         {"Exchange(object&,object)", ves_icall_System_Threading_Interlocked_Exchange_Object},
5367         {"Exchange(single&,single)", ves_icall_System_Threading_Interlocked_Exchange_Single},
5368         {"Increment(int&)", ves_icall_System_Threading_Interlocked_Increment_Int},
5369         {"Increment(long&)", ves_icall_System_Threading_Interlocked_Increment_Long}
5370 };
5371
5372 static const IcallEntry mutex_icalls [] = {
5373         {"CreateMutex_internal", ves_icall_System_Threading_Mutex_CreateMutex_internal},
5374         {"ReleaseMutex_internal", ves_icall_System_Threading_Mutex_ReleaseMutex_internal}
5375 };
5376
5377 static const IcallEntry nativeevents_icalls [] = {
5378         {"CloseEvent_internal", ves_icall_System_Threading_Events_CloseEvent_internal},
5379         {"CreateEvent_internal", ves_icall_System_Threading_Events_CreateEvent_internal},
5380         {"ResetEvent_internal",  ves_icall_System_Threading_Events_ResetEvent_internal},
5381         {"SetEvent_internal",    ves_icall_System_Threading_Events_SetEvent_internal}
5382 };
5383
5384 static const IcallEntry thread_icalls [] = {
5385         {"Abort_internal(object)", ves_icall_System_Threading_Thread_Abort},
5386         {"CurrentThread_internal", mono_thread_current},
5387         {"GetDomainID", ves_icall_System_Threading_Thread_GetDomainID},
5388         {"GetName_internal", ves_icall_System_Threading_Thread_GetName_internal},
5389         {"Join_internal", ves_icall_System_Threading_Thread_Join_internal},
5390         {"ResetAbort_internal()", ves_icall_System_Threading_Thread_ResetAbort},
5391         {"SetName_internal", ves_icall_System_Threading_Thread_SetName_internal},
5392         {"Sleep_internal", ves_icall_System_Threading_Thread_Sleep_internal},
5393         {"SlotHash_lookup", ves_icall_System_Threading_Thread_SlotHash_lookup},
5394         {"SlotHash_store", ves_icall_System_Threading_Thread_SlotHash_store},
5395         {"Start_internal", ves_icall_System_Threading_Thread_Start_internal},
5396         {"Thread_free_internal", ves_icall_System_Threading_Thread_Thread_free_internal},
5397         {"Thread_internal", ves_icall_System_Threading_Thread_Thread_internal},
5398         {"VolatileRead(IntPtr&)", ves_icall_System_Threading_Thread_VolatileReadIntPtr},
5399         {"VolatileRead(UIntPtr&)", ves_icall_System_Threading_Thread_VolatileReadIntPtr},
5400         {"VolatileRead(byte&)", ves_icall_System_Threading_Thread_VolatileRead1},
5401         {"VolatileRead(double&)", ves_icall_System_Threading_Thread_VolatileRead8},
5402         {"VolatileRead(float&)", ves_icall_System_Threading_Thread_VolatileRead4},
5403         {"VolatileRead(int&)", ves_icall_System_Threading_Thread_VolatileRead4},
5404         {"VolatileRead(long&)", ves_icall_System_Threading_Thread_VolatileRead8},
5405         {"VolatileRead(object&)", ves_icall_System_Threading_Thread_VolatileReadIntPtr},
5406         {"VolatileRead(sbyte&)", ves_icall_System_Threading_Thread_VolatileRead1},
5407         {"VolatileRead(short&)", ves_icall_System_Threading_Thread_VolatileRead2},
5408         {"VolatileRead(uint&)", ves_icall_System_Threading_Thread_VolatileRead2},
5409         {"VolatileRead(ulong&)", ves_icall_System_Threading_Thread_VolatileRead8},
5410         {"VolatileRead(ushort&)", ves_icall_System_Threading_Thread_VolatileRead2},
5411         {"VolatileWrite(IntPtr&,IntPtr)", ves_icall_System_Threading_Thread_VolatileWriteIntPtr},
5412         {"VolatileWrite(UIntPtr&,UIntPtr)", ves_icall_System_Threading_Thread_VolatileWriteIntPtr},
5413         {"VolatileWrite(byte&,byte)", ves_icall_System_Threading_Thread_VolatileWrite1},
5414         {"VolatileWrite(double&,double)", ves_icall_System_Threading_Thread_VolatileWrite8},
5415         {"VolatileWrite(float&,float)", ves_icall_System_Threading_Thread_VolatileWrite4},
5416         {"VolatileWrite(int&,int)", ves_icall_System_Threading_Thread_VolatileWrite4},
5417         {"VolatileWrite(long&,long)", ves_icall_System_Threading_Thread_VolatileWrite8},
5418         {"VolatileWrite(object&,object)", ves_icall_System_Threading_Thread_VolatileWriteIntPtr},
5419         {"VolatileWrite(sbyte&,sbyte)", ves_icall_System_Threading_Thread_VolatileWrite1},
5420         {"VolatileWrite(short&,short)", ves_icall_System_Threading_Thread_VolatileWrite2},
5421         {"VolatileWrite(uint&,uint)", ves_icall_System_Threading_Thread_VolatileWrite2},
5422         {"VolatileWrite(ulong&,ulong)", ves_icall_System_Threading_Thread_VolatileWrite8},
5423         {"VolatileWrite(ushort&,ushort)", ves_icall_System_Threading_Thread_VolatileWrite2},
5424         {"current_lcid()", ves_icall_System_Threading_Thread_current_lcid}
5425 };
5426
5427 static const IcallEntry threadpool_icalls [] = {
5428         {"BindHandleInternal", ves_icall_System_Threading_ThreadPool_BindHandle},
5429         {"GetAvailableThreads", ves_icall_System_Threading_ThreadPool_GetAvailableThreads},
5430         {"GetMaxThreads", ves_icall_System_Threading_ThreadPool_GetMaxThreads}
5431 };
5432
5433 static const IcallEntry waithandle_icalls [] = {
5434         {"WaitAll_internal", ves_icall_System_Threading_WaitHandle_WaitAll_internal},
5435         {"WaitAny_internal", ves_icall_System_Threading_WaitHandle_WaitAny_internal},
5436         {"WaitOne_internal", ves_icall_System_Threading_WaitHandle_WaitOne_internal}
5437 };
5438
5439 static const IcallEntry type_icalls [] = {
5440         {"BindGenericParameters", ves_icall_Type_BindGenericParameters},
5441         {"Equals", ves_icall_type_Equals},
5442         {"GetGenericParameterPosition", ves_icall_Type_GetGenericParameterPosition},
5443         {"GetGenericTypeDefinition_impl", ves_icall_Type_GetGenericTypeDefinition_impl},
5444         {"GetInterfaceMapData", ves_icall_Type_GetInterfaceMapData},
5445         {"GetTypeCode", ves_icall_type_GetTypeCode},
5446         {"IsArrayImpl", ves_icall_Type_IsArrayImpl},
5447         {"IsInstanceOfType", ves_icall_type_IsInstanceOfType},
5448         {"get_IsGenericInstance", ves_icall_Type_get_IsGenericInstance},
5449         {"get_IsGenericTypeDefinition", ves_icall_Type_get_IsGenericTypeDefinition},
5450         {"internal_from_handle", ves_icall_type_from_handle},
5451         {"internal_from_name", ves_icall_type_from_name},
5452         {"make_array_type", ves_icall_Type_make_array_type},
5453         {"make_byref_type", ves_icall_Type_make_byref_type},
5454         {"type_is_assignable_from", ves_icall_type_is_assignable_from},
5455         {"type_is_subtype_of", ves_icall_type_is_subtype_of}
5456 };
5457
5458 static const IcallEntry typedref_icalls [] = {
5459         {"ToObject",    mono_TypedReference_ToObject}
5460 };
5461
5462 static const IcallEntry valuetype_icalls [] = {
5463         {"InternalEquals", ves_icall_System_ValueType_Equals},
5464         {"InternalGetHashCode", ves_icall_System_ValueType_InternalGetHashCode}
5465 };
5466
5467 static const IcallEntry web_icalls [] = {
5468         {"GetMachineConfigPath", ves_icall_System_Configuration_DefaultConfig_get_machine_config_path},
5469         {"GetMachineInstallDirectory", ves_icall_System_Web_Util_ICalls_get_machine_install_dir}
5470 };
5471
5472 /* proto
5473 static const IcallEntry array_icalls [] = {
5474 };
5475
5476 */
5477
5478 /* keep the entries all sorted */
5479 static const IcallMap icall_entries [] = {
5480         {"System.Activator", activator_icalls, G_N_ELEMENTS (activator_icalls)},
5481         {"System.AppDomain", appdomain_icalls, G_N_ELEMENTS (appdomain_icalls)},
5482         {"System.AppDomainSetup", appdomainsetup_icalls, G_N_ELEMENTS (appdomainsetup_icalls)},
5483         {"System.ArgIterator", argiterator_icalls, G_N_ELEMENTS (argiterator_icalls)},
5484         {"System.Array", array_icalls, G_N_ELEMENTS (array_icalls)},
5485         {"System.Buffer", buffer_icalls, G_N_ELEMENTS (buffer_icalls)},
5486         {"System.Char", char_icalls, G_N_ELEMENTS (char_icalls)},
5487         {"System.Configuration.DefaultConfig", defaultconf_icalls, G_N_ELEMENTS (defaultconf_icalls)},
5488         {"System.CurrentTimeZone", timezone_icalls, G_N_ELEMENTS (timezone_icalls)},
5489         {"System.DateTime", datetime_icalls, G_N_ELEMENTS (datetime_icalls)},
5490         {"System.Decimal", decimal_icalls, G_N_ELEMENTS (decimal_icalls)},
5491         {"System.Delegate", delegate_icalls, G_N_ELEMENTS (delegate_icalls)},
5492         {"System.Diagnostics.DefaultTraceListener", tracelist_icalls, G_N_ELEMENTS (tracelist_icalls)},
5493         {"System.Diagnostics.FileVersionInfo", fileversion_icalls, G_N_ELEMENTS (fileversion_icalls)},
5494         {"System.Diagnostics.Process", process_icalls, G_N_ELEMENTS (process_icalls)},
5495         {"System.Double", double_icalls, G_N_ELEMENTS (double_icalls)},
5496         {"System.Enum", enum_icalls, G_N_ELEMENTS (enum_icalls)},
5497         {"System.Environment", environment_icalls, G_N_ELEMENTS (environment_icalls)},
5498         {"System.GC", gc_icalls, G_N_ELEMENTS (gc_icalls)},
5499         {"System.Globalization.CompareInfo", compareinfo_icalls, G_N_ELEMENTS (compareinfo_icalls)},
5500         {"System.Globalization.CultureInfo", cultureinfo_icalls, G_N_ELEMENTS (cultureinfo_icalls)},
5501         {"System.IO.FAMWatcher", famwatcher_icalls, G_N_ELEMENTS (famwatcher_icalls)},
5502         {"System.IO.FileSystemWatcher", filewatcher_icalls, G_N_ELEMENTS (filewatcher_icalls)},
5503         {"System.IO.MonoIO", monoio_icalls, G_N_ELEMENTS (monoio_icalls)},
5504         {"System.IO.Path", path_icalls, G_N_ELEMENTS (path_icalls)},
5505         {"System.Math", math_icalls, G_N_ELEMENTS (math_icalls)},
5506         {"System.MonoCustomAttrs", customattrs_icalls, G_N_ELEMENTS (customattrs_icalls)},
5507         {"System.MonoEnumInfo", enuminfo_icalls, G_N_ELEMENTS (enuminfo_icalls)},
5508         {"System.MonoType", monotype_icalls, G_N_ELEMENTS (monotype_icalls)},
5509         {"System.Net.Dns", dns_icalls, G_N_ELEMENTS (dns_icalls)},
5510         {"System.Net.Sockets.Socket", socket_icalls, G_N_ELEMENTS (socket_icalls)},
5511         {"System.Net.Sockets.SocketException", socketex_icalls, G_N_ELEMENTS (socketex_icalls)},
5512         {"System.Object", object_icalls, G_N_ELEMENTS (object_icalls)},
5513         {"System.Reflection.Assembly", assembly_icalls, G_N_ELEMENTS (assembly_icalls)},
5514         {"System.Reflection.Emit.AssemblyBuilder", assemblybuilder_icalls, G_N_ELEMENTS (assemblybuilder_icalls)},
5515         {"System.Reflection.Emit.CustomAttributeBuilder", customattrbuilder_icalls, G_N_ELEMENTS (customattrbuilder_icalls)},
5516         {"System.Reflection.Emit.DynamicMethod", dynamicmethod_icalls, G_N_ELEMENTS (dynamicmethod_icalls)},
5517         {"System.Reflection.Emit.GenericTypeParameterBuilder", generictypeparambuilder_icalls, G_N_ELEMENTS (generictypeparambuilder_icalls)},
5518         {"System.Reflection.Emit.MethodBuilder", methodbuilder_icalls, G_N_ELEMENTS (methodbuilder_icalls)},
5519         {"System.Reflection.Emit.ModuleBuilder", modulebuilder_icalls, G_N_ELEMENTS (modulebuilder_icalls)},
5520         {"System.Reflection.Emit.SignatureHelper", signaturehelper_icalls, G_N_ELEMENTS (signaturehelper_icalls)},
5521         {"System.Reflection.Emit.TypeBuilder", typebuilder_icalls, G_N_ELEMENTS (typebuilder_icalls)},
5522         {"System.Reflection.FieldInfo", fieldinfo_icalls, G_N_ELEMENTS (fieldinfo_icalls)},
5523         {"System.Reflection.MethodBase", methodbase_icalls, G_N_ELEMENTS (methodbase_icalls)},
5524         {"System.Reflection.Module", module_icalls, G_N_ELEMENTS (module_icalls)},
5525         {"System.Reflection.MonoCMethod", monocmethod_icalls, G_N_ELEMENTS (monocmethod_icalls)},
5526         {"System.Reflection.MonoEventInfo", monoeventinfo_icalls, G_N_ELEMENTS (monoeventinfo_icalls)},
5527         {"System.Reflection.MonoField", monofield_icalls, G_N_ELEMENTS (monofield_icalls)},
5528         {"System.Reflection.MonoGenericInst", monogenericinst_icalls, G_N_ELEMENTS (monogenericinst_icalls)},
5529         {"System.Reflection.MonoMethod", monomethod_icalls, G_N_ELEMENTS (monomethod_icalls)},
5530         {"System.Reflection.MonoMethodInfo", monomethodinfo_icalls, G_N_ELEMENTS (monomethodinfo_icalls)},
5531         {"System.Reflection.MonoPropertyInfo", monopropertyinfo_icalls, G_N_ELEMENTS (monopropertyinfo_icalls)},
5532         {"System.Runtime.CompilerServices.RuntimeHelpers", runtimehelpers_icalls, G_N_ELEMENTS (runtimehelpers_icalls)},
5533         {"System.Runtime.InteropServices.GCHandle", gchandle_icalls, G_N_ELEMENTS (gchandle_icalls)},
5534         {"System.Runtime.InteropServices.Marshal", marshal_icalls, G_N_ELEMENTS (marshal_icalls)},
5535         {"System.Runtime.Remoting.Activation.ActivationServices", activationservices_icalls, G_N_ELEMENTS (activationservices_icalls)},
5536         {"System.Runtime.Remoting.Messaging.MonoMethodMessage", monomethodmessage_icalls, G_N_ELEMENTS (monomethodmessage_icalls)},
5537         {"System.Runtime.Remoting.Proxies.RealProxy", realproxy_icalls, G_N_ELEMENTS (realproxy_icalls)},
5538         {"System.Runtime.Remoting.RemotingServices", remotingservices_icalls, G_N_ELEMENTS (remotingservices_icalls)},
5539         {"System.RuntimeMethodHandle", methodhandle_icalls, G_N_ELEMENTS (methodhandle_icalls)},
5540         {"System.Security.Cryptography.RNGCryptoServiceProvider", rng_icalls, G_N_ELEMENTS (rng_icalls)},
5541         {"System.String", string_icalls, G_N_ELEMENTS (string_icalls)},
5542         {"System.Text.Encoding", encoding_icalls, G_N_ELEMENTS (encoding_icalls)},
5543         {"System.Threading.Interlocked", interlocked_icalls, G_N_ELEMENTS (interlocked_icalls)},
5544         {"System.Threading.Monitor", monitor_icalls, G_N_ELEMENTS (monitor_icalls)},
5545         {"System.Threading.Mutex", mutex_icalls, G_N_ELEMENTS (mutex_icalls)},
5546         {"System.Threading.NativeEventCalls", nativeevents_icalls, G_N_ELEMENTS (nativeevents_icalls)},
5547         {"System.Threading.Thread", thread_icalls, G_N_ELEMENTS (thread_icalls)},
5548         {"System.Threading.ThreadPool", threadpool_icalls, G_N_ELEMENTS (threadpool_icalls)},
5549         {"System.Threading.WaitHandle", waithandle_icalls, G_N_ELEMENTS (waithandle_icalls)},
5550         {"System.Type", type_icalls, G_N_ELEMENTS (type_icalls)},
5551         {"System.TypedReference", typedref_icalls, G_N_ELEMENTS (typedref_icalls)},
5552         {"System.ValueType", valuetype_icalls, G_N_ELEMENTS (valuetype_icalls)},
5553         {"System.Web.Util.ICalls", web_icalls, G_N_ELEMENTS (web_icalls)}
5554 };
5555
5556 static GHashTable *icall_hash = NULL;
5557
5558 void
5559 mono_init_icall (void)
5560 {
5561         int i = 0;
5562
5563         /* check that tables are sorted: disable in release */
5564         if (TRUE) {
5565                 int j;
5566                 const IcallMap *imap;
5567                 const IcallEntry *ientry;
5568                 const char *prev_class = NULL;
5569                 const char *prev_method;
5570                 
5571                 for (i = 0; i < G_N_ELEMENTS (icall_entries); ++i) {
5572                         imap = &icall_entries [i];
5573                         prev_method = NULL;
5574                         if (prev_class && strcmp (prev_class, imap->klass) >= 0)
5575                                 g_print ("class %s should come before class %s\n", imap->klass, prev_class);
5576                         prev_class = imap->klass;
5577                         for (j = 0; j < imap->size; ++j) {
5578                                 ientry = &imap->icalls [j];
5579                                 if (prev_method && strcmp (prev_method, ientry->method) >= 0)
5580                                         g_print ("method %s should come before method %s\n", ientry->method, prev_method);
5581                                 prev_method = ientry->method;
5582                         }
5583                 }
5584         }
5585
5586         icall_hash = g_hash_table_new (g_str_hash , g_str_equal);
5587 }
5588
5589 void
5590 mono_add_internal_call (const char *name, gconstpointer method)
5591 {
5592         mono_loader_lock ();
5593
5594         g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
5595
5596         mono_loader_unlock ();
5597 }
5598
5599 static int
5600 compare_class_imap (const void *key, const void *elem)
5601 {
5602         const IcallMap* imap = (const IcallMap*)elem;
5603         return strcmp (key, imap->klass);
5604 }
5605
5606 static const IcallMap*
5607 find_class_icalls (const char *name)
5608 {
5609         return (const IcallMap*) bsearch (name, icall_entries, G_N_ELEMENTS (icall_entries), sizeof (IcallMap), compare_class_imap);
5610 }
5611
5612 static int
5613 compare_method_imap (const void *key, const void *elem)
5614 {
5615         const IcallEntry* ientry = (const IcallEntry*)elem;
5616         return strcmp (key, ientry->method);
5617 }
5618
5619 static void*
5620 find_method_icall (const IcallMap *imap, const char *name)
5621 {
5622         const IcallEntry *ientry = (const IcallEntry*) bsearch (name, imap->icalls, imap->size, sizeof (IcallEntry), compare_method_imap);
5623         if (ientry)
5624                 return (void*)ientry->func;
5625         return NULL;
5626 }
5627
5628 /* 
5629  * we should probably export this as an helper (handle nested types).
5630  * Returns the number of chars written in buf.
5631  */
5632 static int
5633 concat_class_name (char *buf, int bufsize, MonoClass *klass)
5634 {
5635         int nspacelen, cnamelen;
5636         nspacelen = strlen (klass->name_space);
5637         cnamelen = strlen (klass->name);
5638         if (nspacelen + cnamelen + 2 > bufsize)
5639                 return 0;
5640         if (nspacelen) {
5641                 memcpy (buf, klass->name_space, nspacelen);
5642                 buf [nspacelen ++] = '.';
5643         }
5644         memcpy (buf + nspacelen, klass->name, cnamelen);
5645         buf [nspacelen + cnamelen] = 0;
5646         return nspacelen + cnamelen;
5647 }
5648
5649 gpointer
5650 mono_lookup_internal_call (MonoMethod *method)
5651 {
5652         char *sigstart;
5653         char *tmpsig;
5654         char mname [2048];
5655         int typelen = 0, mlen, siglen;
5656         gpointer res;
5657         const IcallMap *imap;
5658
5659         g_assert (method != NULL);
5660
5661         typelen = concat_class_name (mname, sizeof (mname), method->klass);
5662         if (!typelen)
5663                 return NULL;
5664
5665         imap = find_class_icalls (mname);
5666
5667         mname [typelen] = ':';
5668         mname [typelen + 1] = ':';
5669
5670         mlen = strlen (method->name);
5671         memcpy (mname + typelen + 2, method->name, mlen);
5672         sigstart = mname + typelen + 2 + mlen;
5673         *sigstart = 0;
5674
5675         tmpsig = mono_signature_get_desc (method->signature, TRUE);
5676         siglen = strlen (tmpsig);
5677         if (typelen + mlen + siglen + 6 > sizeof (mname))
5678                 return NULL;
5679         sigstart [0] = '(';
5680         memcpy (sigstart + 1, tmpsig, siglen);
5681         sigstart [siglen + 1] = ')';
5682         sigstart [siglen + 2] = 0;
5683         g_free (tmpsig);
5684         
5685         mono_loader_lock ();
5686
5687         res = g_hash_table_lookup (icall_hash, mname);
5688         if (res) {
5689                 mono_loader_unlock ();
5690                 return res;
5691         }
5692         /* try without signature */
5693         *sigstart = 0;
5694         res = g_hash_table_lookup (icall_hash, mname);
5695         if (res) {
5696                 mono_loader_unlock ();
5697                 return res;
5698         }
5699
5700         /* it wasn't found in the static call tables */
5701         if (!imap) {
5702                 mono_loader_unlock ();
5703                 return NULL;
5704         }
5705         res = find_method_icall (imap, sigstart - mlen);
5706         if (res) {
5707                 mono_loader_unlock ();
5708                 return res;
5709         }
5710         /* try _with_ signature */
5711         *sigstart = '(';
5712         res = find_method_icall (imap, sigstart - mlen);
5713         if (res) {
5714                 mono_loader_unlock ();
5715                 return res;
5716         }
5717         
5718         g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname);
5719         g_print ("\nYour mono runtime and corlib are out of sync.\n");
5720         g_print ("Corlib is: %s\n", method->klass->image->name);
5721         g_print ("\nWhen you update one from cvs you need to update, compile and install\nthe other too.\n");
5722         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");
5723         g_print ("If you see other errors or faults after this message they are probably related\n");
5724         g_print ("and you need to fix your mono install first.\n");
5725
5726         mono_loader_unlock ();
5727
5728         return NULL;
5729 }
5730