755147b3faa5b7cf8446425161761843a05bb274
[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/gc.h>
35 #include <mono/metadata/rand.h>
36 #include <mono/metadata/sysmath.h>
37 #include <mono/metadata/debug-symfile.h>
38 #include <mono/metadata/string-icalls.h>
39 #include <mono/io-layer/io-layer.h>
40 #include <mono/utils/strtod.h>
41
42 #if defined (PLATFORM_WIN32)
43 #include <windows.h>
44 #endif
45 #include "decimal.h"
46
47 static MonoString *
48 mono_double_ToStringImpl (double value)
49 {
50         /* FIXME: Handle formats, etc. */
51         const gchar *retVal;
52         retVal = g_strdup_printf ("%g", value);
53         return mono_string_new (mono_domain_get (), retVal);
54 }
55
56 /*
57  * We expect a pointer to a char, not a string
58  */
59 static double
60 mono_double_ParseImpl (char *ptr)
61 {
62         return bsd_strtod (ptr, NULL);
63 }
64
65 static MonoString *
66 mono_float_ToStringImpl (float value)
67 {
68         /* FIXME: Handle formats, etc. */
69         const gchar *retVal;
70         retVal = g_strdup_printf ("%f", value);
71         return mono_string_new (mono_domain_get (), retVal);
72 }
73
74 static MonoObject *
75 ves_icall_System_Array_GetValueImpl (MonoObject *this, guint32 pos)
76 {
77         MonoClass *ac;
78         MonoArray *ao;
79         gint32 esize;
80         gpointer *ea;
81
82         ao = (MonoArray *)this;
83         ac = (MonoClass *)ao->obj.vtable->klass;
84
85         esize = mono_array_element_size (ac);
86         ea = (gpointer*)((char*)ao->vector + (pos * esize));
87
88         if (ac->element_class->valuetype)
89                 return mono_value_box (this->vtable->domain, ac->element_class, ea);
90         else
91                 return *ea;
92 }
93
94 static MonoObject *
95 ves_icall_System_Array_GetValue (MonoObject *this, MonoObject *idxs)
96 {
97         MonoClass *ac, *ic;
98         MonoArray *ao, *io;
99         gint32 i, pos, *ind;
100
101         MONO_CHECK_ARG_NULL (idxs);
102
103         io = (MonoArray *)idxs;
104         ic = (MonoClass *)io->obj.vtable->klass;
105         
106         ao = (MonoArray *)this;
107         ac = (MonoClass *)ao->obj.vtable->klass;
108
109         g_assert (ic->rank == 1);
110         if (io->bounds != NULL || io->max_length !=  ac->rank)
111                 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
112
113         ind = (guint32 *)io->vector;
114
115         if (ao->bounds == NULL) {
116                 if (*ind < 0 || *ind >= ao->max_length)
117                         mono_raise_exception (mono_get_exception_index_out_of_range ());
118
119                 return ves_icall_System_Array_GetValueImpl (this, *ind);
120         }
121         
122         for (i = 0; i < ac->rank; i++)
123                 if ((ind [i] < ao->bounds [i].lower_bound) ||
124                     (ind [i] >= ao->bounds [i].length + ao->bounds [i].lower_bound))
125                         mono_raise_exception (mono_get_exception_index_out_of_range ());
126
127         pos = ind [0] - ao->bounds [0].lower_bound;
128         for (i = 1; i < ac->rank; i++)
129                 pos = pos*ao->bounds [i].length + ind [i] - 
130                         ao->bounds [i].lower_bound;
131
132         return ves_icall_System_Array_GetValueImpl (this, pos);
133 }
134
135 static void
136 ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32 pos)
137 {
138         MonoClass *ac, *vc, *ec;
139         gint32 esize, vsize;
140         gpointer *ea, *va;
141
142         guint64 u64;
143         gint64 i64;
144         gdouble r64;
145
146         if (value)
147                 vc = value->vtable->klass;
148         else
149                 vc = NULL;
150
151         ac = this->obj.vtable->klass;
152         ec = ac->element_class;
153
154         esize = mono_array_element_size (ac);
155         ea = (gpointer*)((char*)this->vector + (pos * esize));
156         va = (gpointer*)((char*)value + sizeof (MonoObject));
157
158         if (!value) {
159                 memset (ea, 0,  esize);
160                 return;
161         }
162
163 #define NO_WIDENING_CONVERSION G_STMT_START{\
164         mono_raise_exception (mono_get_exception_argument ( \
165                 "value", "not a widening conversion")); \
166 }G_STMT_END
167
168 #define CHECK_WIDENING_CONVERSION(extra) G_STMT_START{\
169         if (esize < vsize + ## extra) \
170                 mono_raise_exception (mono_get_exception_argument ( \
171                         "value", "not a widening conversion")); \
172 }G_STMT_END
173
174 #define INVALID_CAST G_STMT_START{\
175         mono_raise_exception (mono_get_exception_invalid_cast ()); \
176 }G_STMT_END
177
178         /* Check element (destination) type. */
179         switch (ec->byval_arg.type) {
180         case MONO_TYPE_STRING:
181                 switch (vc->byval_arg.type) {
182                 case MONO_TYPE_STRING:
183                         break;
184                 default:
185                         INVALID_CAST;
186                 }
187                 break;
188         case MONO_TYPE_BOOLEAN:
189                 switch (vc->byval_arg.type) {
190                 case MONO_TYPE_BOOLEAN:
191                         break;
192                 case MONO_TYPE_CHAR:
193                 case MONO_TYPE_U1:
194                 case MONO_TYPE_U2:
195                 case MONO_TYPE_U4:
196                 case MONO_TYPE_U8:
197                 case MONO_TYPE_I1:
198                 case MONO_TYPE_I2:
199                 case MONO_TYPE_I4:
200                 case MONO_TYPE_I8:
201                 case MONO_TYPE_R4:
202                 case MONO_TYPE_R8:
203                         NO_WIDENING_CONVERSION;
204                 default:
205                         INVALID_CAST;
206                 }
207                 break;
208         }
209
210         if (!ec->valuetype) {
211                 *ea = (gpointer)value;
212                 return;
213         }
214
215         if (mono_object_isinst (value, ec)) {
216                 memcpy (ea, (char *)value + sizeof (MonoObject), esize);
217                 return;
218         }
219
220         if (!vc->valuetype)
221                 INVALID_CAST;
222
223         vsize = mono_class_instance_size (vc) - sizeof (MonoObject);
224
225 #if 0
226         g_message (G_STRLOC ": %d (%d) <= %d (%d)",
227                    ec->byval_arg.type, esize,
228                    vc->byval_arg.type, vsize);
229 #endif
230
231 #define ASSIGN_UNSIGNED(etype) G_STMT_START{\
232         switch (vc->byval_arg.type) { \
233         case MONO_TYPE_U1: \
234         case MONO_TYPE_U2: \
235         case MONO_TYPE_U4: \
236         case MONO_TYPE_U8: \
237         case MONO_TYPE_CHAR: \
238                 CHECK_WIDENING_CONVERSION(0); \
239                 *(## etype *) ea = (## etype) u64; \
240                 return; \
241         /* You can't assign a signed value to an unsigned array. */ \
242         case MONO_TYPE_I1: \
243         case MONO_TYPE_I2: \
244         case MONO_TYPE_I4: \
245         case MONO_TYPE_I8: \
246         /* You can't assign a floating point number to an integer array. */ \
247         case MONO_TYPE_R4: \
248         case MONO_TYPE_R8: \
249                 NO_WIDENING_CONVERSION; \
250         } \
251 }G_STMT_END
252
253 #define ASSIGN_SIGNED(etype) G_STMT_START{\
254         switch (vc->byval_arg.type) { \
255         case MONO_TYPE_I1: \
256         case MONO_TYPE_I2: \
257         case MONO_TYPE_I4: \
258         case MONO_TYPE_I8: \
259                 CHECK_WIDENING_CONVERSION(0); \
260                 *(## etype *) ea = (## etype) i64; \
261                 return; \
262         /* You can assign an unsigned value to a signed array if the array's */ \
263         /* element size is larger than the value size. */ \
264         case MONO_TYPE_U1: \
265         case MONO_TYPE_U2: \
266         case MONO_TYPE_U4: \
267         case MONO_TYPE_U8: \
268         case MONO_TYPE_CHAR: \
269                 CHECK_WIDENING_CONVERSION(1); \
270                 *(## etype *) ea = (## etype) u64; \
271                 return; \
272         /* You can't assign a floating point number to an integer array. */ \
273         case MONO_TYPE_R4: \
274         case MONO_TYPE_R8: \
275                 NO_WIDENING_CONVERSION; \
276         } \
277 }G_STMT_END
278
279 #define ASSIGN_REAL(etype) G_STMT_START{\
280         switch (vc->byval_arg.type) { \
281         case MONO_TYPE_R4: \
282         case MONO_TYPE_R8: \
283                 CHECK_WIDENING_CONVERSION(0); \
284                 *(## etype *) ea = (## etype) r64; \
285                 return; \
286         /* All integer values fit into a floating point array, so we don't */ \
287         /* need to CHECK_WIDENING_CONVERSION here. */ \
288         case MONO_TYPE_I1: \
289         case MONO_TYPE_I2: \
290         case MONO_TYPE_I4: \
291         case MONO_TYPE_I8: \
292                 *(## etype *) ea = (## etype) i64; \
293                 return; \
294         case MONO_TYPE_U1: \
295         case MONO_TYPE_U2: \
296         case MONO_TYPE_U4: \
297         case MONO_TYPE_U8: \
298         case MONO_TYPE_CHAR: \
299                 *(## etype *) ea = (## etype) u64; \
300                 return; \
301         } \
302 }G_STMT_END
303
304         switch (vc->byval_arg.type) {
305         case MONO_TYPE_U1:
306                 u64 = *(guint8 *) va;
307                 break;
308         case MONO_TYPE_U2:
309                 u64 = *(guint16 *) va;
310                 break;
311         case MONO_TYPE_U4:
312                 u64 = *(guint32 *) va;
313                 break;
314         case MONO_TYPE_U8:
315                 u64 = *(guint64 *) va;
316                 break;
317         case MONO_TYPE_I1:
318                 i64 = *(gint8 *) va;
319                 break;
320         case MONO_TYPE_I2:
321                 i64 = *(gint16 *) va;
322                 break;
323         case MONO_TYPE_I4:
324                 i64 = *(gint32 *) va;
325                 break;
326         case MONO_TYPE_I8:
327                 i64 = *(gint64 *) va;
328                 break;
329         case MONO_TYPE_R4:
330                 r64 = *(gfloat *) va;
331                 break;
332         case MONO_TYPE_R8:
333                 r64 = *(gdouble *) va;
334                 break;
335         case MONO_TYPE_CHAR:
336                 u64 = *(guint16 *) va;
337                 break;
338         case MONO_TYPE_BOOLEAN:
339                 /* Boolean is only compatible with itself. */
340                 switch (ec->byval_arg.type) {
341                 case MONO_TYPE_CHAR:
342                 case MONO_TYPE_U1:
343                 case MONO_TYPE_U2:
344                 case MONO_TYPE_U4:
345                 case MONO_TYPE_U8:
346                 case MONO_TYPE_I1:
347                 case MONO_TYPE_I2:
348                 case MONO_TYPE_I4:
349                 case MONO_TYPE_I8:
350                 case MONO_TYPE_R4:
351                 case MONO_TYPE_R8:
352                         NO_WIDENING_CONVERSION;
353                 default:
354                         INVALID_CAST;
355                 }
356                 break;
357         }
358
359         /* If we can't do a direct copy, let's try a widening conversion. */
360         switch (ec->byval_arg.type) {
361         case MONO_TYPE_CHAR:
362                 ASSIGN_UNSIGNED (guint16);
363         case MONO_TYPE_U1:
364                 ASSIGN_UNSIGNED (guint8);
365         case MONO_TYPE_U2:
366                 ASSIGN_UNSIGNED (guint16);
367         case MONO_TYPE_U4:
368                 ASSIGN_UNSIGNED (guint32);
369         case MONO_TYPE_U8:
370                 ASSIGN_UNSIGNED (guint64);
371         case MONO_TYPE_I1:
372                 ASSIGN_SIGNED (gint8);
373         case MONO_TYPE_I2:
374                 ASSIGN_SIGNED (gint16);
375         case MONO_TYPE_I4:
376                 ASSIGN_SIGNED (gint32);
377         case MONO_TYPE_I8:
378                 ASSIGN_SIGNED (gint64);
379         case MONO_TYPE_R4:
380                 ASSIGN_REAL (gfloat);
381         case MONO_TYPE_R8:
382                 ASSIGN_REAL (gdouble);
383         }
384
385         INVALID_CAST;
386         /* Not reached, INVALID_CAST does not return. Just to avoid a compiler warning ... */
387         return;
388
389 #undef INVALID_CAST
390 #undef NO_WIDENING_CONVERSION
391 #undef CHECK_WIDENING_CONVERSION
392 #undef ASSIGN_UNSIGNED
393 #undef ASSIGN_SIGNED
394 #undef ASSIGN_REAL
395 }
396
397 static void 
398 ves_icall_System_Array_SetValue (MonoArray *this, MonoObject *value,
399                                  MonoArray *idxs)
400 {
401         MonoClass *ac, *ic;
402         gint32 i, pos, *ind;
403
404         MONO_CHECK_ARG_NULL (idxs);
405
406         ic = idxs->obj.vtable->klass;
407         ac = this->obj.vtable->klass;
408
409         g_assert (ic->rank == 1);
410         if (idxs->bounds != NULL || idxs->max_length != ac->rank)
411                 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
412
413         ind = (guint32 *)idxs->vector;
414
415         if (this->bounds == NULL) {
416                 if (*ind < 0 || *ind >= this->max_length)
417                         mono_raise_exception (mono_get_exception_index_out_of_range ());
418
419                 ves_icall_System_Array_SetValueImpl (this, value, *ind);
420                 return;
421         }
422         
423         for (i = 0; i < ac->rank; i++)
424                 if ((ind [i] < this->bounds [i].lower_bound) ||
425                     (ind [i] >= this->bounds [i].length + this->bounds [i].lower_bound))
426                         mono_raise_exception (mono_get_exception_index_out_of_range ());
427
428         pos = ind [0] - this->bounds [0].lower_bound;
429         for (i = 1; i < ac->rank; i++)
430                 pos = pos * this->bounds [i].length + ind [i] - 
431                         this->bounds [i].lower_bound;
432
433         ves_icall_System_Array_SetValueImpl (this, value, pos);
434 }
435
436 static MonoArray *
437 ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
438 {
439         MonoClass *aklass;
440         MonoArray *array;
441         gint32 *sizes, i;
442
443         MONO_CHECK_ARG_NULL (type);
444         MONO_CHECK_ARG_NULL (lengths);
445
446         MONO_CHECK_ARG (lengths, mono_array_length (lengths) > 0);
447         if (bounds)
448                 MONO_CHECK_ARG (bounds, mono_array_length (lengths) == mono_array_length (bounds));
449
450         for (i = 0; i < mono_array_length (lengths); i++)
451                 if (mono_array_get (lengths, gint32, i) < 0)
452                         mono_raise_exception (mono_get_exception_argument_out_of_range (NULL));
453
454         aklass = mono_array_class_get (type->type, mono_array_length (lengths));
455
456         sizes = alloca (aklass->rank * sizeof(guint32) * 2);
457         for (i = 0; i < aklass->rank; ++i) {
458                 sizes [i] = mono_array_get (lengths, gint32, i);
459                 if (bounds)
460                         sizes [i + aklass->rank] = mono_array_get (bounds, gint32, i);
461                 else
462                         sizes [i + aklass->rank] = 0;
463         }
464
465         array = mono_array_new_full (mono_domain_get (), aklass, sizes, sizes + aklass->rank);
466
467         return array;
468 }
469
470 static gint32 
471 ves_icall_System_Array_GetRank (MonoObject *this)
472 {
473         return this->vtable->klass->rank;
474 }
475
476 static gint32
477 ves_icall_System_Array_GetLength (MonoArray *this, gint32 dimension)
478 {
479         gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
480         if ((dimension < 0) || (dimension >= rank))
481                 mono_raise_exception (mono_get_exception_index_out_of_range ());
482         
483         if (this->bounds == NULL)
484                 return this->max_length;
485         
486         return this->bounds [dimension].length;
487 }
488
489 static gint32
490 ves_icall_System_Array_GetLowerBound (MonoArray *this, gint32 dimension)
491 {
492         gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
493         if ((dimension < 0) || (dimension >= rank))
494                 mono_raise_exception (mono_get_exception_index_out_of_range ());
495         
496         if (this->bounds == NULL)
497                 return 0;
498         
499         return this->bounds [dimension].lower_bound;
500 }
501
502 static void
503 ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* dest, int dest_idx, int length)
504 {
505         int element_size = mono_array_element_size (source->obj.vtable->klass);
506         void * dest_addr = mono_array_addr_with_size (dest, element_size, dest_idx);
507         void * source_addr = mono_array_addr_with_size (source, element_size, source_idx);
508
509         g_assert (dest_idx + length <= mono_array_length (dest));
510         g_assert (source_idx + length <= mono_array_length (source));
511         memmove (dest_addr, source_addr, element_size * length);
512 }
513
514 static void
515 ves_icall_InitializeArray (MonoArray *array, MonoClassField *field_handle)
516 {
517         MonoClass *klass = array->obj.vtable->klass;
518         guint32 size = mono_array_element_size (klass);
519         int i;
520
521         if (array->bounds == NULL)
522                 size *= array->max_length;
523         else
524                 for (i = 0; i < klass->rank; ++i) 
525                         size *= array->bounds [i].length;
526
527         memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
528
529 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
530 #define SWAP(n) {\
531         gint i; \
532         guint ## n tmp; \
533         guint ## n *data = (guint ## n *) mono_array_addr (array, char, 0); \
534 \
535         for (i = 0; i < size; i += n/8, data++) { \
536                 tmp = read ## n (data); \
537                 *data = tmp; \
538         } \
539 }
540
541         /* printf ("Initialize array with elements of %s type\n", klass->element_class->name); */
542
543         switch (klass->element_class->byval_arg.type) {
544         case MONO_TYPE_CHAR:
545         case MONO_TYPE_I2:
546         case MONO_TYPE_U2:
547                 SWAP (16);
548                 break;
549         case MONO_TYPE_I4:
550         case MONO_TYPE_U4:
551                 SWAP (32);
552                 break;
553         case MONO_TYPE_I8:
554         case MONO_TYPE_U8:
555                 SWAP (64);
556                 break;
557         }
558                  
559 #endif
560 }
561
562 static MonoObject *
563 ves_icall_System_Object_MemberwiseClone (MonoObject *this)
564 {
565         return mono_object_clone (this);
566 }
567
568 #if HAVE_BOEHM_GC
569 #define MONO_OBJECT_ALIGNMENT_SHIFT     3
570 #else
571 #define MONO_OBJECT_ALIGNMENT_SHIFT     2
572 #endif
573
574 /*
575  * Return hashcode based on object address. This function will need to be
576  * smarter in the presence of a moving garbage collector, which will cache
577  * the address hash before relocating the object.
578  *
579  * Wang's address-based hash function:
580  *   http://www.concentric.net/~Ttwang/tech/addrhash.htm
581  */
582 static gint32
583 ves_icall_System_Object_GetHashCode (MonoObject *this)
584 {
585         register guint32 key;
586         key = (GPOINTER_TO_UINT (this) >> MONO_OBJECT_ALIGNMENT_SHIFT) * 2654435761u;
587
588         return key & 0x7fffffff;
589 }
590
591 /*
592  * A hash function for value types. I have no idea if this is a good hash 
593  * function (its similar to g_str_hash).
594  */
595 static gint32
596 ves_icall_System_ValueType_GetHashCode (MonoObject *this)
597 {
598         gint32 i, size;
599         const char *p;
600         guint h = 0;
601
602         MONO_CHECK_ARG_NULL (this);
603
604         size = this->vtable->klass->instance_size - sizeof (MonoObject);
605
606         p = (const char *)this + sizeof (MonoObject);
607
608         for (i = 0; i < size; i++) {
609                 h = (h << 5) - h + *p;
610                 p++;
611         }
612
613         return h;
614 }
615
616 static MonoBoolean
617 ves_icall_System_ValueType_Equals (MonoObject *this, MonoObject *that)
618 {
619         gint32 size;
620         const char *p, *s;
621
622         MONO_CHECK_ARG_NULL (that);
623
624         if (this->vtable != that->vtable)
625                 return FALSE;
626
627         size = this->vtable->klass->instance_size - sizeof (MonoObject);
628
629         p = (const char *)this + sizeof (MonoObject);
630         s = (const char *)that + sizeof (MonoObject);
631
632         return memcmp (p, s, size)? FALSE: TRUE;
633 }
634
635 static MonoReflectionType *
636 ves_icall_System_Object_GetType (MonoObject *obj)
637 {
638         return mono_type_get_object (mono_domain_get (), &obj->vtable->klass->byval_arg);
639 }
640
641 static void
642 mono_type_type_from_obj (MonoReflectionType *mtype, MonoObject *obj)
643 {
644         mtype->type = &obj->vtable->klass->byval_arg;
645         g_assert (mtype->type->type);
646 }
647
648 static gint32
649 ves_icall_AssemblyBuilder_getToken (MonoReflectionAssemblyBuilder *assb, MonoObject *obj)
650 {
651         return mono_image_create_token (assb->dynamic_assembly, obj);
652 }
653
654 static gint32
655 ves_icall_AssemblyBuilder_getPEHeader (MonoReflectionAssemblyBuilder *assb, MonoArray *buf, gint32 *data_size)
656 {
657         int count, hsize;
658         MonoDynamicAssembly *ass = assb->dynamic_assembly;
659
660         hsize = mono_image_get_header (assb, (char*)buf->vector, mono_array_length (buf));
661         if (hsize < 0)
662                 return hsize;
663         count = ass->code.index + ass->meta_size;
664         count += 512 - 1;
665         count &= ~(512 - 1);
666         *data_size = count;
667
668         return hsize;
669 }
670
671 static gint32
672 ves_icall_AssemblyBuilder_getDataChunk (MonoReflectionAssemblyBuilder *assb, MonoArray *buf)
673 {
674         int count, real_data;
675         MonoDynamicAssembly *ass = assb->dynamic_assembly;
676         char *p = mono_array_addr (buf, char, 0);
677         
678         count = real_data = ass->code.index + ass->meta_size;
679         count += 512 - 1;
680         count &= ~(512 - 1);
681         if (count > mono_array_length (buf))
682                 return -1;
683         count -= real_data;
684         
685         memcpy (p, ass->code.data, ass->code.index);
686         p += ass->code.index;
687         memcpy (p, ass->assembly.image->raw_metadata, ass->meta_size);
688         p += ass->meta_size;
689         /* null-pad section */
690         memset (p, 0, count);
691
692         return real_data + count;
693 }
694
695 static MonoReflectionType*
696 ves_icall_type_from_name (MonoString *name)
697 {
698         MonoDomain *domain = mono_domain_get (); 
699         MonoType *type;
700         MonoImage *image;
701         MonoTypeNameParse info;
702         gchar *str;
703         
704         str = mono_string_to_utf8 (name);
705         /*g_print ("requested type %s\n", str);*/
706         if (!mono_reflection_parse_type (str, &info)) {
707                 g_free (str);
708                 g_list_free (info.modifiers);
709                 return NULL;
710         }
711
712         if (info.assembly) {
713                 image = mono_image_loaded (info.assembly);
714                 /* do we need to load if it's not already loaded? */
715                 if (!image) {
716                         g_free (str);
717                         g_list_free (info.modifiers);
718                         return NULL;
719                 }
720         } else
721                 image = mono_defaults.corlib;
722
723         type = mono_reflection_get_type (image, &info, FALSE);
724         g_free (str);
725         g_list_free (info.modifiers);
726         if (!type)
727                 return NULL;
728         /*g_print ("got it\n");*/
729         return mono_type_get_object (domain, type);
730 }
731
732 static MonoReflectionType*
733 ves_icall_type_from_handle (MonoType *handle)
734 {
735         MonoDomain *domain = mono_domain_get (); 
736         MonoClass *klass = mono_class_from_mono_type (handle);
737
738         mono_class_init (klass);
739         return mono_type_get_object (domain, handle);
740 }
741
742 static guint32
743 ves_icall_type_Equals (MonoReflectionType *type, MonoReflectionType *c)
744 {
745         if (type->type && c->type)
746                 return mono_metadata_type_equal (type->type, c->type);
747         g_print ("type equals\n");
748         return 0;
749 }
750
751 static guint32
752 ves_icall_type_is_subtype_of (MonoReflectionType *type, MonoReflectionType *c, MonoBoolean check_interfaces)
753 {
754         MonoDomain *domain; 
755         MonoClass *klass;
756         MonoClass *klassc;
757
758         g_assert (type != NULL);
759         
760         domain = ((MonoObject *)type)->vtable->domain;
761
762         if (!c) /* FIXME: dont know what do do here */
763                 return 0;
764
765         klass = mono_class_from_mono_type (type->type);
766         klassc = mono_class_from_mono_type (c->type);
767
768         /* cut&paste from mono_object_isinst (): keep in sync */
769         if (check_interfaces && (klassc->flags & TYPE_ATTRIBUTE_INTERFACE) && !(klass->flags & TYPE_ATTRIBUTE_INTERFACE)) {
770                 MonoVTable *klass_vt = mono_class_vtable (domain, klass);
771                 if ((klassc->interface_id <= klass->max_interface_id) &&
772                     klass_vt->interface_offsets [klassc->interface_id])
773                         return 1;
774         } else if (check_interfaces && (klassc->flags & TYPE_ATTRIBUTE_INTERFACE) && (klass->flags & TYPE_ATTRIBUTE_INTERFACE)) {
775                 int i;
776
777                 for (i = 0; i < klass->interface_count; i ++) {
778                         MonoClass *ic =  klass->interfaces [i];
779                         if (ic == klassc)
780                                 return 1;
781                 }
782         } else {
783                 /*
784                  * klass->baseval is 0 for interfaces 
785                  */
786                 if (klass->baseval && ((klass->baseval - klassc->baseval) <= klassc->diffval))
787                         return 1;
788         }
789         return 0;
790 }
791
792 static guint32
793 ves_icall_get_attributes (MonoReflectionType *type)
794 {
795         MonoClass *klass = mono_class_from_mono_type (type->type);
796
797         return klass->flags;
798 }
799
800 static void
801 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
802 {
803         MonoDomain *domain = mono_domain_get (); 
804
805         info->parent = mono_type_get_object (domain, &method->klass->byval_arg);
806         info->ret = mono_type_get_object (domain, method->signature->ret);
807         info->attrs = method->flags;
808         info->implattrs = method->iflags;
809 }
810
811 static MonoArray*
812 ves_icall_get_parameter_info (MonoMethod *method)
813 {
814         MonoDomain *domain = mono_domain_get (); 
815         MonoArray *res;
816         static MonoClass *System_Reflection_ParameterInfo;
817         MonoReflectionParameter** args;
818         int i;
819
820         args = mono_param_get_objects (domain, method);
821         if (!System_Reflection_ParameterInfo)
822                 System_Reflection_ParameterInfo = mono_class_from_name (
823                         mono_defaults.corlib, "System.Reflection", "ParameterInfo");
824         res = mono_array_new (domain, System_Reflection_ParameterInfo, method->signature->param_count);
825         for (i = 0; i < method->signature->param_count; ++i) {
826                 mono_array_set (res, gpointer, i, args [i]);
827         }
828         return res;
829 }
830
831 static void
832 ves_icall_get_field_info (MonoReflectionField *field, MonoFieldInfo *info)
833 {
834         MonoDomain *domain = mono_domain_get (); 
835
836         info->parent = mono_type_get_object (domain, &field->klass->byval_arg);
837         info->type = mono_type_get_object (domain, field->field->type);
838         info->name = mono_string_new (domain, field->field->name);
839         info->attrs = field->field->type->attrs;
840 }
841
842 static MonoObject *
843 ves_icall_MonoField_GetValue (MonoReflectionField *field, MonoObject *obj) {
844         MonoObject *res;
845         MonoClass *klass;
846         MonoType *ftype = field->field->type;
847         int type = ftype->type;
848         char *p, *r;
849         guint32 align;
850
851         mono_class_init (field->klass);
852         if (ftype->attrs & FIELD_ATTRIBUTE_STATIC) {
853                 MonoVTable *vtable;
854                 vtable = mono_class_vtable (mono_domain_get (), field->klass);
855                 p = (char*)(vtable->data) + field->field->offset;
856         } else {
857                 p = (char*)obj + field->field->offset;
858         }
859
860         switch (type) {
861         case MONO_TYPE_OBJECT:
862         case MONO_TYPE_STRING:
863         case MONO_TYPE_SZARRAY:
864         case MONO_TYPE_ARRAY:
865                 return *(MonoObject**)p;
866         }
867         klass = mono_class_from_mono_type (ftype);
868         res = mono_object_new (mono_domain_get (), klass);
869         r = (char*)res + sizeof (MonoObject);
870         memcpy (r, p, mono_class_value_size (klass, &align));
871
872         return res;
873 }
874
875 static void
876 ves_icall_get_property_info (MonoReflectionProperty *property, MonoPropertyInfo *info)
877 {
878         MonoDomain *domain = mono_domain_get (); 
879
880         info->parent = mono_type_get_object (domain, &property->klass->byval_arg);
881         info->name = mono_string_new (domain, property->property->name);
882         info->attrs = property->property->attrs;
883         info->get = property->property->get ? mono_method_get_object (domain, property->property->get): NULL;
884         info->set = property->property->set ? mono_method_get_object (domain, property->property->set): NULL;
885         /* 
886          * There may be other methods defined for properties, though, it seems they are not exposed 
887          * in the reflection API 
888          */
889 }
890
891 static void
892 ves_icall_get_event_info (MonoReflectionEvent *event, MonoEventInfo *info)
893 {
894         MonoDomain *domain = mono_domain_get (); 
895
896         info->parent = mono_type_get_object (domain, &event->klass->byval_arg);
897         info->name = mono_string_new (domain, event->event->name);
898         info->attrs = event->event->attrs;
899         info->add_method = event->event->add ? mono_method_get_object (domain, event->event->add): NULL;
900         info->remove_method = event->event->remove ? mono_method_get_object (domain, event->event->remove): NULL;
901         info->raise_method = event->event->raise ? mono_method_get_object (domain, event->event->raise): NULL;
902 }
903
904 static MonoArray*
905 ves_icall_Type_GetInterfaces (MonoReflectionType* type)
906 {
907         MonoDomain *domain = mono_domain_get (); 
908         MonoArray *intf;
909         int ninterf, i;
910         MonoClass *class = mono_class_from_mono_type (type->type);
911         MonoClass *parent;
912
913         ninterf = 0;
914         for (parent = class; parent; parent = parent->parent) {
915                 ninterf += parent->interface_count;
916         }
917         intf = mono_array_new (domain, mono_defaults.monotype_class, ninterf);
918         ninterf = 0;
919         for (parent = class; parent; parent = parent->parent) {
920                 for (i = 0; i < parent->interface_count; ++i) {
921                         mono_array_set (intf, gpointer, ninterf, mono_type_get_object (domain, &parent->interfaces [i]->byval_arg));
922                         ++ninterf;
923                 }
924         }
925         return intf;
926 }
927
928 static MonoReflectionType*
929 ves_icall_MonoType_GetElementType (MonoReflectionType *type)
930 {
931         MonoClass *class = mono_class_from_mono_type (type->type);
932         if (class->enumtype && class->enum_basetype) /* types that are modifierd typebuilkders may not have enum_basetype set */
933                 return mono_type_get_object (mono_object_domain (type), class->enum_basetype);
934         else if (class->element_class)
935                 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
936         else
937                 return NULL;
938 }
939
940 static void
941 ves_icall_get_type_info (MonoType *type, MonoTypeInfo *info)
942 {
943         MonoDomain *domain = mono_domain_get (); 
944         MonoClass *class = mono_class_from_mono_type (type);
945
946         info->parent = class->parent ? mono_type_get_object (domain, &class->parent->byval_arg): NULL;
947         info->name = mono_string_new (domain, class->name);
948         info->name_space = mono_string_new (domain, class->name_space);
949         info->attrs = class->flags;
950         info->rank = class->rank;
951         info->assembly = mono_assembly_get_object (domain, class->image->assembly);
952         if (class->enumtype && class->enum_basetype) /* types that are modifierd typebuilkders may not have enum_basetype set */
953                 info->etype = mono_type_get_object (domain, class->enum_basetype);
954         else if (class->element_class)
955                 info->etype = mono_type_get_object (domain, &class->element_class->byval_arg);
956         else
957                 info->etype = NULL;
958
959         info->isbyref = type->byref;
960         info->ispointer = type->type == MONO_TYPE_PTR;
961         info->isprimitive = (type->type >= MONO_TYPE_BOOLEAN) && (type->type <= MONO_TYPE_R8);
962 }
963
964 static MonoObject *
965 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoArray *params) 
966 {
967         return mono_runtime_invoke_array (method->method, this, params, NULL);
968 }
969
970 static MonoObject *
971 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this, MonoArray *params, MonoArray **outArgs) 
972 {
973         MonoDomain *domain = mono_domain_get (); 
974         MonoMethod *m = method->method;
975         MonoMethodSignature *sig = m->signature;
976         MonoArray *out_args;
977         MonoObject *result;
978         int i, j, outarg_count = 0;
979
980         if (m->klass == mono_defaults.object_class) {
981
982                 if (!strcmp (m->name, "FieldGetter")) {
983                         MonoClass *k = this->vtable->klass;
984                         MonoString *name = mono_array_get (params, MonoString *, 1);
985                         char *str;
986
987                         str = mono_string_to_utf8 (name);
988                 
989                         for (i = 0; i < k->field.count; i++) {
990                                 if (!strcmp (k->fields [i].name, str)) {
991                                         MonoClass *field_klass =  mono_class_from_mono_type (k->fields [i].type);
992                                         if (field_klass->valuetype)
993                                                 result = mono_value_box (domain, field_klass,
994                                                                          (char *)this + k->fields [i].offset);
995                                         else 
996                                                 result = *((gpointer *)((char *)this + k->fields [i].offset));
997                                 
998                                         g_assert (result);
999                                         out_args = mono_array_new (domain, mono_defaults.object_class, 1);
1000                                         *outArgs = out_args;
1001                                         mono_array_set (out_args, gpointer, 0, result);
1002                                         g_free (str);
1003                                         return NULL;
1004                                 }
1005                         }
1006
1007                         g_free (str);
1008                         g_assert_not_reached ();
1009
1010                 } else if (!strcmp (m->name, "FieldSetter")) {
1011                         MonoClass *k = this->vtable->klass;
1012                         MonoString *name = mono_array_get (params, MonoString *, 1);
1013                         int size, align;
1014                         char *str;
1015
1016                         str = mono_string_to_utf8 (name);
1017                 
1018                         for (i = 0; i < k->field.count; i++) {
1019                                 if (!strcmp (k->fields [i].name, str)) {
1020                                         MonoClass *field_klass =  mono_class_from_mono_type (k->fields [i].type);
1021                                         MonoObject *val = mono_array_get (params, gpointer, 2);
1022
1023                                         if (field_klass->valuetype) {
1024                                                 size = mono_type_size (k->fields [i].type, &align);
1025                                                 memcpy ((char *)this + k->fields [i].offset, 
1026                                                         ((char *)val) + sizeof (MonoObject), size);
1027                                         } else 
1028                                                 *((gpointer *)this + k->fields [i].offset) = val;
1029                                 
1030                                         g_assert (result);
1031                                         g_free (str);
1032                                         return NULL;
1033                                 }
1034                         }
1035
1036                         g_free (str);
1037                         g_assert_not_reached ();
1038
1039                 }
1040         }
1041
1042         for (i = 0; i < mono_array_length (params); i++) {
1043                 if (sig->params [i]->byref) 
1044                         outarg_count++;
1045         }
1046
1047         out_args = mono_array_new (domain, mono_defaults.object_class, outarg_count);
1048         
1049         for (i = 0, j = 0; i < mono_array_length (params); i++) {
1050                 if (sig->params [i]->byref) {
1051                         gpointer arg;
1052                         arg = mono_array_get (params, gpointer, i);
1053                         mono_array_set (out_args, gpointer, j, arg);
1054                         j++;
1055                 }
1056         }
1057
1058         /* fixme: handle constructors? */
1059         if (!strcmp (method->method->name, ".ctor"))
1060                 g_assert_not_reached ();
1061
1062         result = mono_runtime_invoke_array (method->method, this, params, NULL);
1063
1064         *outArgs = out_args;
1065
1066         return result;
1067 }
1068
1069 static MonoObject *
1070 ves_icall_System_Enum_ToObject (MonoReflectionType *type, MonoObject *obj)
1071 {
1072         MonoDomain *domain = mono_domain_get (); 
1073         MonoClass *enumc, *objc;
1074         gint32 s1, s2;
1075         MonoObject *res;
1076         
1077         MONO_CHECK_ARG_NULL (type);
1078         MONO_CHECK_ARG_NULL (obj);
1079
1080         enumc = mono_class_from_mono_type (type->type);
1081         objc = obj->vtable->klass;
1082
1083         MONO_CHECK_ARG (obj, enumc->enumtype == TRUE);
1084         MONO_CHECK_ARG (obj, (objc->enumtype) || (objc->byval_arg.type >= MONO_TYPE_I1 &&
1085                                                   objc->byval_arg.type <= MONO_TYPE_U8));
1086         
1087         s1 = mono_class_value_size (enumc, NULL);
1088         s2 = mono_class_value_size (objc, NULL);
1089
1090         res = mono_object_new (domain, enumc);
1091
1092 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
1093         memcpy ((char *)res + sizeof (MonoObject), (char *)obj + sizeof (MonoObject), MIN (s1, s2));
1094 #else
1095         memcpy ((char *)res + sizeof (MonoObject) + (s1 > s2 ? s1 - s2 : 0),
1096                 (char *)obj + sizeof (MonoObject) + (s2 > s1 ? s2 - s1 : 0),
1097                 MIN (s1, s2));
1098 #endif
1099         return res;
1100 }
1101
1102 static MonoObject *
1103 ves_icall_System_Enum_get_value (MonoObject *this)
1104 {
1105         MonoDomain *domain = mono_domain_get (); 
1106         MonoObject *res;
1107         MonoClass *enumc;
1108         gpointer dst;
1109         gpointer src;
1110         int size;
1111
1112         if (!this)
1113                 return NULL;
1114
1115         g_assert (this->vtable->klass->enumtype);
1116         
1117         enumc = mono_class_from_mono_type (this->vtable->klass->enum_basetype);
1118         res = mono_object_new (domain, enumc);
1119         dst = (char *)res + sizeof (MonoObject);
1120         src = (char *)this + sizeof (MonoObject);
1121         size = mono_class_value_size (enumc, NULL);
1122
1123         memcpy (dst, src, size);
1124
1125         return res;
1126 }
1127
1128 static void
1129 ves_icall_get_enum_info (MonoReflectionType *type, MonoEnumInfo *info)
1130 {
1131         MonoDomain *domain = mono_domain_get (); 
1132         MonoClass *enumc = mono_class_from_mono_type (type->type);
1133         guint i, j, nvalues, crow;
1134         MonoClassField *field;
1135         
1136         info->utype = mono_type_get_object (domain, enumc->enum_basetype);
1137         nvalues = enumc->field.count - 1;
1138         info->names = mono_array_new (domain, mono_defaults.string_class, nvalues);
1139         info->values = mono_array_new (domain, enumc, nvalues);
1140         
1141         for (i = 0, j = 0; i < enumc->field.count; ++i) {
1142                 field = &enumc->fields [i];
1143                 if (strcmp ("value__", field->name) == 0)
1144                         continue;
1145                 mono_array_set (info->names, gpointer, j, mono_string_new (domain, field->name));
1146                 if (!field->data) {
1147                         crow = mono_metadata_get_constant_index (enumc->image, MONO_TOKEN_FIELD_DEF | (i+enumc->field.first+1));
1148                         crow = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_VALUE);
1149                         /* 1 is the length of the blob */
1150                         field->data = 1 + mono_metadata_blob_heap (enumc->image, crow);
1151                 }
1152                 switch (enumc->enum_basetype->type) {
1153                 case MONO_TYPE_U1:
1154                 case MONO_TYPE_I1:
1155                         mono_array_set (info->values, gchar, j, *field->data);
1156                         break;
1157                 case MONO_TYPE_CHAR:
1158                 case MONO_TYPE_U2:
1159                 case MONO_TYPE_I2:
1160                         mono_array_set (info->values, gint16, j, read16 (field->data));
1161                         break;
1162                 case MONO_TYPE_U4:
1163                 case MONO_TYPE_I4:
1164                         mono_array_set (info->values, gint32, j, read32 (field->data));
1165                         break;
1166                 case MONO_TYPE_U8:
1167                 case MONO_TYPE_I8:
1168                         mono_array_set (info->values, gint64, j, read64 (field->data));
1169                         break;
1170                 default:
1171                         g_error ("Implement type 0x%02x in get_enum_info", enumc->enum_basetype->type);
1172                 }
1173                 ++j;
1174         }
1175 }
1176
1177 static MonoMethod*
1178 search_method (MonoReflectionType *type, const char *name, guint32 flags, MonoArray *args)
1179 {
1180         MonoClass *klass, *start_class;
1181         MonoMethod *m;
1182         MonoReflectionType *paramt;
1183         int i, j;
1184
1185         start_class = klass = mono_class_from_mono_type (type->type);
1186         while (klass) {
1187                 for (i = 0; i < klass->method.count; ++i) {
1188                         m = klass->methods [i];
1189                         if (!((m->flags & flags) == flags))
1190                                 continue;
1191                         if (strcmp(m->name, name))
1192                                 continue;
1193                         if (m->signature->param_count != mono_array_length (args))
1194                                 continue;
1195                         for (j = 0; j < m->signature->param_count; ++j) {
1196                                 paramt = mono_array_get (args, MonoReflectionType*, j);
1197                                 if (!mono_metadata_type_equal (paramt->type, m->signature->params [j]))
1198                                         break;
1199                         }
1200                         if (j == m->signature->param_count)
1201                                 return m;
1202                 }
1203                 klass = klass->parent;
1204         }
1205         g_print ("Method %s.%s::%s (%d) not found\n", start_class->name_space, start_class->name, name, mono_array_length (args));
1206         return NULL;
1207 }
1208
1209 static MonoReflectionMethod*
1210 ves_icall_get_constructor (MonoReflectionType *type, MonoArray *args)
1211 {
1212         MonoDomain *domain = mono_domain_get (); 
1213         MonoMethod *m;
1214
1215         m = search_method (type, ".ctor", METHOD_ATTRIBUTE_RT_SPECIAL_NAME, args);
1216         if (m)
1217                 return mono_method_get_object (domain, m);
1218         return NULL;
1219 }
1220
1221 static MonoReflectionMethod*
1222 ves_icall_get_method (MonoReflectionType *type, MonoString *name, MonoArray *args)
1223 {
1224         MonoDomain *domain = mono_domain_get (); 
1225         MonoMethod *m;
1226         char *n = mono_string_to_utf8 (name);
1227
1228         m = search_method (type, n, 0, args);
1229         g_free (n);
1230         if (m)
1231                 return mono_method_get_object (domain, m);
1232         return NULL;
1233 }
1234
1235 static MonoProperty*
1236 search_property (MonoClass *klass, char* name, MonoArray *args) {
1237         int i;
1238         MonoProperty *p;
1239
1240         /* FIXME: handle args */
1241         for (i = 0; i < klass->property.count; ++i) {
1242                 p = &klass->properties [i];
1243                 if (strcmp (p->name, name) == 0)
1244                         return p;
1245         }
1246         return NULL;
1247 }
1248
1249 static MonoReflectionProperty*
1250 ves_icall_get_property (MonoReflectionType *type, MonoString *name, MonoArray *args)
1251 {
1252         MonoDomain *domain = mono_domain_get (); 
1253         MonoProperty *p;
1254         MonoClass *class = mono_class_from_mono_type (type->type);
1255         char *n = mono_string_to_utf8 (name);
1256
1257         p = search_property (class, n, args);
1258         g_free (n);
1259         if (p)
1260                 return mono_property_get_object (domain, class, p);
1261         return NULL;
1262 }
1263
1264 enum {
1265         BFLAGS_IgnoreCase = 1,
1266         BFLAGS_DeclaredOnly = 2,
1267         BFLAGS_Instance = 4,
1268         BFLAGS_Static = 8,
1269         BFLAGS_Public = 0x10,
1270         BFLAGS_NonPublic = 0x20,
1271         BFLAGS_InvokeMethod = 0x100,
1272         BFLAGS_CreateInstance = 0x200,
1273         BFLAGS_GetField = 0x400,
1274         BFLAGS_SetField = 0x800,
1275         BFLAGS_GetProperty = 0x1000,
1276         BFLAGS_SetProperty = 0x2000,
1277         BFLAGS_ExactBinding = 0x10000,
1278         BFLAGS_SuppressChangeType = 0x20000,
1279         BFLAGS_OptionalParamBinding = 0x40000
1280 };
1281
1282 static MonoArray*
1283 ves_icall_Type_GetFields (MonoReflectionType *type, guint32 bflags)
1284 {
1285         MonoDomain *domain; 
1286         GSList *l = NULL, *tmp;
1287         static MonoClass *System_Reflection_FieldInfo;
1288         MonoClass *startklass, *klass;
1289         MonoArray *res;
1290         MonoObject *member;
1291         int i, len, match;
1292         MonoClassField *field;
1293
1294         domain = ((MonoObject *)type)->vtable->domain;
1295         klass = startklass = mono_class_from_mono_type (type->type);
1296
1297 handle_parent:  
1298         for (i = 0; i < klass->field.count; ++i) {
1299                 match = 0;
1300                 field = &klass->fields [i];
1301                 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
1302                         if (bflags & BFLAGS_Public)
1303                                 match++;
1304                 } else {
1305                         if (bflags & BFLAGS_NonPublic)
1306                                 match++;
1307                 }
1308                 if (!match)
1309                         continue;
1310                 match = 0;
1311                 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
1312                         if (bflags & BFLAGS_Static)
1313                                 match++;
1314                 } else {
1315                         if (bflags & BFLAGS_Instance)
1316                                 match++;
1317                 }
1318
1319                 if (!match)
1320                         continue;
1321                 member = (MonoObject*)mono_field_get_object (domain, klass, field);
1322                 l = g_slist_prepend (l, member);
1323         }
1324         if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
1325                 goto handle_parent;
1326         len = g_slist_length (l);
1327         if (!System_Reflection_FieldInfo)
1328                 System_Reflection_FieldInfo = mono_class_from_name (
1329                         mono_defaults.corlib, "System.Reflection", "FieldInfo");
1330         res = mono_array_new (domain, System_Reflection_FieldInfo, len);
1331         i = 0;
1332         tmp = g_slist_reverse (l);
1333         for (; tmp; tmp = tmp->next, ++i)
1334                 mono_array_set (res, gpointer, i, tmp->data);
1335         g_slist_free (l);
1336         return res;
1337 }
1338
1339 static MonoArray*
1340 ves_icall_Type_GetMethods (MonoReflectionType *type, guint32 bflags)
1341 {
1342         MonoDomain *domain; 
1343         GSList *l = NULL, *tmp;
1344         static MonoClass *System_Reflection_MethodInfo;
1345         MonoClass *startklass, *klass;
1346         MonoArray *res;
1347         MonoMethod *method;
1348         MonoObject *member;
1349         int i, len, match;
1350                 
1351         domain = ((MonoObject *)type)->vtable->domain;
1352         klass = startklass = mono_class_from_mono_type (type->type);
1353
1354 handle_parent:
1355         for (i = 0; i < klass->method.count; ++i) {
1356                 match = 0;
1357                 method = klass->methods [i];
1358                 if (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0)
1359                         continue;
1360                 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
1361                         if (bflags & BFLAGS_Public)
1362                                 match++;
1363                 } else {
1364                         if (bflags & BFLAGS_NonPublic)
1365                                 match++;
1366                 }
1367                 if (!match)
1368                         continue;
1369                 match = 0;
1370                 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
1371                         if (bflags & BFLAGS_Static)
1372                                 match++;
1373                 } else {
1374                         if (bflags & BFLAGS_Instance)
1375                                 match++;
1376                 }
1377
1378                 if (!match)
1379                         continue;
1380                 match = 0;
1381                 member = (MonoObject*)mono_method_get_object (domain, method);
1382                         
1383                 l = g_slist_prepend (l, member);
1384         }
1385         if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
1386                 goto handle_parent;
1387         len = g_slist_length (l);
1388         if (!System_Reflection_MethodInfo)
1389                 System_Reflection_MethodInfo = mono_class_from_name (
1390                         mono_defaults.corlib, "System.Reflection", "MethodInfo");
1391         res = mono_array_new (domain, System_Reflection_MethodInfo, len);
1392         i = 0;
1393         tmp = l;
1394         for (; tmp; tmp = tmp->next, ++i)
1395                 mono_array_set (res, gpointer, i, tmp->data);
1396         g_slist_free (l);
1397
1398         return res;
1399 }
1400
1401 static MonoArray*
1402 ves_icall_Type_GetConstructors (MonoReflectionType *type, guint32 bflags)
1403 {
1404         MonoDomain *domain; 
1405         GSList *l = NULL, *tmp;
1406         static MonoClass *System_Reflection_ConstructorInfo;
1407         MonoClass *startklass, *klass;
1408         MonoArray *res;
1409         MonoMethod *method;
1410         MonoObject *member;
1411         int i, len, match;
1412
1413         domain = ((MonoObject *)type)->vtable->domain;
1414         klass = startklass = mono_class_from_mono_type (type->type);
1415
1416 handle_parent:  
1417         for (i = 0; i < klass->method.count; ++i) {
1418                 match = 0;
1419                 method = klass->methods [i];
1420                 if (strcmp (method->name, ".ctor") && strcmp (method->name, ".cctor"))
1421                         continue;
1422                 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
1423                         if (bflags & BFLAGS_Public)
1424                                 match++;
1425                 } else {
1426                         if (bflags & BFLAGS_NonPublic)
1427                                 match++;
1428                 }
1429                 if (!match)
1430                         continue;
1431                 match = 0;
1432                 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
1433                         if (bflags & BFLAGS_Static)
1434                                 match++;
1435                 } else {
1436                         if (bflags & BFLAGS_Instance)
1437                                 match++;
1438                 }
1439
1440                 if (!match)
1441                         continue;
1442                 member = (MonoObject*)mono_method_get_object (domain, method);
1443                         
1444                 l = g_slist_prepend (l, member);
1445         }
1446         if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
1447                 goto handle_parent;
1448         len = g_slist_length (l);
1449         if (!System_Reflection_ConstructorInfo)
1450                 System_Reflection_ConstructorInfo = mono_class_from_name (
1451                         mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
1452         res = mono_array_new (domain, System_Reflection_ConstructorInfo, len);
1453         i = 0;
1454         tmp = l;
1455         for (; tmp; tmp = tmp->next, ++i)
1456                 mono_array_set (res, gpointer, i, tmp->data);
1457         g_slist_free (l);
1458         return res;
1459 }
1460
1461 static MonoArray*
1462 ves_icall_Type_GetProperties (MonoReflectionType *type, guint32 bflags)
1463 {
1464         MonoDomain *domain; 
1465         GSList *l = NULL, *tmp;
1466         static MonoClass *System_Reflection_PropertyInfo;
1467         MonoClass *startklass, *klass;
1468         MonoArray *res;
1469         MonoMethod *method;
1470         MonoProperty *prop;
1471         int i, len, match;
1472
1473         domain = ((MonoObject *)type)->vtable->domain;
1474         klass = startklass = mono_class_from_mono_type (type->type);
1475
1476 handle_parent:
1477         for (i = 0; i < klass->property.count; ++i) {
1478                 prop = &klass->properties [i];
1479                 match = 0;
1480                 method = prop->get;
1481                 if (!method)
1482                         method = prop->set;
1483                 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
1484                         if (bflags & BFLAGS_Public)
1485                                 match++;
1486                 } else {
1487                         if (bflags & BFLAGS_NonPublic)
1488                                 match++;
1489                 }
1490                 if (!match)
1491                         continue;
1492                 match = 0;
1493                 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
1494                         if (bflags & BFLAGS_Static)
1495                                 match++;
1496                 } else {
1497                         if (bflags & BFLAGS_Instance)
1498                                 match++;
1499                 }
1500
1501                 if (!match)
1502                         continue;
1503                 match = 0;
1504                 l = g_slist_prepend (l, mono_property_get_object (domain, klass, prop));
1505         }
1506         if (!l && (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent)))
1507                 goto handle_parent;
1508         len = g_slist_length (l);
1509         if (!System_Reflection_PropertyInfo)
1510                 System_Reflection_PropertyInfo = mono_class_from_name (
1511                         mono_defaults.corlib, "System.Reflection", "PropertyInfo");
1512         res = mono_array_new (domain, System_Reflection_PropertyInfo, len);
1513         i = 0;
1514         tmp = l;
1515         for (; tmp; tmp = tmp->next, ++i)
1516                 mono_array_set (res, gpointer, i, tmp->data);
1517         g_slist_free (l);
1518         return res;
1519 }
1520
1521 static MonoArray*
1522 ves_icall_Type_GetEvents (MonoReflectionType *type, guint32 bflags)
1523 {
1524         MonoDomain *domain; 
1525         GSList *l = NULL, *tmp;
1526         static MonoClass *System_Reflection_EventInfo;
1527         MonoClass *startklass, *klass;
1528         MonoArray *res;
1529         MonoMethod *method;
1530         MonoEvent *event;
1531         int i, len, match;
1532
1533         domain = ((MonoObject *)type)->vtable->domain;
1534         klass = startklass = mono_class_from_mono_type (type->type);
1535
1536 handle_parent:  
1537         for (i = 0; i < klass->event.count; ++i) {
1538                 event = &klass->events [i];
1539                 match = 0;
1540                 method = event->add;
1541                 if (!method)
1542                         method = event->remove;
1543                 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
1544                         if (bflags & BFLAGS_Public)
1545                                 match++;
1546                 } else {
1547                         if (bflags & BFLAGS_NonPublic)
1548                                 match++;
1549                 }
1550                 if (!match)
1551                         continue;
1552                 match = 0;
1553                 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
1554                         if (bflags & BFLAGS_Static)
1555                                 match++;
1556                 } else {
1557                         if (bflags & BFLAGS_Instance)
1558                                 match++;
1559                 }
1560
1561                 if (!match)
1562                         continue;
1563                 match = 0;
1564                 l = g_slist_prepend (l, mono_event_get_object (domain, klass, event));
1565         }
1566         if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
1567                 goto handle_parent;
1568         len = g_slist_length (l);
1569         if (!System_Reflection_EventInfo)
1570                 System_Reflection_EventInfo = mono_class_from_name (
1571                         mono_defaults.corlib, "System.Reflection", "EventInfo");
1572         res = mono_array_new (domain, System_Reflection_EventInfo, len);
1573         i = 0;
1574         tmp = l;
1575         for (; tmp; tmp = tmp->next, ++i)
1576                 mono_array_set (res, gpointer, i, tmp->data);
1577         g_slist_free (l);
1578         return res;
1579 }
1580
1581 static MonoArray*
1582 ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags)
1583 {
1584         MonoDomain *domain; 
1585         GSList *l = NULL, *tmp;
1586         GList *tmpn;
1587         MonoClass *startklass, *klass;
1588         MonoArray *res;
1589         MonoObject *member;
1590         int i, len, match;
1591         MonoClass *nested;
1592
1593         domain = ((MonoObject *)type)->vtable->domain;
1594         klass = startklass = mono_class_from_mono_type (type->type);
1595
1596         for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
1597                 match = 0;
1598                 nested = tmpn->data;
1599                 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
1600                         if (bflags & BFLAGS_Public)
1601                                 match++;
1602                 } else {
1603                         if (bflags & BFLAGS_NonPublic)
1604                                 match++;
1605                 }
1606                 if (!match)
1607                         continue;
1608                 member = (MonoObject*)mono_type_get_object (domain, &nested->byval_arg);
1609                 l = g_slist_prepend (l, member);
1610         }
1611         len = g_slist_length (l);
1612         res = mono_array_new (domain, mono_defaults.monotype_class, len);
1613         i = 0;
1614         tmp = g_slist_reverse (l);
1615         for (; tmp; tmp = tmp->next, ++i)
1616                 mono_array_set (res, gpointer, i, tmp->data);
1617         g_slist_free (l);
1618         return res;
1619 }
1620
1621 static gpointer
1622 ves_icall_System_Runtime_InteropServices_Marshal_ReadIntPtr (gpointer ptr)
1623 {
1624         return (gpointer)(*(int *)ptr);
1625 }
1626
1627 static MonoString*
1628 ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringAuto (gpointer ptr)
1629 {
1630         MonoDomain *domain = mono_domain_get (); 
1631
1632         return mono_string_new (domain, (char *)ptr);
1633 }
1634
1635 static guint32 ves_icall_System_Runtime_InteropServices_Marshal_GetLastWin32Error(void)
1636 {
1637         return(GetLastError());
1638 }
1639
1640 static MonoReflectionType*
1641 ves_icall_System_Reflection_Assembly_GetType (MonoReflectionAssembly *assembly, MonoString *name, MonoBoolean throwOnError, MonoBoolean ignoreCase)
1642 {
1643         MonoDomain *domain = mono_domain_get (); 
1644         gchar *str;
1645         MonoType *type;
1646         MonoTypeNameParse info;
1647
1648         str = mono_string_to_utf8 (name);
1649         /*g_print ("requested type %s in %s\n", str, assembly->assembly->name);*/
1650         if (!mono_reflection_parse_type (str, &info)) {
1651                 g_free (str);
1652                 g_list_free (info.modifiers);
1653                 if (throwOnError) /* uhm: this is a parse error, though... */
1654                         mono_raise_exception (mono_get_exception_type_load ());
1655                 /*g_print ("failed parse\n");*/
1656                 return NULL;
1657         }
1658
1659         type = mono_reflection_get_type (assembly->assembly->image, &info, ignoreCase);
1660         g_free (str);
1661         g_list_free (info.modifiers);
1662         if (!type) {
1663                 if (throwOnError)
1664                         mono_raise_exception (mono_get_exception_type_load ());
1665                 /* g_print ("failed find\n"); */
1666                 return NULL;
1667         }
1668         /* g_print ("got it\n"); */
1669         return mono_type_get_object (domain, type);
1670
1671 }
1672
1673 static MonoString *
1674 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *assembly)
1675 {
1676         MonoDomain *domain = mono_domain_get (); 
1677         MonoString *res;
1678         char *name = g_strconcat (
1679                 "file://", assembly->assembly->image->name, NULL);
1680         
1681         res = mono_string_new (domain, name);
1682         g_free (name);
1683         return res;
1684 }
1685
1686 static MonoString *
1687 ves_icall_System_MonoType_getFullName (MonoReflectionType *object)
1688 {
1689         MonoDomain *domain = mono_domain_get (); 
1690         MonoString *res;
1691         gchar *name;
1692
1693         name = mono_type_get_name (object->type);
1694         res = mono_string_new (domain, name);
1695         g_free (name);
1696
1697         return res;
1698 }
1699
1700 static void
1701 ves_icall_System_Reflection_Assembly_FillName (MonoReflectionAssembly *assembly, MonoReflectionAssemblyName *aname)
1702 {
1703         MonoAssemblyName *name = &assembly->assembly->aname;
1704
1705         if (strcmp (name->name, "corlib") == 0)
1706                 aname->name = mono_string_new (mono_object_domain (assembly), "mscorlib");
1707         else
1708                 aname->name = mono_string_new (mono_object_domain (assembly), name->name);
1709         aname->major = name->major;
1710 }
1711
1712 static MonoArray*
1713 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly, MonoBoolean exportedOnly)
1714 {
1715         MonoDomain *domain = mono_domain_get (); 
1716         MonoArray *res;
1717         MonoClass *klass;
1718         MonoTableInfo *tdef = &assembly->assembly->image->tables [MONO_TABLE_TYPEDEF];
1719         int i, count;
1720         guint32 attrs, visibility;
1721
1722         /* we start the count from 1 because we skip the special type <Module> */
1723         if (exportedOnly) {
1724                 count = 0;
1725                 for (i = 1; i < tdef->rows; ++i) {
1726                         attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
1727                         visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
1728                         if (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)
1729                                 count++;
1730                 }
1731         } else {
1732                 count = tdef->rows;
1733         }
1734         res = mono_array_new (domain, mono_defaults.monotype_class, count);
1735         count = 0;
1736         for (i = 1; i < tdef->rows; ++i) {
1737                 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
1738                 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
1739                 if (!exportedOnly || (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)) {
1740                         klass = mono_class_get (assembly->assembly->image, (i + 1) | MONO_TOKEN_TYPE_DEF);
1741                         mono_array_set (res, gpointer, count, mono_type_get_object (domain, &klass->byval_arg));
1742                         count++;
1743                 }
1744         }
1745         
1746         return res;
1747 }
1748
1749 static MonoReflectionType*
1750 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
1751 {
1752         MonoClass *klass;
1753         int isbyref = 0, rank;
1754         char *str = mono_string_to_utf8 (smodifiers);
1755         char *p;
1756
1757         klass = mono_class_from_mono_type (tb->type.type);
1758         p = str;
1759         /* logic taken from mono_reflection_parse_type(): keep in sync */
1760         while (*p) {
1761                 switch (*p) {
1762                 case '&':
1763                         if (isbyref) { /* only one level allowed by the spec */
1764                                 g_free (str);
1765                                 return NULL;
1766                         }
1767                         isbyref = 1;
1768                         p++;
1769                         g_free (str);
1770                         return mono_type_get_object (mono_domain_get (), &klass->this_arg);
1771                         break;
1772                 case '*':
1773                         klass = mono_ptr_class_get (&klass->byval_arg);
1774                         mono_class_init (klass);
1775                         p++;
1776                         break;
1777                 case '[':
1778                         rank = 1;
1779                         p++;
1780                         while (*p) {
1781                                 if (*p == ']')
1782                                         break;
1783                                 if (*p == ',')
1784                                         rank++;
1785                                 else if (*p != '*') { /* '*' means unknown lower bound */
1786                                         g_free (str);
1787                                         return NULL;
1788                                 }
1789                                 ++p;
1790                         }
1791                         if (*p != ']') {
1792                                 g_free (str);
1793                                 return NULL;
1794                         }
1795                         p++;
1796                         klass = mono_array_class_get (&klass->byval_arg, rank);
1797                         mono_class_init (klass);
1798                         break;
1799                 default:
1800                         break;
1801                 }
1802         }
1803         g_free (str);
1804         return mono_type_get_object (mono_domain_get (), &klass->byval_arg);
1805 }
1806
1807 /*
1808  * Magic number to convert a time which is relative to
1809  * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
1810  */
1811 #define EPOCH_ADJUST    ((gint64)62135596800L)
1812
1813 static gint64
1814 ves_icall_System_DateTime_GetNow (void)
1815 {
1816 #ifdef PLATFORM_WIN32
1817         SYSTEMTIME st;
1818         FILETIME ft;
1819         
1820         GetLocalTime (&st);
1821         SystemTimeToFileTime (&st, &ft);
1822         return (gint64)504911232000000000L + ((((gint64)ft.dwHighDateTime)<<32) | ft.dwLowDateTime);
1823 #else
1824         /* FIXME: put this in io-layer and call it GetLocalTime */
1825         struct timeval tv;
1826         gint64 res;
1827
1828         if (gettimeofday (&tv, NULL) == 0) {
1829                 res = (((gint64)tv.tv_sec + EPOCH_ADJUST)* 1000000 + tv.tv_usec)*10;
1830                 return res;
1831         }
1832         /* fixme: raise exception */
1833         return 0;
1834 #endif
1835 }
1836
1837 /*
1838  * This is heavily based on zdump.c from glibc 2.2.
1839  *
1840  *  * data[0]:  start of daylight saving time (in DateTime ticks).
1841  *  * data[1]:  end of daylight saving time (in DateTime ticks).
1842  *  * data[2]:  utcoffset (in TimeSpan ticks).
1843  *  * data[3]:  additional offset when daylight saving (in TimeSpan ticks).
1844  *  * name[0]:  name of this timezone when not daylight saving.
1845  *  * name[1]:  name of this timezone when daylight saving.
1846  *
1847  *  FIXME: This only works with "standard" Unix dates (years between 1900 and 2100) while
1848  *         the class library allows years between 1 and 9999.
1849  *
1850  *  Returns true on success and zero on failure.
1851  */
1852 static guint32
1853 ves_icall_System_CurrentTimeZone_GetTimeZoneData (guint32 year, MonoArray **data, MonoArray **names)
1854 {
1855 #ifndef PLATFORM_WIN32
1856         MonoDomain *domain = mono_domain_get ();
1857         struct tm start, tt;
1858         time_t t;
1859
1860         long int gmtoff;
1861         int is_daylight = 0, day;
1862
1863         memset (&start, 0, sizeof (start));
1864
1865         start.tm_mday = 1;
1866         start.tm_year = year-1900;
1867
1868         t = mktime (&start);
1869 #if defined (HAVE_TIMEZONE)
1870 #define gmt_offset(x) (-1 * (((timezone / 60 / 60) - daylight) * 100))
1871 #elif defined (HAVE_TM_GMTOFF)
1872 #define gmt_offset(x) x.tm_gmtoff
1873 #else
1874 #error Neither HAVE_TIMEZONE nor HAVE_TM_GMTOFF defined. Rerun autoheader, autoconf, etc.
1875 #endif
1876         
1877         gmtoff = gmt_offset (start);
1878         
1879         MONO_CHECK_ARG_NULL (data);
1880         MONO_CHECK_ARG_NULL (names);
1881
1882         (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
1883         (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
1884
1885         /* For each day of the year, calculate the tm_gmtoff. */
1886         for (day = 0; day < 365; day++) {
1887
1888                 t += 3600*24;
1889                 tt = *localtime (&t);
1890
1891                 /* Daylight saving starts or ends here. */
1892                 if (gmt_offset (tt) != gmtoff) {
1893                         char tzone[10];
1894                         struct tm tt1;
1895                         time_t t1;
1896
1897                         /* Try to find the exact hour when daylight saving starts/ends. */
1898                         t1 = t;
1899                         do {
1900                                 t1 -= 3600;
1901                                 tt1 = *localtime (&t1);
1902                         } while (gmt_offset (tt1) != gmtoff);
1903
1904                         /* Try to find the exact minute when daylight saving starts/ends. */
1905                         do {
1906                                 t1 += 60;
1907                                 tt1 = *localtime (&t1);
1908                         } while (gmt_offset (tt1) == gmtoff);
1909                         
1910                         strftime (tzone, 10, "%Z", &tt);
1911                         
1912                         /* Write data, if we're already in daylight saving, we're done. */
1913                         if (is_daylight) {
1914                                 mono_array_set ((*names), gpointer, 0, mono_string_new (domain, tzone));
1915                                 mono_array_set ((*data), gint64, 1, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
1916                                 return 1;
1917                         } else {
1918                                 mono_array_set ((*names), gpointer, 1, mono_string_new (domain, tzone));
1919                                 mono_array_set ((*data), gint64, 0, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
1920                                 is_daylight = 1;
1921                         }
1922
1923                         /* This is only set once when we enter daylight saving. */
1924                         mono_array_set ((*data), gint64, 2, (gint64)gmtoff * 10000000L);
1925                         mono_array_set ((*data), gint64, 3, (gint64)(gmt_offset (tt) - gmtoff) * 10000000L);
1926
1927                         gmtoff = gmt_offset (tt);
1928                 }
1929
1930                 gmtoff = gmt_offset (tt);
1931         }
1932         return 1;
1933 #else
1934         MonoDomain *domain = mono_domain_get ();
1935         TIME_ZONE_INFORMATION tz_info;
1936         FILETIME ft;
1937         int i;
1938
1939         GetTimeZoneInformation (&tz_info);
1940
1941         MONO_CHECK_ARG_NULL (data);
1942         MONO_CHECK_ARG_NULL (names);
1943
1944         (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
1945         (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
1946
1947         for (i = 0; i < 32; ++i)
1948                 if (!tz_info.DaylightName [i])
1949                         break;
1950         mono_array_set ((*names), gpointer, 1, mono_string_new_utf16 (domain, tz_info.DaylightName, i));
1951         for (i = 0; i < 32; ++i)
1952                 if (!tz_info.StandardName [i])
1953                         break;
1954         mono_array_set ((*names), gpointer, 0, mono_string_new_utf16 (domain, tz_info.StandardName, i));
1955
1956         SystemTimeToFileTime (&tz_info.StandardDate, &ft);
1957         mono_array_set ((*data), gint64, 1, ((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime);
1958         SystemTimeToFileTime (&tz_info.DaylightDate, &ft);
1959         mono_array_set ((*data), gint64, 0, ((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime);
1960         mono_array_set ((*data), gint64, 3, tz_info.Bias + tz_info.StandardBias);
1961         mono_array_set ((*data), gint64, 2, tz_info.Bias + tz_info.DaylightBias);
1962
1963         return 1;
1964 #endif
1965 }
1966
1967 static gpointer
1968 ves_icall_System_Object_obj_address (MonoObject *this) {
1969         return this;
1970 }
1971
1972 /* System.Buffer */
1973
1974 static gint32 
1975 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array) {
1976         MonoClass *klass;
1977         MonoTypeEnum etype;
1978         int length, esize;
1979         int i;
1980
1981         klass = array->obj.vtable->klass;
1982         etype = klass->element_class->byval_arg.type;
1983         if (etype < MONO_TYPE_BOOLEAN || etype > MONO_TYPE_R8)
1984                 return -1;
1985
1986         if (array->bounds == NULL)
1987                 length = array->max_length;
1988         else {
1989                 length = 0;
1990                 for (i = 0; i < klass->rank; ++ i)
1991                         length += array->bounds [i].length;
1992         }
1993
1994         esize = mono_array_element_size (klass);
1995         return length * esize;
1996 }
1997
1998 static gint8 
1999 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx) {
2000         return mono_array_get (array, gint8, idx);
2001 }
2002
2003 static void 
2004 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value) {
2005         mono_array_set (array, gint8, idx, value);
2006 }
2007
2008 static void 
2009 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count) {
2010         char *src_buf, *dest_buf;
2011
2012         src_buf = (gint8 *)src->vector + src_offset;
2013         dest_buf = (gint8 *)dest->vector + dest_offset;
2014
2015         memcpy (dest_buf, src_buf, count);
2016 }
2017
2018 static MonoObject *
2019 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this)
2020 {
2021         MonoDomain *domain = mono_domain_get (); 
2022         MonoObject *res;
2023         MonoRealProxy *rp = ((MonoRealProxy *)this);
2024         MonoType *type;
2025         MonoClass *klass;
2026
2027         res = mono_object_new (domain, mono_defaults.transparent_proxy_class);
2028         
2029         ((MonoTransparentProxy *)res)->rp = rp;
2030         type = ((MonoReflectionType *)rp->class_to_proxy)->type;
2031         klass = mono_class_from_mono_type (type);
2032
2033         ((MonoTransparentProxy *)res)->klass = klass;
2034
2035         res->vtable = mono_class_proxy_vtable (domain, klass);
2036
2037         return res;
2038 }
2039
2040 /* System.Environment */
2041
2042 static MonoString *
2043 ves_icall_System_Environment_get_MachineName (void)
2044 {
2045 #if defined (PLATFORM_WIN32)
2046         gunichar2 *buf;
2047         guint32 len;
2048         MonoString *result;
2049
2050         len = MAX_COMPUTERNAME_LENGTH + 1;
2051         buf = g_new (gunichar2, len);
2052
2053         result = NULL;
2054         if (GetComputerName (buf, &len))
2055                 result = mono_string_new_utf16 (mono_domain_get (), buf, len);
2056
2057         g_free (buf);
2058         return result;
2059 #else
2060         gchar *buf;
2061         int len;
2062         MonoString *result;
2063
2064         len = 256;
2065         buf = g_new (gchar, len);
2066
2067         result = NULL;
2068         if (gethostname (buf, len) != 0)
2069                 result = mono_string_new (mono_domain_get (), buf);
2070         
2071         g_free (buf);
2072         return result;
2073 #endif
2074 }
2075
2076 static MonoString *
2077 ves_icall_System_Environment_get_NewLine (void)
2078 {
2079 #if defined (PLATFORM_WIN32)
2080         return mono_string_new (mono_domain_get (), "\r\n");
2081 #else
2082         return mono_string_new (mono_domain_get (), "\n");
2083 #endif
2084 }
2085
2086 static MonoString *
2087 ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name)
2088 {
2089         const gchar *value;
2090         gchar *utf8_name;
2091
2092         if (name == NULL)
2093                 return NULL;
2094
2095         utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
2096         value = g_getenv (utf8_name);
2097         g_free (utf8_name);
2098
2099         if (value == 0)
2100                 return NULL;
2101         
2102         return mono_string_new (mono_domain_get (), value);
2103 }
2104
2105 /*
2106  * There is no standard way to get at environ.
2107  */
2108 extern char **environ;
2109
2110 static MonoArray *
2111 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
2112 {
2113         MonoArray *names;
2114         MonoDomain *domain;
2115         MonoString *str;
2116         gchar **e, **parts;
2117         int n;
2118
2119         n = 0;
2120         for (e = environ; *e != 0; ++ e)
2121                 ++ n;
2122
2123         domain = mono_domain_get ();
2124         names = mono_array_new (domain, mono_defaults.string_class, n);
2125
2126         n = 0;
2127         for (e = environ; *e != 0; ++ e) {
2128                 parts = g_strsplit (*e, "=", 2);
2129                 if (*parts != 0) {
2130                         str = mono_string_new (domain, *parts);
2131                         mono_array_set (names, MonoString *, n, str);
2132                 }
2133
2134                 g_strfreev (parts);
2135
2136                 ++ n;
2137         }
2138
2139         return names;
2140 }
2141
2142 /*
2143  * Returns the number of milliseconds elapsed since the system started.
2144  */
2145 static gint32
2146 ves_icall_System_Environment_get_TickCount (void)
2147 {
2148 #if defined (PLATFORM_WIN32)
2149         return GetTickCount();
2150 #else
2151         struct timeval tv;
2152         struct timezone tz;
2153         gint32 res;
2154
2155         res = (gint32) gettimeofday (&tv, &tz);
2156
2157         if (res != -1)
2158                 res = (gint32) ((tv.tv_sec & 0xFFFFF) * 1000 + (tv.tv_usec / 1000));
2159         return res;
2160 #endif
2161 }
2162
2163
2164 static void
2165 ves_icall_System_Environment_Exit (int result)
2166 {
2167         /* we may need to do some cleanup here... */
2168         exit (result);
2169 }
2170
2171 static void
2172 ves_icall_MonoMethodMessage_InitMessage (MonoMethodMessage *this, 
2173                                          MonoReflectionMethod *method,
2174                                          MonoArray *out_args)
2175 {
2176         MonoDomain *domain = mono_domain_get ();
2177         
2178         mono_message_init (domain, this, method, out_args);
2179 }
2180
2181 static MonoBoolean
2182 ves_icall_IsTransparentProxy (MonoObject *proxy)
2183 {
2184         if (!proxy)
2185                 return 0;
2186
2187         if (proxy->vtable->klass == mono_defaults.transparent_proxy_class)
2188                 return 1;
2189
2190         return 0;
2191 }
2192
2193
2194 /* icall map */
2195
2196 static gconstpointer icall_map [] = {
2197         /*
2198          * System.Array
2199          */
2200         "System.Array::GetValue",         ves_icall_System_Array_GetValue,
2201         "System.Array::SetValue",         ves_icall_System_Array_SetValue,
2202         "System.Array::GetValueImpl",     ves_icall_System_Array_GetValueImpl,
2203         "System.Array::SetValueImpl",     ves_icall_System_Array_SetValueImpl,
2204         "System.Array::GetRank",          ves_icall_System_Array_GetRank,
2205         "System.Array::GetLength",        ves_icall_System_Array_GetLength,
2206         "System.Array::GetLowerBound",    ves_icall_System_Array_GetLowerBound,
2207         "System.Array::CreateInstanceImpl",   ves_icall_System_Array_CreateInstanceImpl,
2208         "System.Array::FastCopy",         ves_icall_System_Array_FastCopy,
2209         "System.Array::Clone",            mono_array_clone,
2210
2211         /*
2212          * System.Object
2213          */
2214         "System.Object::MemberwiseClone", ves_icall_System_Object_MemberwiseClone,
2215         "System.Object::GetType", ves_icall_System_Object_GetType,
2216         "System.Object::GetHashCode", ves_icall_System_Object_GetHashCode,
2217         "System.Object::obj_address", ves_icall_System_Object_obj_address,
2218
2219         /*
2220          * System.ValueType
2221          */
2222         "System.ValueType::GetHashCode", ves_icall_System_ValueType_GetHashCode,
2223         "System.ValueType::Equals", ves_icall_System_ValueType_Equals,
2224
2225         /*
2226          * System.String
2227          */
2228         
2229         "System.String::.ctor(char*)", ves_icall_System_String_ctor_charp,
2230         "System.String::.ctor(char*,uint,uint)", ves_icall_System_String_ctor_charp_int_int,
2231         "System.String::.ctor(sbyte*)", ves_icall_System_String_ctor_sbytep,
2232         "System.String::.ctor(sbyte*,uint,uint)", ves_icall_System_String_ctor_sbytep_int_int,
2233         "System.String::.ctor(sbyte*,uint,uint,System.Text.Encoding)", ves_icall_System_String_ctor_encoding,
2234         "System.String::.ctor(char[])", ves_icall_System_String_ctor_chara,
2235         "System.String::.ctor(char[],uint,uint)", ves_icall_System_String_ctor_chara_int_int,
2236         "System.String::.ctor(char,uint)", ves_icall_System_String_ctor_char_int,
2237         "System.String::InternalEquals", ves_icall_System_String_InternalEquals,
2238         "System.String::InternalJoin", ves_icall_System_String_InternalJoin,
2239         "System.String::InternalInsert", ves_icall_System_String_InternalInsert,
2240         "System.String::InternalReplace(char,char)", ves_icall_System_String_InternalReplace_Char,
2241         "System.String::InternalReplace(string,string)", ves_icall_System_String_InternalReplace_Str,
2242         "System.String::InternalRemove", ves_icall_System_String_InternalRemove,
2243         "System.String::InternalCopyTo", ves_icall_System_String_InternalCopyTo,
2244         "System.String::InternalSplit", ves_icall_System_String_InternalSplit,
2245         "System.String::InternalTrim", ves_icall_System_String_InternalTrim,
2246         "System.String::InternalIndexOf(char,uint,uint)", ves_icall_System_String_InternalIndexOf_Char,
2247         "System.String::InternalIndexOf(string,uint,uint)", ves_icall_System_String_InternalIndexOf_Str,
2248         "System.String::InternalIndexOfAny", ves_icall_System_String_InternalIndexOfAny,
2249         "System.String::InternalLastIndexOf(char,uint,uint)", ves_icall_System_String_InternalLastIndexOf_Char,
2250         "System.String::InternalLastIndexOf(string,uint,uint)", ves_icall_System_String_InternalLastIndexOf_Str,
2251         "System.String::InternalLastIndexOfAny", ves_icall_System_String_InternalLastIndexOfAny,
2252         "System.String::InternalPad", ves_icall_System_String_InternalPad,
2253         "System.String::InternalToLower", ves_icall_System_String_InternalToLower,
2254         "System.String::InternalToUpper", ves_icall_System_String_InternalToUpper,
2255         "System.String::InternalAllocateStr", ves_icall_System_String_InternalAllocateStr,
2256         "System.String::InternalStrcpy(string,uint,string)", ves_icall_System_String_InternalStrcpy_Str,
2257         "System.String::InternalStrcpy(string,uint,string,uint,uint)", ves_icall_System_String_InternalStrcpy_StrN,
2258         "System.String::InternalIntern", ves_icall_System_String_InternalIntern,
2259         "System.String::InternalIsInterned", ves_icall_System_String_InternalIsInterned,
2260         "System.String::InternalCompare(string,uint,string,uint,uint,bool)", ves_icall_System_String_InternalCompareStr_N,
2261         "System.String::GetHashCode", ves_icall_System_String_GetHashCode,
2262         "System.String::get_Chars", ves_icall_System_String_get_Chars,
2263
2264         /*
2265          * System.AppDomain
2266          */
2267         "System.AppDomain::createDomain", ves_icall_System_AppDomain_createDomain,
2268         "System.AppDomain::getCurDomain", ves_icall_System_AppDomain_getCurDomain,
2269         "System.AppDomain::GetData", ves_icall_System_AppDomain_GetData,
2270         "System.AppDomain::SetData", ves_icall_System_AppDomain_SetData,
2271         "System.AppDomain::getSetup", ves_icall_System_AppDomain_getSetup,
2272         "System.AppDomain::getFriendlyName", ves_icall_System_AppDomain_getFriendlyName,
2273         "System.AppDomain::GetAssemblies", ves_icall_System_AppDomain_GetAssemblies,
2274         "System.AppDomain::LoadAssembly", ves_icall_System_AppDomain_LoadAssembly,
2275         "System.AppDomain::Unload", ves_icall_System_AppDomain_Unload,
2276         "System.AppDomain::ExecuteAssembly", ves_icall_System_AppDomain_ExecuteAssembly,
2277
2278         /*
2279          * System.AppDomainSetup
2280          */
2281         "System.AppDomainSetup::InitAppDomainSetup", ves_icall_System_AppDomainSetup_InitAppDomainSetup,
2282
2283         /*
2284          * System.Double
2285          */
2286         "System.Double::ToStringImpl", mono_double_ToStringImpl,
2287         "System.Double::ParseImpl",    mono_double_ParseImpl,
2288
2289         /*
2290          * System.Single
2291          */
2292         "System.Single::ToStringImpl", mono_float_ToStringImpl,
2293
2294         /*
2295          * System.Decimal
2296          */
2297         "System.Decimal::decimal2UInt64", mono_decimal2UInt64,
2298         "System.Decimal::decimal2Int64", mono_decimal2Int64,
2299         "System.Decimal::double2decimal", mono_double2decimal, /* FIXME: wrong signature. */
2300         "System.Decimal::decimalIncr", mono_decimalIncr,
2301         "System.Decimal::decimalSetExponent", mono_decimalSetExponent,
2302         "System.Decimal::decimal2double", mono_decimal2double,
2303         "System.Decimal::decimalFloorAndTrunc", mono_decimalFloorAndTrunc,
2304         "System.Decimal::decimalRound", mono_decimalRound,
2305         "System.Decimal::decimalMult", mono_decimalMult,
2306         "System.Decimal::decimalDiv", mono_decimalDiv,
2307         "System.Decimal::decimalIntDiv", mono_decimalIntDiv,
2308         "System.Decimal::decimalCompare", mono_decimalCompare,
2309         "System.Decimal::string2decimal", mono_string2decimal,
2310         "System.Decimal::decimal2string", mono_decimal2string,
2311
2312         /*
2313          * ModuleBuilder
2314          */
2315         "System.Reflection.Emit.ModuleBuilder::create_modified_type", ves_icall_ModuleBuilder_create_modified_type,
2316         
2317         /*
2318          * AssemblyBuilder
2319          */
2320         "System.Reflection.Emit.AssemblyBuilder::getDataChunk", ves_icall_AssemblyBuilder_getDataChunk,
2321         "System.Reflection.Emit.AssemblyBuilder::getPEHeader", ves_icall_AssemblyBuilder_getPEHeader,
2322         "System.Reflection.Emit.AssemblyBuilder::getUSIndex", mono_image_insert_string,
2323         "System.Reflection.Emit.AssemblyBuilder::getToken", ves_icall_AssemblyBuilder_getToken,
2324         "System.Reflection.Emit.AssemblyBuilder::basic_init", mono_image_basic_init,
2325
2326         /*
2327          * Reflection stuff.
2328          */
2329         "System.Reflection.MonoMethodInfo::get_method_info", ves_icall_get_method_info,
2330         "System.Reflection.MonoMethodInfo::get_parameter_info", ves_icall_get_parameter_info,
2331         "System.Reflection.MonoFieldInfo::get_field_info", ves_icall_get_field_info,
2332         "System.Reflection.MonoPropertyInfo::get_property_info", ves_icall_get_property_info,
2333         "System.Reflection.MonoEventInfo::get_event_info", ves_icall_get_event_info,
2334         "System.Reflection.MonoMethod::InternalInvoke", ves_icall_InternalInvoke,
2335         "System.Reflection.MonoCMethod::InternalInvoke", ves_icall_InternalInvoke,
2336         "System.MonoCustomAttrs::GetCustomAttributes", mono_reflection_get_custom_attrs,
2337         "System.Reflection.Emit.CustomAttributeBuilder::GetBlob", mono_reflection_get_custom_attrs_blob,
2338         "System.Reflection.MonoField::GetValue", ves_icall_MonoField_GetValue,
2339         "System.Reflection.Emit.SignatureHelper::get_signature_local", mono_reflection_sighelper_get_signature_local,
2340         "System.Reflection.Emit.SignatureHelper::get_signature_field", mono_reflection_sighelper_get_signature_field,
2341
2342         
2343         /* System.Enum */
2344
2345         "System.MonoEnumInfo::get_enum_info", ves_icall_get_enum_info,
2346         "System.Enum::get_value", ves_icall_System_Enum_get_value,
2347         "System.Enum::ToObject", ves_icall_System_Enum_ToObject,
2348
2349         /*
2350          * TypeBuilder
2351          */
2352         "System.Reflection.Emit.TypeBuilder::setup_internal_class", mono_reflection_setup_internal_class,
2353         "System.Reflection.Emit.TypeBuilder::create_internal_class", mono_reflection_create_internal_class,
2354
2355         
2356         /*
2357          * MethodBuilder
2358          */
2359         
2360         /*
2361          * System.Type
2362          */
2363         "System.Type::internal_from_name", ves_icall_type_from_name,
2364         "System.Type::internal_from_handle", ves_icall_type_from_handle,
2365         "System.Type::get_constructor", ves_icall_get_constructor,
2366         "System.Type::get_property", ves_icall_get_property,
2367         "System.Type::get_method", ves_icall_get_method,
2368         "System.MonoType::get_attributes", ves_icall_get_attributes,
2369         "System.Type::type_is_subtype_of", ves_icall_type_is_subtype_of,
2370         "System.Type::Equals", ves_icall_type_Equals,
2371
2372         /*
2373          * System.Runtime.CompilerServices.RuntimeHelpers
2374          */
2375         "System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray", ves_icall_InitializeArray,
2376         
2377         /*
2378          * System.Threading
2379          */
2380         "System.Threading.Thread::Thread_internal", ves_icall_System_Threading_Thread_Thread_internal,
2381         "System.Threading.Thread::Thread_free_internal", ves_icall_System_Threading_Thread_Thread_free_internal,
2382         "System.Threading.Thread::Start_internal", ves_icall_System_Threading_Thread_Start_internal,
2383         "System.Threading.Thread::Sleep_internal", ves_icall_System_Threading_Thread_Sleep_internal,
2384         "System.Threading.Thread::CurrentThread_internal", ves_icall_System_Threading_Thread_CurrentThread_internal,
2385         "System.Threading.Thread::CurrentThreadDomain_internal", ves_icall_System_Threading_Thread_CurrentThreadDomain_internal,
2386         "System.Threading.Thread::Join_internal", ves_icall_System_Threading_Thread_Join_internal,
2387         "System.Threading.Thread::SlotHash_lookup", ves_icall_System_Threading_Thread_SlotHash_lookup,
2388         "System.Threading.Thread::SlotHash_store", ves_icall_System_Threading_Thread_SlotHash_store,
2389         "System.Threading.Monitor::Monitor_exit", ves_icall_System_Threading_Monitor_Monitor_exit,
2390         "System.Threading.Monitor::Monitor_test_owner", ves_icall_System_Threading_Monitor_Monitor_test_owner,
2391         "System.Threading.Monitor::Monitor_test_synchronised", ves_icall_System_Threading_Monitor_Monitor_test_synchronised,
2392         "System.Threading.Monitor::Monitor_pulse", ves_icall_System_Threading_Monitor_Monitor_pulse,
2393         "System.Threading.Monitor::Monitor_pulse_all", ves_icall_System_Threading_Monitor_Monitor_pulse_all,
2394         "System.Threading.Monitor::Monitor_try_enter", ves_icall_System_Threading_Monitor_Monitor_try_enter,
2395         "System.Threading.Monitor::Monitor_wait", ves_icall_System_Threading_Monitor_Monitor_wait,
2396         "System.Threading.Mutex::CreateMutex_internal", ves_icall_System_Threading_Mutex_CreateMutex_internal,
2397         "System.Threading.Mutex::ReleaseMutex_internal", ves_icall_System_Threading_Mutex_ReleaseMutex_internal,
2398         "System.Threading.NativeEventCalls::CreateEvent_internal", ves_icall_System_Threading_Events_CreateEvent_internal,
2399         "System.Threading.NativeEventCalls::SetEvent_internal",    ves_icall_System_Threading_Events_SetEvent_internal,
2400         "System.Threading.NativeEventCalls::ResetEvent_internal",  ves_icall_System_Threading_Events_ResetEvent_internal,
2401
2402         /*
2403          * System.Threading.WaitHandle
2404          */
2405         "System.Threading.WaitHandle::WaitAll_internal", ves_icall_System_Threading_WaitHandle_WaitAll_internal,
2406         "System.Threading.WaitHandle::WaitAny_internal", ves_icall_System_Threading_WaitHandle_WaitAny_internal,
2407         "System.Threading.WaitHandle::WaitOne_internal", ves_icall_System_Threading_WaitHandle_WaitOne_internal,
2408
2409         "System.Runtime.InteropServices.Marshal::ReadIntPtr", ves_icall_System_Runtime_InteropServices_Marshal_ReadIntPtr,
2410         "System.Runtime.InteropServices.Marshal::PtrToStringAuto", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringAuto,
2411         "System.Runtime.InteropServices.Marshal::GetLastWin32Error", ves_icall_System_Runtime_InteropServices_Marshal_GetLastWin32Error,
2412
2413         "System.Reflection.Assembly::LoadFrom", ves_icall_System_Reflection_Assembly_LoadFrom,
2414         "System.Reflection.Assembly::GetType", ves_icall_System_Reflection_Assembly_GetType,
2415         "System.Reflection.Assembly::GetTypes", ves_icall_System_Reflection_Assembly_GetTypes,
2416         "System.Reflection.Assembly::FillName", ves_icall_System_Reflection_Assembly_FillName,
2417         "System.Reflection.Assembly::get_code_base", ves_icall_System_Reflection_Assembly_get_code_base,
2418
2419         /*
2420          * System.MonoType.
2421          */
2422         "System.MonoType::getFullName", ves_icall_System_MonoType_getFullName,
2423         "System.MonoType::type_from_obj", mono_type_type_from_obj,
2424         "System.MonoType::GetElementType", ves_icall_MonoType_GetElementType,
2425         "System.MonoType::get_type_info", ves_icall_get_type_info,
2426         "System.MonoType::GetFields", ves_icall_Type_GetFields,
2427         "System.MonoType::GetMethods", ves_icall_Type_GetMethods,
2428         "System.MonoType::GetConstructors", ves_icall_Type_GetConstructors,
2429         "System.MonoType::GetProperties", ves_icall_Type_GetProperties,
2430         "System.MonoType::GetEvents", ves_icall_Type_GetEvents,
2431         "System.MonoType::GetInterfaces", ves_icall_Type_GetInterfaces,
2432         "System.MonoType::GetNestedTypes", ves_icall_Type_GetNestedTypes,
2433
2434         /*
2435          * System.Net.Sockets I/O Services
2436          */
2437         "System.Net.Sockets.Socket::Socket_internal", ves_icall_System_Net_Sockets_Socket_Socket_internal,
2438         "System.Net.Sockets.Socket::Close_internal", ves_icall_System_Net_Sockets_Socket_Close_internal,
2439         "System.Net.Sockets.SocketException::WSAGetLastError_internal", ves_icall_System_Net_Sockets_SocketException_WSAGetLastError_internal,
2440         "System.Net.Sockets.Socket::Available_internal", ves_icall_System_Net_Sockets_Socket_Available_internal,
2441         "System.Net.Sockets.Socket::Blocking_internal", ves_icall_System_Net_Sockets_Socket_Blocking_internal,
2442         "System.Net.Sockets.Socket::Accept_internal", ves_icall_System_Net_Sockets_Socket_Accept_internal,
2443         "System.Net.Sockets.Socket::Listen_internal", ves_icall_System_Net_Sockets_Socket_Listen_internal,
2444         "System.Net.Sockets.Socket::LocalEndPoint_internal", ves_icall_System_Net_Sockets_Socket_LocalEndPoint_internal,
2445         "System.Net.Sockets.Socket::RemoteEndPoint_internal", ves_icall_System_Net_Sockets_Socket_RemoteEndPoint_internal,
2446         "System.Net.Sockets.Socket::Bind_internal", ves_icall_System_Net_Sockets_Socket_Bind_internal,
2447         "System.Net.Sockets.Socket::Connect_internal", ves_icall_System_Net_Sockets_Socket_Connect_internal,
2448         "System.Net.Sockets.Socket::Receive_internal", ves_icall_System_Net_Sockets_Socket_Receive_internal,
2449         "System.Net.Sockets.Socket::RecvFrom_internal", ves_icall_System_Net_Sockets_Socket_RecvFrom_internal,
2450         "System.Net.Sockets.Socket::Send_internal", ves_icall_System_Net_Sockets_Socket_Send_internal,
2451         "System.Net.Sockets.Socket::SendTo_internal", ves_icall_System_Net_Sockets_Socket_SendTo_internal,
2452         "System.Net.Sockets.Socket::Select_internal", ves_icall_System_Net_Sockets_Socket_Select_internal,
2453         "System.Net.Sockets.Socket::Shutdown_internal", ves_icall_System_Net_Sockets_Socket_Shutdown_internal,
2454         "System.Net.Sockets.Socket::GetSocketOption_obj_internal", ves_icall_System_Net_Sockets_Socket_GetSocketOption_obj_internal,
2455         "System.Net.Sockets.Socket::GetSocketOption_arr_internal", ves_icall_System_Net_Sockets_Socket_GetSocketOption_arr_internal,
2456         "System.Net.Sockets.Socket::SetSocketOption_internal", ves_icall_System_Net_Sockets_Socket_SetSocketOption_internal,
2457         "System.Net.Dns::GetHostByName_internal", ves_icall_System_Net_Dns_GetHostByName_internal,
2458         "System.Net.Dns::GetHostByAddr_internal", ves_icall_System_Net_Dns_GetHostByAddr_internal,
2459
2460         /*
2461          * System.Char
2462          */
2463         "System.Char::GetNumericValue", ves_icall_System_Char_GetNumericValue,
2464         "System.Char::GetUnicodeCategory", ves_icall_System_Char_GetUnicodeCategory,
2465         "System.Char::IsControl", ves_icall_System_Char_IsControl,
2466         "System.Char::IsDigit", ves_icall_System_Char_IsDigit,
2467         "System.Char::IsLetter", ves_icall_System_Char_IsLetter,
2468         "System.Char::IsLower", ves_icall_System_Char_IsLower,
2469         "System.Char::IsUpper", ves_icall_System_Char_IsUpper,
2470         "System.Char::IsNumber", ves_icall_System_Char_IsNumber,
2471         "System.Char::IsPunctuation", ves_icall_System_Char_IsPunctuation,
2472         "System.Char::IsSeparator", ves_icall_System_Char_IsSeparator,
2473         "System.Char::IsSurrogate", ves_icall_System_Char_IsSurrogate,
2474         "System.Char::IsSymbol", ves_icall_System_Char_IsSymbol,
2475         "System.Char::IsWhiteSpace", ves_icall_System_Char_IsWhiteSpace,
2476         "System.Char::ToLower", ves_icall_System_Char_ToLower,
2477         "System.Char::ToUpper", ves_icall_System_Char_ToUpper,
2478
2479         "System.Text.Encoding::IConvNewEncoder", ves_icall_iconv_new_encoder,
2480         "System.Text.Encoding::IConvNewDecoder", ves_icall_iconv_new_decoder,
2481         "System.Text.Encoding::IConvReset", ves_icall_iconv_reset,
2482         "System.Text.Encoding::IConvGetByteCount", ves_icall_iconv_get_byte_count,
2483         "System.Text.Encoding::IConvGetBytes", ves_icall_iconv_get_bytes,
2484         "System.Text.Encoding::IConvGetCharCount", ves_icall_iconv_get_char_count,
2485         "System.Text.Encoding::IConvGetChars", ves_icall_iconv_get_chars,
2486
2487         "System.DateTime::GetNow", ves_icall_System_DateTime_GetNow,
2488         "System.CurrentTimeZone::GetTimeZoneData", ves_icall_System_CurrentTimeZone_GetTimeZoneData,
2489
2490         /*
2491          * System.GC
2492          */
2493         "System.GC::InternalCollect", ves_icall_System_GC_InternalCollect,
2494         "System.GC::GetTotalMemory", ves_icall_System_GC_GetTotalMemory,
2495         "System.GC::KeepAlive", ves_icall_System_GC_KeepAlive,
2496         "System.GC::ReRegisterForFinalize", ves_icall_System_GC_ReRegisterForFinalize,
2497         "System.GC::SuppressFinalize", ves_icall_System_GC_SuppressFinalize,
2498         "System.GC::WaitForPendingFinalizers", ves_icall_System_GC_WaitForPendingFinalizers,
2499
2500         /*
2501          * System.Security.Cryptography calls
2502          */
2503
2504          "System.Security.Cryptography.RNGCryptoServiceProvider::GetBytes", ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_GetBytes,
2505          "System.Security.Cryptography.RNGCryptoServiceProvider::GetNonZeroBytes", ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_GetNonZeroBytes,
2506         
2507         /*
2508          * System.Buffer
2509          */
2510         "System.Buffer::ByteLengthInternal", ves_icall_System_Buffer_ByteLengthInternal,
2511         "System.Buffer::GetByteInternal", ves_icall_System_Buffer_GetByteInternal,
2512         "System.Buffer::SetByteInternal", ves_icall_System_Buffer_SetByteInternal,
2513         "System.Buffer::BlockCopyInternal", ves_icall_System_Buffer_BlockCopyInternal,
2514
2515         /*
2516          * System.IO.MonoIO
2517          */
2518         "System.IO.MonoIO::GetLastError", ves_icall_System_IO_MonoIO_GetLastError,
2519         "System.IO.MonoIO::CreateDirectory", ves_icall_System_IO_MonoIO_CreateDirectory,
2520         "System.IO.MonoIO::RemoveDirectory", ves_icall_System_IO_MonoIO_RemoveDirectory,
2521         "System.IO.MonoIO::FindFirstFile", ves_icall_System_IO_MonoIO_FindFirstFile,
2522         "System.IO.MonoIO::FindNextFile", ves_icall_System_IO_MonoIO_FindNextFile,
2523         "System.IO.MonoIO::FindClose", ves_icall_System_IO_MonoIO_FindClose,
2524         "System.IO.MonoIO::GetCurrentDirectory", ves_icall_System_IO_MonoIO_GetCurrentDirectory,
2525         "System.IO.MonoIO::SetCurrentDirectory", ves_icall_System_IO_MonoIO_SetCurrentDirectory,
2526         "System.IO.MonoIO::MoveFile", ves_icall_System_IO_MonoIO_MoveFile,
2527         "System.IO.MonoIO::CopyFile", ves_icall_System_IO_MonoIO_CopyFile,
2528         "System.IO.MonoIO::DeleteFile", ves_icall_System_IO_MonoIO_DeleteFile,
2529         "System.IO.MonoIO::GetFileAttributes", ves_icall_System_IO_MonoIO_GetFileAttributes,
2530         "System.IO.MonoIO::SetFileAttributes", ves_icall_System_IO_MonoIO_SetFileAttributes,
2531         "System.IO.MonoIO::GetFileStat", ves_icall_System_IO_MonoIO_GetFileStat,
2532         "System.IO.MonoIO::Open", ves_icall_System_IO_MonoIO_Open,
2533         "System.IO.MonoIO::Close", ves_icall_System_IO_MonoIO_Close,
2534         "System.IO.MonoIO::Read", ves_icall_System_IO_MonoIO_Read,
2535         "System.IO.MonoIO::Write", ves_icall_System_IO_MonoIO_Write,
2536         "System.IO.MonoIO::Seek", ves_icall_System_IO_MonoIO_Seek,
2537         "System.IO.MonoIO::GetLength", ves_icall_System_IO_MonoIO_GetLength,
2538         "System.IO.MonoIO::SetLength", ves_icall_System_IO_MonoIO_SetLength,
2539         "System.IO.MonoIO::SetFileTime", ves_icall_System_IO_MonoIO_SetFileTime,
2540         "System.IO.MonoIO::Flush", ves_icall_System_IO_MonoIO_Flush,
2541         "System.IO.MonoIO::get_ConsoleOutput", ves_icall_System_IO_MonoIO_get_ConsoleOutput,
2542         "System.IO.MonoIO::get_ConsoleInput", ves_icall_System_IO_MonoIO_get_ConsoleInput,
2543         "System.IO.MonoIO::get_ConsoleError", ves_icall_System_IO_MonoIO_get_ConsoleError,
2544         "System.IO.MonoIO::get_VolumeSeparatorChar", ves_icall_System_IO_MonoIO_get_VolumeSeparatorChar,
2545         "System.IO.MonoIO::get_DirectorySeparatorChar", ves_icall_System_IO_MonoIO_get_DirectorySeparatorChar,
2546         "System.IO.MonoIO::get_AltDirectorySeparatorChar", ves_icall_System_IO_MonoIO_get_AltDirectorySeparatorChar,
2547         "System.IO.MonoIO::get_PathSeparator", ves_icall_System_IO_MonoIO_get_PathSeparator,
2548         "System.IO.MonoIO::get_InvalidPathChars", ves_icall_System_IO_MonoIO_get_InvalidPathChars,
2549
2550         /*
2551          * System.Math
2552          */
2553         "System.Math::Sin", ves_icall_System_Math_Sin,
2554     "System.Math::Cos", ves_icall_System_Math_Cos,
2555     "System.Math::Tan", ves_icall_System_Math_Tan,
2556     "System.Math::Sinh", ves_icall_System_Math_Sinh,
2557     "System.Math::Cosh", ves_icall_System_Math_Cosh,
2558     "System.Math::Tanh", ves_icall_System_Math_Tanh,
2559     "System.Math::Acos", ves_icall_System_Math_Acos,
2560     "System.Math::Asin", ves_icall_System_Math_Asin,
2561     "System.Math::Atan", ves_icall_System_Math_Atan,
2562     "System.Math::Atan2", ves_icall_System_Math_Atan2,
2563     "System.Math::Exp", ves_icall_System_Math_Exp,
2564     "System.Math::Log", ves_icall_System_Math_Log,
2565     "System.Math::Log10", ves_icall_System_Math_Log10,
2566     "System.Math::PowImpl", ves_icall_System_Math_Pow,
2567     "System.Math::Sqrt", ves_icall_System_Math_Sqrt,
2568
2569         /*
2570          * System.Environment
2571          */
2572         "System.Environment::get_MachineName", ves_icall_System_Environment_get_MachineName,
2573         "System.Environment::get_NewLine", ves_icall_System_Environment_get_NewLine,
2574         "System.Environment::GetEnvironmentVariable", ves_icall_System_Environment_GetEnvironmentVariable,
2575         "System.Environment::GetEnvironmentVariableNames", ves_icall_System_Environment_GetEnvironmentVariableNames,
2576         "System.Environment::GetCommandLineArgs", mono_runtime_get_main_args,
2577         "System.Environment::get_TickCount", ves_icall_System_Environment_get_TickCount,
2578         "System.Environment::Exit", ves_icall_System_Environment_Exit,
2579
2580         /*
2581          * System.Runtime.Remoting
2582          */     
2583         "System.Runtime.Remoting.RemotingServices::InternalExecute",
2584         ves_icall_InternalExecute,
2585         "System.Runtime.Remoting.RemotingServices::IsTransparentProxy",
2586         ves_icall_IsTransparentProxy,
2587
2588         /*
2589          * System.Runtime.Remoting.Messaging
2590          */     
2591         "System.Runtime.Remoting.Messaging.MonoMethodMessage::InitMessage",
2592         ves_icall_MonoMethodMessage_InitMessage,
2593         
2594         /*
2595          * System.Runtime.Remoting.Proxies
2596          */     
2597         "System.Runtime.Remoting.Proxies.RealProxy::GetTransparentProxy", 
2598         ves_icall_Remoting_RealProxy_GetTransparentProxy,
2599
2600         /*
2601          * System.Threading.Interlocked
2602          */
2603         "System.Threading.Interlocked::Increment(uint&)", ves_icall_System_Threading_Interlocked_Increment_Int,
2604         "System.Threading.Interlocked::Increment(long&)", ves_icall_System_Threading_Interlocked_Increment_Long,
2605         "System.Threading.Interlocked::Decrement(uint&)", ves_icall_System_Threading_Interlocked_Decrement_Int,
2606         "System.Threading.Interlocked::Decrement(long&)", ves_icall_System_Threading_Interlocked_Decrement_Long,
2607         "System.Threading.Interlocked::CompareExchange(uint&,uint,uint)", ves_icall_System_Threading_Interlocked_CompareExchange_Int,
2608         "System.Threading.Interlocked::CompareExchange(object&,object,object)", ves_icall_System_Threading_Interlocked_CompareExchange_Object,
2609         "System.Threading.Interlocked::CompareExchange(single&,single,single)", ves_icall_System_Threading_Interlocked_CompareExchange_Single,
2610         "System.Threading.Interlocked::Exchange(uint&,uint)", ves_icall_System_Threading_Interlocked_Exchange_Int,
2611         "System.Threading.Interlocked::Exchange(object&,object)", ves_icall_System_Threading_Interlocked_Exchange_Object,
2612         "System.Threading.Interlocked::Exchange(single&,single)", ves_icall_System_Threading_Interlocked_Exchange_Single,
2613
2614         /*
2615          * add other internal calls here
2616          */
2617         NULL, NULL
2618 };
2619
2620 void
2621 mono_init_icall (void)
2622 {
2623         const char *name;
2624         int i = 0;
2625
2626         while ((name = icall_map [i])) {
2627                 mono_add_internal_call (name, icall_map [i+1]);
2628                 i += 2;
2629         }
2630        
2631 }
2632
2633