5 * Dietmar Maurer (dietmar@ximian.com)
6 * Paolo Molaro (lupus@ximian.com)
8 * (C) 2001 Ximian, Inc.
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>
35 ves_icall_System_Array_GetValue (MonoObject *this, MonoObject *idxs)
39 gint32 i, pos, *ind, esize;
42 MONO_CHECK_ARG_NULL (idxs);
44 io = (MonoArray *)idxs;
45 ic = (MonoClass *)io->obj.vtable->klass;
47 ao = (MonoArray *)this;
48 ac = (MonoClass *)ao->obj.vtable->klass;
50 g_assert (ic->rank == 1);
51 if (io->bounds [0].length != ac->rank)
52 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
54 ind = (guint32 *)io->vector;
55 for (i = 0; i < ac->rank; i++)
56 if ((ind [i] < ao->bounds [i].lower_bound) ||
57 (ind [i] >= ao->bounds [i].length + ao->bounds [i].lower_bound))
58 mono_raise_exception (mono_get_exception_index_out_of_range ());
60 pos = ind [0] - ao->bounds [0].lower_bound;
61 for (i = 1; i < ac->rank; i++)
62 pos = pos*ao->bounds [i].length + ind [i] -
63 ao->bounds [i].lower_bound;
65 esize = mono_array_element_size (ac);
66 ea = (gpointer*)((char*)ao->vector + (pos * esize));
68 if (ac->element_class->valuetype)
69 return mono_value_box (this->vtable->domain, ac->element_class, ea);
76 ves_icall_System_Array_SetValue (MonoObject *this, MonoObject *value,
79 MonoArray *ao, *io, *vo;
80 MonoClass *ac, *ic, *vc;
81 gint32 i, pos, *ind, esize;
84 MONO_CHECK_ARG_NULL (idxs);
86 vo = (MonoArray *)value;
88 vc = (MonoClass *)vo->obj.vtable->klass;
92 io = (MonoArray *)idxs;
93 ic = (MonoClass *)io->obj.vtable->klass;
95 ao = (MonoArray *)this;
96 ac = (MonoClass *)ao->obj.vtable->klass;
98 g_assert (ic->rank == 1);
99 if (io->bounds [0].length != ac->rank)
100 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
102 ind = (guint32 *)io->vector;
103 for (i = 0; i < ac->rank; i++)
104 if ((ind [i] < ao->bounds [i].lower_bound) ||
105 (ind [i] >= ao->bounds [i].length + ao->bounds [i].lower_bound))
106 mono_raise_exception (mono_get_exception_index_out_of_range ());
108 if (vo && !mono_object_isinst (value, ac->element_class)) {
109 mono_raise_exception (mono_get_exception_array_type_mismatch ());
113 pos = ind [0] - ao->bounds [0].lower_bound;
114 for (i = 1; i < ac->rank; i++)
115 pos = pos*ao->bounds [i].length + ind [i] -
116 ao->bounds [i].lower_bound;
118 esize = mono_array_element_size (ac);
119 ea = (gpointer*)((char*)ao->vector + (pos * esize));
121 if (ac->element_class->valuetype) {
123 g_assert (vc->valuetype);
124 memcpy (ea, (char *)vo + sizeof (MonoObject), esize);
126 memset (ea, 0, esize);
133 ves_icall_System_Array_CreateInstanceImpl ()
135 g_warning (G_STRLOC ": not implemented");
136 mono_raise_exception (mono_get_exception_not_implemented ());
140 ves_icall_System_Array_GetRank (MonoObject *this)
142 return this->vtable->klass->rank;
146 ves_icall_System_Array_GetLength (MonoArray *this, gint32 dimension)
148 gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
149 if ((dimension < 0) || (dimension >= rank))
150 mono_raise_exception (mono_get_exception_index_out_of_range ());
151 return this->bounds [dimension].length;
155 ves_icall_System_Array_GetLowerBound (MonoArray *this, gint32 dimension)
157 gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
158 if ((dimension < 0) || (dimension >= rank))
159 mono_raise_exception (mono_get_exception_index_out_of_range ());
160 return this->bounds [dimension].lower_bound;
164 ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* dest, int dest_idx, int length)
166 int element_size = mono_array_element_size (source->obj.vtable->klass);
167 void * dest_addr = mono_array_addr_with_size (dest, element_size, dest_idx);
168 void * source_addr = mono_array_addr_with_size (source, element_size, dest_idx);
170 memcpy (dest_addr, source_addr, element_size * length);
174 ves_icall_InitializeArray (MonoArray *array, MonoClassField *field_handle)
176 MonoClass *klass = array->obj.vtable->klass;
177 guint32 size = mono_array_element_size (klass);
180 for (i = 0; i < klass->rank; ++i)
181 size *= array->bounds [i].length;
183 memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
185 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
189 guint ## n *data = (guint ## n *) mono_array_addr (array, char, 0); \
191 for (i = 0; i < size; i += n/8, data++) { \
192 tmp = read ## n (data); \
197 printf ("Initialize array with elements of %s type\n", klass->element_class->name);
199 switch (klass->element_class->byval_arg.type) {
219 ves_icall_System_Object_MemberwiseClone (MonoObject *this)
221 return mono_object_clone (this);
224 static MonoReflectionType *
225 ves_icall_System_Object_GetType (MonoObject *obj)
227 return mono_type_get_object (mono_domain_get (), &obj->vtable->klass->byval_arg);
231 mono_type_type_from_obj (MonoReflectionType *mtype, MonoObject *obj)
233 mtype->type = &obj->vtable->klass->byval_arg;
234 g_assert (mtype->type->type);
238 ves_icall_AssemblyBuilder_getToken (MonoReflectionAssemblyBuilder *assb, MonoObject *obj)
240 return mono_image_create_token (assb->dynamic_assembly, obj);
244 ves_icall_get_data_chunk (MonoReflectionAssemblyBuilder *assb, gint32 type, MonoArray *buf)
248 if (type == 0) { /* get the header */
249 count = mono_image_get_header (assb, (char*)buf->vector, buf->bounds->length);
253 MonoDynamicAssembly *ass = assb->dynamic_assembly;
254 char *p = mono_array_addr (buf, char, 0);
255 count = ass->code.index + ass->meta_size;
256 if (count > buf->bounds->length) {
257 g_print ("assembly data exceed supplied buffer\n");
260 memcpy (p, ass->code.data, ass->code.index);
261 memcpy (p + ass->code.index, ass->assembly.image->raw_metadata, ass->meta_size);
268 static MonoReflectionType*
269 ves_icall_type_from_name (MonoString *name)
271 MonoDomain *domain = mono_domain_get ();
274 MonoTypeNameParse info;
277 str = mono_string_to_utf8 (name);
278 /*g_print ("requested type %s\n", str);*/
279 if (!mono_reflection_parse_type (str, &info)) {
285 image = mono_image_loaded (info.assembly);
286 /* do we need to load if it's not already loaded? */
292 image = mono_defaults.corlib;
293 if (info.nest_name) {
294 klass = mono_class_from_name (image, info.nest_name_space, info.nest_name);
297 mono_class_init (klass);
298 nested = klass->nested_classes;
300 klass = nested->data;
301 if (strcmp (klass->name, info.nest_name) == 0 &&
302 strcmp (klass->name_space, info.nest_name_space) == 0)
308 klass = mono_class_from_name (image, info.name_space, info.name);
313 mono_class_init (klass);
315 klass = mono_array_class_get (klass, info.rank);
317 if (info.isbyref || info.ispointer) /* hack */
318 return mono_type_get_object (domain, &klass->this_arg);
320 return mono_type_get_object (domain, &klass->byval_arg);
323 static MonoReflectionType*
324 ves_icall_type_from_handle (MonoType *handle)
326 MonoDomain *domain = mono_domain_get ();
328 mono_class_init (handle->data.klass);
329 return mono_type_get_object (domain, handle);
333 ves_icall_type_Equals (MonoReflectionType *type, MonoReflectionType *c)
335 if (type->type && c->type)
336 return mono_metadata_type_equal (type->type, c->type);
337 g_print ("type equals\n");
342 ves_icall_type_is_subtype_of (MonoReflectionType *type, MonoReflectionType *c, MonoBoolean check_interfaces)
348 g_assert (type != NULL);
350 domain = ((MonoObject *)type)->vtable->domain;
352 if (!c) /* FIXME: dont know what do do here */
355 klass = mono_class_from_mono_type (type->type);
356 klassc = mono_class_from_mono_type (c->type);
358 /* cut&paste from mono_object_isinst (): keep in sync */
359 if (check_interfaces && (klassc->flags & TYPE_ATTRIBUTE_INTERFACE) && !(klass->flags & TYPE_ATTRIBUTE_INTERFACE)) {
360 MonoVTable *klass_vt = mono_class_vtable (domain, klass);
361 if ((klassc->interface_id <= klass->max_interface_id) &&
362 klass_vt->interface_offsets [klassc->interface_id])
364 } else if (check_interfaces && (klassc->flags & TYPE_ATTRIBUTE_INTERFACE) && (klass->flags & TYPE_ATTRIBUTE_INTERFACE)) {
367 for (i = 0; i < klass->interface_count; i ++) {
368 MonoClass *ic = klass->interfaces [i];
374 * klass->baseval is 0 for interfaces
376 if (klass->baseval && ((klass->baseval - klassc->baseval) <= klassc->diffval))
383 ves_icall_get_attributes (MonoReflectionType *type)
385 MonoClass *klass = mono_class_from_mono_type (type->type);
391 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
393 MonoDomain *domain = mono_domain_get ();
395 info->parent = mono_type_get_object (domain, &method->klass->byval_arg);
396 info->ret = mono_type_get_object (domain, method->signature->ret);
397 info->name = mono_string_new (domain, method->name);
398 info->attrs = method->flags;
399 info->implattrs = method->iflags;
403 ves_icall_get_parameter_info (MonoMethod *method)
405 MonoDomain *domain = mono_domain_get ();
407 static MonoClass *System_Reflection_ParameterInfo;
408 MonoReflectionParameter** args;
411 args = mono_param_get_objects (domain, method);
412 if (!System_Reflection_ParameterInfo)
413 System_Reflection_ParameterInfo = mono_class_from_name (
414 mono_defaults.corlib, "System.Reflection", "ParameterInfo");
415 res = mono_array_new (domain, System_Reflection_ParameterInfo, method->signature->param_count);
416 for (i = 0; i < method->signature->param_count; ++i) {
417 mono_array_set (res, gpointer, i, args [i]);
423 ves_icall_get_field_info (MonoReflectionField *field, MonoFieldInfo *info)
425 MonoDomain *domain = mono_domain_get ();
427 info->parent = mono_type_get_object (domain, &field->klass->byval_arg);
428 info->type = mono_type_get_object (domain, field->field->type);
429 info->name = mono_string_new (domain, field->field->name);
430 info->attrs = field->field->type->attrs;
434 ves_icall_MonoField_GetValue (MonoReflectionField *field, MonoObject *obj) {
437 MonoType *ftype = field->field->type;
438 int type = ftype->type;
442 mono_class_init (field->klass);
443 if (ftype->attrs & FIELD_ATTRIBUTE_STATIC) {
445 vtable = mono_class_vtable (mono_domain_get (), field->klass);
446 p = (char*)(vtable->data) + field->field->offset;
448 p = (char*)obj + field->field->offset;
452 case MONO_TYPE_OBJECT:
453 case MONO_TYPE_STRING:
454 case MONO_TYPE_SZARRAY:
455 case MONO_TYPE_ARRAY:
456 return *(MonoObject**)p;
458 klass = mono_class_from_mono_type (ftype);
459 res = mono_object_new (mono_domain_get (), klass);
460 r = (char*)res + sizeof (MonoObject);
461 memcpy (r, p, mono_class_value_size (klass, &align));
467 ves_icall_get_property_info (MonoReflectionProperty *property, MonoPropertyInfo *info)
469 MonoDomain *domain = mono_domain_get ();
471 info->parent = mono_type_get_object (domain, &property->klass->byval_arg);
472 info->name = mono_string_new (domain, property->property->name);
473 info->attrs = property->property->attrs;
474 info->get = property->property->get ? mono_method_get_object (domain, property->property->get): NULL;
475 info->set = property->property->set ? mono_method_get_object (domain, property->property->set): NULL;
477 * There may be other methods defined for properties, though, it seems they are not exposed
478 * in the reflection API
483 ves_icall_get_type_info (MonoType *type, MonoTypeInfo *info)
485 MonoDomain *domain = mono_domain_get ();
486 MonoClass *class = mono_class_from_mono_type (type);
491 info->parent = class->parent ? mono_type_get_object (domain, &class->parent->byval_arg): NULL;
492 info->name = mono_string_new (domain, class->name);
493 info->name_space = mono_string_new (domain, class->name_space);
494 info->attrs = class->flags;
495 info->rank = class->rank;
496 info->assembly = NULL; /* FIXME */
498 info->etype = mono_type_get_object (domain, class->enum_basetype);
499 else if (class->element_class)
500 info->etype = mono_type_get_object (domain, &class->element_class->byval_arg);
505 for (parent = class; parent; parent = parent->parent) {
506 ninterf += parent->interface_count;
508 intf = mono_array_new (domain, mono_defaults.monotype_class, ninterf);
510 for (parent = class; parent; parent = parent->parent) {
511 for (i = 0; i < parent->interface_count; ++i) {
512 mono_array_set (intf, gpointer, ninterf, mono_type_get_object (domain, &parent->interfaces [i]->byval_arg));
516 info->interfaces = intf;
520 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoArray *params) {
521 //MonoMethodSignature *sig = method->method->signature;
524 * Do we need to copy the values so that the called method can't change them?
531 ves_icall_System_Enum_ToObject (MonoReflectionType *type, MonoObject *obj)
533 MonoDomain *domain = mono_domain_get ();
538 MONO_CHECK_ARG_NULL (type);
539 MONO_CHECK_ARG_NULL (obj);
541 enumc = mono_class_from_mono_type (type->type);
543 MONO_CHECK_ARG (obj, enumc->enumtype == TRUE);
544 MONO_CHECK_ARG (obj, obj->vtable->klass->byval_arg.type >= MONO_TYPE_I1 &&
545 obj->vtable->klass->byval_arg.type <= MONO_TYPE_U8);
548 s1 = mono_class_value_size (enumc, NULL);
549 s2 = mono_class_value_size (obj->vtable->klass, NULL);
551 res = mono_object_new (domain, enumc);
553 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
554 memcpy ((gpointer)res + sizeof (MonoObject), (gpointer)obj + sizeof (MonoObject), MIN (s1, s2));
556 memcpy ((gpointer)res + sizeof (MonoObject) + (s1 > s2 ? s1 - s2 : 0),
557 (gpointer)obj + sizeof (MonoObject) + (s2 > s1 ? s2 - s1 : 0),
564 ves_icall_System_Enum_get_value (MonoObject *this)
566 MonoDomain *domain = mono_domain_get ();
576 g_assert (this->vtable->klass->enumtype);
578 enumc = mono_class_from_mono_type (this->vtable->klass->enum_basetype);
579 res = mono_object_new (domain, enumc);
580 dst = (gpointer)res + sizeof (MonoObject);
581 src = (gpointer)this + sizeof (MonoObject);
582 size = mono_class_value_size (enumc, NULL);
584 memcpy (dst, src, size);
590 ves_icall_get_enum_info (MonoReflectionType *type, MonoEnumInfo *info)
592 MonoDomain *domain = mono_domain_get ();
593 MonoClass *enumc = mono_class_from_mono_type (type->type);
594 guint i, j, nvalues, crow;
595 MonoClassField *field;
597 info->utype = mono_type_get_object (domain, enumc->enum_basetype);
598 nvalues = enumc->field.count - 1;
599 info->names = mono_array_new (domain, mono_defaults.string_class, nvalues);
600 info->values = mono_array_new (domain, mono_class_from_mono_type (enumc->enum_basetype), nvalues);
602 for (i = 0, j = 0; i < enumc->field.count; ++i) {
603 field = &enumc->fields [i];
604 if (strcmp ("value__", field->name) == 0)
606 mono_array_set (info->names, gpointer, j, mono_string_new (domain, field->name));
608 crow = mono_metadata_get_constant_index (enumc->image, MONO_TOKEN_FIELD_DEF | (i+enumc->field.first+1));
609 crow = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_VALUE);
610 /* 1 is the length of the blob */
611 field->data = 1 + mono_metadata_blob_heap (enumc->image, crow);
613 switch (enumc->enum_basetype->type) {
616 mono_array_set (info->values, gchar, j, *field->data);
621 mono_array_set (info->values, gint16, j, read16 (field->data));
625 mono_array_set (info->values, gint32, j, read32 (field->data));
629 mono_array_set (info->values, gint64, j, read64 (field->data));
632 g_error ("Implement type 0x%02x in get_enum_info", enumc->enum_basetype->type);
639 search_method (MonoReflectionType *type, char *name, guint32 flags, MonoArray *args)
641 MonoClass *klass, *start_class;
643 MonoReflectionType *paramt;
646 start_class = klass = mono_class_from_mono_type (type->type);
648 for (i = 0; i < klass->method.count; ++i) {
649 m = klass->methods [i];
650 if (!((m->flags & flags) == flags))
652 if (strcmp(m->name, name))
654 if (m->signature->param_count != mono_array_length (args))
656 for (j = 0; j < m->signature->param_count; ++j) {
657 paramt = mono_array_get (args, MonoReflectionType*, j);
658 if (!mono_metadata_type_equal (paramt->type, m->signature->params [j]))
661 if (j == m->signature->param_count)
664 klass = klass->parent;
666 g_print ("Method %s.%s::%s (%d) not found\n", start_class->name_space, start_class->name, name, mono_array_length (args));
670 static MonoReflectionMethod*
671 ves_icall_get_constructor (MonoReflectionType *type, MonoArray *args)
673 MonoDomain *domain = mono_domain_get ();
676 m = search_method (type, ".ctor", METHOD_ATTRIBUTE_RT_SPECIAL_NAME, args);
678 return mono_method_get_object (domain, m);
682 static MonoReflectionMethod*
683 ves_icall_get_method (MonoReflectionType *type, MonoString *name, MonoArray *args)
685 MonoDomain *domain = mono_domain_get ();
687 char *n = mono_string_to_utf8 (name);
689 m = search_method (type, n, 0, args);
692 return mono_method_get_object (domain, m);
697 search_property (MonoClass *klass, char* name, MonoArray *args) {
701 /* FIXME: handle args */
702 for (i = 0; i < klass->property.count; ++i) {
703 p = &klass->properties [i];
704 if (strcmp (p->name, name) == 0)
710 static MonoReflectionProperty*
711 ves_icall_get_property (MonoReflectionType *type, MonoString *name, MonoArray *args)
713 MonoDomain *domain = mono_domain_get ();
715 MonoClass *class = mono_class_from_mono_type (type->type);
716 char *n = mono_string_to_utf8 (name);
718 p = search_property (class, n, args);
721 return mono_property_get_object (domain, class, p);
726 BFLAGS_IgnoreCase = 1,
727 BFLAGS_DeclaredOnly = 2,
730 BFLAGS_Public = 0x10,
731 BFLAGS_NonPublic = 0x20,
732 BFLAGS_InvokeMethod = 0x100,
733 BFLAGS_CreateInstance = 0x200,
734 BFLAGS_GetField = 0x400,
735 BFLAGS_SetField = 0x800,
736 BFLAGS_GetProperty = 0x1000,
737 BFLAGS_SetProperty = 0x2000,
738 BFLAGS_ExactBinding = 0x10000,
739 BFLAGS_SuppressChangeType = 0x20000,
740 BFLAGS_OptionalParamBinding = 0x40000
745 * Note: the filter is applied from within corlib.
748 ves_icall_type_find_members (MonoReflectionType *type, guint32 membertypes, guint32 bflags)
751 GSList *l = NULL, *tmp;
752 static MonoClass *System_Reflection_MemberInfo;
753 MonoClass *startklass, *klass;
757 int i, is_ctor, len, match;
759 domain = ((MonoObject *)type)->vtable->domain;
760 klass = startklass = mono_class_from_mono_type (type->type);
762 /* FIXME: check the bindingflags */
764 if (membertypes & (1|8)) { /* constructors and methods */
765 for (i = 0; i < klass->method.count; ++i) {
767 method = klass->methods [i];
768 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
769 if (bflags & BFLAGS_Public)
772 if (bflags & BFLAGS_NonPublic)
778 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
779 if (bflags & BFLAGS_Static)
782 if (bflags & BFLAGS_Instance)
789 member = (MonoObject*)mono_method_get_object (domain, method);
791 is_ctor = strcmp (method->name, ".ctor") == 0 ||
792 strcmp (method->name, ".cctor") == 0;
793 if (is_ctor && (membertypes & 1)) {
794 l = g_slist_prepend (l, member);
797 if (!is_ctor && (membertypes & 8)) {
798 l = g_slist_prepend (l, member);
802 if (membertypes & 4) { /* fields */
803 MonoClassField *field;
804 for (i = 0; i < klass->field.count; ++i) {
806 field = &klass->fields [i];
807 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
808 if (bflags & BFLAGS_Public)
811 if (bflags & BFLAGS_NonPublic)
817 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
818 if (bflags & BFLAGS_Static)
821 if (bflags & BFLAGS_Instance)
827 member = (MonoObject*)mono_field_get_object (domain, klass, field);
828 l = g_slist_prepend (l, member);
831 if (membertypes & 16) { /* properties */
833 for (i = 0; i < klass->property.count; ++i) {
834 prop = &klass->properties [i];
839 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
840 if (bflags & BFLAGS_Public)
843 if (bflags & BFLAGS_NonPublic)
849 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
850 if (bflags & BFLAGS_Static)
853 if (bflags & BFLAGS_Instance)
860 l = g_slist_prepend (l, mono_property_get_object (domain, klass, prop));
863 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
865 len = g_slist_length (l);
866 if (!System_Reflection_MemberInfo)
867 System_Reflection_MemberInfo = mono_class_from_name (
868 mono_defaults.corlib, "System.Reflection", "MemberInfo");
869 res = mono_array_new (domain, System_Reflection_MemberInfo, len);
872 for (; tmp; tmp = tmp->next, ++i)
873 mono_array_set (res, gpointer, i, tmp->data);
879 ves_icall_System_Runtime_InteropServices_Marshal_ReadIntPtr (gpointer ptr)
881 return (gpointer)(*(int *)ptr);
885 ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringAuto (gpointer ptr)
887 MonoDomain *domain = mono_domain_get ();
889 return mono_string_new (domain, (char *)ptr);
892 static guint32 ves_icall_System_Runtime_InteropServices_Marshal_GetLastWin32Error(void)
894 return(GetLastError());
897 static MonoReflectionType*
898 ves_icall_System_Reflection_Assembly_GetType (MonoReflectionAssembly *assembly, MonoString *type, MonoBoolean throwOnError, MonoBoolean ignoreCase)
900 MonoDomain *domain = mono_domain_get ();
901 /* FIXME : use ignoreCase */
902 gchar *name, *namespace, *str;
903 char *byref, *isarray, *ispointer;
907 str = namespace = mono_string_to_utf8 (type);
908 /*g_print ("requested type %s in %s\n", str, assembly->assembly->name);*/
910 name = strrchr (str, '.');
911 byref = strrchr (str, '&');
912 ispointer = strrchr (str, '*');
917 isarray = strrchr (str, '[');
938 klass = mono_class_from_name (assembly->assembly->image, namespace, name);
942 mono_raise_exception (mono_get_exception_type_load ());
946 mono_class_init (klass);
949 klass = mono_array_class_get (klass, rank);
950 mono_class_init (klass);
951 /*g_print ("got array class %s [%d] (0x%x)\n", klass->element_class->name, klass->rank, klass->this_arg.type);*/
954 if (byref || ispointer)
955 return mono_type_get_object (domain, &klass->this_arg);
957 return mono_type_get_object (domain, &klass->byval_arg);
961 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *assembly)
963 MonoDomain *domain = mono_domain_get ();
965 char *name = g_strconcat (
966 "file://", assembly->assembly->image->name, NULL);
968 res = mono_string_new (domain, name);
974 ves_icall_System_MonoType_assQualifiedName (MonoReflectionType *object)
976 MonoDomain *domain = mono_domain_get ();
977 /* FIXME : real rules are more complicated (internal classes,
978 reference types, array types, etc. */
984 switch (object->type->type) {
985 case MONO_TYPE_SZARRAY:
986 klass = object->type->data.type->data.klass;
990 klass = object->type->data.type->data.klass;
994 klass = object->type->data.klass;
998 fullname = g_strconcat (klass->name_space, ".",
999 klass->name, append, ",",
1000 klass->image->assembly_name, NULL);
1001 res = mono_string_new (domain, fullname);
1007 static MonoReflectionType*
1008 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionType *tb, gint32 arrayrank, MonoBoolean isbyref)
1012 klass = mono_class_from_mono_type (tb->type);
1014 klass = mono_array_class_get (klass, arrayrank);
1015 return mono_type_get_object (mono_domain_get (), isbyref? &klass->this_arg: &klass->byval_arg);
1019 ves_icall_System_PAL_GetCurrentDirectory (MonoObject *object)
1021 MonoDomain *domain = mono_domain_get ();
1023 gchar *path = g_get_current_dir ();
1024 res = mono_string_new (domain, path);
1030 * Magic number to convert a time which is relative to
1031 * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
1033 #define EPOCH_ADJUST ((gint64)62135596800L)
1036 ves_icall_System_DateTime_GetNow ()
1038 #ifndef PLATFORM_WIN32
1039 /* FIXME: put this in io-layer and call it GetLocalTime */
1043 if (gettimeofday (&tv, NULL) == 0) {
1044 res = (((gint64)tv.tv_sec + EPOCH_ADJUST)* 1000000 + tv.tv_usec)*10;
1048 /* fixme: raise exception */
1054 * This is heavily based on zdump.c from glibc 2.2.
1056 * * data[0]: start of daylight saving time (in DateTime ticks).
1057 * * data[1]: end of daylight saving time (in DateTime ticks).
1058 * * data[2]: utcoffset (in TimeSpan ticks).
1059 * * data[3]: additional offset when daylight saving (in TimeSpan ticks).
1060 * * name[0]: name of this timezone when not daylight saving.
1061 * * name[1]: name of this timezone when daylight saving.
1063 * FIXME: This only works with "standard" Unix dates (years between 1900 and 2100) while
1064 * the class library allows years between 1 and 9999.
1066 * Returns true on success and zero on failure.
1069 ves_icall_System_CurrentTimeZone_GetTimeZoneData (guint32 year, MonoArray **data, MonoArray **names)
1071 #ifndef PLATFORM_WIN32
1072 MonoDomain *domain = mono_domain_get ();
1073 struct tm start, tt;
1077 int is_daylight = 0, day;
1079 memset (&start, 0, sizeof (start));
1082 start.tm_year = year-1900;
1084 t = mktime (&start);
1085 gmtoff = start.tm_gmtoff;
1087 MONO_CHECK_ARG_NULL (data);
1088 MONO_CHECK_ARG_NULL (names);
1090 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
1091 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
1093 /* For each day of the year, calculate the tm_gmtoff. */
1094 for (day = 0; day < 365; day++) {
1097 tt = *localtime (&t);
1099 /* Daylight saving starts or ends here. */
1100 if (tt.tm_gmtoff != gmtoff) {
1104 /* Try to find the exact hour when daylight saving starts/ends. */
1108 tt1 = *localtime (&t1);
1109 } while (tt1.tm_gmtoff != gmtoff);
1111 /* Try to find the exact minute when daylight saving starts/ends. */
1114 tt1 = *localtime (&t1);
1115 } while (tt1.tm_gmtoff == gmtoff);
1117 /* Write data, if we're already in daylight saving, we're done. */
1119 mono_array_set ((*names), gpointer, 0, mono_string_new (domain, tt.tm_zone));
1120 mono_array_set ((*data), gint64, 1, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
1123 mono_array_set ((*names), gpointer, 1, mono_string_new (domain, tt.tm_zone));
1124 mono_array_set ((*data), gint64, 0, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
1128 /* This is only set once when we enter daylight saving. */
1129 mono_array_set ((*data), gint64, 2, (gint64)gmtoff * 10000000L);
1130 mono_array_set ((*data), gint64, 3, (gint64)(tt.tm_gmtoff - gmtoff) * 10000000L);
1132 gmtoff = tt.tm_gmtoff;
1135 gmtoff = tt.tm_gmtoff;
1143 static gpointer icall_map [] = {
1147 "System.Array::GetValue", ves_icall_System_Array_GetValue,
1148 "System.Array::SetValue", ves_icall_System_Array_SetValue,
1149 "System.Array::GetRank", ves_icall_System_Array_GetRank,
1150 "System.Array::GetLength", ves_icall_System_Array_GetLength,
1151 "System.Array::GetLowerBound", ves_icall_System_Array_GetLowerBound,
1152 "System.Array::CreateInstanceImpl", ves_icall_System_Array_CreateInstanceImpl,
1153 "System.Array::FastCopy", ves_icall_System_Array_FastCopy,
1154 "System.Array::Clone", mono_array_clone,
1159 "System.Object::MemberwiseClone", ves_icall_System_Object_MemberwiseClone,
1160 "System.Object::GetType", ves_icall_System_Object_GetType,
1165 "System.String::_IsInterned", mono_string_is_interned,
1166 "System.String::_Intern", mono_string_intern,
1171 "System.AppDomain::createDomain", ves_icall_System_AppDomain_createDomain,
1172 "System.AppDomain::getCurDomain", ves_icall_System_AppDomain_getCurDomain,
1173 "System.AppDomain::GetData", ves_icall_System_AppDomain_GetData,
1174 "System.AppDomain::SetData", ves_icall_System_AppDomain_SetData,
1175 "System.AppDomain::getSetup", ves_icall_System_AppDomain_getSetup,
1176 "System.AppDomain::getFriendlyName", ves_icall_System_AppDomain_getFriendlyName,
1177 "System.AppDomain::GetAssemblies", ves_icall_System_AppDomain_GetAssemblies,
1178 "System.AppDomain::LoadAssembly", ves_icall_System_AppDomain_LoadAssembly,
1179 "System.AppDomain::Unload", ves_icall_System_AppDomain_Unload,
1180 "System.AppDomain::ExecuteAssembly", ves_icall_System_AppDomain_ExecuteAssembly,
1183 * System.AppDomainSetup
1185 "System.AppDomainSetup::InitAppDomainSetup", ves_icall_System_AppDomainSetup_InitAppDomainSetup,
1190 "System.Decimal::decimal2UInt64", mono_decimal2UInt64,
1191 "System.Decimal::decimal2Int64", mono_decimal2Int64,
1192 "System.Decimal::double2decimal", mono_double2decimal, /* FIXME: wrong signature. */
1193 "System.Decimal::decimalIncr", mono_decimalIncr,
1194 "System.Decimal::decimalSetExponent", mono_decimalSetExponent,
1195 "System.Decimal::decimal2double", mono_decimal2double,
1196 "System.Decimal::decimalFloorAndTrunc", mono_decimalFloorAndTrunc,
1197 "System.Decimal::decimalRound", mono_decimalRound,
1198 "System.Decimal::decimalMult", mono_decimalMult,
1199 "System.Decimal::decimalDiv", mono_decimalDiv,
1200 "System.Decimal::decimalIntDiv", mono_decimalIntDiv,
1201 "System.Decimal::decimalCompare", mono_decimalCompare,
1202 "System.Decimal::string2decimal", mono_string2decimal,
1203 "System.Decimal::decimal2string", mono_decimal2string,
1208 "System.Reflection.Emit.ModuleBuilder::create_modified_type", ves_icall_ModuleBuilder_create_modified_type,
1213 "System.Reflection.Emit.AssemblyBuilder::getDataChunk", ves_icall_get_data_chunk,
1214 "System.Reflection.Emit.AssemblyBuilder::getUSIndex", mono_image_insert_string,
1215 "System.Reflection.Emit.AssemblyBuilder::getToken", ves_icall_AssemblyBuilder_getToken,
1216 "System.Reflection.Emit.AssemblyBuilder::basic_init", mono_image_basic_init,
1221 "System.Reflection.MonoMethodInfo::get_method_info", ves_icall_get_method_info,
1222 "System.Reflection.MonoMethodInfo::get_parameter_info", ves_icall_get_parameter_info,
1223 "System.Reflection.MonoFieldInfo::get_field_info", ves_icall_get_field_info,
1224 "System.Reflection.MonoPropertyInfo::get_property_info", ves_icall_get_property_info,
1225 "System.Reflection.MonoMethod::InternalInvoke", ves_icall_InternalInvoke,
1226 "System.MonoCustomAttrs::GetCustomAttributes", mono_reflection_get_custom_attrs,
1227 "System.Reflection.Emit.CustomAttributeBuilder::GetBlob", mono_reflection_get_custom_attrs_blob,
1228 "System.Reflection.MonoField::GetValue", ves_icall_MonoField_GetValue,
1232 "System.MonoEnumInfo::get_enum_info", ves_icall_get_enum_info,
1233 "System.Enum::get_value", ves_icall_System_Enum_get_value,
1234 "System.Enum::ToObject", ves_icall_System_Enum_ToObject,
1239 "System.Reflection.Emit.TypeBuilder::setup_internal_class", mono_reflection_setup_internal_class,
1248 "System.Type::internal_from_name", ves_icall_type_from_name,
1249 "System.Type::internal_from_handle", ves_icall_type_from_handle,
1250 "System.Type::get_constructor", ves_icall_get_constructor,
1251 "System.Type::get_property", ves_icall_get_property,
1252 "System.Type::get_method", ves_icall_get_method,
1253 "System.MonoType::get_attributes", ves_icall_get_attributes,
1254 "System.Type::type_is_subtype_of", ves_icall_type_is_subtype_of,
1255 "System.Type::Equals", ves_icall_type_Equals,
1256 "System.Type::FindMembers", ves_icall_type_find_members,
1259 * System.Runtime.CompilerServices.RuntimeHelpers
1261 "System.Runtime.CompilerServices.RuntimeHelpers::InitializeArray", ves_icall_InitializeArray,
1266 "System.Threading.Thread::Thread_internal", ves_icall_System_Threading_Thread_Thread_internal,
1267 "System.Threading.Thread::Start_internal", ves_icall_System_Threading_Thread_Start_internal,
1268 "System.Threading.Thread::Sleep_internal", ves_icall_System_Threading_Thread_Sleep_internal,
1269 "System.Threading.Thread::CurrentThread_internal", ves_icall_System_Threading_Thread_CurrentThread_internal,
1270 "System.Threading.Thread::Join_internal", ves_icall_System_Threading_Thread_Join_internal,
1271 "System.Threading.Thread::SlotHash_lookup", ves_icall_System_Threading_Thread_SlotHash_lookup,
1272 "System.Threading.Thread::SlotHash_store", ves_icall_System_Threading_Thread_SlotHash_store,
1273 "System.Threading.Monitor::Monitor_exit", ves_icall_System_Threading_Monitor_Monitor_exit,
1274 "System.Threading.Monitor::Monitor_test_owner", ves_icall_System_Threading_Monitor_Monitor_test_owner,
1275 "System.Threading.Monitor::Monitor_test_synchronised", ves_icall_System_Threading_Monitor_Monitor_test_synchronised,
1276 "System.Threading.Monitor::Monitor_pulse", ves_icall_System_Threading_Monitor_Monitor_pulse,
1277 "System.Threading.Monitor::Monitor_pulse_all", ves_icall_System_Threading_Monitor_Monitor_pulse_all,
1278 "System.Threading.Monitor::Monitor_try_enter", ves_icall_System_Threading_Monitor_Monitor_try_enter,
1279 "System.Threading.Monitor::Monitor_wait", ves_icall_System_Threading_Monitor_Monitor_wait,
1280 "System.Threading.Mutex::CreateMutex_internal", ves_icall_System_Threading_Mutex_CreateMutex_internal,
1281 "System.Threading.Mutex::ReleaseMutex_internal", ves_icall_System_Threading_Mutex_ReleaseMutex_internal,
1282 "System.Threading.NativeEventCalls::CreateEvent_internal", ves_icall_System_Threading_Events_CreateEvent_internal,
1283 "System.Threading.NativeEventCalls::SetEvent_internal", ves_icall_System_Threading_Events_SetEvent_internal,
1284 "System.Threading.NativeEventCalls::ResetEvent_internal", ves_icall_System_Threading_Events_ResetEvent_internal,
1287 * System.Threading.WaitHandle
1289 "System.Threading.WaitHandle::WaitAll_internal", ves_icall_System_Threading_WaitHandle_WaitAll_internal,
1290 "System.Threading.WaitHandle::WaitAny_internal", ves_icall_System_Threading_WaitHandle_WaitAny_internal,
1291 "System.Threading.WaitHandle::WaitOne_internal", ves_icall_System_Threading_WaitHandle_WaitOne_internal,
1293 "System.Runtime.InteropServices.Marshal::ReadIntPtr", ves_icall_System_Runtime_InteropServices_Marshal_ReadIntPtr,
1294 "System.Runtime.InteropServices.Marshal::PtrToStringAuto", ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringAuto,
1295 "System.Runtime.InteropServices.Marshal::GetLastWin32Error", ves_icall_System_Runtime_InteropServices_Marshal_GetLastWin32Error,
1297 "System.Reflection.Assembly::GetType", ves_icall_System_Reflection_Assembly_GetType,
1298 "System.Reflection.Assembly::get_code_base", ves_icall_System_Reflection_Assembly_get_code_base,
1303 "System.MonoType::assQualifiedName", ves_icall_System_MonoType_assQualifiedName,
1304 "System.MonoType::type_from_obj", mono_type_type_from_obj,
1305 "System.MonoType::get_type_info", ves_icall_get_type_info,
1307 "System.PAL.OpSys::GetCurrentDirectory", ves_icall_System_PAL_GetCurrentDirectory,
1310 * System.PAL.OpSys I/O Services
1312 "System.PAL.OpSys::GetStdHandle", ves_icall_System_PAL_OpSys_GetStdHandle,
1313 "System.PAL.OpSys::ReadFile", ves_icall_System_PAL_OpSys_ReadFile,
1314 "System.PAL.OpSys::WriteFile", ves_icall_System_PAL_OpSys_WriteFile,
1315 "System.PAL.OpSys::SetLengthFile", ves_icall_System_PAL_OpSys_SetLengthFile,
1316 "System.PAL.OpSys::OpenFile", ves_icall_System_PAL_OpSys_OpenFile,
1317 "System.PAL.OpSys::CloseFile", ves_icall_System_PAL_OpSys_CloseFile,
1318 "System.PAL.OpSys::SeekFile", ves_icall_System_PAL_OpSys_SeekFile,
1319 "System.PAL.OpSys::DeleteFile", ves_icall_System_PAL_OpSys_DeleteFile,
1320 "System.PAL.OpSys::ExistsFile", ves_icall_System_PAL_OpSys_ExistsFile,
1321 "System.PAL.OpSys::GetFileTime", ves_icall_System_PAL_OpSys_GetFileTime,
1322 "System.PAL.OpSys::SetFileTime", ves_icall_System_PAL_OpSys_SetFileTime,
1325 * System.Net.Sockets I/O Services
1327 "System.Net.Sockets.Socket::Socket_internal", ves_icall_System_Net_Sockets_Socket_Socket_internal,
1328 "System.Net.Sockets.Socket::Close_internal", ves_icall_System_Net_Sockets_Socket_Close_internal,
1329 "System.Net.Sockets.SocketException::WSAGetLastError_internal", ves_icall_System_Net_Sockets_SocketException_WSAGetLastError_internal,
1330 "System.Net.Sockets.Socket::Available_internal", ves_icall_System_Net_Sockets_Socket_Available_internal,
1331 "System.Net.Sockets.Socket::Blocking_internal", ves_icall_System_Net_Sockets_Socket_Blocking_internal,
1332 "System.Net.Sockets.Socket::Accept_internal", ves_icall_System_Net_Sockets_Socket_Accept_internal,
1333 "System.Net.Sockets.Socket::Listen_internal", ves_icall_System_Net_Sockets_Socket_Listen_internal,
1334 "System.Net.Sockets.Socket::LocalEndPoint_internal", ves_icall_System_Net_Sockets_Socket_LocalEndPoint_internal,
1335 "System.Net.Sockets.Socket::RemoteEndPoint_internal", ves_icall_System_Net_Sockets_Socket_RemoteEndPoint_internal,
1336 "System.Net.Sockets.Socket::Bind_internal", ves_icall_System_Net_Sockets_Socket_Bind_internal,
1337 "System.Net.Sockets.Socket::Connect_internal", ves_icall_System_Net_Sockets_Socket_Connect_internal,
1338 "System.Net.Sockets.Socket::Receive_internal", ves_icall_System_Net_Sockets_Socket_Receive_internal,
1339 "System.Net.Sockets.Socket::RecvFrom_internal", ves_icall_System_Net_Sockets_Socket_RecvFrom_internal,
1340 "System.Net.Sockets.Socket::Send_internal", ves_icall_System_Net_Sockets_Socket_Send_internal,
1341 "System.Net.Sockets.Socket::SendTo_internal", ves_icall_System_Net_Sockets_Socket_SendTo_internal,
1342 "System.Net.Sockets.Socket::Select_internal", ves_icall_System_Net_Sockets_Socket_Select_internal,
1343 "System.Net.Sockets.Socket::Shutdown_internal", ves_icall_System_Net_Sockets_Socket_Shutdown_internal,
1344 "System.Net.Sockets.Socket::GetSocketOption_obj_internal", ves_icall_System_Net_Sockets_Socket_GetSocketOption_obj_internal,
1345 "System.Net.Sockets.Socket::GetSocketOption_arr_internal", ves_icall_System_Net_Sockets_Socket_GetSocketOption_arr_internal,
1346 "System.Net.Sockets.Socket::SetSocketOption_internal", ves_icall_System_Net_Sockets_Socket_SetSocketOption_internal,
1347 "System.Net.Dns::GetHostByName_internal", ves_icall_System_Net_Dns_GetHostByName_internal,
1348 "System.Net.Dns::GetHostByAddr_internal", ves_icall_System_Net_Dns_GetHostByAddr_internal,
1353 "System.Char::GetNumericValue", ves_icall_System_Char_GetNumericValue,
1354 "System.Char::GetUnicodeCategory", ves_icall_System_Char_GetUnicodeCategory,
1355 "System.Char::IsControl", ves_icall_System_Char_IsControl,
1356 "System.Char::IsDigit", ves_icall_System_Char_IsDigit,
1357 "System.Char::IsLetter", ves_icall_System_Char_IsLetter,
1358 "System.Char::IsLower", ves_icall_System_Char_IsLower,
1359 "System.Char::IsUpper", ves_icall_System_Char_IsUpper,
1360 "System.Char::IsNumber", ves_icall_System_Char_IsNumber,
1361 "System.Char::IsPunctuation", ves_icall_System_Char_IsPunctuation,
1362 "System.Char::IsSeparator", ves_icall_System_Char_IsSeparator,
1363 "System.Char::IsSurrogate", ves_icall_System_Char_IsSurrogate,
1364 "System.Char::IsSymbol", ves_icall_System_Char_IsSymbol,
1365 "System.Char::IsWhiteSpace", ves_icall_System_Char_IsWhiteSpace,
1366 "System.Char::ToLower", ves_icall_System_Char_ToLower,
1367 "System.Char::ToUpper", ves_icall_System_Char_ToUpper,
1369 "System.Text.Encoding::IConvNewEncoder", ves_icall_iconv_new_encoder,
1370 "System.Text.Encoding::IConvNewDecoder", ves_icall_iconv_new_decoder,
1371 "System.Text.Encoding::IConvReset", ves_icall_iconv_reset,
1372 "System.Text.Encoding::IConvGetByteCount", ves_icall_iconv_get_byte_count,
1373 "System.Text.Encoding::IConvGetBytes", ves_icall_iconv_get_bytes,
1374 "System.Text.Encoding::IConvGetCharCount", ves_icall_iconv_get_char_count,
1375 "System.Text.Encoding::IConvGetChars", ves_icall_iconv_get_chars,
1377 "System.DateTime::GetNow", ves_icall_System_DateTime_GetNow,
1378 "System.CurrentTimeZone::GetTimeZoneData", ves_icall_System_CurrentTimeZone_GetTimeZoneData,
1381 * System.Security.Cryptography calls
1384 "System.Security.Cryptography.RNGCryptoServiceProvider::GetBytes", ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_GetBytes,
1385 "System.Security.Cryptography.RNG_CryptoServiceProvider::GetNonZeroBytes", ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_GetNonZeroBytes,
1388 * add other internal calls here
1399 while ((n = icall_map [i])) {
1400 mono_add_internal_call (n, icall_map [i+1]);