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