2003-02-04 Dietmar Maurer <dietmar@ximian.com>
[mono.git] / mono / metadata / icall.c
1 /*
2  * icall.c:
3  *
4  * Authors:
5  *   Dietmar Maurer (dietmar@ximian.com)
6  *   Paolo Molaro (lupus@ximian.com)
7  *       Patrik Torstensson (patrik.torstensson@labs2.com)
8  *
9  * (C) 2001 Ximian, Inc.
10  */
11
12 #include <config.h>
13 #include <glib.h>
14 #include <stdarg.h>
15 #include <string.h>
16 #include <sys/time.h>
17 #include <unistd.h>
18 #if defined (PLATFORM_WIN32)
19 #include <stdlib.h>
20 #endif
21
22 #include <mono/metadata/object.h>
23 #include <mono/metadata/threads.h>
24 #include <mono/metadata/reflection.h>
25 #include <mono/metadata/assembly.h>
26 #include <mono/metadata/tabledefs.h>
27 #include <mono/metadata/exception.h>
28 #include <mono/metadata/file-io.h>
29 #include <mono/metadata/socket-io.h>
30 #include <mono/metadata/mono-endian.h>
31 #include <mono/metadata/tokentype.h>
32 #include <mono/metadata/unicode.h>
33 #include <mono/metadata/appdomain.h>
34 #include <mono/metadata/marshal.h>
35 #include <mono/metadata/gc-internal.h>
36 #include <mono/metadata/rand.h>
37 #include <mono/metadata/sysmath.h>
38 #include <mono/metadata/string-icalls.h>
39 #include <mono/metadata/debug-mono-symfile.h>
40 #include <mono/metadata/process.h>
41 #include <mono/metadata/environment.h>
42 #include <mono/io-layer/io-layer.h>
43 #include <mono/utils/strtod.h>
44
45 #if defined (PLATFORM_WIN32)
46 #include <windows.h>
47 #endif
48 #include "decimal.h"
49
50 static MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void);
51
52 static MonoString *
53 mono_double_ToStringImpl (double value)
54 {
55         /* FIXME: Handle formats, etc. */
56         MonoString *s;
57         gchar *retVal;
58
59         MONO_ARCH_SAVE_REGS;
60
61         retVal = g_strdup_printf ("%.15g", value);
62         s = mono_string_new (mono_domain_get (), retVal);
63         g_free (retVal);
64         return s;
65 }
66
67 /*
68  * We expect a pointer to a char, not a string
69  */
70 static double
71 mono_double_ParseImpl (char *ptr)
72 {
73         gchar *endptr = NULL;
74         gdouble result;
75
76         MONO_ARCH_SAVE_REGS;
77
78         if (*ptr)
79                 result = bsd_strtod (ptr, &endptr);
80
81         if (!*ptr || (endptr && *endptr))
82                 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib,
83                                                                 "System",
84                                                                 "FormatException"));
85         
86         return result;
87 }
88
89 static MonoString *
90 mono_float_ToStringImpl (float value)
91 {
92         MONO_ARCH_SAVE_REGS;
93
94         return mono_double_ToStringImpl (value);
95 }
96
97 static MonoObject *
98 ves_icall_System_Array_GetValueImpl (MonoObject *this, guint32 pos)
99 {
100         MonoClass *ac;
101         MonoArray *ao;
102         gint32 esize;
103         gpointer *ea;
104
105         MONO_ARCH_SAVE_REGS;
106
107         ao = (MonoArray *)this;
108         ac = (MonoClass *)ao->obj.vtable->klass;
109
110         esize = mono_array_element_size (ac);
111         ea = (gpointer*)((char*)ao->vector + (pos * esize));
112
113         if (ac->element_class->valuetype)
114                 return mono_value_box (this->vtable->domain, ac->element_class, ea);
115         else
116                 return *ea;
117 }
118
119 static MonoObject *
120 ves_icall_System_Array_GetValue (MonoObject *this, MonoObject *idxs)
121 {
122         MonoClass *ac, *ic;
123         MonoArray *ao, *io;
124         gint32 i, pos, *ind;
125
126         MONO_ARCH_SAVE_REGS;
127
128         MONO_CHECK_ARG_NULL (idxs);
129
130         io = (MonoArray *)idxs;
131         ic = (MonoClass *)io->obj.vtable->klass;
132         
133         ao = (MonoArray *)this;
134         ac = (MonoClass *)ao->obj.vtable->klass;
135
136         g_assert (ic->rank == 1);
137         if (io->bounds != NULL || io->max_length !=  ac->rank)
138                 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
139
140         ind = (guint32 *)io->vector;
141
142         if (ao->bounds == NULL) {
143                 if (*ind < 0 || *ind >= ao->max_length)
144                         mono_raise_exception (mono_get_exception_index_out_of_range ());
145
146                 return ves_icall_System_Array_GetValueImpl (this, *ind);
147         }
148         
149         for (i = 0; i < ac->rank; i++)
150                 if ((ind [i] < ao->bounds [i].lower_bound) ||
151                     (ind [i] >= ao->bounds [i].length + ao->bounds [i].lower_bound))
152                         mono_raise_exception (mono_get_exception_index_out_of_range ());
153
154         pos = ind [0] - ao->bounds [0].lower_bound;
155         for (i = 1; i < ac->rank; i++)
156                 pos = pos*ao->bounds [i].length + ind [i] - 
157                         ao->bounds [i].lower_bound;
158
159         return ves_icall_System_Array_GetValueImpl (this, pos);
160 }
161
162 static void
163 ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32 pos)
164 {
165         MonoClass *ac, *vc, *ec;
166         gint32 esize, vsize;
167         gpointer *ea, *va;
168
169         guint64 u64;
170         gint64 i64;
171         gdouble r64;
172
173         MONO_ARCH_SAVE_REGS;
174
175         if (value)
176                 vc = value->vtable->klass;
177         else
178                 vc = NULL;
179
180         ac = this->obj.vtable->klass;
181         ec = ac->element_class;
182
183         esize = mono_array_element_size (ac);
184         ea = (gpointer*)((char*)this->vector + (pos * esize));
185         va = (gpointer*)((char*)value + sizeof (MonoObject));
186
187         if (!value) {
188                 memset (ea, 0,  esize);
189                 return;
190         }
191
192 #define NO_WIDENING_CONVERSION G_STMT_START{\
193         mono_raise_exception (mono_get_exception_argument ( \
194                 "value", "not a widening conversion")); \
195 }G_STMT_END
196
197 #define CHECK_WIDENING_CONVERSION(extra) G_STMT_START{\
198         if (esize < vsize + (extra)) \
199                 mono_raise_exception (mono_get_exception_argument ( \
200                         "value", "not a widening conversion")); \
201 }G_STMT_END
202
203 #define INVALID_CAST G_STMT_START{\
204         mono_raise_exception (mono_get_exception_invalid_cast ()); \
205 }G_STMT_END
206
207         /* Check element (destination) type. */
208         switch (ec->byval_arg.type) {
209         case MONO_TYPE_STRING:
210                 switch (vc->byval_arg.type) {
211                 case MONO_TYPE_STRING:
212                         break;
213                 default:
214                         INVALID_CAST;
215                 }
216                 break;
217         case MONO_TYPE_BOOLEAN:
218                 switch (vc->byval_arg.type) {
219                 case MONO_TYPE_BOOLEAN:
220                         break;
221                 case MONO_TYPE_CHAR:
222                 case MONO_TYPE_U1:
223                 case MONO_TYPE_U2:
224                 case MONO_TYPE_U4:
225                 case MONO_TYPE_U8:
226                 case MONO_TYPE_I1:
227                 case MONO_TYPE_I2:
228                 case MONO_TYPE_I4:
229                 case MONO_TYPE_I8:
230                 case MONO_TYPE_R4:
231                 case MONO_TYPE_R8:
232                         NO_WIDENING_CONVERSION;
233                 default:
234                         INVALID_CAST;
235                 }
236                 break;
237         }
238
239         if (!ec->valuetype) {
240                 *ea = (gpointer)value;
241                 return;
242         }
243
244         if (mono_object_isinst (value, ec)) {
245                 memcpy (ea, (char *)value + sizeof (MonoObject), esize);
246                 return;
247         }
248
249         if (!vc->valuetype)
250                 INVALID_CAST;
251
252         vsize = mono_class_instance_size (vc) - sizeof (MonoObject);
253
254 #if 0
255         g_message (G_STRLOC ": %d (%d) <= %d (%d)",
256                    ec->byval_arg.type, esize,
257                    vc->byval_arg.type, vsize);
258 #endif
259
260 #define ASSIGN_UNSIGNED(etype) G_STMT_START{\
261         switch (vc->byval_arg.type) { \
262         case MONO_TYPE_U1: \
263         case MONO_TYPE_U2: \
264         case MONO_TYPE_U4: \
265         case MONO_TYPE_U8: \
266         case MONO_TYPE_CHAR: \
267                 CHECK_WIDENING_CONVERSION(0); \
268                 *(etype *) ea = (etype) u64; \
269                 return; \
270         /* You can't assign a signed value to an unsigned array. */ \
271         case MONO_TYPE_I1: \
272         case MONO_TYPE_I2: \
273         case MONO_TYPE_I4: \
274         case MONO_TYPE_I8: \
275         /* You can't assign a floating point number to an integer array. */ \
276         case MONO_TYPE_R4: \
277         case MONO_TYPE_R8: \
278                 NO_WIDENING_CONVERSION; \
279         } \
280 }G_STMT_END
281
282 #define ASSIGN_SIGNED(etype) G_STMT_START{\
283         switch (vc->byval_arg.type) { \
284         case MONO_TYPE_I1: \
285         case MONO_TYPE_I2: \
286         case MONO_TYPE_I4: \
287         case MONO_TYPE_I8: \
288                 CHECK_WIDENING_CONVERSION(0); \
289                 *(etype *) ea = (etype) i64; \
290                 return; \
291         /* You can assign an unsigned value to a signed array if the array's */ \
292         /* element size is larger than the value size. */ \
293         case MONO_TYPE_U1: \
294         case MONO_TYPE_U2: \
295         case MONO_TYPE_U4: \
296         case MONO_TYPE_U8: \
297         case MONO_TYPE_CHAR: \
298                 CHECK_WIDENING_CONVERSION(1); \
299                 *(etype *) ea = (etype) u64; \
300                 return; \
301         /* You can't assign a floating point number to an integer array. */ \
302         case MONO_TYPE_R4: \
303         case MONO_TYPE_R8: \
304                 NO_WIDENING_CONVERSION; \
305         } \
306 }G_STMT_END
307
308 #define ASSIGN_REAL(etype) G_STMT_START{\
309         switch (vc->byval_arg.type) { \
310         case MONO_TYPE_R4: \
311         case MONO_TYPE_R8: \
312                 CHECK_WIDENING_CONVERSION(0); \
313                 *(etype *) ea = (etype) r64; \
314                 return; \
315         /* All integer values fit into a floating point array, so we don't */ \
316         /* need to CHECK_WIDENING_CONVERSION here. */ \
317         case MONO_TYPE_I1: \
318         case MONO_TYPE_I2: \
319         case MONO_TYPE_I4: \
320         case MONO_TYPE_I8: \
321                 *(etype *) ea = (etype) i64; \
322                 return; \
323         case MONO_TYPE_U1: \
324         case MONO_TYPE_U2: \
325         case MONO_TYPE_U4: \
326         case MONO_TYPE_U8: \
327         case MONO_TYPE_CHAR: \
328                 *(etype *) ea = (etype) u64; \
329                 return; \
330         } \
331 }G_STMT_END
332
333         switch (vc->byval_arg.type) {
334         case MONO_TYPE_U1:
335                 u64 = *(guint8 *) va;
336                 break;
337         case MONO_TYPE_U2:
338                 u64 = *(guint16 *) va;
339                 break;
340         case MONO_TYPE_U4:
341                 u64 = *(guint32 *) va;
342                 break;
343         case MONO_TYPE_U8:
344                 u64 = *(guint64 *) va;
345                 break;
346         case MONO_TYPE_I1:
347                 i64 = *(gint8 *) va;
348                 break;
349         case MONO_TYPE_I2:
350                 i64 = *(gint16 *) va;
351                 break;
352         case MONO_TYPE_I4:
353                 i64 = *(gint32 *) va;
354                 break;
355         case MONO_TYPE_I8:
356                 i64 = *(gint64 *) va;
357                 break;
358         case MONO_TYPE_R4:
359                 r64 = *(gfloat *) va;
360                 break;
361         case MONO_TYPE_R8:
362                 r64 = *(gdouble *) va;
363                 break;
364         case MONO_TYPE_CHAR:
365                 u64 = *(guint16 *) va;
366                 break;
367         case MONO_TYPE_BOOLEAN:
368                 /* Boolean is only compatible with itself. */
369                 switch (ec->byval_arg.type) {
370                 case MONO_TYPE_CHAR:
371                 case MONO_TYPE_U1:
372                 case MONO_TYPE_U2:
373                 case MONO_TYPE_U4:
374                 case MONO_TYPE_U8:
375                 case MONO_TYPE_I1:
376                 case MONO_TYPE_I2:
377                 case MONO_TYPE_I4:
378                 case MONO_TYPE_I8:
379                 case MONO_TYPE_R4:
380                 case MONO_TYPE_R8:
381                         NO_WIDENING_CONVERSION;
382                 default:
383                         INVALID_CAST;
384                 }
385                 break;
386         }
387
388         /* If we can't do a direct copy, let's try a widening conversion. */
389         switch (ec->byval_arg.type) {
390         case MONO_TYPE_CHAR:
391                 ASSIGN_UNSIGNED (guint16);
392         case MONO_TYPE_U1:
393                 ASSIGN_UNSIGNED (guint8);
394         case MONO_TYPE_U2:
395                 ASSIGN_UNSIGNED (guint16);
396         case MONO_TYPE_U4:
397                 ASSIGN_UNSIGNED (guint32);
398         case MONO_TYPE_U8:
399                 ASSIGN_UNSIGNED (guint64);
400         case MONO_TYPE_I1:
401                 ASSIGN_SIGNED (gint8);
402         case MONO_TYPE_I2:
403                 ASSIGN_SIGNED (gint16);
404         case MONO_TYPE_I4:
405                 ASSIGN_SIGNED (gint32);
406         case MONO_TYPE_I8:
407                 ASSIGN_SIGNED (gint64);
408         case MONO_TYPE_R4:
409                 ASSIGN_REAL (gfloat);
410         case MONO_TYPE_R8:
411                 ASSIGN_REAL (gdouble);
412         }
413
414         INVALID_CAST;
415         /* Not reached, INVALID_CAST does not return. Just to avoid a compiler warning ... */
416         return;
417
418 #undef INVALID_CAST
419 #undef NO_WIDENING_CONVERSION
420 #undef CHECK_WIDENING_CONVERSION
421 #undef ASSIGN_UNSIGNED
422 #undef ASSIGN_SIGNED
423 #undef ASSIGN_REAL
424 }
425
426 static void 
427 ves_icall_System_Array_SetValue (MonoArray *this, MonoObject *value,
428                                  MonoArray *idxs)
429 {
430         MonoClass *ac, *ic;
431         gint32 i, pos, *ind;
432
433         MONO_ARCH_SAVE_REGS;
434
435         MONO_CHECK_ARG_NULL (idxs);
436
437         ic = idxs->obj.vtable->klass;
438         ac = this->obj.vtable->klass;
439
440         g_assert (ic->rank == 1);
441         if (idxs->bounds != NULL || idxs->max_length != ac->rank)
442                 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
443
444         ind = (guint32 *)idxs->vector;
445
446         if (this->bounds == NULL) {
447                 if (*ind < 0 || *ind >= this->max_length)
448                         mono_raise_exception (mono_get_exception_index_out_of_range ());
449
450                 ves_icall_System_Array_SetValueImpl (this, value, *ind);
451                 return;
452         }
453         
454         for (i = 0; i < ac->rank; i++)
455                 if ((ind [i] < this->bounds [i].lower_bound) ||
456                     (ind [i] >= this->bounds [i].length + this->bounds [i].lower_bound))
457                         mono_raise_exception (mono_get_exception_index_out_of_range ());
458
459         pos = ind [0] - this->bounds [0].lower_bound;
460         for (i = 1; i < ac->rank; i++)
461                 pos = pos * this->bounds [i].length + ind [i] - 
462                         this->bounds [i].lower_bound;
463
464         ves_icall_System_Array_SetValueImpl (this, value, pos);
465 }
466
467 static MonoArray *
468 ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
469 {
470         MonoClass *aklass;
471         MonoArray *array;
472         gint32 *sizes, i;
473
474         MONO_ARCH_SAVE_REGS;
475
476         MONO_CHECK_ARG_NULL (type);
477         MONO_CHECK_ARG_NULL (lengths);
478
479         MONO_CHECK_ARG (lengths, mono_array_length (lengths) > 0);
480         if (bounds)
481                 MONO_CHECK_ARG (bounds, mono_array_length (lengths) == mono_array_length (bounds));
482
483         for (i = 0; i < mono_array_length (lengths); i++)
484                 if (mono_array_get (lengths, gint32, i) < 0)
485                         mono_raise_exception (mono_get_exception_argument_out_of_range (NULL));
486
487         aklass = mono_array_class_get (type->type, mono_array_length (lengths));
488
489         sizes = alloca (aklass->rank * sizeof(guint32) * 2);
490         for (i = 0; i < aklass->rank; ++i) {
491                 sizes [i] = mono_array_get (lengths, gint32, i);
492                 if (bounds)
493                         sizes [i + aklass->rank] = mono_array_get (bounds, gint32, i);
494                 else
495                         sizes [i + aklass->rank] = 0;
496         }
497
498         array = mono_array_new_full (mono_object_domain (type), aklass, sizes, sizes + aklass->rank);
499
500         return array;
501 }
502
503 static gint32 
504 ves_icall_System_Array_GetRank (MonoObject *this)
505 {
506         MONO_ARCH_SAVE_REGS;
507
508         return this->vtable->klass->rank;
509 }
510
511 static gint32
512 ves_icall_System_Array_GetLength (MonoArray *this, gint32 dimension)
513 {
514         gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
515
516         MONO_ARCH_SAVE_REGS;
517
518         if ((dimension < 0) || (dimension >= rank))
519                 mono_raise_exception (mono_get_exception_index_out_of_range ());
520         
521         if (this->bounds == NULL)
522                 return this->max_length;
523         
524         return this->bounds [dimension].length;
525 }
526
527 static gint32
528 ves_icall_System_Array_GetLowerBound (MonoArray *this, gint32 dimension)
529 {
530         gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
531
532         MONO_ARCH_SAVE_REGS;
533
534         if ((dimension < 0) || (dimension >= rank))
535                 mono_raise_exception (mono_get_exception_index_out_of_range ());
536         
537         if (this->bounds == NULL)
538                 return 0;
539         
540         return this->bounds [dimension].lower_bound;
541 }
542
543 static void
544 ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* dest, int dest_idx, int length)
545 {
546         int element_size = mono_array_element_size (source->obj.vtable->klass);
547         void * dest_addr = mono_array_addr_with_size (dest, element_size, dest_idx);
548         void * source_addr = mono_array_addr_with_size (source, element_size, source_idx);
549
550         MONO_ARCH_SAVE_REGS;
551
552         g_assert (dest_idx + length <= mono_array_length (dest));
553         g_assert (source_idx + length <= mono_array_length (source));
554         memmove (dest_addr, source_addr, element_size * length);
555 }
556
557 static void
558 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoArray *array, MonoClassField *field_handle)
559 {
560         MonoClass *klass = array->obj.vtable->klass;
561         guint32 size = mono_array_element_size (klass);
562         int i;
563
564         MONO_ARCH_SAVE_REGS;
565
566         if (array->bounds == NULL)
567                 size *= array->max_length;
568         else
569                 for (i = 0; i < klass->rank; ++i) 
570                         size *= array->bounds [i].length;
571
572         memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
573
574 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
575 #define SWAP(n) {\
576         gint i; \
577         guint ## n tmp; \
578         guint ## n *data = (guint ## n *) mono_array_addr (array, char, 0); \
579 \
580         for (i = 0; i < size; i += n/8, data++) { \
581                 tmp = read ## n (data); \
582                 *data = tmp; \
583         } \
584 }
585
586         /* printf ("Initialize array with elements of %s type\n", klass->element_class->name); */
587
588         switch (klass->element_class->byval_arg.type) {
589         case MONO_TYPE_CHAR:
590         case MONO_TYPE_I2:
591         case MONO_TYPE_U2:
592                 SWAP (16);
593                 break;
594         case MONO_TYPE_I4:
595         case MONO_TYPE_U4:
596                 SWAP (32);
597                 break;
598         case MONO_TYPE_I8:
599         case MONO_TYPE_U8:
600                 SWAP (64);
601                 break;
602         }
603                  
604 #endif
605 }
606
607 static gint
608 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData (void)
609 {
610         MONO_ARCH_SAVE_REGS;
611
612         return offsetof (MonoString, chars);
613 }
614
615 static MonoObject *
616 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue (MonoObject *obj)
617 {
618         MONO_ARCH_SAVE_REGS;
619
620         if ((obj == NULL) || (! (obj->vtable->klass->valuetype)))
621                 return obj;
622         else
623                 return mono_object_clone (obj);
624 }
625
626 static void
627 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (MonoType *handle)
628 {
629         MonoClass *klass;
630
631         MONO_ARCH_SAVE_REGS;
632
633         MONO_CHECK_ARG_NULL (handle);
634
635         klass = mono_class_from_mono_type (handle);
636         MONO_CHECK_ARG (handle, klass);
637
638         /* This will call the type constructor */
639         if (! (klass->flags & TYPE_ATTRIBUTE_INTERFACE))
640                 mono_class_vtable (mono_domain_get (), klass);
641 }
642
643 static MonoObject *
644 ves_icall_System_Object_MemberwiseClone (MonoObject *this)
645 {
646         MONO_ARCH_SAVE_REGS;
647
648         return mono_object_clone (this);
649 }
650
651 #if HAVE_BOEHM_GC
652 #define MONO_OBJECT_ALIGNMENT_SHIFT     3
653 #else
654 #define MONO_OBJECT_ALIGNMENT_SHIFT     2
655 #endif
656
657 /*
658  * Return hashcode based on object address. This function will need to be
659  * smarter in the presence of a moving garbage collector, which will cache
660  * the address hash before relocating the object.
661  *
662  * Wang's address-based hash function:
663  *   http://www.concentric.net/~Ttwang/tech/addrhash.htm
664  */
665 static gint32
666 ves_icall_System_Object_GetHashCode (MonoObject *this)
667 {
668         register guint32 key;
669
670         MONO_ARCH_SAVE_REGS;
671
672         key = (GPOINTER_TO_UINT (this) >> MONO_OBJECT_ALIGNMENT_SHIFT) * 2654435761u;
673
674         return key & 0x7fffffff;
675 }
676
677 /*
678  * A hash function for value types. I have no idea if this is a good hash 
679  * function (its similar to g_str_hash).
680  */
681 static gint32
682 ves_icall_System_ValueType_GetHashCode (MonoObject *this)
683 {
684         gint32 i, size;
685         const char *p;
686         guint h = 0;
687
688         MONO_ARCH_SAVE_REGS;
689
690         MONO_CHECK_ARG_NULL (this);
691
692         size = this->vtable->klass->instance_size - sizeof (MonoObject);
693
694         p = (const char *)this + sizeof (MonoObject);
695
696         for (i = 0; i < size; i++) {
697                 h = (h << 5) - h + *p;
698                 p++;
699         }
700
701         return h;
702 }
703
704 static MonoBoolean
705 ves_icall_System_ValueType_Equals (MonoObject *this, MonoObject *that)
706 {
707         gint32 size;
708         const char *p, *s;
709
710         MONO_ARCH_SAVE_REGS;
711
712         MONO_CHECK_ARG_NULL (that);
713
714         if (this->vtable != that->vtable)
715                 return FALSE;
716
717         size = this->vtable->klass->instance_size - sizeof (MonoObject);
718
719         p = (const char *)this + sizeof (MonoObject);
720         s = (const char *)that + sizeof (MonoObject);
721
722         return memcmp (p, s, size)? FALSE: TRUE;
723 }
724
725 static MonoReflectionType *
726 ves_icall_System_Object_GetType (MonoObject *obj)
727 {
728         MONO_ARCH_SAVE_REGS;
729
730         return mono_type_get_object (mono_object_domain (obj), &obj->vtable->klass->byval_arg);
731 }
732
733 static void
734 mono_type_type_from_obj (MonoReflectionType *mtype, MonoObject *obj)
735 {
736         MONO_ARCH_SAVE_REGS;
737
738         mtype->type = &obj->vtable->klass->byval_arg;
739         g_assert (mtype->type->type);
740 }
741
742 static gint32
743 ves_icall_AssemblyBuilder_getToken (MonoReflectionAssemblyBuilder *assb, MonoObject *obj)
744 {
745         MONO_ARCH_SAVE_REGS;
746
747         return mono_image_create_token (assb->dynamic_assembly, obj);
748 }
749
750 static gint32
751 ves_icall_AssemblyBuilder_getDataChunk (MonoReflectionAssemblyBuilder *assb, MonoArray *buf, gint32 offset)
752 {
753         int count;
754         MonoDynamicAssembly *ass = assb->dynamic_assembly;
755         char *p = mono_array_addr (buf, char, 0);
756
757         MONO_ARCH_SAVE_REGS;
758
759         mono_image_create_pefile (assb);
760
761         if (offset >= ass->pefile.index)
762                 return 0;
763         count = mono_array_length (buf);
764         count = MIN (count, ass->pefile.index - offset);
765         
766         memcpy (p, ass->pefile.data + offset, count);
767
768         return count;
769 }
770
771 static MonoReflectionType*
772 ves_icall_type_from_name (MonoString *name,
773                           MonoBoolean throwOnError,
774                           MonoBoolean ignoreCase)
775 {
776         gchar *str;
777         MonoType *type = NULL;
778         MonoAssembly *assembly;
779         MonoTypeNameParse info;
780
781         MONO_ARCH_SAVE_REGS;
782
783         str = mono_string_to_utf8 (name);
784         if (!mono_reflection_parse_type (str, &info)) {
785                 g_free (str);
786                 g_list_free (info.modifiers);
787                 g_list_free (info.nested);
788                 if (throwOnError) /* uhm: this is a parse error, though... */
789                         mono_raise_exception (mono_get_exception_type_load ());
790
791                 return NULL;
792         }
793
794         if (info.assembly.name) {
795                 assembly = mono_assembly_load (&info.assembly, NULL, NULL);
796         } else {
797                 MonoReflectionAssembly *refass;
798
799                 refass = ves_icall_System_Reflection_Assembly_GetCallingAssembly  ();
800                 assembly = refass->assembly;
801         }
802
803         if (assembly)
804                 type = mono_reflection_get_type (assembly->image, &info, ignoreCase);
805         
806         if (!info.assembly.name && !type) /* try mscorlib */
807                 type = mono_reflection_get_type (NULL, &info, ignoreCase);
808
809         if (!type) {
810                 MonoReflectionAssembly *assembly;
811                 char *fullName;
812
813                 if (info.name_space)
814                         fullName = g_strdup_printf ("%s.%s", info.name_space, info.name);
815                 else
816                         fullName = g_strdup (info.name);
817                 assembly = 
818                         mono_domain_try_type_resolve (
819                                 mono_domain_get (),
820                                 (MonoObject*)mono_string_new (mono_domain_get (), fullName));
821                 if (assembly)
822                         type = mono_reflection_get_type (assembly->assembly->image, 
823                                                                                          &info, ignoreCase);
824                 g_free (fullName);
825         }
826
827         g_free (str);
828         g_list_free (info.modifiers);
829         g_list_free (info.nested);
830         if (!type) {
831                 if (throwOnError)
832                         mono_raise_exception (mono_get_exception_type_load ());
833
834                 return NULL;
835         }
836
837         return mono_type_get_object (mono_domain_get (), type);
838 }
839
840 static MonoReflectionType*
841 ves_icall_type_from_handle (MonoType *handle)
842 {
843         MonoDomain *domain = mono_domain_get (); 
844         MonoClass *klass = mono_class_from_mono_type (handle);
845
846         MONO_ARCH_SAVE_REGS;
847
848         mono_class_init (klass);
849         return mono_type_get_object (domain, handle);
850 }
851
852 static guint32
853 ves_icall_type_Equals (MonoReflectionType *type, MonoReflectionType *c)
854 {
855         MONO_ARCH_SAVE_REGS;
856
857         if (type->type && c->type)
858                 return mono_metadata_type_equal (type->type, c->type);
859         g_print ("type equals\n");
860         return 0;
861 }
862
863 /* System.TypeCode */
864 typedef enum {
865         TYPECODE_EMPTY,
866         TYPECODE_OBJECT,
867         TYPECODE_DBNULL,
868         TYPECODE_BOOLEAN,
869         TYPECODE_CHAR,
870         TYPECODE_SBYTE,
871         TYPECODE_BYTE,
872         TYPECODE_INT16,
873         TYPECODE_UINT16,
874         TYPECODE_INT32,
875         TYPECODE_UINT32,
876         TYPECODE_INT64,
877         TYPECODE_UINT64,
878         TYPECODE_SINGLE,
879         TYPECODE_DOUBLE,
880         TYPECODE_DECIMAL,
881         TYPECODE_DATETIME,
882         TYPECODE_STRING = 18
883 } TypeCode;
884
885 static guint32
886 ves_icall_type_GetTypeCode (MonoReflectionType *type)
887 {
888         int t = type->type->type;
889
890         MONO_ARCH_SAVE_REGS;
891
892 handle_enum:
893         switch (t) {
894         case MONO_TYPE_VOID:
895                 return TYPECODE_OBJECT;
896         case MONO_TYPE_BOOLEAN:
897                 return TYPECODE_BOOLEAN;
898         case MONO_TYPE_U1:
899                 return TYPECODE_BYTE;
900         case MONO_TYPE_I1:
901                 return TYPECODE_SBYTE;
902         case MONO_TYPE_U2:
903                 return TYPECODE_UINT16;
904         case MONO_TYPE_I2:
905                 return TYPECODE_INT16;
906         case MONO_TYPE_CHAR:
907                 return TYPECODE_CHAR;
908         case MONO_TYPE_PTR:
909         case MONO_TYPE_U:
910         case MONO_TYPE_I:
911                 return TYPECODE_OBJECT;
912         case MONO_TYPE_U4:
913                 return TYPECODE_UINT32;
914         case MONO_TYPE_I4:
915                 return TYPECODE_INT32;
916         case MONO_TYPE_U8:
917                 return TYPECODE_UINT64;
918         case MONO_TYPE_I8:
919                 return TYPECODE_INT64;
920         case MONO_TYPE_R4:
921                 return TYPECODE_SINGLE;
922         case MONO_TYPE_R8:
923                 return TYPECODE_DOUBLE;
924         case MONO_TYPE_VALUETYPE:
925                 if (type->type->data.klass->enumtype) {
926                         t = type->type->data.klass->enum_basetype->type;
927                         goto handle_enum;
928                 } else {
929                         MonoClass *k =  type->type->data.klass;
930                         if (strcmp (k->name_space, "System") == 0) {
931                                 if (strcmp (k->name, "Decimal") == 0)
932                                         return TYPECODE_DECIMAL;
933                                 else if (strcmp (k->name, "DateTime") == 0)
934                                         return TYPECODE_DATETIME;
935                                 else if (strcmp (k->name, "DBNull") == 0)
936                                         return TYPECODE_DBNULL;
937                         }
938                 }
939                 /* handle datetime, dbnull.. */
940                 return TYPECODE_OBJECT;
941         case MONO_TYPE_STRING:
942                 return TYPECODE_STRING;
943         case MONO_TYPE_SZARRAY:
944         case MONO_TYPE_ARRAY:
945         case MONO_TYPE_OBJECT:
946                 return TYPECODE_OBJECT;
947         case MONO_TYPE_CLASS:
948                 return TYPECODE_OBJECT;
949         default:
950                 g_error ("type 0x%02x not handled in GetTypeCode()", t);
951         }
952         return 0;
953 }
954
955 static guint32
956 ves_icall_type_is_subtype_of (MonoReflectionType *type, MonoReflectionType *c, MonoBoolean check_interfaces)
957 {
958         MonoDomain *domain; 
959         MonoClass *klass;
960         MonoClass *klassc;
961
962         MONO_ARCH_SAVE_REGS;
963
964         g_assert (type != NULL);
965         
966         domain = ((MonoObject *)type)->vtable->domain;
967
968         if (!c) /* FIXME: dont know what do do here */
969                 return 0;
970
971         klass = mono_class_from_mono_type (type->type);
972         klassc = mono_class_from_mono_type (c->type);
973
974         /* cut&paste from mono_object_isinst (): keep in sync */
975         if (check_interfaces && (klassc->flags & TYPE_ATTRIBUTE_INTERFACE) && !(klass->flags & TYPE_ATTRIBUTE_INTERFACE)) {
976                 MonoVTable *klass_vt = mono_class_vtable (domain, klass);
977                 if ((klassc->interface_id <= klass->max_interface_id) &&
978                     klass_vt->interface_offsets [klassc->interface_id])
979                         return 1;
980         } else if (check_interfaces && (klassc->flags & TYPE_ATTRIBUTE_INTERFACE) && (klass->flags & TYPE_ATTRIBUTE_INTERFACE)) {
981                 int i;
982
983                 for (i = 0; i < klass->interface_count; i ++) {
984                         MonoClass *ic =  klass->interfaces [i];
985                         if (ic == klassc)
986                                 return 1;
987                 }
988         } else {
989                 /*
990                  * klass->baseval is 0 for interfaces 
991                  */
992                 if (klass->baseval && ((klass->baseval - klassc->baseval) <= klassc->diffval))
993                         return 1;
994         }
995         return 0;
996 }
997
998 static guint32
999 ves_icall_get_attributes (MonoReflectionType *type)
1000 {
1001         MonoClass *klass = mono_class_from_mono_type (type->type);
1002
1003         MONO_ARCH_SAVE_REGS;
1004
1005         return klass->flags;
1006 }
1007
1008 static void
1009 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
1010 {
1011         MonoDomain *domain = mono_domain_get ();
1012
1013         MONO_ARCH_SAVE_REGS;
1014
1015         info->parent = mono_type_get_object (domain, &method->klass->byval_arg);
1016         info->ret = mono_type_get_object (domain, method->signature->ret);
1017         info->attrs = method->flags;
1018         info->implattrs = method->iflags;
1019 }
1020
1021 static MonoArray*
1022 ves_icall_get_parameter_info (MonoMethod *method)
1023 {
1024         MonoDomain *domain = mono_domain_get (); 
1025         MonoArray *res;
1026         static MonoClass *System_Reflection_ParameterInfo;
1027         MonoReflectionParameter** args;
1028         int i;
1029
1030         MONO_ARCH_SAVE_REGS;
1031
1032         args = mono_param_get_objects (domain, method);
1033         if (!System_Reflection_ParameterInfo)
1034                 System_Reflection_ParameterInfo = mono_class_from_name (
1035                         mono_defaults.corlib, "System.Reflection", "ParameterInfo");
1036         res = mono_array_new (domain, System_Reflection_ParameterInfo, method->signature->param_count);
1037         for (i = 0; i < method->signature->param_count; ++i) {
1038                 mono_array_set (res, gpointer, i, args [i]);
1039         }
1040         return res;
1041 }
1042
1043 static void
1044 ves_icall_get_field_info (MonoReflectionField *field, MonoFieldInfo *info)
1045 {
1046         MonoDomain *domain = mono_object_domain (field); 
1047
1048         MONO_ARCH_SAVE_REGS;
1049
1050         info->parent = mono_type_get_object (domain, &field->klass->byval_arg);
1051         info->type = mono_type_get_object (domain, field->field->type);
1052         info->name = mono_string_new (domain, field->field->name);
1053         info->attrs = field->field->type->attrs;
1054 }
1055
1056 static MonoObject *
1057 ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj)
1058 {       
1059         MonoObject *o;
1060         MonoClassField *cf = field->field;
1061         MonoClass *klass;
1062         MonoVTable *vtable;
1063         MonoDomain *domain = mono_object_domain (field); 
1064         gchar *v;
1065         gboolean is_static = FALSE;
1066         gboolean is_ref = FALSE;
1067
1068         MONO_ARCH_SAVE_REGS;
1069
1070         mono_class_init (field->klass);
1071
1072         switch (cf->type->type) {
1073         case MONO_TYPE_STRING:
1074         case MONO_TYPE_OBJECT:
1075         case MONO_TYPE_CLASS:
1076         case MONO_TYPE_ARRAY:
1077         case MONO_TYPE_SZARRAY:
1078                 is_ref = TRUE;
1079                 break;
1080         case MONO_TYPE_U1:
1081         case MONO_TYPE_I1:
1082         case MONO_TYPE_BOOLEAN:
1083         case MONO_TYPE_U2:
1084         case MONO_TYPE_I2:
1085         case MONO_TYPE_CHAR:
1086         case MONO_TYPE_U:
1087         case MONO_TYPE_I:
1088         case MONO_TYPE_U4:
1089         case MONO_TYPE_I4:
1090         case MONO_TYPE_R4:
1091         case MONO_TYPE_U8:
1092         case MONO_TYPE_I8:
1093         case MONO_TYPE_R8:
1094         case MONO_TYPE_VALUETYPE:
1095                 is_ref = cf->type->byref;
1096                 break;
1097         default:
1098                 g_error ("type 0x%x not handled in "
1099                          "ves_icall_Monofield_GetValue", cf->type->type);
1100                 return NULL;
1101         }
1102
1103         if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) {
1104                 is_static = TRUE;
1105                 vtable = mono_class_vtable (domain, field->klass);
1106         }
1107         
1108         if (is_ref) {
1109                 if (is_static) {
1110                         mono_field_static_get_value (vtable, cf, &o);
1111                 } else {
1112                         mono_field_get_value (obj, cf, &o);
1113                 }
1114                 return o;
1115         }
1116
1117         /* boxed value type */
1118         klass = mono_class_from_mono_type (cf->type);
1119         o = mono_object_new (domain, klass);
1120         v = ((gchar *) o) + sizeof (MonoObject);
1121         if (is_static) {
1122                 mono_field_static_get_value (vtable, cf, v);
1123         } else {
1124                 mono_field_get_value (obj, cf, v);
1125         }
1126
1127         return o;
1128 }
1129
1130 static void
1131 ves_icall_FieldInfo_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value)
1132 {
1133         MonoClassField *cf = field->field;
1134         gchar *v;
1135
1136         MONO_ARCH_SAVE_REGS;
1137
1138         v = (gchar *) value;
1139         if (!cf->type->byref) {
1140                 switch (cf->type->type) {
1141                 case MONO_TYPE_U1:
1142                 case MONO_TYPE_I1:
1143                 case MONO_TYPE_BOOLEAN:
1144                 case MONO_TYPE_U2:
1145                 case MONO_TYPE_I2:
1146                 case MONO_TYPE_CHAR:
1147                 case MONO_TYPE_U:
1148                 case MONO_TYPE_I:
1149                 case MONO_TYPE_U4:
1150                 case MONO_TYPE_I4:
1151                 case MONO_TYPE_R4:
1152                 case MONO_TYPE_U8:
1153                 case MONO_TYPE_I8:
1154                 case MONO_TYPE_R8:
1155                 case MONO_TYPE_VALUETYPE:
1156                         v += sizeof (MonoObject);
1157                         break;
1158                 case MONO_TYPE_STRING:
1159                 case MONO_TYPE_OBJECT:
1160                 case MONO_TYPE_CLASS:
1161                 case MONO_TYPE_ARRAY:
1162                 case MONO_TYPE_SZARRAY:
1163                         /* Do nothing */
1164                         break;
1165                 default:
1166                         g_error ("type 0x%x not handled in "
1167                                  "ves_icall_FieldInfo_SetValueInternal", cf->type->type);
1168                         return;
1169                 }
1170         }
1171
1172         if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) {
1173                 MonoVTable *vtable = mono_class_vtable (mono_object_domain (field), field->klass);
1174                 mono_field_static_set_value (vtable, cf, v);
1175         } else {
1176                 mono_field_set_value (obj, cf, v);
1177         }
1178 }
1179
1180 static void
1181 ves_icall_get_property_info (MonoReflectionProperty *property, MonoPropertyInfo *info)
1182 {
1183         MonoDomain *domain = mono_object_domain (property); 
1184
1185         MONO_ARCH_SAVE_REGS;
1186
1187         info->parent = mono_type_get_object (domain, &property->klass->byval_arg);
1188         info->name = mono_string_new (domain, property->property->name);
1189         info->attrs = property->property->attrs;
1190         info->get = property->property->get ? mono_method_get_object (domain, property->property->get, NULL): NULL;
1191         info->set = property->property->set ? mono_method_get_object (domain, property->property->set, NULL): NULL;
1192         /* 
1193          * There may be other methods defined for properties, though, it seems they are not exposed 
1194          * in the reflection API 
1195          */
1196 }
1197
1198 static void
1199 ves_icall_get_event_info (MonoReflectionEvent *event, MonoEventInfo *info)
1200 {
1201         MonoDomain *domain = mono_object_domain (event); 
1202
1203         MONO_ARCH_SAVE_REGS;
1204
1205         info->parent = mono_type_get_object (domain, &event->klass->byval_arg);
1206         info->name = mono_string_new (domain, event->event->name);
1207         info->attrs = event->event->attrs;
1208         info->add_method = event->event->add ? mono_method_get_object (domain, event->event->add, NULL): NULL;
1209         info->remove_method = event->event->remove ? mono_method_get_object (domain, event->event->remove, NULL): NULL;
1210         info->raise_method = event->event->raise ? mono_method_get_object (domain, event->event->raise, NULL): NULL;
1211 }
1212
1213 static MonoArray*
1214 ves_icall_Type_GetInterfaces (MonoReflectionType* type)
1215 {
1216         MonoDomain *domain = mono_object_domain (type); 
1217         MonoArray *intf;
1218         int ninterf, i;
1219         MonoClass *class = mono_class_from_mono_type (type->type);
1220         MonoClass *parent;
1221
1222         MONO_ARCH_SAVE_REGS;
1223
1224         ninterf = 0;
1225         for (parent = class; parent; parent = parent->parent) {
1226                 ninterf += parent->interface_count;
1227         }
1228         intf = mono_array_new (domain, mono_defaults.monotype_class, ninterf);
1229         ninterf = 0;
1230         for (parent = class; parent; parent = parent->parent) {
1231                 for (i = 0; i < parent->interface_count; ++i) {
1232                         mono_array_set (intf, gpointer, ninterf, mono_type_get_object (domain, &parent->interfaces [i]->byval_arg));
1233                         ++ninterf;
1234                 }
1235         }
1236         return intf;
1237 }
1238
1239 static void
1240 ves_icall_Type_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType *iface, MonoArray **targets, MonoArray **methods)
1241 {
1242         MonoClass *class = mono_class_from_mono_type (type->type);
1243         MonoClass *iclass = mono_class_from_mono_type (iface->type);
1244         MonoReflectionMethod *member;
1245         int i, len, ioffset;
1246         MonoDomain *domain;
1247
1248         MONO_ARCH_SAVE_REGS;
1249
1250         /* type doesn't implement iface: the exception is thrown in managed code */
1251         if ((iclass->interface_id > class->max_interface_id) || !class->interface_offsets [iclass->interface_id])
1252                         return;
1253
1254         len = iclass->method.count;
1255         ioffset = class->interface_offsets [iclass->interface_id];
1256         domain = mono_object_domain (type);
1257         *targets = mono_array_new (domain, mono_defaults.method_info_class, len);
1258         *methods = mono_array_new (domain, mono_defaults.method_info_class, len);
1259         for (i = 0; i < len; ++i) {
1260                 member = mono_method_get_object (domain, iclass->methods [i], iclass);
1261                 mono_array_set (*methods, gpointer, i, member);
1262                 member = mono_method_get_object (domain, class->vtable [i + ioffset], class);
1263                 mono_array_set (*targets, gpointer, i, member);
1264         }
1265 }
1266
1267 static MonoReflectionType*
1268 ves_icall_MonoType_GetElementType (MonoReflectionType *type)
1269 {
1270         MonoClass *class = mono_class_from_mono_type (type->type);
1271
1272         MONO_ARCH_SAVE_REGS;
1273
1274         if (class->enumtype && class->enum_basetype) /* types that are modifierd typebuilkders may not have enum_basetype set */
1275                 return mono_type_get_object (mono_object_domain (type), class->enum_basetype);
1276         else if (class->element_class)
1277                 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
1278         else
1279                 return NULL;
1280 }
1281
1282 static MonoReflectionType*
1283 ves_icall_get_type_parent (MonoReflectionType *type)
1284 {
1285         MonoClass *class = mono_class_from_mono_type (type->type);
1286
1287         MONO_ARCH_SAVE_REGS;
1288
1289         return class->parent ? mono_type_get_object (mono_object_domain (type), &class->parent->byval_arg): NULL;
1290 }
1291
1292 static MonoBoolean
1293 ves_icall_type_ispointer (MonoReflectionType *type)
1294 {
1295         MONO_ARCH_SAVE_REGS;
1296
1297         return type->type->type == MONO_TYPE_PTR;
1298 }
1299
1300 static MonoBoolean
1301 ves_icall_type_isbyref (MonoReflectionType *type)
1302 {
1303         MONO_ARCH_SAVE_REGS;
1304
1305         return type->type->byref;
1306 }
1307
1308 static MonoReflectionModule*
1309 ves_icall_MonoType_get_Module (MonoReflectionType *type)
1310 {
1311         MonoClass *class = mono_class_from_mono_type (type->type);
1312
1313         MONO_ARCH_SAVE_REGS;
1314
1315         return mono_module_get_object (mono_object_domain (type), class->image);
1316 }
1317
1318 static void
1319 ves_icall_get_type_info (MonoType *type, MonoTypeInfo *info)
1320 {
1321         MonoDomain *domain = mono_domain_get (); 
1322         MonoClass *class = mono_class_from_mono_type (type);
1323
1324         MONO_ARCH_SAVE_REGS;
1325
1326         info->nested_in = class->nested_in ? mono_type_get_object (domain, &class->nested_in->byval_arg): NULL;
1327         info->name = mono_string_new (domain, class->name);
1328         info->name_space = mono_string_new (domain, class->name_space);
1329         info->rank = class->rank;
1330         info->assembly = mono_assembly_get_object (domain, class->image->assembly);
1331         if (class->enumtype && class->enum_basetype) /* types that are modifierd typebuilkders may not have enum_basetype set */
1332                 info->etype = mono_type_get_object (domain, class->enum_basetype);
1333         else if (class->element_class)
1334                 info->etype = mono_type_get_object (domain, &class->element_class->byval_arg);
1335         else
1336                 info->etype = NULL;
1337
1338         info->isprimitive = (!type->byref && (type->type >= MONO_TYPE_BOOLEAN) && (type->type <= MONO_TYPE_R8));
1339 }
1340
1341 static MonoObject *
1342 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoArray *params) 
1343 {
1344         /* 
1345          * Invoke from reflection is supposed to always be a virtual call (the API
1346          * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
1347          * greater flexibility.
1348          */
1349         MonoMethod *m = method->method;
1350         int pcount;
1351
1352         MONO_ARCH_SAVE_REGS;
1353
1354         if (this) {
1355                 if (!mono_object_isinst (this, m->klass))
1356                         mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
1357                 m = mono_object_get_virtual_method (this, m);
1358         } else if (!(m->flags & METHOD_ATTRIBUTE_STATIC) && strcmp (m->name, ".ctor"))
1359                 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
1360
1361         pcount = params? mono_array_length (params): 0;
1362         if (pcount != m->signature->param_count)
1363                 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
1364
1365         return mono_runtime_invoke_array (m, this, params, NULL);
1366 }
1367
1368 static MonoObject *
1369 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this, MonoArray *params, MonoArray **outArgs) 
1370 {
1371         MonoDomain *domain = mono_object_domain (method); 
1372         MonoMethod *m = method->method;
1373         MonoMethodSignature *sig = m->signature;
1374         MonoArray *out_args;
1375         MonoObject *result;
1376         int i, j, outarg_count = 0;
1377
1378         MONO_ARCH_SAVE_REGS;
1379
1380         if (m->klass == mono_defaults.object_class) {
1381
1382                 if (!strcmp (m->name, "FieldGetter")) {
1383                         MonoClass *k = this->vtable->klass;
1384                         MonoString *name = mono_array_get (params, MonoString *, 1);
1385                         char *str;
1386
1387                         str = mono_string_to_utf8 (name);
1388                 
1389                         for (i = 0; i < k->field.count; i++) {
1390                                 if (!strcmp (k->fields [i].name, str)) {
1391                                         MonoClass *field_klass =  mono_class_from_mono_type (k->fields [i].type);
1392                                         if (field_klass->valuetype)
1393                                                 result = mono_value_box (domain, field_klass,
1394                                                                          (char *)this + k->fields [i].offset);
1395                                         else 
1396                                                 result = *((gpointer *)((char *)this + k->fields [i].offset));
1397                                 
1398                                         g_assert (result);
1399                                         out_args = mono_array_new (domain, mono_defaults.object_class, 1);
1400                                         *outArgs = out_args;
1401                                         mono_array_set (out_args, gpointer, 0, result);
1402                                         g_free (str);
1403                                         return NULL;
1404                                 }
1405                         }
1406
1407                         g_free (str);
1408                         g_assert_not_reached ();
1409
1410                 } else if (!strcmp (m->name, "FieldSetter")) {
1411                         MonoClass *k = this->vtable->klass;
1412                         MonoString *name = mono_array_get (params, MonoString *, 1);
1413                         int size, align;
1414                         char *str;
1415
1416                         str = mono_string_to_utf8 (name);
1417                 
1418                         for (i = 0; i < k->field.count; i++) {
1419                                 if (!strcmp (k->fields [i].name, str)) {
1420                                         MonoClass *field_klass =  mono_class_from_mono_type (k->fields [i].type);
1421                                         MonoObject *val = mono_array_get (params, gpointer, 2);
1422
1423                                         if (field_klass->valuetype) {
1424                                                 size = mono_type_size (k->fields [i].type, &align);
1425                                                 memcpy ((char *)this + k->fields [i].offset, 
1426                                                         ((char *)val) + sizeof (MonoObject), size);
1427                                         } else 
1428                                                 *((gpointer *)this + k->fields [i].offset) = val;
1429                                 
1430                                         out_args = mono_array_new (domain, mono_defaults.object_class, 0);
1431                                         *outArgs = out_args;
1432
1433                                         g_free (str);
1434                                         return NULL;
1435                                 }
1436                         }
1437
1438                         g_free (str);
1439                         g_assert_not_reached ();
1440
1441                 }
1442         }
1443
1444         for (i = 0; i < mono_array_length (params); i++) {
1445                 if (sig->params [i]->byref) 
1446                         outarg_count++;
1447         }
1448
1449         out_args = mono_array_new (domain, mono_defaults.object_class, outarg_count);
1450         
1451         for (i = 0, j = 0; i < mono_array_length (params); i++) {
1452                 if (sig->params [i]->byref) {
1453                         gpointer arg;
1454                         arg = mono_array_get (params, gpointer, i);
1455                         mono_array_set (out_args, gpointer, j, arg);
1456                         j++;
1457                 }
1458         }
1459
1460         /* fixme: handle constructors? */
1461         if (!strcmp (method->method->name, ".ctor"))
1462                 g_assert_not_reached ();
1463
1464         result = mono_runtime_invoke_array (method->method, this, params, NULL);
1465
1466         *outArgs = out_args;
1467
1468         return result;
1469 }
1470
1471 static MonoObject *
1472 ves_icall_System_Enum_ToObject (MonoReflectionType *type, MonoObject *obj)
1473 {
1474         MonoDomain *domain; 
1475         MonoClass *enumc, *objc;
1476         gint32 s1, s2;
1477         MonoObject *res;
1478         
1479         MONO_ARCH_SAVE_REGS;
1480
1481         MONO_CHECK_ARG_NULL (type);
1482         MONO_CHECK_ARG_NULL (obj);
1483
1484         domain = mono_object_domain (type); 
1485         enumc = mono_class_from_mono_type (type->type);
1486         objc = obj->vtable->klass;
1487
1488         MONO_CHECK_ARG (obj, enumc->enumtype == TRUE);
1489         MONO_CHECK_ARG (obj, (objc->enumtype) || (objc->byval_arg.type >= MONO_TYPE_I1 &&
1490                                                   objc->byval_arg.type <= MONO_TYPE_U8));
1491         
1492         s1 = mono_class_value_size (enumc, NULL);
1493         s2 = mono_class_value_size (objc, NULL);
1494
1495         res = mono_object_new (domain, enumc);
1496
1497 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1498         memcpy ((char *)res + sizeof (MonoObject), (char *)obj + sizeof (MonoObject), MIN (s1, s2));
1499 #else
1500         memcpy ((char *)res + sizeof (MonoObject) + (s1 > s2 ? s1 - s2 : 0),
1501                 (char *)obj + sizeof (MonoObject) + (s2 > s1 ? s2 - s1 : 0),
1502                 MIN (s1, s2));
1503 #endif
1504         return res;
1505 }
1506
1507 static MonoObject *
1508 ves_icall_System_Enum_get_value (MonoObject *this)
1509 {
1510         MonoObject *res;
1511         MonoClass *enumc;
1512         gpointer dst;
1513         gpointer src;
1514         int size;
1515
1516         MONO_ARCH_SAVE_REGS;
1517
1518         if (!this)
1519                 return NULL;
1520
1521         g_assert (this->vtable->klass->enumtype);
1522         
1523         enumc = mono_class_from_mono_type (this->vtable->klass->enum_basetype);
1524         res = mono_object_new (mono_object_domain (this), enumc);
1525         dst = (char *)res + sizeof (MonoObject);
1526         src = (char *)this + sizeof (MonoObject);
1527         size = mono_class_value_size (enumc, NULL);
1528
1529         memcpy (dst, src, size);
1530
1531         return res;
1532 }
1533
1534 static void
1535 ves_icall_get_enum_info (MonoReflectionType *type, MonoEnumInfo *info)
1536 {
1537         MonoDomain *domain = mono_object_domain (type); 
1538         MonoClass *enumc = mono_class_from_mono_type (type->type);
1539         guint i, j, nvalues, crow;
1540         MonoClassField *field;
1541         
1542         MONO_ARCH_SAVE_REGS;
1543
1544         info->utype = mono_type_get_object (domain, enumc->enum_basetype);
1545         nvalues = enumc->field.count - 1;
1546         info->names = mono_array_new (domain, mono_defaults.string_class, nvalues);
1547         info->values = mono_array_new (domain, enumc, nvalues);
1548         
1549         for (i = 0, j = 0; i < enumc->field.count; ++i) {
1550                 field = &enumc->fields [i];
1551                 if (strcmp ("value__", field->name) == 0)
1552                         continue;
1553                 mono_array_set (info->names, gpointer, j, mono_string_new (domain, field->name));
1554                 if (!field->data) {
1555                         crow = mono_metadata_get_constant_index (enumc->image, MONO_TOKEN_FIELD_DEF | (i+enumc->field.first+1));
1556                         crow = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_VALUE);
1557                         /* 1 is the length of the blob */
1558                         field->data = 1 + mono_metadata_blob_heap (enumc->image, crow);
1559                 }
1560                 switch (enumc->enum_basetype->type) {
1561                 case MONO_TYPE_U1:
1562                 case MONO_TYPE_I1:
1563                         mono_array_set (info->values, gchar, j, *field->data);
1564                         break;
1565                 case MONO_TYPE_CHAR:
1566                 case MONO_TYPE_U2:
1567                 case MONO_TYPE_I2:
1568                         mono_array_set (info->values, gint16, j, read16 (field->data));
1569                         break;
1570                 case MONO_TYPE_U4:
1571                 case MONO_TYPE_I4:
1572                         mono_array_set (info->values, gint32, j, read32 (field->data));
1573                         break;
1574                 case MONO_TYPE_U8:
1575                 case MONO_TYPE_I8:
1576                         mono_array_set (info->values, gint64, j, read64 (field->data));
1577                         break;
1578                 default:
1579                         g_error ("Implement type 0x%02x in get_enum_info", enumc->enum_basetype->type);
1580                 }
1581                 ++j;
1582         }
1583 }
1584
1585 enum {
1586         BFLAGS_IgnoreCase = 1,
1587         BFLAGS_DeclaredOnly = 2,
1588         BFLAGS_Instance = 4,
1589         BFLAGS_Static = 8,
1590         BFLAGS_Public = 0x10,
1591         BFLAGS_NonPublic = 0x20,
1592         BFLAGS_InvokeMethod = 0x100,
1593         BFLAGS_CreateInstance = 0x200,
1594         BFLAGS_GetField = 0x400,
1595         BFLAGS_SetField = 0x800,
1596         BFLAGS_GetProperty = 0x1000,
1597         BFLAGS_SetProperty = 0x2000,
1598         BFLAGS_ExactBinding = 0x10000,
1599         BFLAGS_SuppressChangeType = 0x20000,
1600         BFLAGS_OptionalParamBinding = 0x40000
1601 };
1602
1603 static MonoFieldInfo *
1604 ves_icall_Type_GetField (MonoReflectionType *type, MonoString *name, guint32 bflags)
1605 {
1606         MonoDomain *domain; 
1607         MonoClass *startklass, *klass;
1608         int i, match;
1609         MonoClassField *field;
1610         char *utf8_name;
1611         domain = ((MonoObject *)type)->vtable->domain;
1612         klass = startklass = mono_class_from_mono_type (type->type);
1613
1614         MONO_ARCH_SAVE_REGS;
1615
1616         if (!name)
1617                 return NULL;
1618
1619 handle_parent:  
1620         for (i = 0; i < klass->field.count; ++i) {
1621                 match = 0;
1622                 field = &klass->fields [i];
1623                 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
1624                         if (bflags & BFLAGS_Public)
1625                                 match++;
1626                 } else {
1627                         if (bflags & BFLAGS_NonPublic)
1628                                 match++;
1629                 }
1630                 if (!match)
1631                         continue;
1632                 match = 0;
1633                 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
1634                         if (bflags & BFLAGS_Static)
1635                                 match++;
1636                 } else {
1637                         if (bflags & BFLAGS_Instance)
1638                                 match++;
1639                 }
1640
1641                 if (!match)
1642                         continue;
1643                 
1644                 utf8_name = mono_string_to_utf8 (name);
1645
1646                 if (strcmp (field->name, utf8_name)) {
1647                         g_free (utf8_name);
1648                         continue;
1649                 }
1650                 g_free (utf8_name);
1651                 
1652                 return (MonoFieldInfo *)mono_field_get_object (domain, klass, field);
1653         }
1654         if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
1655                 goto handle_parent;
1656
1657         return NULL;
1658 }
1659
1660 static MonoArray*
1661 ves_icall_Type_GetFields (MonoReflectionType *type, guint32 bflags)
1662 {
1663         MonoDomain *domain; 
1664         GSList *l = NULL, *tmp;
1665         MonoClass *startklass, *klass;
1666         MonoArray *res;
1667         MonoObject *member;
1668         int i, len, match;
1669         MonoClassField *field;
1670
1671         MONO_ARCH_SAVE_REGS;
1672
1673         domain = ((MonoObject *)type)->vtable->domain;
1674         klass = startklass = mono_class_from_mono_type (type->type);
1675
1676 handle_parent:  
1677         for (i = 0; i < klass->field.count; ++i) {
1678                 match = 0;
1679                 field = &klass->fields [i];
1680                 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
1681                         if (bflags & BFLAGS_Public)
1682                                 match++;
1683                 } else {
1684                         if (bflags & BFLAGS_NonPublic)
1685                                 match++;
1686                 }
1687                 if (!match)
1688                         continue;
1689                 match = 0;
1690                 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
1691                         if (bflags & BFLAGS_Static)
1692                                 match++;
1693                 } else {
1694                         if (bflags & BFLAGS_Instance)
1695                                 match++;
1696                 }
1697
1698                 if (!match)
1699                         continue;
1700                 member = (MonoObject*)mono_field_get_object (domain, klass, field);
1701                 l = g_slist_prepend (l, member);
1702         }
1703         if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
1704                 goto handle_parent;
1705         len = g_slist_length (l);
1706         res = mono_array_new (domain, mono_defaults.field_info_class, len);
1707         i = 0;
1708         tmp = g_slist_reverse (l);
1709         for (; tmp; tmp = tmp->next, ++i)
1710                 mono_array_set (res, gpointer, i, tmp->data);
1711         g_slist_free (l);
1712         return res;
1713 }
1714
1715 static MonoArray*
1716 ves_icall_Type_GetMethods (MonoReflectionType *type, guint32 bflags)
1717 {
1718         MonoDomain *domain; 
1719         GSList *l = NULL, *tmp;
1720         MonoClass *startklass, *klass;
1721         MonoArray *res;
1722         MonoMethod *method;
1723         MonoObject *member;
1724         int i, len, match;
1725         GHashTable *method_slots = g_hash_table_new (NULL, NULL);
1726                 
1727         MONO_ARCH_SAVE_REGS;
1728
1729         domain = ((MonoObject *)type)->vtable->domain;
1730         klass = startklass = mono_class_from_mono_type (type->type);
1731         len = 0;
1732
1733 handle_parent:
1734         for (i = 0; i < klass->method.count; ++i) {
1735                 match = 0;
1736                 method = klass->methods [i];
1737                 if (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0)
1738                         continue;
1739                 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
1740                         if (bflags & BFLAGS_Public)
1741                                 match++;
1742                 } else {
1743                         if (bflags & BFLAGS_NonPublic)
1744                                 match++;
1745                 }
1746                 if (!match)
1747                         continue;
1748                 match = 0;
1749                 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
1750                         if (bflags & BFLAGS_Static)
1751                                 match++;
1752                 } else {
1753                         if (bflags & BFLAGS_Instance)
1754                                 match++;
1755                 }
1756
1757                 if (!match)
1758                         continue;
1759                 match = 0;
1760                 if (g_hash_table_lookup (method_slots, GUINT_TO_POINTER (method->slot)))
1761                         continue;
1762                 g_hash_table_insert (method_slots, GUINT_TO_POINTER (method->slot), method);
1763                 member = (MonoObject*)mono_method_get_object (domain, method, startklass);
1764                 
1765                 l = g_slist_prepend (l, member);
1766                 len++;
1767         }
1768         if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
1769                 goto handle_parent;
1770         res = mono_array_new (domain, mono_defaults.method_info_class, len);
1771         i = 0;
1772         tmp = l;
1773         for (; tmp; tmp = tmp->next, ++i)
1774                 mono_array_set (res, gpointer, i, tmp->data);
1775         g_slist_free (l);
1776         g_hash_table_destroy (method_slots);
1777         return res;
1778 }
1779
1780 static MonoArray*
1781 ves_icall_Type_GetConstructors (MonoReflectionType *type, guint32 bflags)
1782 {
1783         MonoDomain *domain; 
1784         GSList *l = NULL, *tmp;
1785         static MonoClass *System_Reflection_ConstructorInfo;
1786         MonoClass *startklass, *klass;
1787         MonoArray *res;
1788         MonoMethod *method;
1789         MonoObject *member;
1790         int i, len, match;
1791
1792         MONO_ARCH_SAVE_REGS;
1793
1794         domain = ((MonoObject *)type)->vtable->domain;
1795         klass = startklass = mono_class_from_mono_type (type->type);
1796
1797         for (i = 0; i < klass->method.count; ++i) {
1798                 match = 0;
1799                 method = klass->methods [i];
1800                 if (strcmp (method->name, ".ctor") && strcmp (method->name, ".cctor"))
1801                         continue;
1802                 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
1803                         if (bflags & BFLAGS_Public)
1804                                 match++;
1805                 } else {
1806                         if (bflags & BFLAGS_NonPublic)
1807                                 match++;
1808                 }
1809                 if (!match)
1810                         continue;
1811                 match = 0;
1812                 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
1813                         if (bflags & BFLAGS_Static)
1814                                 match++;
1815                 } else {
1816                         if (bflags & BFLAGS_Instance)
1817                                 match++;
1818                 }
1819
1820                 if (!match)
1821                         continue;
1822                 member = (MonoObject*)mono_method_get_object (domain, method, startklass);
1823                         
1824                 l = g_slist_prepend (l, member);
1825         }
1826         len = g_slist_length (l);
1827         if (!System_Reflection_ConstructorInfo)
1828                 System_Reflection_ConstructorInfo = mono_class_from_name (
1829                         mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
1830         res = mono_array_new (domain, System_Reflection_ConstructorInfo, len);
1831         i = 0;
1832         tmp = g_slist_reverse (l);
1833         for (; tmp; tmp = tmp->next, ++i)
1834                 mono_array_set (res, gpointer, i, tmp->data);
1835         g_slist_free (l);
1836         return res;
1837 }
1838
1839 static MonoArray*
1840 ves_icall_Type_GetProperties (MonoReflectionType *type, guint32 bflags)
1841 {
1842         MonoDomain *domain; 
1843         GSList *l = NULL, *tmp;
1844         static MonoClass *System_Reflection_PropertyInfo;
1845         MonoClass *startklass, *klass;
1846         MonoArray *res;
1847         MonoMethod *method;
1848         MonoProperty *prop;
1849         int i, match;
1850         int len = 0;
1851         GHashTable *method_slots = g_hash_table_new (NULL, NULL);
1852
1853         MONO_ARCH_SAVE_REGS;
1854
1855         domain = ((MonoObject *)type)->vtable->domain;
1856         klass = startklass = mono_class_from_mono_type (type->type);
1857
1858 handle_parent:
1859         for (i = 0; i < klass->property.count; ++i) {
1860                 prop = &klass->properties [i];
1861                 match = 0;
1862                 method = prop->get;
1863                 if (!method)
1864                         method = prop->set;
1865                 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
1866                         if (bflags & BFLAGS_Public)
1867                                 match++;
1868                 } else {
1869                         if (bflags & BFLAGS_NonPublic)
1870                                 match++;
1871                 }
1872                 if (!match)
1873                         continue;
1874                 match = 0;
1875                 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
1876                         if (bflags & BFLAGS_Static)
1877                                 match++;
1878                 } else {
1879                         if (bflags & BFLAGS_Instance)
1880                                 match++;
1881                 }
1882
1883                 if (!match)
1884                         continue;
1885                 match = 0;
1886
1887                 if (g_hash_table_lookup (method_slots, GUINT_TO_POINTER (method->slot)))
1888                         continue;
1889                 g_hash_table_insert (method_slots, GUINT_TO_POINTER (method->slot), prop);
1890
1891                 l = g_slist_prepend (l, mono_property_get_object (domain, klass, prop));
1892                 len++;
1893         }
1894         if ((!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent)))
1895                 goto handle_parent;
1896         if (!System_Reflection_PropertyInfo)
1897                 System_Reflection_PropertyInfo = mono_class_from_name (
1898                         mono_defaults.corlib, "System.Reflection", "PropertyInfo");
1899         res = mono_array_new (domain, System_Reflection_PropertyInfo, len);
1900         i = 0;
1901         tmp = l;
1902         for (; tmp; tmp = tmp->next, ++i)
1903                 mono_array_set (res, gpointer, i, tmp->data);
1904         g_slist_free (l);
1905         g_hash_table_destroy (method_slots);
1906         return res;
1907 }
1908
1909 static MonoReflectionEvent *
1910 ves_icall_MonoType_GetEvent (MonoReflectionType *type, MonoString *name, guint32 bflags)
1911 {
1912         MonoDomain *domain;
1913         MonoClass *klass;
1914         gint i;
1915         MonoEvent *event;
1916         MonoMethod *method;
1917         gchar *event_name;
1918
1919         MONO_ARCH_SAVE_REGS;
1920
1921         event_name = mono_string_to_utf8 (name);
1922         klass = mono_class_from_mono_type (type->type);
1923         domain = mono_object_domain (type);
1924
1925 handle_parent:  
1926         for (i = 0; i < klass->event.count; i++) {
1927                 event = &klass->events [i];
1928                 if (strcmp (event->name, event_name))
1929                         continue;
1930
1931                 method = event->add;
1932                 if (!method)
1933                         method = event->remove;
1934
1935                 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
1936                         if (!(bflags & BFLAGS_Public))
1937                                 continue;
1938                 } else {
1939                         if (!(bflags & BFLAGS_NonPublic))
1940                                 continue;
1941                 }
1942
1943                 g_free (event_name);
1944                 return mono_event_get_object (domain, klass, event);
1945         }
1946
1947         if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
1948                 goto handle_parent;
1949
1950         g_free (event_name);
1951         return NULL;
1952 }
1953
1954 static MonoArray*
1955 ves_icall_Type_GetEvents (MonoReflectionType *type, guint32 bflags)
1956 {
1957         MonoDomain *domain; 
1958         GSList *l = NULL, *tmp;
1959         static MonoClass *System_Reflection_EventInfo;
1960         MonoClass *startklass, *klass;
1961         MonoArray *res;
1962         MonoMethod *method;
1963         MonoEvent *event;
1964         int i, len, match;
1965
1966         MONO_ARCH_SAVE_REGS;
1967
1968         domain = ((MonoObject *)type)->vtable->domain;
1969         klass = startklass = mono_class_from_mono_type (type->type);
1970
1971 handle_parent:  
1972         for (i = 0; i < klass->event.count; ++i) {
1973                 event = &klass->events [i];
1974                 match = 0;
1975                 method = event->add;
1976                 if (!method)
1977                         method = event->remove;
1978                 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
1979                         if (bflags & BFLAGS_Public)
1980                                 match++;
1981                 } else {
1982                         if (bflags & BFLAGS_NonPublic)
1983                                 match++;
1984                 }
1985                 if (!match)
1986                         continue;
1987                 match = 0;
1988                 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
1989                         if (bflags & BFLAGS_Static)
1990                                 match++;
1991                 } else {
1992                         if (bflags & BFLAGS_Instance)
1993                                 match++;
1994                 }
1995
1996                 if (!match)
1997                         continue;
1998                 match = 0;
1999                 l = g_slist_prepend (l, mono_event_get_object (domain, klass, event));
2000         }
2001         if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
2002                 goto handle_parent;
2003         len = g_slist_length (l);
2004         if (!System_Reflection_EventInfo)
2005                 System_Reflection_EventInfo = mono_class_from_name (
2006                         mono_defaults.corlib, "System.Reflection", "EventInfo");
2007         res = mono_array_new (domain, System_Reflection_EventInfo, len);
2008         i = 0;
2009         tmp = l;
2010         for (; tmp; tmp = tmp->next, ++i)
2011                 mono_array_set (res, gpointer, i, tmp->data);
2012         g_slist_free (l);
2013         return res;
2014 }
2015
2016 static MonoArray*
2017 ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags)
2018 {
2019         MonoDomain *domain; 
2020         GSList *l = NULL, *tmp;
2021         GList *tmpn;
2022         MonoClass *startklass, *klass;
2023         MonoArray *res;
2024         MonoObject *member;
2025         int i, len, match;
2026         MonoClass *nested;
2027
2028         MONO_ARCH_SAVE_REGS;
2029
2030         domain = ((MonoObject *)type)->vtable->domain;
2031         klass = startklass = mono_class_from_mono_type (type->type);
2032
2033         for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
2034                 match = 0;
2035                 nested = tmpn->data;
2036                 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
2037                         if (bflags & BFLAGS_Public)
2038                                 match++;
2039                 } else {
2040                         if (bflags & BFLAGS_NonPublic)
2041                                 match++;
2042                 }
2043                 if (!match)
2044                         continue;
2045                 member = (MonoObject*)mono_type_get_object (domain, &nested->byval_arg);
2046                 l = g_slist_prepend (l, member);
2047         }
2048         len = g_slist_length (l);
2049         res = mono_array_new (domain, mono_defaults.monotype_class, len);
2050         i = 0;
2051         tmp = g_slist_reverse (l);
2052         for (; tmp; tmp = tmp->next, ++i)
2053                 mono_array_set (res, gpointer, i, tmp->data);
2054         g_slist_free (l);
2055         return res;
2056 }
2057
2058 static MonoReflectionType*
2059 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *assembly, MonoString *name, MonoBoolean throwOnError, MonoBoolean ignoreCase)
2060 {
2061         gchar *str;
2062         MonoType *type;
2063         MonoTypeNameParse info;
2064
2065         MONO_ARCH_SAVE_REGS;
2066
2067         str = mono_string_to_utf8 (name);
2068         /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
2069         if (!mono_reflection_parse_type (str, &info)) {
2070                 g_free (str);
2071                 g_list_free (info.modifiers);
2072                 g_list_free (info.nested);
2073                 if (throwOnError) /* uhm: this is a parse error, though... */
2074                         mono_raise_exception (mono_get_exception_type_load ());
2075                 /*g_print ("failed parse\n");*/
2076                 return NULL;
2077         }
2078
2079         type = mono_reflection_get_type (assembly->assembly->image, &info, ignoreCase);
2080         g_free (str);
2081         g_list_free (info.modifiers);
2082         g_list_free (info.nested);
2083         if (!type) {
2084                 if (throwOnError)
2085                         mono_raise_exception (mono_get_exception_type_load ());
2086                 /* g_print ("failed find\n"); */
2087                 return NULL;
2088         }
2089         /* g_print ("got it\n"); */
2090         return mono_type_get_object (mono_object_domain (assembly), type);
2091
2092 }
2093
2094 static MonoString *
2095 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *assembly)
2096 {
2097         MonoDomain *domain = mono_object_domain (assembly); 
2098         MonoString *res;
2099         char *name = g_strconcat (
2100                 "file://", assembly->assembly->image->name, NULL);
2101         
2102         MONO_ARCH_SAVE_REGS;
2103
2104         res = mono_string_new (domain, name);
2105         g_free (name);
2106         return res;
2107 }
2108
2109 static MonoString *
2110 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssembly *assembly)
2111 {
2112         MonoDomain *domain = mono_object_domain (assembly); 
2113         MonoString *res;
2114         char *name = g_build_filename (
2115                 assembly->assembly->basedir,
2116                 assembly->assembly->image->module_name, NULL);
2117
2118         MONO_ARCH_SAVE_REGS;
2119
2120         res = mono_string_new (domain, name);
2121         g_free (name);
2122         return res;
2123 }
2124
2125 static MonoReflectionMethod*
2126 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssembly *assembly) 
2127 {
2128         guint32 token = mono_image_get_entry_point (assembly->assembly->image);
2129
2130         MONO_ARCH_SAVE_REGS;
2131
2132         if (!token)
2133                 return NULL;
2134         return mono_method_get_object (mono_object_domain (assembly), mono_get_method (assembly->assembly->image, token, NULL), NULL);
2135 }
2136
2137 static MonoArray*
2138 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssembly *assembly) 
2139 {
2140         MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
2141         MonoArray *result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, table->rows);
2142         int i;
2143         const char *val;
2144
2145         MONO_ARCH_SAVE_REGS;
2146
2147         for (i = 0; i < table->rows; ++i) {
2148                 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_MANIFEST_NAME));
2149                 mono_array_set (result, gpointer, i, mono_string_new (mono_object_domain (assembly), val));
2150         }
2151         return result;
2152 }
2153
2154 static MonoArray*
2155 ves_icall_System_Reflection_Assembly_GetReferencedAssemblies (MonoReflectionAssembly *assembly) 
2156 {
2157         static MonoClass *System_Reflection_AssemblyName;
2158         MonoArray *result;
2159         MonoAssembly **ptr;
2160         MonoDomain *domain = mono_object_domain (assembly);
2161         int i, count = 0;
2162
2163         MONO_ARCH_SAVE_REGS;
2164
2165         if (!System_Reflection_AssemblyName)
2166                 System_Reflection_AssemblyName = mono_class_from_name (
2167                         mono_defaults.corlib, "System.Reflection", "AssemblyName");
2168
2169         for (ptr = assembly->assembly->image->references; ptr && *ptr; ptr++)
2170                 count++;
2171
2172         result = mono_array_new (mono_object_domain (assembly), System_Reflection_AssemblyName, count);
2173
2174         for (i = 0; i < count; i++) {
2175                 MonoAssembly *assem = assembly->assembly->image->references [i];
2176                 MonoReflectionAssemblyName *aname;
2177                 char *codebase;
2178
2179                 aname = (MonoReflectionAssemblyName *) mono_object_new (
2180                         domain, System_Reflection_AssemblyName);
2181
2182                 if (strcmp (assem->aname.name, "corlib") == 0)
2183                         aname->name = mono_string_new (domain, "mscorlib");
2184                 else
2185                         aname->name = mono_string_new (domain, assem->aname.name);
2186                 aname->major = assem->aname.major;
2187
2188                 codebase = g_strconcat ("file://", assembly->assembly->image->references [i]->image->name, NULL);
2189                 aname->codebase = mono_string_new (domain, codebase);
2190                 g_free (codebase);
2191                 mono_array_set (result, gpointer, i, aname);
2192         }
2193         return result;
2194 }
2195
2196 /* move this in some file in mono/util/ */
2197 static char *
2198 g_concat_dir_and_file (const char *dir, const char *file)
2199 {
2200         g_return_val_if_fail (dir != NULL, NULL);
2201         g_return_val_if_fail (file != NULL, NULL);
2202
2203         /*
2204          * If the directory name doesn't have a / on the end, we need
2205          * to add one so we get a proper path to the file
2206          */
2207         if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
2208                 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
2209         else
2210                 return g_strconcat (dir, file, NULL);
2211 }
2212
2213 static MonoObject*
2214 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssembly *assembly, MonoString *name) 
2215 {
2216         char *n = mono_string_to_utf8 (name);
2217         MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
2218         guint32 i;
2219         guint32 cols [MONO_MANIFEST_SIZE];
2220         const char *val;
2221         MonoObject *result;
2222
2223         MONO_ARCH_SAVE_REGS;
2224
2225         for (i = 0; i < table->rows; ++i) {
2226                 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
2227                 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
2228                 if (strcmp (val, n) == 0)
2229                         break;
2230         }
2231         g_free (n);
2232         if (i == table->rows)
2233                 return NULL;
2234         /* FIXME */
2235         if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
2236                 guint32 size;
2237                 MonoArray *data;
2238                 val = mono_image_get_resource (assembly->assembly->image, cols [MONO_MANIFEST_OFFSET], &size);
2239                 if (!val)
2240                         return NULL;
2241                 data = mono_array_new (mono_object_domain (assembly), mono_defaults.byte_class, size);
2242                 memcpy (mono_array_addr (data, char, 0), val, size);
2243                 return (MonoObject*)data;
2244         }
2245         switch (cols [MONO_MANIFEST_IMPLEMENTATION] & IMPLEMENTATION_MASK) {
2246         case IMPLEMENTATION_FILE:
2247                 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> IMPLEMENTATION_BITS;
2248                 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
2249                 i = mono_metadata_decode_row_col (table, i - 1, MONO_FILE_NAME);
2250                 val = mono_metadata_string_heap (assembly->assembly->image, i);
2251                 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
2252                 result = (MonoObject*)mono_string_new (mono_object_domain (assembly), n);
2253                 /* check hash if needed */
2254                 g_free (n);
2255                 return result;
2256         case IMPLEMENTATION_ASSEMBLYREF:
2257         case IMPLEMENTATION_EXP_TYPE:
2258                 /* FIXME */
2259                 break;
2260         }
2261         return NULL;
2262 }
2263
2264 static MonoObject*
2265 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssembly *assembly, MonoString *name) 
2266 {
2267         MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
2268         MonoArray *result;
2269         int i;
2270         const char *val;
2271         char *n;
2272
2273         MONO_ARCH_SAVE_REGS;
2274
2275         /* check hash if needed */
2276         if (name) {
2277                 n = mono_string_to_utf8 (name);
2278                 for (i = 0; i < table->rows; ++i) {
2279                         val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
2280                         if (strcmp (val, n) == 0) {
2281                                 MonoString *fn;
2282                                 g_free (n);
2283                                 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
2284                                 fn = mono_string_new (mono_object_domain (assembly), n);
2285                                 g_free (n);
2286                                 return (MonoObject*)fn;
2287                         }
2288                 }
2289                 g_free (n);
2290                 return NULL;
2291         }
2292
2293         for (i = 0; i < table->rows; ++i) {
2294                 result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, table->rows);
2295                 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
2296                 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
2297                 mono_array_set (result, gpointer, i, mono_string_new (mono_object_domain (assembly), n));
2298                 g_free (n);
2299         }
2300         return (MonoObject*)result;
2301 }
2302
2303 static MonoReflectionMethod*
2304 ves_icall_GetCurrentMethod (void) 
2305 {
2306         MonoMethod *m = mono_method_get_last_managed ();
2307
2308         MONO_ARCH_SAVE_REGS;
2309
2310         return mono_method_get_object (mono_domain_get (), m, NULL);
2311 }
2312
2313 static MonoReflectionAssembly*
2314 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (void)
2315 {
2316         MonoMethod *m = mono_method_get_last_managed ();
2317
2318         MONO_ARCH_SAVE_REGS;
2319
2320         return mono_assembly_get_object (mono_domain_get (), m->klass->image->assembly);
2321 }
2322
2323
2324 static gboolean
2325 get_caller (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
2326 {
2327         MonoMethod **dest = data;
2328
2329         /* skip unmanaged frames */
2330         if (!managed)
2331                 return FALSE;
2332
2333         if (m == *dest) {
2334                 *dest = NULL;
2335                 return FALSE;
2336         }
2337         if (!(*dest)) {
2338                 *dest = m;
2339                 return TRUE;
2340         }
2341         return FALSE;
2342 }
2343
2344 static MonoReflectionAssembly*
2345 ves_icall_System_Reflection_Assembly_GetEntryAssembly (void)
2346 {
2347         MonoDomain* domain = mono_domain_get ();
2348
2349         MONO_ARCH_SAVE_REGS;
2350
2351         g_assert (domain->entry_assembly);
2352         return mono_assembly_get_object (domain, domain->entry_assembly);
2353 }
2354
2355
2356 static MonoReflectionAssembly*
2357 ves_icall_System_Reflection_Assembly_GetCallingAssembly (void)
2358 {
2359         MonoMethod *m = mono_method_get_last_managed ();
2360         MonoMethod *dest = m;
2361
2362         MONO_ARCH_SAVE_REGS;
2363
2364         mono_stack_walk (get_caller, &dest);
2365         if (!dest)
2366                 dest = m;
2367         return mono_assembly_get_object (mono_domain_get (), dest->klass->image->assembly);
2368 }
2369
2370 static MonoString *
2371 ves_icall_System_MonoType_getFullName (MonoReflectionType *object)
2372 {
2373         MonoDomain *domain = mono_object_domain (object); 
2374         MonoString *res;
2375         gchar *name;
2376
2377         MONO_ARCH_SAVE_REGS;
2378
2379         name = mono_type_get_name (object->type);
2380         res = mono_string_new (domain, name);
2381         g_free (name);
2382
2383         return res;
2384 }
2385
2386 static void
2387 ves_icall_System_Reflection_Assembly_FillName (MonoReflectionAssembly *assembly, MonoReflectionAssemblyName *aname)
2388 {
2389         MonoAssemblyName *name = &assembly->assembly->aname;
2390
2391         MONO_ARCH_SAVE_REGS;
2392
2393         if (strcmp (name->name, "corlib") == 0)
2394                 aname->name = mono_string_new (mono_object_domain (assembly), "mscorlib");
2395         else
2396                 aname->name = mono_string_new (mono_object_domain (assembly), name->name);
2397
2398         aname->major = name->major;
2399         aname->minor = name->minor;
2400         aname->build = name->build;
2401         aname->revision = name->revision;
2402 }
2403
2404 static MonoArray*
2405 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly, MonoBoolean exportedOnly)
2406 {
2407         MonoDomain *domain = mono_object_domain (assembly); 
2408         MonoArray *res;
2409         MonoClass *klass;
2410         MonoTableInfo *tdef = &assembly->assembly->image->tables [MONO_TABLE_TYPEDEF];
2411         int i, count;
2412         guint32 attrs, visibility;
2413
2414         MONO_ARCH_SAVE_REGS;
2415
2416         /* we start the count from 1 because we skip the special type <Module> */
2417         if (exportedOnly) {
2418                 count = 0;
2419                 for (i = 1; i < tdef->rows; ++i) {
2420                         attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
2421                         visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
2422                         if (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)
2423                                 count++;
2424                 }
2425         } else {
2426                 count = tdef->rows - 1;
2427         }
2428         res = mono_array_new (domain, mono_defaults.monotype_class, count);
2429         count = 0;
2430         for (i = 1; i < tdef->rows; ++i) {
2431                 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
2432                 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
2433                 if (!exportedOnly || (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)) {
2434                         klass = mono_class_get (assembly->assembly->image, (i + 1) | MONO_TOKEN_TYPE_DEF);
2435                         mono_array_set (res, gpointer, count, mono_type_get_object (domain, &klass->byval_arg));
2436                         count++;
2437                 }
2438         }
2439         
2440         return res;
2441 }
2442
2443 static MonoReflectionType*
2444 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
2445 {
2446         MonoClass *klass;
2447         int isbyref = 0, rank;
2448         char *str = mono_string_to_utf8 (smodifiers);
2449         char *p;
2450
2451         MONO_ARCH_SAVE_REGS;
2452
2453         klass = mono_class_from_mono_type (tb->type.type);
2454         p = str;
2455         /* logic taken from mono_reflection_parse_type(): keep in sync */
2456         while (*p) {
2457                 switch (*p) {
2458                 case '&':
2459                         if (isbyref) { /* only one level allowed by the spec */
2460                                 g_free (str);
2461                                 return NULL;
2462                         }
2463                         isbyref = 1;
2464                         p++;
2465                         g_free (str);
2466                         return mono_type_get_object (mono_object_domain (tb), &klass->this_arg);
2467                         break;
2468                 case '*':
2469                         klass = mono_ptr_class_get (&klass->byval_arg);
2470                         mono_class_init (klass);
2471                         p++;
2472                         break;
2473                 case '[':
2474                         rank = 1;
2475                         p++;
2476                         while (*p) {
2477                                 if (*p == ']')
2478                                         break;
2479                                 if (*p == ',')
2480                                         rank++;
2481                                 else if (*p != '*') { /* '*' means unknown lower bound */
2482                                         g_free (str);
2483                                         return NULL;
2484                                 }
2485                                 ++p;
2486                         }
2487                         if (*p != ']') {
2488                                 g_free (str);
2489                                 return NULL;
2490                         }
2491                         p++;
2492                         klass = mono_array_class_get (&klass->byval_arg, rank);
2493                         mono_class_init (klass);
2494                         break;
2495                 default:
2496                         break;
2497                 }
2498         }
2499         g_free (str);
2500         return mono_type_get_object (mono_object_domain (tb), &klass->byval_arg);
2501 }
2502
2503 static MonoObject *
2504 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
2505                                                    MonoReflectionMethod *info)
2506 {
2507         MonoClass *delegate_class = mono_class_from_mono_type (type->type);
2508         MonoObject *delegate;
2509         gpointer func;
2510
2511         MONO_ARCH_SAVE_REGS;
2512
2513         mono_assert (delegate_class->parent == mono_defaults.multicastdelegate_class);
2514
2515         delegate = mono_object_new (mono_object_domain (type), delegate_class);
2516
2517         func = mono_compile_method (info->method);
2518
2519         mono_delegate_ctor (delegate, target, func);
2520
2521         return delegate;
2522 }
2523
2524 /*
2525  * Magic number to convert a time which is relative to
2526  * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
2527  */
2528 #define EPOCH_ADJUST    ((gint64)62135596800L)
2529
2530 static gint64
2531 ves_icall_System_DateTime_GetNow (void)
2532 {
2533 #ifdef PLATFORM_WIN32
2534         SYSTEMTIME st;
2535         FILETIME ft;
2536         
2537         GetLocalTime (&st);
2538         SystemTimeToFileTime (&st, &ft);
2539         return (gint64)504911232000000000L + ((((gint64)ft.dwHighDateTime)<<32) | ft.dwLowDateTime);
2540 #else
2541         /* FIXME: put this in io-layer and call it GetLocalTime */
2542         struct timeval tv;
2543         gint64 res;
2544
2545         MONO_ARCH_SAVE_REGS;
2546
2547         if (gettimeofday (&tv, NULL) == 0) {
2548                 res = (((gint64)tv.tv_sec + EPOCH_ADJUST)* 1000000 + tv.tv_usec)*10;
2549                 return res;
2550         }
2551         /* fixme: raise exception */
2552         return 0;
2553 #endif
2554 }
2555
2556 /*
2557  * This is heavily based on zdump.c from glibc 2.2.
2558  *
2559  *  * data[0]:  start of daylight saving time (in DateTime ticks).
2560  *  * data[1]:  end of daylight saving time (in DateTime ticks).
2561  *  * data[2]:  utcoffset (in TimeSpan ticks).
2562  *  * data[3]:  additional offset when daylight saving (in TimeSpan ticks).
2563  *  * name[0]:  name of this timezone when not daylight saving.
2564  *  * name[1]:  name of this timezone when daylight saving.
2565  *
2566  *  FIXME: This only works with "standard" Unix dates (years between 1900 and 2100) while
2567  *         the class library allows years between 1 and 9999.
2568  *
2569  *  Returns true on success and zero on failure.
2570  */
2571 static guint32
2572 ves_icall_System_CurrentTimeZone_GetTimeZoneData (guint32 year, MonoArray **data, MonoArray **names)
2573 {
2574 #ifndef PLATFORM_WIN32
2575         MonoDomain *domain = mono_domain_get ();
2576         struct tm start, tt;
2577         time_t t;
2578
2579         long int gmtoff;
2580         int is_daylight = 0, day;
2581
2582         MONO_ARCH_SAVE_REGS;
2583
2584         if ((year < 1900) || (year > 2100))
2585                 mono_raise_exception (mono_get_exception_not_implemented ());
2586
2587         memset (&start, 0, sizeof (start));
2588
2589         start.tm_mday = 1;
2590         start.tm_year = year-1900;
2591
2592         t = mktime (&start);
2593 #if defined (HAVE_TIMEZONE)
2594 #define gmt_offset(x) (-1 * (((timezone / 60 / 60) - daylight) * 100))
2595 #elif defined (HAVE_TM_GMTOFF)
2596 #define gmt_offset(x) x.tm_gmtoff
2597 #else
2598 #error Neither HAVE_TIMEZONE nor HAVE_TM_GMTOFF defined. Rerun autoheader, autoconf, etc.
2599 #endif
2600         
2601         gmtoff = gmt_offset (start);
2602
2603         MONO_CHECK_ARG_NULL (data);
2604         MONO_CHECK_ARG_NULL (names);
2605
2606         (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
2607         (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
2608
2609         /* For each day of the year, calculate the tm_gmtoff. */
2610         for (day = 0; day < 365; day++) {
2611
2612                 t += 3600*24;
2613                 tt = *localtime (&t);
2614
2615                 /* Daylight saving starts or ends here. */
2616                 if (gmt_offset (tt) != gmtoff) {
2617                         char tzone[10];
2618                         struct tm tt1;
2619                         time_t t1;
2620
2621                         /* Try to find the exact hour when daylight saving starts/ends. */
2622                         t1 = t;
2623                         do {
2624                                 t1 -= 3600;
2625                                 tt1 = *localtime (&t1);
2626                         } while (gmt_offset (tt1) != gmtoff);
2627
2628                         /* Try to find the exact minute when daylight saving starts/ends. */
2629                         do {
2630                                 t1 += 60;
2631                                 tt1 = *localtime (&t1);
2632                         } while (gmt_offset (tt1) == gmtoff);
2633                         
2634                         strftime (tzone, 10, "%Z", &tt);
2635                         
2636                         /* Write data, if we're already in daylight saving, we're done. */
2637                         if (is_daylight) {
2638                                 mono_array_set ((*names), gpointer, 0, mono_string_new (domain, tzone));
2639                                 mono_array_set ((*data), gint64, 1, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
2640                                 return 1;
2641                         } else {
2642                                 mono_array_set ((*names), gpointer, 1, mono_string_new (domain, tzone));
2643                                 mono_array_set ((*data), gint64, 0, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
2644                                 is_daylight = 1;
2645                         }
2646
2647                         /* This is only set once when we enter daylight saving. */
2648                         mono_array_set ((*data), gint64, 2, (gint64)gmtoff * 10000000L);
2649                         mono_array_set ((*data), gint64, 3, (gint64)(gmt_offset (tt) - gmtoff) * 10000000L);
2650
2651                         gmtoff = gmt_offset (tt);
2652                 }
2653
2654                 gmtoff = gmt_offset (tt);
2655         }
2656         return 1;
2657 #else
2658         MonoDomain *domain = mono_domain_get ();
2659         TIME_ZONE_INFORMATION tz_info;
2660         FILETIME ft;
2661         int i;
2662
2663         GetTimeZoneInformation (&tz_info);
2664
2665         MONO_CHECK_ARG_NULL (data);
2666         MONO_CHECK_ARG_NULL (names);
2667
2668         (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
2669         (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
2670
2671         for (i = 0; i < 32; ++i)
2672                 if (!tz_info.DaylightName [i])
2673                         break;
2674         mono_array_set ((*names), gpointer, 1, mono_string_new_utf16 (domain, tz_info.DaylightName, i));
2675         for (i = 0; i < 32; ++i)
2676                 if (!tz_info.StandardName [i])
2677                         break;
2678         mono_array_set ((*names), gpointer, 0, mono_string_new_utf16 (domain, tz_info.StandardName, i));
2679
2680         SystemTimeToFileTime (&tz_info.StandardDate, &ft);
2681         mono_array_set ((*data), gint64, 1, ((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime);
2682         SystemTimeToFileTime (&tz_info.DaylightDate, &ft);
2683         mono_array_set ((*data), gint64, 0, ((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime);
2684         mono_array_set ((*data), gint64, 3, tz_info.Bias + tz_info.StandardBias);
2685         mono_array_set ((*data), gint64, 2, tz_info.Bias + tz_info.DaylightBias);
2686
2687         return 1;
2688 #endif
2689 }
2690
2691 static gpointer
2692 ves_icall_System_Object_obj_address (MonoObject *this) 
2693 {
2694         MONO_ARCH_SAVE_REGS;
2695
2696         return this;
2697 }
2698
2699 /* System.Buffer */
2700
2701 static gint32 
2702 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array) 
2703 {
2704         MonoClass *klass;
2705         MonoTypeEnum etype;
2706         int length, esize;
2707         int i;
2708
2709         MONO_ARCH_SAVE_REGS;
2710
2711         klass = array->obj.vtable->klass;
2712         etype = klass->element_class->byval_arg.type;
2713         if (etype < MONO_TYPE_BOOLEAN || etype > MONO_TYPE_R8)
2714                 return -1;
2715
2716         if (array->bounds == NULL)
2717                 length = array->max_length;
2718         else {
2719                 length = 0;
2720                 for (i = 0; i < klass->rank; ++ i)
2721                         length += array->bounds [i].length;
2722         }
2723
2724         esize = mono_array_element_size (klass);
2725         return length * esize;
2726 }
2727
2728 static gint8 
2729 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx) 
2730 {
2731         MONO_ARCH_SAVE_REGS;
2732
2733         return mono_array_get (array, gint8, idx);
2734 }
2735
2736 static void 
2737 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value) 
2738 {
2739         MONO_ARCH_SAVE_REGS;
2740
2741         mono_array_set (array, gint8, idx, value);
2742 }
2743
2744 static void 
2745 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count) 
2746 {
2747         char *src_buf, *dest_buf;
2748
2749         MONO_ARCH_SAVE_REGS;
2750
2751         src_buf = (gint8 *)src->vector + src_offset;
2752         dest_buf = (gint8 *)dest->vector + dest_offset;
2753
2754         memcpy (dest_buf, src_buf, count);
2755 }
2756
2757 static MonoObject *
2758 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this)
2759 {
2760         MonoDomain *domain = mono_object_domain (this); 
2761         MonoObject *res;
2762         MonoRealProxy *rp = ((MonoRealProxy *)this);
2763         MonoType *type;
2764         MonoClass *klass;
2765
2766         MONO_ARCH_SAVE_REGS;
2767
2768         res = mono_object_new (domain, mono_defaults.transparent_proxy_class);
2769         
2770         ((MonoTransparentProxy *)res)->rp = rp;
2771         type = ((MonoReflectionType *)rp->class_to_proxy)->type;
2772         klass = mono_class_from_mono_type (type);
2773
2774         ((MonoTransparentProxy *)res)->klass = klass;
2775
2776         res->vtable = mono_class_proxy_vtable (domain, klass);
2777
2778         return res;
2779 }
2780
2781 /* System.Environment */
2782
2783 static MonoString *
2784 ves_icall_System_Environment_get_MachineName (void)
2785 {
2786 #if defined (PLATFORM_WIN32)
2787         gunichar2 *buf;
2788         guint32 len;
2789         MonoString *result;
2790
2791         len = MAX_COMPUTERNAME_LENGTH + 1;
2792         buf = g_new (gunichar2, len);
2793
2794         result = NULL;
2795         if (GetComputerName (buf, (PDWORD) &len))
2796                 result = mono_string_new_utf16 (mono_domain_get (), buf, len);
2797
2798         g_free (buf);
2799         return result;
2800 #else
2801         gchar *buf;
2802         int len;
2803         MonoString *result;
2804
2805         MONO_ARCH_SAVE_REGS;
2806
2807         len = 256;
2808         buf = g_new (gchar, len);
2809
2810         result = NULL;
2811         if (gethostname (buf, len) == 0)
2812                 result = mono_string_new (mono_domain_get (), buf);
2813         
2814         g_free (buf);
2815         return result;
2816 #endif
2817 }
2818
2819 static int
2820 ves_icall_System_Environment_get_Platform (void)
2821 {
2822         MONO_ARCH_SAVE_REGS;
2823
2824 #if defined (PLATFORM_WIN32)
2825         /* Win32NT */
2826         return 2;
2827 #else
2828         /* Unix */
2829         return 128;
2830 #endif
2831 }
2832
2833 static MonoString *
2834 ves_icall_System_Environment_get_NewLine (void)
2835 {
2836         MONO_ARCH_SAVE_REGS;
2837
2838 #if defined (PLATFORM_WIN32)
2839         return mono_string_new (mono_domain_get (), "\r\n");
2840 #else
2841         return mono_string_new (mono_domain_get (), "\n");
2842 #endif
2843 }
2844
2845 static MonoString *
2846 ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name)
2847 {
2848         const gchar *value;
2849         gchar *utf8_name;
2850
2851         MONO_ARCH_SAVE_REGS;
2852
2853         if (name == NULL)
2854                 return NULL;
2855
2856         utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
2857         value = g_getenv (utf8_name);
2858         g_free (utf8_name);
2859
2860         if (value == 0)
2861                 return NULL;
2862         
2863         return mono_string_new (mono_domain_get (), value);
2864 }
2865
2866 /*
2867  * There is no standard way to get at environ.
2868  */
2869 extern char **environ;
2870
2871 static MonoArray *
2872 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
2873 {
2874         MonoArray *names;
2875         MonoDomain *domain;
2876         MonoString *str;
2877         gchar **e, **parts;
2878         int n;
2879
2880         MONO_ARCH_SAVE_REGS;
2881
2882         n = 0;
2883         for (e = environ; *e != 0; ++ e)
2884                 ++ n;
2885
2886         domain = mono_domain_get ();
2887         names = mono_array_new (domain, mono_defaults.string_class, n);
2888
2889         n = 0;
2890         for (e = environ; *e != 0; ++ e) {
2891                 parts = g_strsplit (*e, "=", 2);
2892                 if (*parts != 0) {
2893                         str = mono_string_new (domain, *parts);
2894                         mono_array_set (names, MonoString *, n, str);
2895                 }
2896
2897                 g_strfreev (parts);
2898
2899                 ++ n;
2900         }
2901
2902         return names;
2903 }
2904
2905 /*
2906  * Returns the number of milliseconds elapsed since the system started.
2907  */
2908 static gint32
2909 ves_icall_System_Environment_get_TickCount (void)
2910 {
2911 #if defined (PLATFORM_WIN32)
2912         return GetTickCount();
2913 #else
2914         struct timeval tv;
2915         struct timezone tz;
2916         gint32 res;
2917
2918         MONO_ARCH_SAVE_REGS;
2919
2920         res = (gint32) gettimeofday (&tv, &tz);
2921
2922         if (res != -1)
2923                 res = (gint32) ((tv.tv_sec & 0xFFFFF) * 1000 + (tv.tv_usec / 1000));
2924         return res;
2925 #endif
2926 }
2927
2928
2929 static void
2930 ves_icall_System_Environment_Exit (int result)
2931 {
2932         MONO_ARCH_SAVE_REGS;
2933
2934         /* we may need to do some cleanup here... */
2935         exit (result);
2936 }
2937
2938 static MonoString*
2939 ves_icall_System_Text_Encoding_InternalCodePage (void) 
2940 {
2941         const char *cset;
2942
2943         MONO_ARCH_SAVE_REGS;
2944
2945         g_get_charset (&cset);
2946         /* g_print ("charset: %s\n", cset); */
2947         /* handle some common aliases */
2948         switch (*cset) {
2949         case 'A':
2950                 if (strcmp (cset, "ANSI_X3.4-1968") == 0)
2951                         cset = "us-ascii";
2952                 break;
2953         }
2954         return mono_string_new (mono_domain_get (), cset);
2955 }
2956
2957 static void
2958 ves_icall_MonoMethodMessage_InitMessage (MonoMethodMessage *this, 
2959                                          MonoReflectionMethod *method,
2960                                          MonoArray *out_args)
2961 {
2962         MONO_ARCH_SAVE_REGS;
2963
2964         mono_message_init (mono_object_domain (this), this, method, out_args);
2965 }
2966
2967 static MonoBoolean
2968 ves_icall_IsTransparentProxy (MonoObject *proxy)
2969 {
2970         MONO_ARCH_SAVE_REGS;
2971
2972         if (!proxy)
2973                 return 0;
2974
2975         if (proxy->vtable->klass == mono_defaults.transparent_proxy_class)
2976                 return 1;
2977
2978         return 0;
2979 }
2980
2981 static MonoObject *
2982 ves_icall_System_Runtime_Serialization_FormatterServices_GetUninitializedObject_Internal (MonoReflectionType *type)
2983 {
2984         MonoClass *klass;
2985         MonoObject *obj;
2986         MonoDomain *domain;
2987         
2988         MONO_ARCH_SAVE_REGS;
2989
2990         domain = mono_object_domain (type);
2991         klass = mono_class_from_mono_type (type->type);
2992
2993         if (klass->rank >= 1) {
2994                 g_assert (klass->rank == 1);
2995                 obj = (MonoObject *) mono_array_new (domain, klass->element_class, 0);
2996         } else {
2997                 obj = mono_object_new (domain, klass);
2998         }
2999
3000         return obj;
3001 }
3002
3003 static MonoString *
3004 ves_icall_System_IO_get_temp_path (void)
3005 {
3006         MONO_ARCH_SAVE_REGS;
3007
3008         return mono_string_new (mono_domain_get (), g_get_tmp_dir ());
3009 }
3010
3011 static gpointer
3012 ves_icall_RuntimeMethod_GetFunctionPointer (MonoMethod *method)
3013 {
3014         MONO_ARCH_SAVE_REGS;
3015
3016         return mono_compile_method (method);
3017 }
3018
3019 char * mono_cfg_dir = "";
3020
3021 void    
3022 mono_install_get_config_dir()
3023 {       
3024   mono_cfg_dir = getenv ("MONO_CFG_DIR");
3025
3026   if (!mono_cfg_dir)
3027     mono_cfg_dir = MONO_CFG_DIR; 
3028 }
3029
3030
3031 static MonoString *
3032 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
3033 {
3034         static MonoString *mcpath;
3035         gchar *path;
3036
3037         MONO_ARCH_SAVE_REGS;
3038
3039         if (mcpath != NULL)
3040                 return mcpath;
3041
3042         path = g_build_path (G_DIR_SEPARATOR_S, mono_cfg_dir, "mono", "machine.config", NULL);
3043
3044 #if defined (PLATFORM_WIN32)
3045         /* Avoid mixing '/' and '\\' */
3046         {
3047                 gint i;
3048                 for (i = strlen (path) - 1; i >= 0; i--)
3049                         if (path [i] == '/')
3050                                 path [i] = '\\';
3051         }
3052 #endif
3053         mcpath = mono_string_new (mono_domain_get (), path);
3054         g_free (path);
3055
3056         return mcpath;
3057 }
3058
3059 static void
3060 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
3061 {
3062 #if defined (PLATFORM_WIN32)
3063         static void (*output_debug) (gchar *);
3064         static gboolean tried_loading = FALSE;
3065         gchar *str;
3066
3067         MONO_ARCH_SAVE_REGS;
3068
3069         if (!tried_loading && output_debug == NULL) {
3070                 GModule *k32;
3071
3072                 tried_loading = TRUE;
3073                 k32 = g_module_open ("kernel32", G_MODULE_BIND_LAZY);
3074                 if (!k32) {
3075                         gchar *error = g_strdup (g_module_error ());
3076                         g_warning ("Failed to load kernel32.dll: %s\n", error);
3077                         g_free (error);
3078                         return;
3079                 }
3080
3081                 g_module_symbol (k32, "OutputDebugStringW", (gpointer *) &output_debug);
3082                 if (!output_debug) {
3083                         gchar *error = g_strdup (g_module_error ());
3084                         g_warning ("Failed to load OutputDebugStringW: %s\n", error);
3085                         g_free (error);
3086                         return;
3087                 }
3088         }
3089
3090         if (output_debug == NULL)
3091                 return;
3092         
3093         str = mono_string_to_utf8 (message);
3094         output_debug (str);
3095         g_free (str);
3096 #else
3097         g_warning ("WriteWindowsDebugString called and PLATFORM_WIN32 not defined!\n");
3098 #endif
3099 }
3100
3101 /* Only used for value types */
3102 static MonoObject *
3103 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
3104 {
3105         MonoClass *klass;
3106         MonoDomain *domain;
3107         
3108         MONO_ARCH_SAVE_REGS;
3109
3110         domain = mono_object_domain (type);
3111         klass = mono_class_from_mono_type (type->type);
3112
3113         return mono_object_new (domain, klass);
3114 }
3115
3116 static MonoReflectionMethod *
3117 ves_icall_MonoMethod_get_base_definition (MonoReflectionMethod *m)
3118 {
3119         MonoClass *klass;
3120         MonoMethod *method = m->method;
3121         MonoMethod *result = NULL;
3122
3123         MONO_ARCH_SAVE_REGS;
3124
3125         if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
3126              method->klass->flags & TYPE_ATTRIBUTE_INTERFACE ||
3127              method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
3128                 return m;
3129
3130         if (method->klass == NULL || (klass = method->klass->parent) == NULL)
3131                 return m;
3132
3133         if (klass->vtable_size > method->slot)
3134                 result = klass->vtable [method->slot];
3135
3136         if (result == NULL)
3137                 return m;
3138
3139         return mono_method_get_object (mono_domain_get (), result, NULL);
3140 }
3141
3142 /* icall map */
3143
3144 static gconstpointer icall_map [] = {
3145         /*
3146          * System.Array
3147          */
3148         "System.Array::GetValue",         ves_icall_System_Array_GetValue,
3149         "System.Array::SetValue",         ves_icall_System_Array_SetValue,
3150         "System.Array::GetValueImpl",     ves_icall_System_Array_GetValueImpl,
3151         "System.Array::SetValueImpl",     ves_icall_System_Array_SetValueImpl,
3152         "System.Array::GetRank",          ves_icall_System_Array_GetRank,
3153         "System.Array::GetLength",        ves_icall_System_Array_GetLength,
3154         "System.Array::GetLowerBound",    ves_icall_System_Array_GetLowerBound,
3155         "System.Array::CreateInstanceImpl",   ves_icall_System_Array_CreateInstanceImpl,
3156         "System.Array::FastCopy",         ves_icall_System_Array_FastCopy,
3157         "System.Array::Clone",            mono_array_clone,
3158
3159         /*
3160          * System.Object
3161          */
3162         "System.Object::MemberwiseClone", ves_icall_System_Object_MemberwiseClone,
3163         "System.Object::GetType", ves_icall_System_Object_GetType,
3164         "System.Object::GetHashCode", ves_icall_System_Object_GetHashCode,
3165         "System.Object::obj_address", ves_icall_System_Object_obj_address,
3166
3167         /*
3168          * System.ValueType
3169          */
3170         "System.ValueType::GetHashCode", ves_icall_System_ValueType_GetHashCode,
3171         "System.ValueType::Equals", ves_icall_System_ValueType_Equals,
3172
3173         /*
3174          * System.String
3175          */
3176         
3177         "System.String::.ctor(char*)", ves_icall_System_String_ctor_charp,
3178         "System.String::.ctor(char*,int,int)", ves_icall_System_String_ctor_charp_int_int,
3179         "System.String::.ctor(sbyte*)", ves_icall_System_String_ctor_sbytep,
3180         "System.String::.ctor(sbyte*,int,int)", ves_icall_System_String_ctor_sbytep_int_int,
3181         "System.String::.ctor(sbyte*,int,int,System.Text.Encoding)", ves_icall_System_String_ctor_encoding,
3182         "System.String::.ctor(char[])", ves_icall_System_String_ctor_chara,
3183         "System.String::.ctor(char[],int,int)", ves_icall_System_String_ctor_chara_int_int,
3184         "System.String::.ctor(char,int)", ves_icall_System_String_ctor_char_int,
3185         "System.String::InternalEquals", ves_icall_System_String_InternalEquals,
3186         "System.String::InternalJoin", ves_icall_System_String_InternalJoin,
3187         "System.String::InternalInsert", ves_icall_System_String_InternalInsert,
3188         "System.String::InternalReplace(char,char)", ves_icall_System_String_InternalReplace_Char,
3189         "System.String::InternalReplace(string,string)", ves_icall_System_String_InternalReplace_Str,
3190         "System.String::InternalRemove", ves_icall_System_String_InternalRemove,
3191         "System.String::InternalCopyTo", ves_icall_System_String_InternalCopyTo,
3192         "System.String::InternalSplit", ves_icall_System_String_InternalSplit,
3193         "System.String::InternalTrim", ves_icall_System_String_InternalTrim,
3194         "System.String::InternalIndexOf(char,int,int)", ves_icall_System_String_InternalIndexOf_Char,
3195         "System.String::InternalIndexOf(string,int,int)", ves_icall_System_String_InternalIndexOf_Str,
3196         "System.String::InternalIndexOfAny", ves_icall_System_String_InternalIndexOfAny,
3197         "System.String::InternalLastIndexOf(char,int,int)", ves_icall_System_String_InternalLastIndexOf_Char,
3198         "System.String::InternalLastIndexOf(string,int,int)", ves_icall_System_String_InternalLastIndexOf_Str,
3199         "System.String::InternalLastIndexOfAny", ves_icall_System_String_InternalLastIndexOfAny,
3200         "System.String::InternalPad", ves_icall_System_String_InternalPad,
3201         "System.String::InternalToLower", ves_icall_System_String_InternalToLower,
3202         "System.String::InternalToUpper", ves_icall_System_String_InternalToUpper,
3203         "System.String::InternalAllocateStr", ves_icall_System_String_InternalAllocateStr,
3204         "System.String::InternalStrcpy(string,int,string)", ves_icall_System_String_InternalStrcpy_Str,
3205         "System.String::InternalStrcpy(string,int,string,int,int)", ves_icall_System_String_InternalStrcpy_StrN,
3206         "System.String::InternalIntern", ves_icall_System_String_InternalIntern,
3207         "System.String::InternalIsInterned", ves_icall_System_String_InternalIsInterned,
3208         "System.String::InternalCompare(string,int,string,int,int,int)", ves_icall_System_String_InternalCompareStr_N,
3209         "System.String::GetHashCode", ves_icall_System_String_GetHashCode,
3210         "System.String::get_Chars", ves_icall_System_String_get_Chars,
3211
3212         /*
3213          * System.AppDomain
3214          */
3215         "System.AppDomain::createDomain", ves_icall_System_AppDomain_createDomain,
3216         "System.AppDomain::getCurDomain", ves_icall_System_AppDomain_getCurDomain,
3217         "System.AppDomain::GetData", ves_icall_System_AppDomain_GetData,
3218         "System.AppDomain::SetData", ves_icall_System_AppDomain_SetData,
3219         "System.AppDomain::getSetup", ves_icall_System_AppDomain_getSetup,
3220         "System.AppDomain::getFriendlyName", ves_icall_System_AppDomain_getFriendlyName,
3221         "System.AppDomain::GetAssemblies", ves_icall_System_AppDomain_GetAssemblies,
3222         "System.AppDomain::LoadAssembly", ves_icall_System_AppDomain_LoadAssembly,
3223         "System.AppDomain::Unload", ves_icall_System_AppDomain_Unload,
3224         "System.AppDomain::ExecuteAssembly", ves_icall_System_AppDomain_ExecuteAssembly,
3225         "System.AppDomain::InternalSetDomain", ves_icall_System_AppDomain_InternalSetDomain,
3226         "System.AppDomain::InternalSetDomainByID", ves_icall_System_AppDomain_InternalSetDomainByID,
3227         "System.AppDomain::InternalSetContext", ves_icall_System_AppDomain_InternalSetContext,
3228         "System.AppDomain::InternalGetContext", ves_icall_System_AppDomain_InternalGetContext,
3229
3230         /*
3231          * System.AppDomainSetup
3232          */
3233         "System.AppDomainSetup::InitAppDomainSetup", ves_icall_System_AppDomainSetup_InitAppDomainSetup,
3234
3235         /*
3236          * System.Double
3237          */
3238         "System.Double::ToStringImpl", mono_double_ToStringImpl,
3239         "System.Double::ParseImpl",    mono_double_ParseImpl,
3240
3241         /*
3242          * System.Single
3243          */
3244         "System.Single::ToStringImpl", mono_float_ToStringImpl,
3245
3246         /*
3247          * System.Decimal
3248          */
3249         "System.Decimal::decimal2UInt64", mono_decimal2UInt64,
3250         "System.Decimal::decimal2Int64", mono_decimal2Int64,
3251         "System.Decimal::double2decimal", mono_double2decimal, /* FIXME: wrong signature. */
3252         "System.Decimal::decimalIncr", mono_decimalIncr,
3253         "System.Decimal::decimalSetExponent", mono_decimalSetExponent,
3254         "System.Decimal::decimal2double", mono_decimal2double,
3255         "System.Decimal::decimalFloorAndTrunc", mono_decimalFloorAndTrunc,
3256         "System.Decimal::decimalRound", mono_decimalRound,
3257         "System.Decimal::decimalMult", mono_decimalMult,
3258         "System.Decimal::decimalDiv", mono_decimalDiv,
3259         "System.Decimal::decimalIntDiv", mono_decimalIntDiv,
3260         "System.Decimal::decimalCompare", mono_decimalCompare,
3261         "System.Decimal::string2decimal", mono_string2decimal,
3262         "System.Decimal::decimal2string", mono_decimal2string,
3263
3264         /*
3265          * ModuleBuilder
3266          */
3267         "System.Reflection.Emit.ModuleBuilder::create_modified_type", ves_icall_ModuleBuilder_create_modified_type,
3268         "System.Reflection.Emit.ModuleBuilder::basic_init", mono_image_module_basic_init,
3269         
3270         /*
3271          * AssemblyBuilder
3272          */
3273         "System.Reflection.Emit.AssemblyBuilder::getDataChunk", ves_icall_AssemblyBuilder_getDataChunk,
3274         "System.Reflection.Emit.AssemblyBuilder::getUSIndex", mono_image_insert_string,
3275         "System.Reflection.Emit.AssemblyBuilder::getToken", ves_icall_AssemblyBuilder_getToken,
3276         "System.Reflection.Emit.AssemblyBuilder::basic_init", mono_image_basic_init,
3277
3278         /*
3279          * Reflection stuff.
3280          */
3281         "System.Reflection.MonoMethodInfo::get_method_info", ves_icall_get_method_info,
3282         "System.Reflection.MonoMethodInfo::get_parameter_info", ves_icall_get_parameter_info,
3283         "System.Reflection.MonoFieldInfo::get_field_info", ves_icall_get_field_info,
3284         "System.Reflection.MonoPropertyInfo::get_property_info", ves_icall_get_property_info,
3285         "System.Reflection.MonoEventInfo::get_event_info", ves_icall_get_event_info,
3286         "System.Reflection.MonoMethod::InternalInvoke", ves_icall_InternalInvoke,
3287         "System.Reflection.MonoCMethod::InternalInvoke", ves_icall_InternalInvoke,
3288         "System.Reflection.MethodBase::GetCurrentMethod", ves_icall_GetCurrentMethod,
3289         "System.MonoCustomAttrs::GetCustomAttributes", mono_reflection_get_custom_attrs,
3290         "System.Reflection.Emit.CustomAttributeBuilder::GetBlob", mono_reflection_get_custom_attrs_blob,
3291         "System.Reflection.MonoField::GetValueInternal", ves_icall_MonoField_GetValueInternal,
3292         "System.Reflection.MonoField::SetValueInternal", ves_icall_FieldInfo_SetValueInternal,
3293         "System.Reflection.Emit.SignatureHelper::get_signature_local", mono_reflection_sighelper_get_signature_local,
3294         "System.Reflection.Emit.SignatureHelper::get_signature_field", mono_reflection_sighelper_get_signature_field,
3295
3296         "System.RuntimeMethodHandle::GetFunctionPointer", ves_icall_RuntimeMethod_GetFunctionPointer,
3297         "System.Reflection.MonoMethod::get_base_definition", ves_icall_MonoMethod_get_base_definition,
3298         
3299         /* System.Enum */
3300
3301         "System.MonoEnumInfo::get_enum_info", ves_icall_get_enum_info,
3302         "System.Enum::get_value", ves_icall_System_Enum_get_value,
3303         "System.Enum::ToObject", ves_icall_System_Enum_ToObject,
3304
3305         /*
3306          * TypeBuilder
3307          */
3308         "System.Reflection.Emit.TypeBuilder::setup_internal_class", mono_reflection_setup_internal_class,
3309         "System.Reflection.Emit.TypeBuilder::create_internal_class", mono_reflection_create_internal_class,
3310         "System.Reflection.Emit.TypeBuilder::create_runtime_class", mono_reflection_create_runtime_class,
3311         
3312         /*
3313          * MethodBuilder
3314          */
3315         
3316         /*
3317          * System.Type
3318          */
3319         "System.Type::internal_from_name", ves_icall_type_from_name,
3320         "System.Type::internal_from_handle", ves_icall_type_from_handle,
3321         "System.MonoType::get_attributes", ves_icall_get_attributes,
3322         "System.Type::type_is_subtype_of", ves_icall_type_is_subtype_of,
3323         "System.Type::Equals", ves_icall_type_Equals,
3324         "System.Type::GetTypeCode", ves_icall_type_GetTypeCode,
3325         "System.Type::GetInterfaceMapData", ves_icall_Type_GetInterfaceMapData,
3326
3327         /*
3328          * System.Runtime.CompilerServices.RuntimeHelpers
3329          */
3330         "System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray", ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray,
3331         "System.Runtime.CompilerServices.RuntimeHelpers::GetOffsetToStringData", ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData,
3332         "System.Runtime.CompilerServices.RuntimeHelpers::GetObjectValue", ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue,
3333         "System.Runtime.CompilerServices.RuntimeHelpers::RunClassConstructor", ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor,
3334         
3335         /*
3336          * System.Threading
3337          */
3338         "System.Threading.Thread::Abort(object)", ves_icall_System_Threading_Thread_Abort,
3339         "System.Threading.Thread::ResetAbort", ves_icall_System_Threading_Thread_ResetAbort,
3340         "System.Threading.Thread::Thread_internal", ves_icall_System_Threading_Thread_Thread_internal,
3341         "System.Threading.Thread::Thread_free_internal", ves_icall_System_Threading_Thread_Thread_free_internal,
3342         "System.Threading.Thread::Start_internal", ves_icall_System_Threading_Thread_Start_internal,
3343         "System.Threading.Thread::Sleep_internal", ves_icall_System_Threading_Thread_Sleep_internal,
3344         "System.Threading.Thread::CurrentThread_internal", mono_thread_current,
3345         "System.Threading.Thread::Join_internal", ves_icall_System_Threading_Thread_Join_internal,
3346         "System.Threading.Thread::SlotHash_lookup", ves_icall_System_Threading_Thread_SlotHash_lookup,
3347         "System.Threading.Thread::SlotHash_store", ves_icall_System_Threading_Thread_SlotHash_store,
3348         "System.Threading.Thread::GetDomainID", ves_icall_System_Threading_Thread_GetDomainID,
3349         "System.Threading.Monitor::Monitor_exit", ves_icall_System_Threading_Monitor_Monitor_exit,
3350         "System.Threading.Monitor::Monitor_test_owner", ves_icall_System_Threading_Monitor_Monitor_test_owner,
3351         "System.Threading.Monitor::Monitor_test_synchronised", ves_icall_System_Threading_Monitor_Monitor_test_synchronised,
3352         "System.Threading.Monitor::Monitor_pulse", ves_icall_System_Threading_Monitor_Monitor_pulse,
3353         "System.Threading.Monitor::Monitor_pulse_all", ves_icall_System_Threading_Monitor_Monitor_pulse_all,
3354         "System.Threading.Monitor::Monitor_try_enter", ves_icall_System_Threading_Monitor_Monitor_try_enter,
3355         "System.Threading.Monitor::Monitor_wait", ves_icall_System_Threading_Monitor_Monitor_wait,
3356         "System.Threading.Mutex::CreateMutex_internal", ves_icall_System_Threading_Mutex_CreateMutex_internal,
3357         "System.Threading.Mutex::ReleaseMutex_internal", ves_icall_System_Threading_Mutex_ReleaseMutex_internal,
3358         "System.Threading.NativeEventCalls::CreateEvent_internal", ves_icall_System_Threading_Events_CreateEvent_internal,
3359         "System.Threading.NativeEventCalls::SetEvent_internal",    ves_icall_System_Threading_Events_SetEvent_internal,
3360         "System.Threading.NativeEventCalls::ResetEvent_internal",  ves_icall_System_Threading_Events_ResetEvent_internal,
3361
3362         /*
3363          * System.Threading.WaitHandle
3364          */
3365         "System.Threading.WaitHandle::WaitAll_internal", ves_icall_System_Threading_WaitHandle_WaitAll_internal,
3366         "System.Threading.WaitHandle::WaitAny_internal", ves_icall_System_Threading_WaitHandle_WaitAny_internal,
3367         "System.Threading.WaitHandle::WaitOne_internal", ves_icall_System_Threading_WaitHandle_WaitOne_internal,
3368
3369         /*
3370          * System.Runtime.InteropServices.Marshal
3371          */
3372         "System.Runtime.InteropServices.Marshal::ReadIntPtr", ves_icall_System_Runtime_InteropServices_Marshal_ReadIntPtr,
3373         "System.Runtime.InteropServices.Marshal::ReadByte", ves_icall_System_Runtime_InteropServices_Marshal_ReadByte,
3374         "System.Runtime.InteropServices.Marshal::ReadInt16", ves_icall_System_Runtime_InteropServices_Marshal_ReadInt16,
3375         "System.Runtime.InteropServices.Marshal::ReadInt32", ves_icall_System_Runtime_InteropServices_Marshal_ReadInt32,
3376         "System.Runtime.InteropServices.Marshal::ReadInt64", ves_icall_System_Runtime_InteropServices_Marshal_ReadInt64,
3377         "System.Runtime.InteropServices.Marshal::WriteIntPtr", ves_icall_System_Runtime_InteropServices_Marshal_WriteIntPtr,
3378         "System.Runtime.InteropServices.Marshal::WriteByte", ves_icall_System_Runtime_InteropServices_Marshal_WriteByte,
3379         "System.Runtime.InteropServices.Marshal::WriteInt16", ves_icall_System_Runtime_InteropServices_Marshal_WriteInt16,
3380         "System.Runtime.InteropServices.Marshal::WriteInt32", ves_icall_System_Runtime_InteropServices_Marshal_WriteInt32,
3381         "System.Runtime.InteropServices.Marshal::WriteInt64", ves_icall_System_Runtime_InteropServices_Marshal_WriteInt64,
3382
3383         "System.Runtime.InteropServices.Marshal::PtrToStringAnsi(intptr)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringAnsi,
3384         "System.Runtime.InteropServices.Marshal::PtrToStringAnsi(intptr,int)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringAnsi_len,
3385         "System.Runtime.InteropServices.Marshal::PtrToStringAuto(intptr)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringAnsi,
3386         "System.Runtime.InteropServices.Marshal::PtrToStringAuto(intptr,int)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringAnsi_len,
3387         "System.Runtime.InteropServices.Marshal::PtrToStringUni(intptr)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringUni,
3388         "System.Runtime.InteropServices.Marshal::PtrToStringUni(intptr,int)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringUni_len,
3389         "System.Runtime.InteropServices.Marshal::PtrToStringBSTR", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringBSTR,
3390
3391         "System.Runtime.InteropServices.Marshal::GetLastWin32Error", ves_icall_System_Runtime_InteropServices_Marshal_GetLastWin32Error,
3392         "System.Runtime.InteropServices.Marshal::AllocHGlobal", mono_marshal_alloc,
3393         "System.Runtime.InteropServices.Marshal::FreeHGlobal", mono_marshal_free,
3394         "System.Runtime.InteropServices.Marshal::ReAllocHGlobal", mono_marshal_realloc,
3395         "System.Runtime.InteropServices.Marshal::copy_to_unmanaged", ves_icall_System_Runtime_InteropServices_Marshal_copy_to_unmanaged,
3396         "System.Runtime.InteropServices.Marshal::copy_from_unmanaged", ves_icall_System_Runtime_InteropServices_Marshal_copy_from_unmanaged,
3397         "System.Runtime.InteropServices.Marshal::SizeOf", ves_icall_System_Runtime_InteropServices_Marshal_SizeOf,
3398         "System.Runtime.InteropServices.Marshal::StructureToPtr", ves_icall_System_Runtime_InteropServices_Marshal_StructureToPtr,
3399         "System.Runtime.InteropServices.Marshal::PtrToStructure(intptr,object)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStructure,
3400         "System.Runtime.InteropServices.Marshal::PtrToStructure(intptr,System.Type)", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStructure_type,
3401         "System.Runtime.InteropServices.Marshal::OffsetOf", ves_icall_System_Runtime_InteropServices_Marshal_OffsetOf,
3402         "System.Runtime.InteropServices.Marshal::StringToHGlobalAnsi", ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalAnsi,
3403         "System.Runtime.InteropServices.Marshal::StringToHGlobalAuto", ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalAnsi,
3404         "System.Runtime.InteropServices.Marshal::StringToHGlobalUni", ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalUni,
3405         "System.Runtime.InteropServices.Marshal::DestroyStructure", ves_icall_System_Runtime_InteropServices_Marshal_DestroyStructure,
3406
3407
3408         "System.Reflection.Assembly::LoadFrom", ves_icall_System_Reflection_Assembly_LoadFrom,
3409         "System.Reflection.Assembly::InternalGetType", ves_icall_System_Reflection_Assembly_InternalGetType,
3410         "System.Reflection.Assembly::GetTypes", ves_icall_System_Reflection_Assembly_GetTypes,
3411         "System.Reflection.Assembly::FillName", ves_icall_System_Reflection_Assembly_FillName,
3412         "System.Reflection.Assembly::get_code_base", ves_icall_System_Reflection_Assembly_get_code_base,
3413         "System.Reflection.Assembly::get_location", ves_icall_System_Reflection_Assembly_get_location,
3414         "System.Reflection.Assembly::GetExecutingAssembly", ves_icall_System_Reflection_Assembly_GetExecutingAssembly,
3415         "System.Reflection.Assembly::GetEntryAssembly", ves_icall_System_Reflection_Assembly_GetEntryAssembly,
3416         "System.Reflection.Assembly::GetCallingAssembly", ves_icall_System_Reflection_Assembly_GetCallingAssembly,
3417         "System.Reflection.Assembly::get_EntryPoint", ves_icall_System_Reflection_Assembly_get_EntryPoint,
3418         "System.Reflection.Assembly::GetManifestResourceNames", ves_icall_System_Reflection_Assembly_GetManifestResourceNames,
3419         "System.Reflection.Assembly::GetManifestResourceInternal", ves_icall_System_Reflection_Assembly_GetManifestResourceInternal,
3420         "System.Reflection.Assembly::GetFilesInternal", ves_icall_System_Reflection_Assembly_GetFilesInternal,
3421         "System.Reflection.Assembly::GetReferencedAssemblies", ves_icall_System_Reflection_Assembly_GetReferencedAssemblies,
3422
3423         /*
3424          * System.MonoType.
3425          */
3426         "System.MonoType::getFullName", ves_icall_System_MonoType_getFullName,
3427         "System.MonoType::type_from_obj", mono_type_type_from_obj,
3428         "System.MonoType::GetElementType", ves_icall_MonoType_GetElementType,
3429         "System.MonoType::get_type_info", ves_icall_get_type_info,
3430         "System.MonoType::get_BaseType", ves_icall_get_type_parent,
3431         "System.MonoType::get_Module", ves_icall_MonoType_get_Module,
3432         "System.MonoType::IsPointerImpl", ves_icall_type_ispointer,
3433         "System.MonoType::IsByRefImpl", ves_icall_type_isbyref,
3434         "System.MonoType::GetField", ves_icall_Type_GetField,
3435         "System.MonoType::GetFields", ves_icall_Type_GetFields,
3436         "System.MonoType::GetMethods", ves_icall_Type_GetMethods,
3437         "System.MonoType::GetConstructors", ves_icall_Type_GetConstructors,
3438         "System.MonoType::GetProperties", ves_icall_Type_GetProperties,
3439         "System.MonoType::GetEvents", ves_icall_Type_GetEvents,
3440         "System.MonoType::InternalGetEvent", ves_icall_MonoType_GetEvent,
3441         "System.MonoType::GetInterfaces", ves_icall_Type_GetInterfaces,
3442         "System.MonoType::GetNestedTypes", ves_icall_Type_GetNestedTypes,
3443
3444         /*
3445          * System.Net.Sockets I/O Services
3446          */
3447         "System.Net.Sockets.Socket::Socket_internal", ves_icall_System_Net_Sockets_Socket_Socket_internal,
3448         "System.Net.Sockets.Socket::Close_internal", ves_icall_System_Net_Sockets_Socket_Close_internal,
3449         "System.Net.Sockets.SocketException::WSAGetLastError_internal", ves_icall_System_Net_Sockets_SocketException_WSAGetLastError_internal,
3450         "System.Net.Sockets.Socket::Available_internal", ves_icall_System_Net_Sockets_Socket_Available_internal,
3451         "System.Net.Sockets.Socket::Blocking_internal", ves_icall_System_Net_Sockets_Socket_Blocking_internal,
3452         "System.Net.Sockets.Socket::Accept_internal", ves_icall_System_Net_Sockets_Socket_Accept_internal,
3453         "System.Net.Sockets.Socket::Listen_internal", ves_icall_System_Net_Sockets_Socket_Listen_internal,
3454         "System.Net.Sockets.Socket::LocalEndPoint_internal", ves_icall_System_Net_Sockets_Socket_LocalEndPoint_internal,
3455         "System.Net.Sockets.Socket::RemoteEndPoint_internal", ves_icall_System_Net_Sockets_Socket_RemoteEndPoint_internal,
3456         "System.Net.Sockets.Socket::Bind_internal", ves_icall_System_Net_Sockets_Socket_Bind_internal,
3457         "System.Net.Sockets.Socket::Connect_internal", ves_icall_System_Net_Sockets_Socket_Connect_internal,
3458         "System.Net.Sockets.Socket::Receive_internal", ves_icall_System_Net_Sockets_Socket_Receive_internal,
3459         "System.Net.Sockets.Socket::RecvFrom_internal", ves_icall_System_Net_Sockets_Socket_RecvFrom_internal,
3460         "System.Net.Sockets.Socket::Send_internal", ves_icall_System_Net_Sockets_Socket_Send_internal,
3461         "System.Net.Sockets.Socket::SendTo_internal", ves_icall_System_Net_Sockets_Socket_SendTo_internal,
3462         "System.Net.Sockets.Socket::Select_internal", ves_icall_System_Net_Sockets_Socket_Select_internal,
3463         "System.Net.Sockets.Socket::Shutdown_internal", ves_icall_System_Net_Sockets_Socket_Shutdown_internal,
3464         "System.Net.Sockets.Socket::GetSocketOption_obj_internal", ves_icall_System_Net_Sockets_Socket_GetSocketOption_obj_internal,
3465         "System.Net.Sockets.Socket::GetSocketOption_arr_internal", ves_icall_System_Net_Sockets_Socket_GetSocketOption_arr_internal,
3466         "System.Net.Sockets.Socket::SetSocketOption_internal", ves_icall_System_Net_Sockets_Socket_SetSocketOption_internal,
3467         "System.Net.Dns::GetHostByName_internal(string,string&,string[]&,string[]&)", ves_icall_System_Net_Dns_GetHostByName_internal,
3468         "System.Net.Dns::GetHostByAddr_internal(string,string&,string[]&,string[]&)", ves_icall_System_Net_Dns_GetHostByAddr_internal,
3469         "System.Net.Dns::GetHostName_internal(string&)", ves_icall_System_Net_Dns_GetHostName_internal,
3470
3471         /*
3472          * System.Char
3473          */
3474         "System.Char::GetNumericValue", ves_icall_System_Char_GetNumericValue,
3475         "System.Char::GetUnicodeCategory", ves_icall_System_Char_GetUnicodeCategory,
3476         "System.Char::IsControl", ves_icall_System_Char_IsControl,
3477         "System.Char::IsDigit", ves_icall_System_Char_IsDigit,
3478         "System.Char::IsLetter", ves_icall_System_Char_IsLetter,
3479         "System.Char::IsLower", ves_icall_System_Char_IsLower,
3480         "System.Char::IsUpper", ves_icall_System_Char_IsUpper,
3481         "System.Char::IsNumber", ves_icall_System_Char_IsNumber,
3482         "System.Char::IsPunctuation", ves_icall_System_Char_IsPunctuation,
3483         "System.Char::IsSeparator", ves_icall_System_Char_IsSeparator,
3484         "System.Char::IsSurrogate", ves_icall_System_Char_IsSurrogate,
3485         "System.Char::IsSymbol", ves_icall_System_Char_IsSymbol,
3486         "System.Char::IsWhiteSpace", ves_icall_System_Char_IsWhiteSpace,
3487         "System.Char::ToLower", ves_icall_System_Char_ToLower,
3488         "System.Char::ToUpper", ves_icall_System_Char_ToUpper,
3489
3490         /*
3491          * System.Text.Encoding
3492          */
3493         "System.Text.Encoding::InternalCodePage", ves_icall_System_Text_Encoding_InternalCodePage,
3494
3495         "System.DateTime::GetNow", ves_icall_System_DateTime_GetNow,
3496         "System.CurrentTimeZone::GetTimeZoneData", ves_icall_System_CurrentTimeZone_GetTimeZoneData,
3497
3498         /*
3499          * System.GC
3500          */
3501         "System.GC::InternalCollect", ves_icall_System_GC_InternalCollect,
3502         "System.GC::GetTotalMemory", ves_icall_System_GC_GetTotalMemory,
3503         "System.GC::KeepAlive", ves_icall_System_GC_KeepAlive,
3504         "System.GC::ReRegisterForFinalize", ves_icall_System_GC_ReRegisterForFinalize,
3505         "System.GC::SuppressFinalize", ves_icall_System_GC_SuppressFinalize,
3506         "System.GC::WaitForPendingFinalizers", ves_icall_System_GC_WaitForPendingFinalizers,
3507         "System.Runtime.InteropServices.GCHandle::GetTarget", ves_icall_System_GCHandle_GetTarget,
3508         "System.Runtime.InteropServices.GCHandle::GetTargetHandle", ves_icall_System_GCHandle_GetTargetHandle,
3509         "System.Runtime.InteropServices.GCHandle::FreeHandle", ves_icall_System_GCHandle_FreeHandle,
3510         "System.Runtime.InteropServices.GCHandle::GetAddrOfPinnedObject", ves_icall_System_GCHandle_GetAddrOfPinnedObject,
3511
3512         /*
3513          * System.Security.Cryptography calls
3514          */
3515
3516          "System.Security.Cryptography.RNGCryptoServiceProvider::InternalGetBytes", ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_InternalGetBytes,
3517          "System.Security.Cryptography.RNGCryptoServiceProvider::InternalGetNonZeroBytes", ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_InternalGetNonZeroBytes,
3518         
3519         /*
3520          * System.Buffer
3521          */
3522         "System.Buffer::ByteLengthInternal", ves_icall_System_Buffer_ByteLengthInternal,
3523         "System.Buffer::GetByteInternal", ves_icall_System_Buffer_GetByteInternal,
3524         "System.Buffer::SetByteInternal", ves_icall_System_Buffer_SetByteInternal,
3525         "System.Buffer::BlockCopyInternal", ves_icall_System_Buffer_BlockCopyInternal,
3526
3527         /*
3528          * System.IO.MonoIO
3529          */
3530         "System.IO.MonoIO::CreateDirectory(string,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_CreateDirectory,
3531         "System.IO.MonoIO::RemoveDirectory(string,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_RemoveDirectory,
3532         "System.IO.MonoIO::FindFirstFile(string,System.IO.MonoIOStat&,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_FindFirstFile,
3533         "System.IO.MonoIO::FindNextFile(intptr,System.IO.MonoIOStat&,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_FindNextFile,
3534         "System.IO.MonoIO::FindClose(intptr,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_FindClose,
3535         "System.IO.MonoIO::GetCurrentDirectory(System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_GetCurrentDirectory,
3536         "System.IO.MonoIO::SetCurrentDirectory(string,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_SetCurrentDirectory,
3537         "System.IO.MonoIO::MoveFile(string,string,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_MoveFile,
3538         "System.IO.MonoIO::CopyFile(string,string,bool,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_CopyFile,
3539         "System.IO.MonoIO::DeleteFile(string,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_DeleteFile,
3540         "System.IO.MonoIO::GetFileAttributes(string,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_GetFileAttributes,
3541         "System.IO.MonoIO::SetFileAttributes(string,System.IO.FileAttributes,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_SetFileAttributes,
3542         "System.IO.MonoIO::GetFileType(intptr,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_GetFileType,
3543         "System.IO.MonoIO::GetFileStat(string,System.IO.MonoIOStat&,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_GetFileStat,
3544         "System.IO.MonoIO::Open(string,System.IO.FileMode,System.IO.FileAccess,System.IO.FileShare,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_Open,
3545         "System.IO.MonoIO::Close(intptr,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_Close,
3546         "System.IO.MonoIO::Read(intptr,byte[],int,int,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_Read,
3547         "System.IO.MonoIO::Write(intptr,byte[],int,int,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_Write,
3548         "System.IO.MonoIO::Seek(intptr,long,System.IO.SeekOrigin,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_Seek,
3549         "System.IO.MonoIO::GetLength(intptr,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_GetLength,
3550         "System.IO.MonoIO::SetLength(intptr,long,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_SetLength,
3551         "System.IO.MonoIO::SetFileTime(intptr,long,long,long,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_SetFileTime,
3552         "System.IO.MonoIO::Flush(intptr,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_Flush,
3553         "System.IO.MonoIO::get_ConsoleOutput", ves_icall_System_IO_MonoIO_get_ConsoleOutput,
3554         "System.IO.MonoIO::get_ConsoleInput", ves_icall_System_IO_MonoIO_get_ConsoleInput,
3555         "System.IO.MonoIO::get_ConsoleError", ves_icall_System_IO_MonoIO_get_ConsoleError,
3556         "System.IO.MonoIO::CreatePipe(intptr&,intptr&)", ves_icall_System_IO_MonoIO_CreatePipe,
3557         "System.IO.MonoIO::get_VolumeSeparatorChar", ves_icall_System_IO_MonoIO_get_VolumeSeparatorChar,
3558         "System.IO.MonoIO::get_DirectorySeparatorChar", ves_icall_System_IO_MonoIO_get_DirectorySeparatorChar,
3559         "System.IO.MonoIO::get_AltDirectorySeparatorChar", ves_icall_System_IO_MonoIO_get_AltDirectorySeparatorChar,
3560         "System.IO.MonoIO::get_PathSeparator", ves_icall_System_IO_MonoIO_get_PathSeparator,
3561         "System.IO.MonoIO::get_InvalidPathChars", ves_icall_System_IO_MonoIO_get_InvalidPathChars,
3562
3563         /*
3564          * System.Math
3565          */
3566         "System.Math::Sin", ves_icall_System_Math_Sin,
3567         "System.Math::Cos", ves_icall_System_Math_Cos,
3568         "System.Math::Tan", ves_icall_System_Math_Tan,
3569         "System.Math::Sinh", ves_icall_System_Math_Sinh,
3570         "System.Math::Cosh", ves_icall_System_Math_Cosh,
3571         "System.Math::Tanh", ves_icall_System_Math_Tanh,
3572         "System.Math::Acos", ves_icall_System_Math_Acos,
3573         "System.Math::Asin", ves_icall_System_Math_Asin,
3574         "System.Math::Atan", ves_icall_System_Math_Atan,
3575         "System.Math::Atan2", ves_icall_System_Math_Atan2,
3576         "System.Math::Exp", ves_icall_System_Math_Exp,
3577         "System.Math::Log", ves_icall_System_Math_Log,
3578         "System.Math::Log10", ves_icall_System_Math_Log10,
3579         "System.Math::Pow", ves_icall_System_Math_Pow,
3580         "System.Math::Sqrt", ves_icall_System_Math_Sqrt,
3581
3582         /*
3583          * System.Environment
3584          */
3585         "System.Environment::get_MachineName", ves_icall_System_Environment_get_MachineName,
3586         "System.Environment::get_NewLine", ves_icall_System_Environment_get_NewLine,
3587         "System.Environment::GetEnvironmentVariable", ves_icall_System_Environment_GetEnvironmentVariable,
3588         "System.Environment::GetEnvironmentVariableNames", ves_icall_System_Environment_GetEnvironmentVariableNames,
3589         "System.Environment::GetCommandLineArgs", mono_runtime_get_main_args,
3590         "System.Environment::get_TickCount", ves_icall_System_Environment_get_TickCount,
3591         "System.Environment::Exit", ves_icall_System_Environment_Exit,
3592         "System.Environment::get_Platform", ves_icall_System_Environment_get_Platform,
3593         "System.Environment::get_ExitCode", mono_environment_exitcode_get,
3594         "System.Environment::set_ExitCode", mono_environment_exitcode_set,
3595
3596         /*
3597          * System.Runtime.Remoting
3598          */     
3599         "System.Runtime.Remoting.RemotingServices::InternalExecute",
3600         ves_icall_InternalExecute,
3601         "System.Runtime.Remoting.RemotingServices::IsTransparentProxy",
3602         ves_icall_IsTransparentProxy,
3603
3604         /*
3605          * System.Runtime.Remoting.Messaging
3606          */     
3607         "System.Runtime.Remoting.Messaging.MonoMethodMessage::InitMessage",
3608         ves_icall_MonoMethodMessage_InitMessage,
3609         
3610         /*
3611          * System.Runtime.Remoting.Proxies
3612          */     
3613         "System.Runtime.Remoting.Proxies.RealProxy::InternalGetTransparentProxy", 
3614         ves_icall_Remoting_RealProxy_GetTransparentProxy,
3615
3616         /*
3617          * System.Threading.Interlocked
3618          */
3619         "System.Threading.Interlocked::Increment(int&)", ves_icall_System_Threading_Interlocked_Increment_Int,
3620         "System.Threading.Interlocked::Increment(long&)", ves_icall_System_Threading_Interlocked_Increment_Long,
3621         "System.Threading.Interlocked::Decrement(int&)", ves_icall_System_Threading_Interlocked_Decrement_Int,
3622         "System.Threading.Interlocked::Decrement(long&)", ves_icall_System_Threading_Interlocked_Decrement_Long,
3623         "System.Threading.Interlocked::CompareExchange(int&,int,int)", ves_icall_System_Threading_Interlocked_CompareExchange_Int,
3624         "System.Threading.Interlocked::CompareExchange(object&,object,object)", ves_icall_System_Threading_Interlocked_CompareExchange_Object,
3625         "System.Threading.Interlocked::CompareExchange(single&,single,single)", ves_icall_System_Threading_Interlocked_CompareExchange_Single,
3626         "System.Threading.Interlocked::Exchange(int&,int)", ves_icall_System_Threading_Interlocked_Exchange_Int,
3627         "System.Threading.Interlocked::Exchange(object&,object)", ves_icall_System_Threading_Interlocked_Exchange_Object,
3628         "System.Threading.Interlocked::Exchange(single&,single)", ves_icall_System_Threading_Interlocked_Exchange_Single,
3629
3630         /*
3631          * System.Diagnostics.Process
3632          */
3633         "System.Diagnostics.Process::GetProcess_internal(int)", ves_icall_System_Diagnostics_Process_GetProcess_internal,
3634         "System.Diagnostics.Process::GetProcesses_internal()", ves_icall_System_Diagnostics_Process_GetProcesses_internal,
3635         "System.Diagnostics.Process::GetPid_internal()", ves_icall_System_Diagnostics_Process_GetPid_internal,
3636         "System.Diagnostics.Process::Process_free_internal(intptr)", ves_icall_System_Diagnostics_Process_Process_free_internal,
3637         "System.Diagnostics.Process::GetModules_internal()", ves_icall_System_Diagnostics_Process_GetModules_internal,
3638         "System.Diagnostics.Process::Start_internal(string,string,intptr,intptr,intptr,ProcInfo&)", ves_icall_System_Diagnostics_Process_Start_internal,
3639         "System.Diagnostics.Process::WaitForExit_internal(intptr,int)", ves_icall_System_Diagnostics_Process_WaitForExit_internal,
3640         "System.Diagnostics.Process::ExitTime_internal(intptr)", ves_icall_System_Diagnostics_Process_ExitTime_internal,
3641         "System.Diagnostics.Process::StartTime_internal(intptr)", ves_icall_System_Diagnostics_Process_StartTime_internal,
3642         "System.Diagnostics.Process::ExitCode_internal(intptr)", ves_icall_System_Diagnostics_Process_ExitCode_internal,
3643         "System.Diagnostics.Process::ProcessName_internal(intptr)", ves_icall_System_Diagnostics_Process_ProcessName_internal,
3644         "System.Diagnostics.Process::GetWorkingSet_internal(intptr,int&,int&)", ves_icall_System_Diagnostics_Process_GetWorkingSet_internal,
3645         "System.Diagnostics.Process::SetWorkingSet_internal(intptr,int,int,bool)", ves_icall_System_Diagnostics_Process_SetWorkingSet_internal,
3646         "System.Diagnostics.FileVersionInfo::GetVersionInfo_internal(string)", ves_icall_System_Diagnostics_FileVersionInfo_GetVersionInfo_internal,
3647
3648         /* 
3649          * System.Delegate
3650          */
3651         "System.Delegate::CreateDelegate_internal", ves_icall_System_Delegate_CreateDelegate_internal,
3652
3653         /* 
3654          * System.Runtime.Serialization
3655          */
3656         "System.Runtime.Serialization.FormatterServices::GetUninitializedObjectInternal",
3657         ves_icall_System_Runtime_Serialization_FormatterServices_GetUninitializedObject_Internal,
3658
3659         /*
3660          * System.IO.Path
3661          */
3662         "System.IO.Path::get_temp_path", ves_icall_System_IO_get_temp_path,
3663
3664         /*
3665          * Private icalls for the Mono Debugger
3666          */
3667         "System.Reflection.Assembly::MonoDebugger_GetMethod",
3668         ves_icall_MonoDebugger_GetMethod,
3669
3670         "System.Reflection.Assembly::MonoDebugger_GetLocalTypeFromSignature",
3671         ves_icall_MonoDebugger_GetLocalTypeFromSignature,
3672
3673         "System.Reflection.Assembly::MonoDebugger_GetType",
3674         ves_icall_MonoDebugger_GetType,
3675
3676         /*
3677          * System.Configuration
3678          */
3679         "System.Configuration.DefaultConfig::get_machine_config_path",
3680         ves_icall_System_Configuration_DefaultConfig_get_machine_config_path,
3681
3682         /*
3683          * System.Diagnostics.DefaultTraceListener
3684          */
3685         "System.Diagnostics.DefaultTraceListener::WriteWindowsDebugString",
3686         ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString,
3687         /*
3688          * System.Activator
3689          */
3690         "System.Activator::CreateInstanceInternal",
3691         ves_icall_System_Activator_CreateInstanceInternal,
3692
3693         /*
3694          * add other internal calls here
3695          */
3696         NULL, NULL
3697 };
3698
3699 void
3700 mono_init_icall (void)
3701 {
3702         const char *name;
3703         int i = 0;
3704
3705         while ((name = icall_map [i])) {
3706                 mono_add_internal_call (name, icall_map [i+1]);
3707                 i += 2;
3708         }
3709        
3710 }
3711
3712