185b914461b12083d8809a3f3d6e201d6452b74b
[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  *
8  * (C) 2001 Ximian, Inc.
9  */
10
11 #include <config.h>
12 #include <glib.h>
13 #include <stdarg.h>
14 #include <string.h>
15 #include <sys/time.h>
16 #include <unistd.h>
17
18 #include <mono/metadata/object.h>
19 #include <mono/metadata/threads.h>
20 #include <mono/metadata/reflection.h>
21 #include <mono/metadata/assembly.h>
22 #include <mono/metadata/tabledefs.h>
23 #include <mono/metadata/exception.h>
24 #include <mono/metadata/file-io.h>
25 #include <mono/metadata/socket-io.h>
26 #include <mono/metadata/mono-endian.h>
27 #include <mono/metadata/tokentype.h>
28 #include <mono/metadata/unicode.h>
29 #include <mono/metadata/appdomain.h>
30 #include <mono/metadata/rand.h>
31 #include <mono/io-layer/io-layer.h>
32 #include "decimal.h"
33
34 static MonoObject *
35 ves_icall_System_Array_GetValue (MonoObject *this, MonoObject *idxs)
36 {
37         MonoClass *ac, *ic;
38         MonoArray *ao, *io;
39         gint32 i, pos, *ind, esize;
40         gpointer *ea;
41
42         MONO_CHECK_ARG_NULL (idxs);
43
44         io = (MonoArray *)idxs;
45         ic = (MonoClass *)io->obj.vtable->klass;
46         
47         ao = (MonoArray *)this;
48         ac = (MonoClass *)ao->obj.vtable->klass;
49
50         g_assert (ic->rank == 1);
51         if (io->bounds [0].length != ac->rank)
52                 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
53
54         ind = (guint32 *)io->vector;
55         for (i = 0; i < ac->rank; i++)
56                 if ((ind [i] < ao->bounds [i].lower_bound) ||
57                     (ind [i] >= ao->bounds [i].length + ao->bounds [i].lower_bound))
58                         mono_raise_exception (mono_get_exception_index_out_of_range ());
59
60         pos = ind [0] - ao->bounds [0].lower_bound;
61         for (i = 1; i < ac->rank; i++)
62                 pos = pos*ao->bounds [i].length + ind [i] - 
63                         ao->bounds [i].lower_bound;
64
65         esize = mono_array_element_size (ac);
66         ea = (gpointer*)((char*)ao->vector + (pos * esize));
67
68         if (ac->element_class->valuetype)
69                 return mono_value_box (this->vtable->domain, ac->element_class, ea);
70         else {
71                 return *ea;
72         }
73 }
74
75 static void 
76 ves_icall_System_Array_SetValue (MonoObject *this, MonoObject *value,
77                                  MonoObject *idxs)
78 {
79         MonoArray *ao, *io, *vo;
80         MonoClass *ac, *ic, *vc;
81         gint32 i, pos, *ind, esize;
82         gpointer *ea;
83
84         MONO_CHECK_ARG_NULL (idxs);
85
86         vo = (MonoArray *)value;
87         if (vo)
88                 vc = (MonoClass *)vo->obj.vtable->klass;
89         else
90                 vc = NULL;
91
92         io = (MonoArray *)idxs;
93         ic = (MonoClass *)io->obj.vtable->klass;
94         
95         ao = (MonoArray *)this;
96         ac = (MonoClass *)ao->obj.vtable->klass;
97
98         g_assert (ic->rank == 1);
99         if (io->bounds [0].length != ac->rank)
100                 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
101
102         ind = (guint32 *)io->vector;
103         for (i = 0; i < ac->rank; i++)
104                 if ((ind [i] < ao->bounds [i].lower_bound) ||
105                     (ind [i] >= ao->bounds [i].length + ao->bounds [i].lower_bound))
106                         mono_raise_exception (mono_get_exception_index_out_of_range ());
107
108         if (vo && !mono_object_isinst (value, ac->element_class)) {
109                 mono_raise_exception (mono_get_exception_array_type_mismatch ());
110                 return;
111         }
112
113         pos = ind [0] - ao->bounds [0].lower_bound;
114         for (i = 1; i < ac->rank; i++)
115                 pos = pos*ao->bounds [i].length + ind [i] - 
116                         ao->bounds [i].lower_bound;
117
118         esize = mono_array_element_size (ac);
119         ea = (gpointer*)((char*)ao->vector + (pos * esize));
120
121         if (ac->element_class->valuetype) {
122                 if (vo) {
123                         g_assert (vc->valuetype);
124                         memcpy (ea, (char *)vo + sizeof (MonoObject), esize);
125                 } else
126                         memset (ea, 0,  esize);
127         } else
128                 *ea = (gpointer)vo;
129
130 }
131
132 static void
133 ves_icall_System_Array_CreateInstanceImpl ()
134 {
135         g_warning (G_STRLOC ": not implemented");
136         mono_raise_exception (mono_get_exception_not_implemented ());
137 }
138
139 static gint32 
140 ves_icall_System_Array_GetRank (MonoObject *this)
141 {
142         return this->vtable->klass->rank;
143 }
144
145 static gint32
146 ves_icall_System_Array_GetLength (MonoArray *this, gint32 dimension)
147 {
148         gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
149         if ((dimension < 0) || (dimension >= rank))
150                 mono_raise_exception (mono_get_exception_index_out_of_range ());
151         return this->bounds [dimension].length;
152 }
153
154 static gint32
155 ves_icall_System_Array_GetLowerBound (MonoArray *this, gint32 dimension)
156 {
157         gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
158         if ((dimension < 0) || (dimension >= rank))
159                 mono_raise_exception (mono_get_exception_index_out_of_range ());
160         return this->bounds [dimension].lower_bound;
161 }
162
163 static void
164 ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* dest, int dest_idx, int length)
165 {
166         int element_size = mono_array_element_size (source->obj.vtable->klass);
167         void * dest_addr = mono_array_addr_with_size (dest, element_size, dest_idx);
168         void * source_addr = mono_array_addr_with_size (source, element_size, dest_idx);
169
170         memcpy (dest_addr, source_addr, element_size * length);
171 }
172
173 static void
174 ves_icall_InitializeArray (MonoArray *array, MonoClassField *field_handle)
175 {
176         MonoClass *klass = array->obj.vtable->klass;
177         guint32 size = mono_array_element_size (klass);
178         int i;
179
180         for (i = 0; i < klass->rank; ++i) 
181                 size *= array->bounds [i].length;
182
183         memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
184
185 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
186 #define SWAP(n) {\
187         gint i; \
188         guint ## n tmp; \
189         guint ## n *data = (guint ## n *) mono_array_addr (array, char, 0); \
190 \
191         for (i = 0; i < size; i += n/8, data++) { \
192                 tmp = read ## n (data); \
193                 *data = tmp; \
194         } \
195 }
196
197         printf ("Initialize array with elements of %s type\n", klass->element_class->name);
198
199         switch (klass->element_class->byval_arg.type) {
200         case MONO_TYPE_CHAR:
201         case MONO_TYPE_I2:
202         case MONO_TYPE_U2:
203                 SWAP (16);
204                 break;
205         case MONO_TYPE_I4:
206         case MONO_TYPE_U4:
207                 SWAP (32);
208                 break;
209         case MONO_TYPE_I8:
210         case MONO_TYPE_U8:
211                 SWAP (64);
212                 break;
213         }
214                  
215 #endif
216 }
217
218 static MonoObject *
219 ves_icall_System_Object_MemberwiseClone (MonoObject *this)
220 {
221         return mono_object_clone (this);
222 }
223
224 static MonoReflectionType *
225 ves_icall_System_Object_GetType (MonoObject *obj)
226 {
227         return mono_type_get_object (mono_domain_get (), &obj->vtable->klass->byval_arg);
228 }
229
230 static void
231 mono_type_type_from_obj (MonoReflectionType *mtype, MonoObject *obj)
232 {
233         mtype->type = &obj->vtable->klass->byval_arg;
234         g_assert (mtype->type->type);
235 }
236
237 static gint32
238 ves_icall_AssemblyBuilder_getToken (MonoReflectionAssemblyBuilder *assb, MonoObject *obj)
239 {
240         return mono_image_create_token (assb->dynamic_assembly, obj);
241 }
242
243 static gint32
244 ves_icall_get_data_chunk (MonoReflectionAssemblyBuilder *assb, gint32 type, MonoArray *buf)
245 {
246         int count;
247
248         if (type == 0) { /* get the header */
249                 count = mono_image_get_header (assb, (char*)buf->vector, buf->bounds->length);
250                 if (count != -1)
251                         return count;
252         } else {
253                 MonoDynamicAssembly *ass = assb->dynamic_assembly;
254                 char *p = mono_array_addr (buf, char, 0);
255                 count = ass->code.index + ass->meta_size;
256                 if (count > buf->bounds->length) {
257                         g_print ("assembly data exceed supplied buffer\n");
258                         return 0;
259                 }
260                 memcpy (p, ass->code.data, ass->code.index);
261                 memcpy (p + ass->code.index, ass->assembly.image->raw_metadata, ass->meta_size);
262                 return count;
263         }
264         
265         return 0;
266 }
267
268 static MonoReflectionType*
269 ves_icall_type_from_name (MonoString *name)
270 {
271         MonoDomain *domain = mono_domain_get (); 
272         MonoClass *klass;
273         MonoImage *image;
274         MonoTypeNameParse info;
275         gchar *str;
276         
277         str = mono_string_to_utf8 (name);
278         /*g_print ("requested type %s\n", str);*/
279         if (!mono_reflection_parse_type (str, &info)) {
280                 g_free (str);
281                 return NULL;
282         }
283
284         if (info.assembly) {
285                 image = mono_image_loaded (info.assembly);
286                 /* do we need to load if it's not already loaded? */
287                 if (!image) {
288                         g_free (str);
289                         return NULL;
290                 }
291         } else
292                 image = mono_defaults.corlib;
293         if (info.nest_name) {
294                 klass = mono_class_from_name (image, info.nest_name_space, info.nest_name);
295                 if (klass) {
296                         GList *nested;
297                         mono_class_init (klass);
298                         nested = klass->nested_classes;
299                         while (nested) {
300                                 klass = nested->data;
301                                 if (strcmp (klass->name, info.nest_name) == 0 &&
302                                                 strcmp (klass->name_space, info.nest_name_space) == 0)
303                                         break;
304                                 klass = NULL;
305                         }
306                 }
307         } else {
308                 klass = mono_class_from_name (image, info.name_space, info.name);
309         }
310         g_free (str);
311         if (!klass)
312                 return NULL;
313         mono_class_init (klass);
314         if (info.rank)
315                 klass = mono_array_class_get (klass, info.rank);
316         
317         if (info.isbyref || info.ispointer) /* hack */
318                 return mono_type_get_object (domain, &klass->this_arg);
319         else
320                 return mono_type_get_object (domain, &klass->byval_arg);
321 }
322
323 static MonoReflectionType*
324 ves_icall_type_from_handle (MonoType *handle)
325 {
326         MonoDomain *domain = mono_domain_get (); 
327
328         mono_class_init (handle->data.klass);
329         return mono_type_get_object (domain, handle);
330 }
331
332 static guint32
333 ves_icall_type_Equals (MonoReflectionType *type, MonoReflectionType *c)
334 {
335         if (type->type && c->type)
336                 return mono_metadata_type_equal (type->type, c->type);
337         g_print ("type equals\n");
338         return 0;
339 }
340
341 static guint32
342 ves_icall_type_is_subtype_of (MonoReflectionType *type, MonoReflectionType *c, MonoBoolean check_interfaces)
343 {
344         MonoDomain *domain; 
345         MonoClass *klass;
346         MonoClass *klassc;
347
348         g_assert (type != NULL);
349         
350         domain = ((MonoObject *)type)->vtable->domain;
351
352         if (!c) /* FIXME: dont know what do do here */
353                 return 0;
354
355         klass = mono_class_from_mono_type (type->type);
356         klassc = mono_class_from_mono_type (c->type);
357
358         /* cut&paste from mono_object_isinst (): keep in sync */
359         if (check_interfaces && (klassc->flags & TYPE_ATTRIBUTE_INTERFACE) && !(klass->flags & TYPE_ATTRIBUTE_INTERFACE)) {
360                 MonoVTable *klass_vt = mono_class_vtable (domain, klass);
361                 if ((klassc->interface_id <= klass->max_interface_id) &&
362                     klass_vt->interface_offsets [klassc->interface_id])
363                         return 1;
364         } else if (check_interfaces && (klassc->flags & TYPE_ATTRIBUTE_INTERFACE) && (klass->flags & TYPE_ATTRIBUTE_INTERFACE)) {
365                 int i;
366
367                 for (i = 0; i < klass->interface_count; i ++) {
368                         MonoClass *ic =  klass->interfaces [i];
369                         if (ic == klassc)
370                                 return 1;
371                 }
372         } else {
373                 /*
374                  * klass->baseval is 0 for interfaces 
375                  */
376                 if (klass->baseval && ((klass->baseval - klassc->baseval) <= klassc->diffval))
377                         return 1;
378         }
379         return 0;
380 }
381
382 static guint32
383 ves_icall_get_attributes (MonoReflectionType *type)
384 {
385         MonoClass *klass = mono_class_from_mono_type (type->type);
386
387         return klass->flags;
388 }
389
390 static void
391 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
392 {
393         MonoDomain *domain = mono_domain_get (); 
394
395         info->parent = mono_type_get_object (domain, &method->klass->byval_arg);
396         info->ret = mono_type_get_object (domain, method->signature->ret);
397         info->name = mono_string_new (domain, method->name);
398         info->attrs = method->flags;
399         info->implattrs = method->iflags;
400 }
401
402 static MonoArray*
403 ves_icall_get_parameter_info (MonoMethod *method)
404 {
405         MonoDomain *domain = mono_domain_get (); 
406         MonoArray *res;
407         static MonoClass *System_Reflection_ParameterInfo;
408         MonoReflectionParameter** args;
409         int i;
410
411         args = mono_param_get_objects (domain, method);
412         if (!System_Reflection_ParameterInfo)
413                 System_Reflection_ParameterInfo = mono_class_from_name (
414                         mono_defaults.corlib, "System.Reflection", "ParameterInfo");
415         res = mono_array_new (domain, System_Reflection_ParameterInfo, method->signature->param_count);
416         for (i = 0; i < method->signature->param_count; ++i) {
417                 mono_array_set (res, gpointer, i, args [i]);
418         }
419         return res;
420 }
421
422 static void
423 ves_icall_get_field_info (MonoReflectionField *field, MonoFieldInfo *info)
424 {
425         MonoDomain *domain = mono_domain_get (); 
426
427         info->parent = mono_type_get_object (domain, &field->klass->byval_arg);
428         info->type = mono_type_get_object (domain, field->field->type);
429         info->name = mono_string_new (domain, field->field->name);
430         info->attrs = field->field->type->attrs;
431 }
432
433 static MonoObject *
434 ves_icall_MonoField_GetValue (MonoReflectionField *field, MonoObject *obj) {
435         MonoObject *res;
436         MonoClass *klass;
437         MonoType *ftype = field->field->type;
438         int type = ftype->type;
439         char *p, *r;
440         guint32 align;
441
442         mono_class_init (field->klass);
443         if (ftype->attrs & FIELD_ATTRIBUTE_STATIC) {
444                 MonoVTable *vtable;
445                 vtable = mono_class_vtable (mono_domain_get (), field->klass);
446                 p = (char*)(vtable->data) + field->field->offset;
447         } else {
448                 p = (char*)obj + field->field->offset;
449         }
450
451         switch (type) {
452         case MONO_TYPE_OBJECT:
453         case MONO_TYPE_STRING:
454         case MONO_TYPE_SZARRAY:
455         case MONO_TYPE_ARRAY:
456                 return *(MonoObject**)p;
457         }
458         klass = mono_class_from_mono_type (ftype);
459         res = mono_object_new (mono_domain_get (), klass);
460         r = (char*)res + sizeof (MonoObject);
461         memcpy (r, p, mono_class_value_size (klass, &align));
462
463         return res;
464 }
465
466 static void
467 ves_icall_get_property_info (MonoReflectionProperty *property, MonoPropertyInfo *info)
468 {
469         MonoDomain *domain = mono_domain_get (); 
470
471         info->parent = mono_type_get_object (domain, &property->klass->byval_arg);
472         info->name = mono_string_new (domain, property->property->name);
473         info->attrs = property->property->attrs;
474         info->get = property->property->get ? mono_method_get_object (domain, property->property->get): NULL;
475         info->set = property->property->set ? mono_method_get_object (domain, property->property->set): NULL;
476         /* 
477          * There may be other methods defined for properties, though, it seems they are not exposed 
478          * in the reflection API 
479          */
480 }
481
482 static void
483 ves_icall_get_type_info (MonoType *type, MonoTypeInfo *info)
484 {
485         MonoDomain *domain = mono_domain_get (); 
486         MonoClass *class = mono_class_from_mono_type (type);
487         MonoClass *parent;
488         MonoArray *intf;
489         int ninterf, i;
490         
491         info->parent = class->parent ? mono_type_get_object (domain, &class->parent->byval_arg): NULL;
492         info->name = mono_string_new (domain, class->name);
493         info->name_space = mono_string_new (domain, class->name_space);
494         info->attrs = class->flags;
495         info->rank = class->rank;
496         info->assembly = NULL; /* FIXME */
497         if (class->enumtype)
498                 info->etype = mono_type_get_object (domain, class->enum_basetype);
499         else if (class->element_class)
500                 info->etype = mono_type_get_object (domain, &class->element_class->byval_arg);
501         else
502                 info->etype = NULL;
503
504         ninterf = 0;
505         for (parent = class; parent; parent = parent->parent) {
506                 ninterf += parent->interface_count;
507         }
508         intf = mono_array_new (domain, mono_defaults.monotype_class, ninterf);
509         ninterf = 0;
510         for (parent = class; parent; parent = parent->parent) {
511                 for (i = 0; i < parent->interface_count; ++i) {
512                         mono_array_set (intf, gpointer, ninterf, mono_type_get_object (domain, &parent->interfaces [i]->byval_arg));
513                         ++ninterf;
514                 }
515         }
516         info->interfaces = intf;
517 }
518
519 static MonoObject*
520 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoArray *params) {
521         //MonoMethodSignature *sig = method->method->signature;
522
523         /*
524          * Do we need to copy the values so that the called method can't change them?
525          */
526
527         return NULL;
528 }
529
530 static MonoObject *
531 ves_icall_System_Enum_ToObject (MonoReflectionType *type, MonoObject *obj)
532 {
533         MonoDomain *domain = mono_domain_get (); 
534         MonoClass *enumc;
535         gint32 s1, s2;
536         MonoObject *res;
537         
538         MONO_CHECK_ARG_NULL (type);
539         MONO_CHECK_ARG_NULL (obj);
540
541         enumc = mono_class_from_mono_type (type->type);
542
543         MONO_CHECK_ARG (obj, enumc->enumtype == TRUE);
544         MONO_CHECK_ARG (obj, obj->vtable->klass->byval_arg.type >= MONO_TYPE_I1 &&  
545                         obj->vtable->klass->byval_arg.type <= MONO_TYPE_U8);
546
547         
548         s1 = mono_class_value_size (enumc, NULL);
549         s2 = mono_class_value_size (obj->vtable->klass, NULL);
550
551         res = mono_object_new (domain, enumc);
552
553 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
554         memcpy ((gpointer)res + sizeof (MonoObject), (gpointer)obj + sizeof (MonoObject), MIN (s1, s2));
555 #else
556         memcpy ((gpointer)res + sizeof (MonoObject) + (s1 > s2 ? s1 - s2 : 0),
557                 (gpointer)obj + sizeof (MonoObject) + (s2 > s1 ? s2 - s1 : 0),
558                 MIN (s1, s2));
559 #endif
560         return res;
561 }
562
563 static MonoObject *
564 ves_icall_System_Enum_get_value (MonoObject *this)
565 {
566         MonoDomain *domain = mono_domain_get (); 
567         MonoObject *res;
568         MonoClass *enumc;
569         gpointer dst;
570         gpointer src;
571         int size;
572
573         if (!this)
574                 return NULL;
575
576         g_assert (this->vtable->klass->enumtype);
577         
578         enumc = mono_class_from_mono_type (this->vtable->klass->enum_basetype);
579         res = mono_object_new (domain, enumc);
580         dst = (gpointer)res + sizeof (MonoObject);
581         src = (gpointer)this + sizeof (MonoObject);
582         size = mono_class_value_size (enumc, NULL);
583
584         memcpy (dst, src, size);
585
586         return res;
587 }
588
589 static void
590 ves_icall_get_enum_info (MonoReflectionType *type, MonoEnumInfo *info)
591 {
592         MonoDomain *domain = mono_domain_get (); 
593         MonoClass *enumc = mono_class_from_mono_type (type->type);
594         guint i, j, nvalues, crow;
595         MonoClassField *field;
596         
597         info->utype = mono_type_get_object (domain, enumc->enum_basetype);
598         nvalues = enumc->field.count - 1;
599         info->names = mono_array_new (domain, mono_defaults.string_class, nvalues);
600         info->values = mono_array_new (domain, mono_class_from_mono_type (enumc->enum_basetype), nvalues);
601         
602         for (i = 0, j = 0; i < enumc->field.count; ++i) {
603                 field = &enumc->fields [i];
604                 if (strcmp ("value__", field->name) == 0)
605                         continue;
606                 mono_array_set (info->names, gpointer, j, mono_string_new (domain, field->name));
607                 if (!field->data) {
608                         crow = mono_metadata_get_constant_index (enumc->image, MONO_TOKEN_FIELD_DEF | (i+enumc->field.first+1));
609                         crow = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_VALUE);
610                         /* 1 is the length of the blob */
611                         field->data = 1 + mono_metadata_blob_heap (enumc->image, crow);
612                 }
613                 switch (enumc->enum_basetype->type) {
614                 case MONO_TYPE_U1:
615                 case MONO_TYPE_I1:
616                         mono_array_set (info->values, gchar, j, *field->data);
617                         break;
618                 case MONO_TYPE_CHAR:
619                 case MONO_TYPE_U2:
620                 case MONO_TYPE_I2:
621                         mono_array_set (info->values, gint16, j, read16 (field->data));
622                         break;
623                 case MONO_TYPE_U4:
624                 case MONO_TYPE_I4:
625                         mono_array_set (info->values, gint32, j, read32 (field->data));
626                         break;
627                 case MONO_TYPE_U8:
628                 case MONO_TYPE_I8:
629                         mono_array_set (info->values, gint64, j, read64 (field->data));
630                         break;
631                 default:
632                         g_error ("Implement type 0x%02x in get_enum_info", enumc->enum_basetype->type);
633                 }
634                 ++j;
635         }
636 }
637
638 static MonoMethod*
639 search_method (MonoReflectionType *type, char *name, guint32 flags, MonoArray *args)
640 {
641         MonoClass *klass, *start_class;
642         MonoMethod *m;
643         MonoReflectionType *paramt;
644         int i, j;
645
646         start_class = klass = mono_class_from_mono_type (type->type);
647         while (klass) {
648                 for (i = 0; i < klass->method.count; ++i) {
649                         m = klass->methods [i];
650                         if (!((m->flags & flags) == flags))
651                                 continue;
652                         if (strcmp(m->name, name))
653                                 continue;
654                         if (m->signature->param_count != mono_array_length (args))
655                                 continue;
656                         for (j = 0; j < m->signature->param_count; ++j) {
657                                 paramt = mono_array_get (args, MonoReflectionType*, j);
658                                 if (!mono_metadata_type_equal (paramt->type, m->signature->params [j]))
659                                         break;
660                         }
661                         if (j == m->signature->param_count)
662                                 return m;
663                 }
664                 klass = klass->parent;
665         }
666         g_print ("Method %s.%s::%s (%d) not found\n", start_class->name_space, start_class->name, name, mono_array_length (args));
667         return NULL;
668 }
669
670 static MonoReflectionMethod*
671 ves_icall_get_constructor (MonoReflectionType *type, MonoArray *args)
672 {
673         MonoDomain *domain = mono_domain_get (); 
674         MonoMethod *m;
675
676         m = search_method (type, ".ctor", METHOD_ATTRIBUTE_RT_SPECIAL_NAME, args);
677         if (m)
678                 return mono_method_get_object (domain, m);
679         return NULL;
680 }
681
682 static MonoReflectionMethod*
683 ves_icall_get_method (MonoReflectionType *type, MonoString *name, MonoArray *args)
684 {
685         MonoDomain *domain = mono_domain_get (); 
686         MonoMethod *m;
687         char *n = mono_string_to_utf8 (name);
688
689         m = search_method (type, n, 0, args);
690         g_free (n);
691         if (m)
692                 return mono_method_get_object (domain, m);
693         return NULL;
694 }
695
696 static MonoProperty*
697 search_property (MonoClass *klass, char* name, MonoArray *args) {
698         int i;
699         MonoProperty *p;
700
701         /* FIXME: handle args */
702         for (i = 0; i < klass->property.count; ++i) {
703                 p = &klass->properties [i];
704                 if (strcmp (p->name, name) == 0)
705                         return p;
706         }
707         return NULL;
708 }
709
710 static MonoReflectionProperty*
711 ves_icall_get_property (MonoReflectionType *type, MonoString *name, MonoArray *args)
712 {
713         MonoDomain *domain = mono_domain_get (); 
714         MonoProperty *p;
715         MonoClass *class = mono_class_from_mono_type (type->type);
716         char *n = mono_string_to_utf8 (name);
717
718         p = search_property (class, n, args);
719         g_free (n);
720         if (p)
721                 return mono_property_get_object (domain, class, p);
722         return NULL;
723 }
724
725 enum {
726         BFLAGS_IgnoreCase = 1,
727         BFLAGS_DeclaredOnly = 2,
728         BFLAGS_Instance = 4,
729         BFLAGS_Static = 8,
730         BFLAGS_Public = 0x10,
731         BFLAGS_NonPublic = 0x20,
732         BFLAGS_InvokeMethod = 0x100,
733         BFLAGS_CreateInstance = 0x200,
734         BFLAGS_GetField = 0x400,
735         BFLAGS_SetField = 0x800,
736         BFLAGS_GetProperty = 0x1000,
737         BFLAGS_SetProperty = 0x2000,
738         BFLAGS_ExactBinding = 0x10000,
739         BFLAGS_SuppressChangeType = 0x20000,
740         BFLAGS_OptionalParamBinding = 0x40000
741 };
742
743
744 /*
745  * Note: the filter is applied from within corlib.
746  */
747 static MonoArray*
748 ves_icall_type_find_members (MonoReflectionType *type, guint32 membertypes, guint32 bflags)
749 {
750         MonoDomain *domain; 
751         GSList *l = NULL, *tmp;
752         static MonoClass *System_Reflection_MemberInfo;
753         MonoClass *startklass, *klass;
754         MonoArray *res;
755         MonoMethod *method;
756         MonoObject *member;
757         int i, is_ctor, len, match;
758
759         domain = ((MonoObject *)type)->vtable->domain;
760         klass = startklass = mono_class_from_mono_type (type->type);
761
762         /* FIXME: check the bindingflags */
763 handle_parent:  
764         if (membertypes & (1|8)) { /* constructors and methods */
765                 for (i = 0; i < klass->method.count; ++i) {
766                         match = 0;
767                         method = klass->methods [i];
768                         if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
769                                 if (bflags & BFLAGS_Public)
770                                         match++;
771                         } else {
772                                 if (bflags & BFLAGS_NonPublic)
773                                         match++;
774                         }
775                         if (!match)
776                                 continue;
777                         match = 0;
778                         if (method->flags & METHOD_ATTRIBUTE_STATIC) {
779                                 if (bflags & BFLAGS_Static)
780                                         match++;
781                         } else {
782                                 if (bflags & BFLAGS_Instance)
783                                         match++;
784                         }
785
786                         if (!match)
787                                 continue;
788                         match = 0;
789                         member = (MonoObject*)mono_method_get_object (domain, method);
790                         
791                         is_ctor = strcmp (method->name, ".ctor") == 0 ||
792                                         strcmp (method->name, ".cctor") == 0;
793                         if (is_ctor && (membertypes & 1)) {
794                                 l = g_slist_prepend (l, member);
795                                 continue;
796                         }
797                         if (!is_ctor && (membertypes & 8)) {
798                                 l = g_slist_prepend (l, member);
799                         }
800                 }
801         }
802         if (membertypes & 4) { /* fields */
803                 MonoClassField *field;
804                 for (i = 0; i < klass->field.count; ++i) {
805                         match = 0;
806                         field = &klass->fields [i];
807                         if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
808                                 if (bflags & BFLAGS_Public)
809                                         match++;
810                         } else {
811                                 if (bflags & BFLAGS_NonPublic)
812                                         match++;
813                         }
814                         if (!match)
815                                 continue;
816                         match = 0;
817                         if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
818                                 if (bflags & BFLAGS_Static)
819                                         match++;
820                         } else {
821                                 if (bflags & BFLAGS_Instance)
822                                         match++;
823                         }
824
825                         if (!match)
826                                 continue;
827                         member = (MonoObject*)mono_field_get_object (domain, klass, field);
828                         l = g_slist_prepend (l, member);
829                 }
830         }
831         if (membertypes & 16) { /* properties */
832                 MonoProperty *prop;
833                 for (i = 0; i < klass->property.count; ++i) {
834                         prop = &klass->properties [i];
835                         match = 0;
836                         method = prop->get;
837                         if (!method)
838                                 method = prop->set;
839                         if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
840                                 if (bflags & BFLAGS_Public)
841                                         match++;
842                         } else {
843                                 if (bflags & BFLAGS_NonPublic)
844                                         match++;
845                         }
846                         if (!match)
847                                 continue;
848                         match = 0;
849                         if (method->flags & METHOD_ATTRIBUTE_STATIC) {
850                                 if (bflags & BFLAGS_Static)
851                                         match++;
852                         } else {
853                                 if (bflags & BFLAGS_Instance)
854                                         match++;
855                         }
856
857                         if (!match)
858                                 continue;
859                         match = 0;
860                         l = g_slist_prepend (l, mono_property_get_object (domain, klass, prop));
861                 }
862         }
863         if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
864                 goto handle_parent;
865         len = g_slist_length (l);
866         if (!System_Reflection_MemberInfo)
867                 System_Reflection_MemberInfo = mono_class_from_name (
868                         mono_defaults.corlib, "System.Reflection", "MemberInfo");
869         res = mono_array_new (domain, System_Reflection_MemberInfo, len);
870         i = 0;
871         tmp = l;
872         for (; tmp; tmp = tmp->next, ++i)
873                 mono_array_set (res, gpointer, i, tmp->data);
874         g_slist_free (l);
875         return res;
876 }
877
878 static gpointer
879 ves_icall_System_Runtime_InteropServices_Marshal_ReadIntPtr (gpointer ptr)
880 {
881         return (gpointer)(*(int *)ptr);
882 }
883
884 static MonoString*
885 ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringAuto (gpointer ptr)
886 {
887         MonoDomain *domain = mono_domain_get (); 
888
889         return mono_string_new (domain, (char *)ptr);
890 }
891
892 static guint32 ves_icall_System_Runtime_InteropServices_Marshal_GetLastWin32Error(void)
893 {
894         return(GetLastError());
895 }
896
897 static MonoReflectionType*
898 ves_icall_System_Reflection_Assembly_GetType (MonoReflectionAssembly *assembly, MonoString *type, MonoBoolean throwOnError, MonoBoolean ignoreCase)
899 {
900         MonoDomain *domain = mono_domain_get (); 
901         /* FIXME : use ignoreCase */
902         gchar *name, *namespace, *str;
903         char *byref, *isarray, *ispointer;
904         guint rank;
905         MonoClass *klass;
906
907         str = namespace = mono_string_to_utf8 (type);
908         /*g_print ("requested type %s in %s\n", str, assembly->assembly->name);*/
909
910         name = strrchr (str, '.');
911         byref = strrchr (str, '&');
912         ispointer = strrchr (str, '*');
913         if (byref)
914                 *byref = 0;
915         if (ispointer)
916                 *ispointer = 0;
917         isarray = strrchr (str, '[');
918         if (isarray) {
919                 rank = 1;
920                 *isarray = 0;
921                 while (*isarray) {
922                         if (*isarray == ',')
923                                 rank++;
924                         if (*isarray == ']')
925                                 break;
926                         ++isarray;
927                 }
928         }
929
930         if (name) {
931                 *name = 0;
932                 ++name;
933         } else {
934                 namespace = "";
935                 name = str;
936         }
937
938         klass = mono_class_from_name (assembly->assembly->image, namespace, name);
939         g_free (str);
940         if (!klass) {
941                 if (throwOnError)
942                         mono_raise_exception (mono_get_exception_type_load ());
943                 return NULL;
944         }
945         if (!klass->inited)
946                 mono_class_init (klass);
947
948         if (isarray) {
949                 klass = mono_array_class_get (klass, rank);
950                 mono_class_init (klass);
951                 /*g_print ("got array class %s [%d] (0x%x)\n", klass->element_class->name, klass->rank, klass->this_arg.type);*/
952         }
953
954         if (byref || ispointer)
955                 return mono_type_get_object (domain, &klass->this_arg);
956         else
957                 return mono_type_get_object (domain, &klass->byval_arg);
958 }
959
960 static MonoString *
961 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *assembly)
962 {
963         MonoDomain *domain = mono_domain_get (); 
964         MonoString *res;
965         char *name = g_strconcat (
966                 "file://", assembly->assembly->image->name, NULL);
967         
968         res = mono_string_new (domain, name);
969         g_free (name);
970         return res;
971 }
972
973 static MonoString *
974 ves_icall_System_MonoType_assQualifiedName (MonoReflectionType *object)
975 {
976         MonoDomain *domain = mono_domain_get (); 
977         /* FIXME : real rules are more complicated (internal classes,
978           reference types, array types, etc. */
979         MonoString *res;
980         gchar *fullname;
981         MonoClass *klass;
982         char *append = NULL;
983
984         switch (object->type->type) {
985         case MONO_TYPE_SZARRAY:
986                 klass = object->type->data.type->data.klass;
987                 append = "[]";
988                 break;
989         case MONO_TYPE_PTR:
990                 klass = object->type->data.type->data.klass;
991                 append = "*";
992                 break;
993         default:
994                 klass = object->type->data.klass;
995                 break;
996         }
997
998         fullname = g_strconcat (klass->name_space, ".",
999                                    klass->name, append, ",",
1000                                    klass->image->assembly_name, NULL);
1001         res = mono_string_new (domain, fullname);
1002         g_free (fullname);
1003
1004         return res;
1005 }
1006
1007 static MonoReflectionType*
1008 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionType *tb, gint32 arrayrank, MonoBoolean isbyref)
1009 {
1010         MonoClass *klass;
1011
1012         klass = mono_class_from_mono_type (tb->type);
1013         if (arrayrank)
1014                 klass = mono_array_class_get (klass, arrayrank);
1015         return mono_type_get_object (mono_domain_get (), isbyref? &klass->this_arg: &klass->byval_arg);
1016 }
1017
1018 static MonoString *
1019 ves_icall_System_PAL_GetCurrentDirectory (MonoObject *object)
1020 {
1021         MonoDomain *domain = mono_domain_get (); 
1022         MonoString *res;
1023         gchar *path = g_get_current_dir ();
1024         res = mono_string_new (domain, path);
1025         g_free (path);
1026         return res;
1027 }
1028
1029 /*
1030  * Magic number to convert a time which is relative to
1031  * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
1032  */
1033 #define EPOCH_ADJUST    ((gint64)62135596800L)
1034
1035 static gint64
1036 ves_icall_System_DateTime_GetNow ()
1037 {
1038 #ifndef PLATFORM_WIN32
1039         /* FIXME: put this in io-layer and call it GetLocalTime */
1040         struct timeval tv;
1041         gint64 res;
1042
1043         if (gettimeofday (&tv, NULL) == 0) {
1044                 res = (((gint64)tv.tv_sec + EPOCH_ADJUST)* 1000000 + tv.tv_usec)*10;
1045                 return res;
1046         }
1047
1048         /* fixme: raise exception */
1049 #endif
1050         return 0;
1051 }
1052
1053 /*
1054  * This is heavily based on zdump.c from glibc 2.2.
1055  *
1056  *  * data[0]:  start of daylight saving time (in DateTime ticks).
1057  *  * data[1]:  end of daylight saving time (in DateTime ticks).
1058  *  * data[2]:  utcoffset (in TimeSpan ticks).
1059  *  * data[3]:  additional offset when daylight saving (in TimeSpan ticks).
1060  *  * name[0]:  name of this timezone when not daylight saving.
1061  *  * name[1]:  name of this timezone when daylight saving.
1062  *
1063  *  FIXME: This only works with "standard" Unix dates (years between 1900 and 2100) while
1064  *         the class library allows years between 1 and 9999.
1065  *
1066  *  Returns true on success and zero on failure.
1067  */
1068 static guint32
1069 ves_icall_System_CurrentTimeZone_GetTimeZoneData (guint32 year, MonoArray **data, MonoArray **names)
1070 {
1071 #ifndef PLATFORM_WIN32
1072         MonoDomain *domain = mono_domain_get ();
1073         struct tm start, tt;
1074         time_t t;
1075
1076         long int gmtoff;
1077         int is_daylight = 0, day;
1078
1079         memset (&start, 0, sizeof (start));
1080
1081         start.tm_mday = 1;
1082         start.tm_year = year-1900;
1083
1084         t = mktime (&start);
1085         gmtoff = start.tm_gmtoff;
1086
1087         MONO_CHECK_ARG_NULL (data);
1088         MONO_CHECK_ARG_NULL (names);
1089
1090         (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
1091         (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
1092
1093         /* For each day of the year, calculate the tm_gmtoff. */
1094         for (day = 0; day < 365; day++) {
1095
1096                 t += 3600*24;
1097                 tt = *localtime (&t);
1098
1099                 /* Daylight saving starts or ends here. */
1100                 if (tt.tm_gmtoff != gmtoff) {
1101                         struct tm tt1;
1102                         time_t t1;
1103
1104                         /* Try to find the exact hour when daylight saving starts/ends. */
1105                         t1 = t;
1106                         do {
1107                                 t1 -= 3600;
1108                                 tt1 = *localtime (&t1);
1109                         } while (tt1.tm_gmtoff != gmtoff);
1110
1111                         /* Try to find the exact minute when daylight saving starts/ends. */
1112                         do {
1113                                 t1 += 60;
1114                                 tt1 = *localtime (&t1);
1115                         } while (tt1.tm_gmtoff == gmtoff);
1116
1117                         /* Write data, if we're already in daylight saving, we're done. */
1118                         if (is_daylight) {
1119                                 mono_array_set ((*names), gpointer, 0, mono_string_new (domain, tt.tm_zone));
1120                                 mono_array_set ((*data), gint64, 1, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
1121                                 return 1;
1122                         } else {
1123                                 mono_array_set ((*names), gpointer, 1, mono_string_new (domain, tt.tm_zone));
1124                                 mono_array_set ((*data), gint64, 0, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
1125                                 is_daylight = 1;
1126                         }
1127
1128                         /* This is only set once when we enter daylight saving. */
1129                         mono_array_set ((*data), gint64, 2, (gint64)gmtoff * 10000000L);
1130                         mono_array_set ((*data), gint64, 3, (gint64)(tt.tm_gmtoff - gmtoff) * 10000000L);
1131
1132                         gmtoff = tt.tm_gmtoff;
1133                 }
1134
1135                 gmtoff = tt.tm_gmtoff;
1136         }
1137
1138         return 0;
1139 #endif
1140 }
1141
1142
1143 static gpointer icall_map [] = {
1144         /*
1145          * System.Array
1146          */
1147         "System.Array::GetValue",         ves_icall_System_Array_GetValue,
1148         "System.Array::SetValue",         ves_icall_System_Array_SetValue,
1149         "System.Array::GetRank",          ves_icall_System_Array_GetRank,
1150         "System.Array::GetLength",        ves_icall_System_Array_GetLength,
1151         "System.Array::GetLowerBound",    ves_icall_System_Array_GetLowerBound,
1152         "System.Array::CreateInstanceImpl",   ves_icall_System_Array_CreateInstanceImpl,
1153         "System.Array::FastCopy",         ves_icall_System_Array_FastCopy,
1154         "System.Array::Clone",            mono_array_clone,
1155
1156         /*
1157          * System.Object
1158          */
1159         "System.Object::MemberwiseClone", ves_icall_System_Object_MemberwiseClone,
1160         "System.Object::GetType", ves_icall_System_Object_GetType,
1161
1162         /*
1163          * System.String
1164          */
1165         "System.String::_IsInterned", mono_string_is_interned,
1166         "System.String::_Intern", mono_string_intern,
1167
1168         /*
1169          * System.AppDomain
1170          */
1171         "System.AppDomain::createDomain", ves_icall_System_AppDomain_createDomain,
1172         "System.AppDomain::getCurDomain", ves_icall_System_AppDomain_getCurDomain,
1173         "System.AppDomain::GetData", ves_icall_System_AppDomain_GetData,
1174         "System.AppDomain::SetData", ves_icall_System_AppDomain_SetData,
1175         "System.AppDomain::getSetup", ves_icall_System_AppDomain_getSetup,
1176         "System.AppDomain::getFriendlyName", ves_icall_System_AppDomain_getFriendlyName,
1177         "System.AppDomain::GetAssemblies", ves_icall_System_AppDomain_GetAssemblies,
1178         "System.AppDomain::LoadAssembly", ves_icall_System_AppDomain_LoadAssembly,
1179         "System.AppDomain::Unload", ves_icall_System_AppDomain_Unload,
1180         "System.AppDomain::ExecuteAssembly", ves_icall_System_AppDomain_ExecuteAssembly,
1181
1182         /*
1183          * System.AppDomainSetup
1184          */
1185         "System.AppDomainSetup::InitAppDomainSetup", ves_icall_System_AppDomainSetup_InitAppDomainSetup,
1186
1187         /*
1188          * System.Decimal
1189          */
1190         "System.Decimal::decimal2UInt64", mono_decimal2UInt64,
1191         "System.Decimal::decimal2Int64", mono_decimal2Int64,
1192         "System.Decimal::double2decimal", mono_double2decimal, /* FIXME: wrong signature. */
1193         "System.Decimal::decimalIncr", mono_decimalIncr,
1194         "System.Decimal::decimalSetExponent", mono_decimalSetExponent,
1195         "System.Decimal::decimal2double", mono_decimal2double,
1196         "System.Decimal::decimalFloorAndTrunc", mono_decimalFloorAndTrunc,
1197         "System.Decimal::decimalRound", mono_decimalRound,
1198         "System.Decimal::decimalMult", mono_decimalMult,
1199         "System.Decimal::decimalDiv", mono_decimalDiv,
1200         "System.Decimal::decimalIntDiv", mono_decimalIntDiv,
1201         "System.Decimal::decimalCompare", mono_decimalCompare,
1202         "System.Decimal::string2decimal", mono_string2decimal,
1203         "System.Decimal::decimal2string", mono_decimal2string,
1204
1205         /*
1206          * ModuleBuilder
1207          */
1208         "System.Reflection.Emit.ModuleBuilder::create_modified_type", ves_icall_ModuleBuilder_create_modified_type,
1209         
1210         /*
1211          * AssemblyBuilder
1212          */
1213         "System.Reflection.Emit.AssemblyBuilder::getDataChunk", ves_icall_get_data_chunk,
1214         "System.Reflection.Emit.AssemblyBuilder::getUSIndex", mono_image_insert_string,
1215         "System.Reflection.Emit.AssemblyBuilder::getToken", ves_icall_AssemblyBuilder_getToken,
1216         "System.Reflection.Emit.AssemblyBuilder::basic_init", mono_image_basic_init,
1217
1218         /*
1219          * Reflection stuff.
1220          */
1221         "System.Reflection.MonoMethodInfo::get_method_info", ves_icall_get_method_info,
1222         "System.Reflection.MonoMethodInfo::get_parameter_info", ves_icall_get_parameter_info,
1223         "System.Reflection.MonoFieldInfo::get_field_info", ves_icall_get_field_info,
1224         "System.Reflection.MonoPropertyInfo::get_property_info", ves_icall_get_property_info,
1225         "System.Reflection.MonoMethod::InternalInvoke", ves_icall_InternalInvoke,
1226         "System.MonoCustomAttrs::GetCustomAttributes", mono_reflection_get_custom_attrs,
1227         "System.Reflection.Emit.CustomAttributeBuilder::GetBlob", mono_reflection_get_custom_attrs_blob,
1228         "System.Reflection.MonoField::GetValue", ves_icall_MonoField_GetValue,
1229         
1230         /* System.Enum */
1231
1232         "System.MonoEnumInfo::get_enum_info", ves_icall_get_enum_info,
1233         "System.Enum::get_value", ves_icall_System_Enum_get_value,
1234         "System.Enum::ToObject", ves_icall_System_Enum_ToObject,
1235
1236         /*
1237          * TypeBuilder
1238          */
1239         "System.Reflection.Emit.TypeBuilder::setup_internal_class", mono_reflection_setup_internal_class,
1240         
1241         /*
1242          * MethodBuilder
1243          */
1244         
1245         /*
1246          * System.Type
1247          */
1248         "System.Type::internal_from_name", ves_icall_type_from_name,
1249         "System.Type::internal_from_handle", ves_icall_type_from_handle,
1250         "System.Type::get_constructor", ves_icall_get_constructor,
1251         "System.Type::get_property", ves_icall_get_property,
1252         "System.Type::get_method", ves_icall_get_method,
1253         "System.MonoType::get_attributes", ves_icall_get_attributes,
1254         "System.Type::type_is_subtype_of", ves_icall_type_is_subtype_of,
1255         "System.Type::Equals", ves_icall_type_Equals,
1256         "System.Type::FindMembers", ves_icall_type_find_members,
1257
1258         /*
1259          * System.Runtime.CompilerServices.RuntimeHelpers
1260          */
1261         "System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray", ves_icall_InitializeArray,
1262         
1263         /*
1264          * System.Threading
1265          */
1266         "System.Threading.Thread::Thread_internal", ves_icall_System_Threading_Thread_Thread_internal,
1267         "System.Threading.Thread::Start_internal", ves_icall_System_Threading_Thread_Start_internal,
1268         "System.Threading.Thread::Sleep_internal", ves_icall_System_Threading_Thread_Sleep_internal,
1269         "System.Threading.Thread::CurrentThread_internal", ves_icall_System_Threading_Thread_CurrentThread_internal,
1270         "System.Threading.Thread::Join_internal", ves_icall_System_Threading_Thread_Join_internal,
1271         "System.Threading.Thread::SlotHash_lookup", ves_icall_System_Threading_Thread_SlotHash_lookup,
1272         "System.Threading.Thread::SlotHash_store", ves_icall_System_Threading_Thread_SlotHash_store,
1273         "System.Threading.Monitor::Monitor_exit", ves_icall_System_Threading_Monitor_Monitor_exit,
1274         "System.Threading.Monitor::Monitor_test_owner", ves_icall_System_Threading_Monitor_Monitor_test_owner,
1275         "System.Threading.Monitor::Monitor_test_synchronised", ves_icall_System_Threading_Monitor_Monitor_test_synchronised,
1276         "System.Threading.Monitor::Monitor_pulse", ves_icall_System_Threading_Monitor_Monitor_pulse,
1277         "System.Threading.Monitor::Monitor_pulse_all", ves_icall_System_Threading_Monitor_Monitor_pulse_all,
1278         "System.Threading.Monitor::Monitor_try_enter", ves_icall_System_Threading_Monitor_Monitor_try_enter,
1279         "System.Threading.Monitor::Monitor_wait", ves_icall_System_Threading_Monitor_Monitor_wait,
1280         "System.Threading.Mutex::CreateMutex_internal", ves_icall_System_Threading_Mutex_CreateMutex_internal,
1281         "System.Threading.Mutex::ReleaseMutex_internal", ves_icall_System_Threading_Mutex_ReleaseMutex_internal,
1282         "System.Threading.NativeEventCalls::CreateEvent_internal", ves_icall_System_Threading_Events_CreateEvent_internal,
1283         "System.Threading.NativeEventCalls::SetEvent_internal",    ves_icall_System_Threading_Events_SetEvent_internal,
1284         "System.Threading.NativeEventCalls::ResetEvent_internal",  ves_icall_System_Threading_Events_ResetEvent_internal,
1285
1286         /*
1287          * System.Threading.WaitHandle
1288          */
1289         "System.Threading.WaitHandle::WaitAll_internal", ves_icall_System_Threading_WaitHandle_WaitAll_internal,
1290         "System.Threading.WaitHandle::WaitAny_internal", ves_icall_System_Threading_WaitHandle_WaitAny_internal,
1291         "System.Threading.WaitHandle::WaitOne_internal", ves_icall_System_Threading_WaitHandle_WaitOne_internal,
1292
1293         "System.Runtime.InteropServices.Marshal::ReadIntPtr", ves_icall_System_Runtime_InteropServices_Marshal_ReadIntPtr,
1294         "System.Runtime.InteropServices.Marshal::PtrToStringAuto", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringAuto,
1295         "System.Runtime.InteropServices.Marshal::GetLastWin32Error", ves_icall_System_Runtime_InteropServices_Marshal_GetLastWin32Error,
1296
1297         "System.Reflection.Assembly::GetType", ves_icall_System_Reflection_Assembly_GetType,
1298         "System.Reflection.Assembly::get_code_base", ves_icall_System_Reflection_Assembly_get_code_base,
1299
1300         /*
1301          * System.MonoType.
1302          */
1303         "System.MonoType::assQualifiedName", ves_icall_System_MonoType_assQualifiedName,
1304         "System.MonoType::type_from_obj", mono_type_type_from_obj,
1305         "System.MonoType::get_type_info", ves_icall_get_type_info,
1306
1307         "System.PAL.OpSys::GetCurrentDirectory", ves_icall_System_PAL_GetCurrentDirectory,
1308
1309         /*
1310          * System.PAL.OpSys I/O Services
1311          */
1312         "System.PAL.OpSys::GetStdHandle", ves_icall_System_PAL_OpSys_GetStdHandle,
1313         "System.PAL.OpSys::ReadFile", ves_icall_System_PAL_OpSys_ReadFile,
1314         "System.PAL.OpSys::WriteFile", ves_icall_System_PAL_OpSys_WriteFile,
1315         "System.PAL.OpSys::SetLengthFile", ves_icall_System_PAL_OpSys_SetLengthFile,
1316         "System.PAL.OpSys::OpenFile", ves_icall_System_PAL_OpSys_OpenFile,
1317         "System.PAL.OpSys::CloseFile", ves_icall_System_PAL_OpSys_CloseFile,
1318         "System.PAL.OpSys::SeekFile", ves_icall_System_PAL_OpSys_SeekFile,
1319         "System.PAL.OpSys::DeleteFile", ves_icall_System_PAL_OpSys_DeleteFile,
1320         "System.PAL.OpSys::ExistsFile", ves_icall_System_PAL_OpSys_ExistsFile,
1321         "System.PAL.OpSys::GetFileTime", ves_icall_System_PAL_OpSys_GetFileTime,
1322         "System.PAL.OpSys::SetFileTime", ves_icall_System_PAL_OpSys_SetFileTime,
1323
1324         /*
1325          * System.Net.Sockets I/O Services
1326          */
1327         "System.Net.Sockets.Socket::Socket_internal", ves_icall_System_Net_Sockets_Socket_Socket_internal,
1328         "System.Net.Sockets.Socket::Close_internal", ves_icall_System_Net_Sockets_Socket_Close_internal,
1329         "System.Net.Sockets.SocketException::WSAGetLastError_internal", ves_icall_System_Net_Sockets_SocketException_WSAGetLastError_internal,
1330         "System.Net.Sockets.Socket::Available_internal", ves_icall_System_Net_Sockets_Socket_Available_internal,
1331         "System.Net.Sockets.Socket::Blocking_internal", ves_icall_System_Net_Sockets_Socket_Blocking_internal,
1332         "System.Net.Sockets.Socket::Accept_internal", ves_icall_System_Net_Sockets_Socket_Accept_internal,
1333         "System.Net.Sockets.Socket::Listen_internal", ves_icall_System_Net_Sockets_Socket_Listen_internal,
1334         "System.Net.Sockets.Socket::LocalEndPoint_internal", ves_icall_System_Net_Sockets_Socket_LocalEndPoint_internal,
1335         "System.Net.Sockets.Socket::RemoteEndPoint_internal", ves_icall_System_Net_Sockets_Socket_RemoteEndPoint_internal,
1336         "System.Net.Sockets.Socket::Bind_internal", ves_icall_System_Net_Sockets_Socket_Bind_internal,
1337         "System.Net.Sockets.Socket::Connect_internal", ves_icall_System_Net_Sockets_Socket_Connect_internal,
1338         "System.Net.Sockets.Socket::Receive_internal", ves_icall_System_Net_Sockets_Socket_Receive_internal,
1339         "System.Net.Sockets.Socket::RecvFrom_internal", ves_icall_System_Net_Sockets_Socket_RecvFrom_internal,
1340         "System.Net.Sockets.Socket::Send_internal", ves_icall_System_Net_Sockets_Socket_Send_internal,
1341         "System.Net.Sockets.Socket::SendTo_internal", ves_icall_System_Net_Sockets_Socket_SendTo_internal,
1342         "System.Net.Sockets.Socket::Select_internal", ves_icall_System_Net_Sockets_Socket_Select_internal,
1343         "System.Net.Sockets.Socket::Shutdown_internal", ves_icall_System_Net_Sockets_Socket_Shutdown_internal,
1344         "System.Net.Sockets.Socket::GetSocketOption_obj_internal", ves_icall_System_Net_Sockets_Socket_GetSocketOption_obj_internal,
1345         "System.Net.Sockets.Socket::GetSocketOption_arr_internal", ves_icall_System_Net_Sockets_Socket_GetSocketOption_arr_internal,
1346         "System.Net.Sockets.Socket::SetSocketOption_internal", ves_icall_System_Net_Sockets_Socket_SetSocketOption_internal,
1347         "System.Net.Dns::GetHostByName_internal", ves_icall_System_Net_Dns_GetHostByName_internal,
1348         "System.Net.Dns::GetHostByAddr_internal", ves_icall_System_Net_Dns_GetHostByAddr_internal,
1349
1350         /*
1351          * System.Char
1352          */
1353         "System.Char::GetNumericValue", ves_icall_System_Char_GetNumericValue,
1354         "System.Char::GetUnicodeCategory", ves_icall_System_Char_GetUnicodeCategory,
1355         "System.Char::IsControl", ves_icall_System_Char_IsControl,
1356         "System.Char::IsDigit", ves_icall_System_Char_IsDigit,
1357         "System.Char::IsLetter", ves_icall_System_Char_IsLetter,
1358         "System.Char::IsLower", ves_icall_System_Char_IsLower,
1359         "System.Char::IsUpper", ves_icall_System_Char_IsUpper,
1360         "System.Char::IsNumber", ves_icall_System_Char_IsNumber,
1361         "System.Char::IsPunctuation", ves_icall_System_Char_IsPunctuation,
1362         "System.Char::IsSeparator", ves_icall_System_Char_IsSeparator,
1363         "System.Char::IsSurrogate", ves_icall_System_Char_IsSurrogate,
1364         "System.Char::IsSymbol", ves_icall_System_Char_IsSymbol,
1365         "System.Char::IsWhiteSpace", ves_icall_System_Char_IsWhiteSpace,
1366         "System.Char::ToLower", ves_icall_System_Char_ToLower,
1367         "System.Char::ToUpper", ves_icall_System_Char_ToUpper,
1368
1369         "System.Text.Encoding::IConvNewEncoder", ves_icall_iconv_new_encoder,
1370         "System.Text.Encoding::IConvNewDecoder", ves_icall_iconv_new_decoder,
1371         "System.Text.Encoding::IConvReset", ves_icall_iconv_reset,
1372         "System.Text.Encoding::IConvGetByteCount", ves_icall_iconv_get_byte_count,
1373         "System.Text.Encoding::IConvGetBytes", ves_icall_iconv_get_bytes,
1374         "System.Text.Encoding::IConvGetCharCount", ves_icall_iconv_get_char_count,
1375         "System.Text.Encoding::IConvGetChars", ves_icall_iconv_get_chars,
1376
1377         "System.DateTime::GetNow", ves_icall_System_DateTime_GetNow,
1378         "System.CurrentTimeZone::GetTimeZoneData", ves_icall_System_CurrentTimeZone_GetTimeZoneData,
1379
1380         /*
1381          * System.Security.Cryptography calls
1382          */
1383
1384          "System.Security.Cryptography.RNGCryptoServiceProvider::GetBytes", ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_GetBytes,
1385          "System.Security.Cryptography.RNG_CryptoServiceProvider::GetNonZeroBytes", ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_GetNonZeroBytes,
1386
1387         /*
1388          * add other internal calls here
1389          */
1390         NULL, NULL
1391 };
1392
1393 void
1394 mono_init_icall ()
1395 {
1396         char *n;
1397         int i = 0;
1398
1399         while ((n = icall_map [i])) {
1400                 mono_add_internal_call (n, icall_map [i+1]);
1401                 i += 2;
1402         }
1403        
1404 }
1405
1406