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