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