5 * Dietmar Maurer (dietmar@ximian.com)
6 * Paolo Molaro (lupus@ximian.com)
7 * Patrik Torstensson (patrik.torstensson@labs2.com)
9 * (C) 2001 Ximian, Inc.
17 #ifdef HAVE_SYS_TIME_H
23 #if defined (PLATFORM_WIN32)
27 #include <mono/metadata/object.h>
28 #include <mono/metadata/threads.h>
29 #include <mono/metadata/threads-types.h>
30 #include <mono/metadata/threadpool.h>
31 #include <mono/metadata/monitor.h>
32 #include <mono/metadata/reflection.h>
33 #include <mono/metadata/assembly.h>
34 #include <mono/metadata/tabledefs.h>
35 #include <mono/metadata/exception.h>
36 #include <mono/metadata/file-io.h>
37 #include <mono/metadata/console-io.h>
38 #include <mono/metadata/socket-io.h>
39 #include <mono/metadata/mono-endian.h>
40 #include <mono/metadata/tokentype.h>
41 #include <mono/metadata/domain-internals.h>
42 #include <mono/metadata/metadata-internals.h>
43 #include <mono/metadata/class-internals.h>
44 #include <mono/metadata/marshal.h>
45 #include <mono/metadata/gc-internal.h>
46 #include <mono/metadata/mono-gc.h>
47 #include <mono/metadata/rand.h>
48 #include <mono/metadata/sysmath.h>
49 #include <mono/metadata/string-icalls.h>
50 #include <mono/metadata/debug-helpers.h>
51 #include <mono/metadata/process.h>
52 #include <mono/metadata/environment.h>
53 #include <mono/metadata/profiler-private.h>
54 #include <mono/metadata/locales.h>
55 #include <mono/metadata/filewatcher.h>
56 #include <mono/metadata/char-conversions.h>
57 #include <mono/metadata/security.h>
58 #include <mono/metadata/mono-config.h>
59 #include <mono/metadata/cil-coff.h>
60 #include <mono/metadata/security-manager.h>
61 #include <mono/io-layer/io-layer.h>
62 #include <mono/utils/strtod.h>
63 #include <mono/utils/monobitset.h>
65 #if defined (PLATFORM_WIN32)
71 static MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void);
74 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional);
76 static inline MonoBoolean
77 is_generic_parameter (MonoType *type)
79 return !type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR);
83 * We expect a pointer to a char, not a string
86 mono_double_ParseImpl (char *ptr, double *result)
95 *result = strtod (ptr, &endptr);
98 *result = bsd_strtod (ptr, &endptr);
101 if (!*ptr || (endptr && *endptr))
108 mono_class_get_throw (MonoImage *image, guint32 type_token)
110 MonoClass *class = mono_class_get (image, type_token);
111 MonoLoaderError *error;
117 error = mono_loader_get_last_error ();
118 g_assert (error != NULL);
120 ex = mono_loader_error_prepare_exception (error);
121 mono_raise_exception (ex);
126 ves_icall_System_Array_GetValueImpl (MonoObject *this, guint32 pos)
135 ao = (MonoArray *)this;
136 ac = (MonoClass *)ao->obj.vtable->klass;
138 esize = mono_array_element_size (ac);
139 ea = (gpointer*)((char*)ao->vector + (pos * esize));
141 if (ac->element_class->valuetype)
142 return mono_value_box (this->vtable->domain, ac->element_class, ea);
148 ves_icall_System_Array_GetValue (MonoObject *this, MonoObject *idxs)
156 MONO_CHECK_ARG_NULL (idxs);
158 io = (MonoArray *)idxs;
159 ic = (MonoClass *)io->obj.vtable->klass;
161 ao = (MonoArray *)this;
162 ac = (MonoClass *)ao->obj.vtable->klass;
164 g_assert (ic->rank == 1);
165 if (io->bounds != NULL || io->max_length != ac->rank)
166 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
168 ind = (gint32 *)io->vector;
170 if (ao->bounds == NULL) {
171 if (*ind < 0 || *ind >= ao->max_length)
172 mono_raise_exception (mono_get_exception_index_out_of_range ());
174 return ves_icall_System_Array_GetValueImpl (this, *ind);
177 for (i = 0; i < ac->rank; i++)
178 if ((ind [i] < ao->bounds [i].lower_bound) ||
179 (ind [i] >= ao->bounds [i].length + ao->bounds [i].lower_bound))
180 mono_raise_exception (mono_get_exception_index_out_of_range ());
182 pos = ind [0] - ao->bounds [0].lower_bound;
183 for (i = 1; i < ac->rank; i++)
184 pos = pos*ao->bounds [i].length + ind [i] -
185 ao->bounds [i].lower_bound;
187 return ves_icall_System_Array_GetValueImpl (this, pos);
191 ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32 pos)
193 MonoClass *ac, *vc, *ec;
205 vc = value->vtable->klass;
209 ac = this->obj.vtable->klass;
210 ec = ac->element_class;
212 esize = mono_array_element_size (ac);
213 ea = (gpointer*)((char*)this->vector + (pos * esize));
214 va = (gpointer*)((char*)value + sizeof (MonoObject));
217 memset (ea, 0, esize);
221 #define NO_WIDENING_CONVERSION G_STMT_START{\
222 mono_raise_exception (mono_get_exception_argument ( \
223 "value", "not a widening conversion")); \
226 #define CHECK_WIDENING_CONVERSION(extra) G_STMT_START{\
227 if (esize < vsize + (extra)) \
228 mono_raise_exception (mono_get_exception_argument ( \
229 "value", "not a widening conversion")); \
232 #define INVALID_CAST G_STMT_START{\
233 mono_raise_exception (mono_get_exception_invalid_cast ()); \
236 /* Check element (destination) type. */
237 switch (ec->byval_arg.type) {
238 case MONO_TYPE_STRING:
239 switch (vc->byval_arg.type) {
240 case MONO_TYPE_STRING:
246 case MONO_TYPE_BOOLEAN:
247 switch (vc->byval_arg.type) {
248 case MONO_TYPE_BOOLEAN:
261 NO_WIDENING_CONVERSION;
268 if (!ec->valuetype) {
269 if (!mono_object_isinst (value, ec))
271 *ea = (gpointer)value;
275 if (mono_object_isinst (value, ec)) {
276 memcpy (ea, (char *)value + sizeof (MonoObject), esize);
283 vsize = mono_class_instance_size (vc) - sizeof (MonoObject);
285 et = ec->byval_arg.type;
286 if (et == MONO_TYPE_VALUETYPE && ec->byval_arg.data.klass->enumtype)
287 et = ec->byval_arg.data.klass->enum_basetype->type;
289 vt = vc->byval_arg.type;
290 if (vt == MONO_TYPE_VALUETYPE && vc->byval_arg.data.klass->enumtype)
291 vt = vc->byval_arg.data.klass->enum_basetype->type;
293 #define ASSIGN_UNSIGNED(etype) G_STMT_START{\
299 case MONO_TYPE_CHAR: \
300 CHECK_WIDENING_CONVERSION(0); \
301 *(etype *) ea = (etype) u64; \
303 /* You can't assign a signed value to an unsigned array. */ \
308 /* You can't assign a floating point number to an integer array. */ \
311 NO_WIDENING_CONVERSION; \
315 #define ASSIGN_SIGNED(etype) G_STMT_START{\
321 CHECK_WIDENING_CONVERSION(0); \
322 *(etype *) ea = (etype) i64; \
324 /* You can assign an unsigned value to a signed array if the array's */ \
325 /* element size is larger than the value size. */ \
330 case MONO_TYPE_CHAR: \
331 CHECK_WIDENING_CONVERSION(1); \
332 *(etype *) ea = (etype) u64; \
334 /* You can't assign a floating point number to an integer array. */ \
337 NO_WIDENING_CONVERSION; \
341 #define ASSIGN_REAL(etype) G_STMT_START{\
345 CHECK_WIDENING_CONVERSION(0); \
346 *(etype *) ea = (etype) r64; \
348 /* All integer values fit into a floating point array, so we don't */ \
349 /* need to CHECK_WIDENING_CONVERSION here. */ \
354 *(etype *) ea = (etype) i64; \
360 case MONO_TYPE_CHAR: \
361 *(etype *) ea = (etype) u64; \
368 u64 = *(guint8 *) va;
371 u64 = *(guint16 *) va;
374 u64 = *(guint32 *) va;
377 u64 = *(guint64 *) va;
383 i64 = *(gint16 *) va;
386 i64 = *(gint32 *) va;
389 i64 = *(gint64 *) va;
392 r64 = *(gfloat *) va;
395 r64 = *(gdouble *) va;
398 u64 = *(guint16 *) va;
400 case MONO_TYPE_BOOLEAN:
401 /* Boolean is only compatible with itself. */
414 NO_WIDENING_CONVERSION;
421 /* If we can't do a direct copy, let's try a widening conversion. */
424 ASSIGN_UNSIGNED (guint16);
426 ASSIGN_UNSIGNED (guint8);
428 ASSIGN_UNSIGNED (guint16);
430 ASSIGN_UNSIGNED (guint32);
432 ASSIGN_UNSIGNED (guint64);
434 ASSIGN_SIGNED (gint8);
436 ASSIGN_SIGNED (gint16);
438 ASSIGN_SIGNED (gint32);
440 ASSIGN_SIGNED (gint64);
442 ASSIGN_REAL (gfloat);
444 ASSIGN_REAL (gdouble);
448 /* Not reached, INVALID_CAST does not return. Just to avoid a compiler warning ... */
452 #undef NO_WIDENING_CONVERSION
453 #undef CHECK_WIDENING_CONVERSION
454 #undef ASSIGN_UNSIGNED
460 ves_icall_System_Array_SetValue (MonoArray *this, MonoObject *value,
468 MONO_CHECK_ARG_NULL (idxs);
470 ic = idxs->obj.vtable->klass;
471 ac = this->obj.vtable->klass;
473 g_assert (ic->rank == 1);
474 if (idxs->bounds != NULL || idxs->max_length != ac->rank)
475 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
477 ind = (gint32 *)idxs->vector;
479 if (this->bounds == NULL) {
480 if (*ind < 0 || *ind >= this->max_length)
481 mono_raise_exception (mono_get_exception_index_out_of_range ());
483 ves_icall_System_Array_SetValueImpl (this, value, *ind);
487 for (i = 0; i < ac->rank; i++)
488 if ((ind [i] < this->bounds [i].lower_bound) ||
489 (ind [i] >= this->bounds [i].length + this->bounds [i].lower_bound))
490 mono_raise_exception (mono_get_exception_index_out_of_range ());
492 pos = ind [0] - this->bounds [0].lower_bound;
493 for (i = 1; i < ac->rank; i++)
494 pos = pos * this->bounds [i].length + ind [i] -
495 this->bounds [i].lower_bound;
497 ves_icall_System_Array_SetValueImpl (this, value, pos);
501 ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
506 gboolean bounded = FALSE;
510 MONO_CHECK_ARG_NULL (type);
511 MONO_CHECK_ARG_NULL (lengths);
513 MONO_CHECK_ARG (lengths, mono_array_length (lengths) > 0);
515 MONO_CHECK_ARG (bounds, mono_array_length (lengths) == mono_array_length (bounds));
517 for (i = 0; i < mono_array_length (lengths); i++)
518 if (mono_array_get (lengths, gint32, i) < 0)
519 mono_raise_exception (mono_get_exception_argument_out_of_range (NULL));
521 if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint32, 0) != 0))
522 /* vectors are not the same as one dimensional arrays with no-zero bounds */
527 aklass = mono_bounded_array_class_get (mono_class_from_mono_type (type->type), mono_array_length (lengths), bounded);
529 sizes = alloca (aklass->rank * sizeof(guint32) * 2);
530 for (i = 0; i < aklass->rank; ++i) {
531 sizes [i] = mono_array_get (lengths, guint32, i);
533 sizes [i + aklass->rank] = mono_array_get (bounds, guint32, i);
535 sizes [i + aklass->rank] = 0;
538 array = mono_array_new_full (mono_object_domain (type), aklass, sizes, sizes + aklass->rank);
544 ves_icall_System_Array_GetRank (MonoObject *this)
548 return this->vtable->klass->rank;
552 ves_icall_System_Array_GetLength (MonoArray *this, gint32 dimension)
554 gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
558 if ((dimension < 0) || (dimension >= rank))
559 mono_raise_exception (mono_get_exception_index_out_of_range ());
561 if (this->bounds == NULL)
562 return this->max_length;
564 return this->bounds [dimension].length;
568 ves_icall_System_Array_GetLowerBound (MonoArray *this, gint32 dimension)
570 gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
574 if ((dimension < 0) || (dimension >= rank))
575 mono_raise_exception (mono_get_exception_index_out_of_range ());
577 if (this->bounds == NULL)
580 return this->bounds [dimension].lower_bound;
584 ves_icall_System_Array_ClearInternal (MonoArray *arr, int idx, int length)
586 int sz = mono_array_element_size (mono_object_class (arr));
587 memset (mono_array_addr_with_size (arr, sz, idx), 0, length * sz);
591 ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* dest, int dest_idx, int length)
596 MonoClass *src_class;
597 MonoClass *dest_class;
602 if (source->obj.vtable->klass->rank != dest->obj.vtable->klass->rank)
605 if (source->bounds || dest->bounds)
608 if ((dest_idx + length > mono_array_length (dest)) ||
609 (source_idx + length > mono_array_length (source)))
612 src_class = source->obj.vtable->klass->element_class;
613 dest_class = dest->obj.vtable->klass->element_class;
616 * Handle common cases.
619 /* Case1: object[] -> valuetype[] (ArrayList::ToArray) */
620 if (src_class == mono_defaults.object_class && dest_class->valuetype) {
621 int has_refs = dest_class->has_references;
622 for (i = source_idx; i < source_idx + length; ++i) {
623 MonoObject *elem = mono_array_get (source, MonoObject*, i);
624 if (elem && !mono_object_isinst (elem, dest_class))
628 element_size = mono_array_element_size (dest->obj.vtable->klass);
629 memset (mono_array_addr_with_size (dest, element_size, dest_idx), 0, element_size * length);
630 for (i = 0; i < length; ++i) {
631 MonoObject *elem = mono_array_get (source, MonoObject*, source_idx + i);
632 void *addr = mono_array_addr_with_size (dest, element_size, dest_idx + i);
636 mono_value_copy (addr, (char *)elem + sizeof (MonoObject), dest_class);
638 memcpy (addr, (char *)elem + sizeof (MonoObject), element_size);
643 /* Check if we're copying a char[] <==> (u)short[] */
644 if (src_class != dest_class) {
645 if (dest_class->valuetype || dest_class->enumtype || src_class->valuetype || src_class->enumtype)
648 if (mono_class_is_subclass_of (src_class, dest_class, FALSE))
650 /* Case2: object[] -> reftype[] (ArrayList::ToArray) */
651 else if (mono_class_is_subclass_of (dest_class, src_class, FALSE))
652 for (i = source_idx; i < source_idx + length; ++i) {
653 MonoObject *elem = mono_array_get (source, MonoObject*, i);
654 if (elem && !mono_object_isinst (elem, dest_class))
661 if (dest_class->valuetype) {
662 element_size = mono_array_element_size (source->obj.vtable->klass);
663 source_addr = mono_array_addr_with_size (source, element_size, source_idx);
664 if (dest_class->has_references) {
665 mono_value_copy_array (dest, dest_idx, source_addr, length);
667 dest_addr = mono_array_addr_with_size (dest, element_size, dest_idx);
668 memmove (dest_addr, source_addr, element_size * length);
671 mono_array_memcpy_refs (dest, dest_idx, source, source_idx, length);
678 ves_icall_System_Array_GetGenericValueImpl (MonoObject *this, guint32 pos, gpointer value)
687 ao = (MonoArray *)this;
688 ac = (MonoClass *)ao->obj.vtable->klass;
690 esize = mono_array_element_size (ac);
691 ea = (gpointer*)((char*)ao->vector + (pos * esize));
693 memcpy (value, ea, esize);
697 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoArray *array, MonoClassField *field_handle)
699 MonoClass *klass = array->obj.vtable->klass;
700 guint32 size = mono_array_element_size (klass);
702 size *= array->max_length;
704 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
706 guint ## n *data = (guint ## n *) mono_array_addr (array, char, 0); \
707 guint ## n *src = (guint ## n *) field_handle->data; \
708 guint ## n *end = (guint ## n *)((char*)src + size); \
710 for (; src < end; data++, src++) { \
711 *data = read ## n (src); \
715 /* printf ("Initialize array with elements of %s type\n", klass->element_class->name); */
717 switch (mono_type_get_underlying_type (&klass->element_class->byval_arg)->type) {
734 memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
738 memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
740 if (klass->element_class->byval_arg.type == MONO_TYPE_R8) {
743 double *data = (double*)mono_array_addr (array, double, 0);
745 for (i = 0; i < size; i++, data++) {
755 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData (void)
759 return offsetof (MonoString, chars);
763 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue (MonoObject *obj)
767 if ((obj == NULL) || (! (obj->vtable->klass->valuetype)))
770 return mono_object_clone (obj);
774 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (MonoType *handle)
780 MONO_CHECK_ARG_NULL (handle);
782 klass = mono_class_from_mono_type (handle);
783 MONO_CHECK_ARG (handle, klass);
785 /* This will call the type constructor */
786 if (! (klass->flags & TYPE_ATTRIBUTE_INTERFACE))
787 mono_runtime_class_init (mono_class_vtable (mono_domain_get (), klass));
791 ves_icall_System_Object_MemberwiseClone (MonoObject *this)
795 return mono_object_clone (this);
799 ves_icall_System_ValueType_InternalGetHashCode (MonoObject *this, MonoArray **fields)
802 MonoObject **values = NULL;
806 MonoClassField* field;
811 klass = mono_object_class (this);
813 if (mono_class_num_fields (klass) == 0)
814 return mono_object_hash (this);
817 * Compute the starting value of the hashcode for fields of primitive
818 * types, and return the remaining fields in an array to the managed side.
819 * This way, we can avoid costly reflection operations in managed code.
822 while ((field = mono_class_get_fields (klass, &iter))) {
823 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
825 if (mono_field_is_deleted (field))
827 /* FIXME: Add more types */
828 switch (field->type->type) {
830 result ^= *(gint32*)((guint8*)this + field->offset);
832 case MONO_TYPE_STRING: {
834 s = *(MonoString**)((guint8*)this + field->offset);
836 result ^= mono_string_hash (s);
841 values = g_newa (MonoObject*, mono_class_num_fields (klass));
842 o = mono_field_get_value_object (mono_object_domain (this), field, this);
843 values [count++] = o;
849 *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
850 for (i = 0; i < count; ++i)
851 mono_array_setref (*fields, i, values [i]);
859 ves_icall_System_ValueType_Equals (MonoObject *this, MonoObject *that, MonoArray **fields)
862 MonoObject **values = NULL;
864 MonoClassField* field;
870 MONO_CHECK_ARG_NULL (that);
872 if (this->vtable != that->vtable)
875 klass = mono_object_class (this);
878 * Do the comparison for fields of primitive type and return a result if
879 * possible. Otherwise, return the remaining fields in an array to the
880 * managed side. This way, we can avoid costly reflection operations in
885 while ((field = mono_class_get_fields (klass, &iter))) {
886 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
888 if (mono_field_is_deleted (field))
890 /* FIXME: Add more types */
891 switch (field->type->type) {
893 if (*(gint32*)((guint8*)this + field->offset) != *(gint32*)((guint8*)that + field->offset))
896 case MONO_TYPE_STRING: {
898 guint32 s1len, s2len;
899 s1 = *(MonoString**)((guint8*)this + field->offset);
900 s2 = *(MonoString**)((guint8*)that + field->offset);
903 if ((s1 == NULL) || (s2 == NULL))
905 s1len = mono_string_length (s1);
906 s2len = mono_string_length (s2);
910 if (memcmp (mono_string_chars (s1), mono_string_chars (s2), s1len * sizeof (gunichar2)) != 0)
916 values = g_newa (MonoObject*, mono_class_num_fields (klass) * 2);
917 o = mono_field_get_value_object (mono_object_domain (this), field, this);
918 values [count++] = o;
919 o = mono_field_get_value_object (mono_object_domain (this), field, that);
920 values [count++] = o;
926 *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
927 for (i = 0; i < count; ++i)
928 mono_array_setref (*fields, i, values [i]);
935 static MonoReflectionType *
936 ves_icall_System_Object_GetType (MonoObject *obj)
940 if (obj->vtable->klass != mono_defaults.transparent_proxy_class)
941 return mono_type_get_object (mono_object_domain (obj), &obj->vtable->klass->byval_arg);
943 return mono_type_get_object (mono_object_domain (obj), &((MonoTransparentProxy*)obj)->remote_class->proxy_class->byval_arg);
947 mono_type_type_from_obj (MonoReflectionType *mtype, MonoObject *obj)
951 mtype->type = &obj->vtable->klass->byval_arg;
952 g_assert (mtype->type->type);
956 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj)
960 MONO_CHECK_ARG_NULL (obj);
962 return mono_image_create_token (mb->dynamic_image, obj, TRUE);
966 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder *mb,
967 MonoReflectionMethod *method,
968 MonoArray *opt_param_types)
972 MONO_CHECK_ARG_NULL (method);
974 return mono_image_create_method_token (
975 mb->dynamic_image, (MonoObject *) method, opt_param_types);
979 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder *mb, HANDLE file)
983 mono_image_create_pefile (mb, file);
987 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
991 mono_image_build_metadata (mb);
995 get_caller (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
997 MonoMethod **dest = data;
999 /* skip unmanaged frames */
1014 static MonoReflectionType *
1015 type_from_name (const char *str, MonoBoolean ignoreCase)
1017 MonoType *type = NULL;
1018 MonoAssembly *assembly = NULL;
1019 MonoTypeNameParse info;
1020 char *temp_str = g_strdup (str);
1021 gboolean type_resolve = FALSE;
1023 MONO_ARCH_SAVE_REGS;
1025 /* mono_reflection_parse_type() mangles the string */
1026 if (!mono_reflection_parse_type (temp_str, &info)) {
1027 g_list_free (info.modifiers);
1028 g_list_free (info.nested);
1033 if (info.assembly.name) {
1034 assembly = mono_assembly_load (&info.assembly, NULL, NULL);
1036 MonoMethod *m = mono_method_get_last_managed ();
1037 MonoMethod *dest = m;
1039 mono_stack_walk_no_il (get_caller, &dest);
1044 * FIXME: mono_method_get_last_managed() sometimes returns NULL, thus
1045 * causing ves_icall_System_Reflection_Assembly_GetCallingAssembly()
1046 * to crash. This only seems to happen in some strange remoting
1047 * scenarios and I was unable to figure out what's happening there.
1048 * Dec 10, 2005 - Martin.
1052 assembly = dest->klass->image->assembly;
1054 g_warning (G_STRLOC);
1059 type = mono_reflection_get_type (assembly->image, &info, ignoreCase, &type_resolve);
1061 if (!info.assembly.name && !type) /* try mscorlib */
1062 type = mono_reflection_get_type (NULL, &info, ignoreCase, &type_resolve);
1064 g_list_free (info.modifiers);
1065 g_list_free (info.nested);
1071 return mono_type_get_object (mono_domain_get (), type);
1075 MonoReflectionType *
1076 mono_type_get (const char *str)
1078 char *copy = g_strdup (str);
1079 MonoReflectionType *type = type_from_name (copy, FALSE);
1086 static MonoReflectionType*
1087 ves_icall_type_from_name (MonoString *name,
1088 MonoBoolean throwOnError,
1089 MonoBoolean ignoreCase)
1091 char *str = mono_string_to_utf8 (name);
1092 MonoReflectionType *type;
1094 type = type_from_name (str, ignoreCase);
1097 MonoException *e = NULL;
1100 e = mono_get_exception_type_load (name, NULL);
1102 mono_loader_clear_error ();
1104 mono_raise_exception (e);
1111 static MonoReflectionType*
1112 ves_icall_type_from_handle (MonoType *handle)
1114 MonoDomain *domain = mono_domain_get ();
1115 MonoClass *klass = mono_class_from_mono_type (handle);
1117 MONO_ARCH_SAVE_REGS;
1119 mono_class_init (klass);
1120 return mono_type_get_object (domain, handle);
1124 ves_icall_System_Type_EqualsInternal (MonoReflectionType *type, MonoReflectionType *c)
1126 MONO_ARCH_SAVE_REGS;
1128 if (c && type->type && c->type)
1129 return mono_metadata_type_equal (type->type, c->type);
1134 /* System.TypeCode */
1153 TYPECODE_STRING = 18
1157 ves_icall_type_GetTypeCodeInternal (MonoReflectionType *type)
1159 int t = type->type->type;
1161 MONO_ARCH_SAVE_REGS;
1163 if (type->type->byref)
1164 return TYPECODE_OBJECT;
1168 case MONO_TYPE_VOID:
1169 return TYPECODE_OBJECT;
1170 case MONO_TYPE_BOOLEAN:
1171 return TYPECODE_BOOLEAN;
1173 return TYPECODE_BYTE;
1175 return TYPECODE_SBYTE;
1177 return TYPECODE_UINT16;
1179 return TYPECODE_INT16;
1180 case MONO_TYPE_CHAR:
1181 return TYPECODE_CHAR;
1185 return TYPECODE_OBJECT;
1187 return TYPECODE_UINT32;
1189 return TYPECODE_INT32;
1191 return TYPECODE_UINT64;
1193 return TYPECODE_INT64;
1195 return TYPECODE_SINGLE;
1197 return TYPECODE_DOUBLE;
1198 case MONO_TYPE_VALUETYPE:
1199 if (type->type->data.klass->enumtype) {
1200 t = type->type->data.klass->enum_basetype->type;
1203 MonoClass *k = type->type->data.klass;
1204 if (strcmp (k->name_space, "System") == 0) {
1205 if (strcmp (k->name, "Decimal") == 0)
1206 return TYPECODE_DECIMAL;
1207 else if (strcmp (k->name, "DateTime") == 0)
1208 return TYPECODE_DATETIME;
1211 return TYPECODE_OBJECT;
1212 case MONO_TYPE_STRING:
1213 return TYPECODE_STRING;
1214 case MONO_TYPE_SZARRAY:
1215 case MONO_TYPE_ARRAY:
1216 case MONO_TYPE_OBJECT:
1218 case MONO_TYPE_MVAR:
1219 case MONO_TYPE_TYPEDBYREF:
1220 return TYPECODE_OBJECT;
1221 case MONO_TYPE_CLASS:
1223 MonoClass *k = type->type->data.klass;
1224 if (strcmp (k->name_space, "System") == 0) {
1225 if (strcmp (k->name, "DBNull") == 0)
1226 return TYPECODE_DBNULL;
1229 return TYPECODE_OBJECT;
1230 case MONO_TYPE_GENERICINST:
1231 return TYPECODE_OBJECT;
1233 g_error ("type 0x%02x not handled in GetTypeCode()", t);
1239 ves_icall_type_is_subtype_of (MonoReflectionType *type, MonoReflectionType *c, MonoBoolean check_interfaces)
1245 MONO_ARCH_SAVE_REGS;
1247 g_assert (type != NULL);
1249 domain = ((MonoObject *)type)->vtable->domain;
1251 if (!c) /* FIXME: dont know what do do here */
1254 klass = mono_class_from_mono_type (type->type);
1255 klassc = mono_class_from_mono_type (c->type);
1257 if (type->type->byref)
1258 return klassc == mono_defaults.object_class;
1260 return mono_class_is_subclass_of (klass, klassc, check_interfaces);
1264 ves_icall_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType *c)
1270 MONO_ARCH_SAVE_REGS;
1272 g_assert (type != NULL);
1274 domain = ((MonoObject *)type)->vtable->domain;
1276 klass = mono_class_from_mono_type (type->type);
1277 klassc = mono_class_from_mono_type (c->type);
1279 if (type->type->byref && !c->type->byref)
1282 return mono_class_is_assignable_from (klass, klassc);
1286 ves_icall_type_IsInstanceOfType (MonoReflectionType *type, MonoObject *obj)
1288 MonoClass *klass = mono_class_from_mono_type (type->type);
1289 return mono_object_isinst (obj, klass) != NULL;
1293 ves_icall_get_attributes (MonoReflectionType *type)
1295 MonoClass *klass = mono_class_from_mono_type (type->type);
1297 MONO_ARCH_SAVE_REGS;
1299 return klass->flags;
1302 static MonoReflectionMarshal*
1303 ves_icall_System_Reflection_FieldInfo_GetUnmanagedMarshal (MonoReflectionField *field)
1305 MonoClass *klass = field->field->parent;
1306 MonoMarshalType *info;
1309 if (klass->generic_container ||
1310 (klass->generic_class && klass->generic_class->context.class_inst->is_open))
1313 info = mono_marshal_load_type_info (klass);
1315 for (i = 0; i < info->num_fields; ++i) {
1316 if (info->fields [i].field == field->field) {
1317 if (!info->fields [i].mspec)
1320 return mono_reflection_marshal_from_marshal_spec (field->object.vtable->domain, klass, info->fields [i].mspec);
1327 static MonoReflectionField*
1328 ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoClass *klass)
1333 klass = handle->parent;
1335 /* FIXME: check that handle is a field of klass or of a parent: return null
1336 * and throw the exception in managed code.
1338 return mono_field_get_object (mono_domain_get (), klass, handle);
1341 static MonoReflectionField*
1342 ves_icall_System_Reflection_FieldInfo_internal_from_handle (MonoClassField *handle)
1344 MONO_ARCH_SAVE_REGS;
1348 return mono_field_get_object (mono_domain_get (), handle->parent, handle);
1352 ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionField *field, MonoBoolean optional)
1354 MonoType *type = field->field->type;
1356 return type_array_from_modifiers (field->field->parent->image, type, optional);
1360 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
1362 MonoDomain *domain = mono_domain_get ();
1363 MonoMethodSignature* sig;
1364 MONO_ARCH_SAVE_REGS;
1366 sig = mono_method_signature (method);
1368 g_assert (mono_loader_get_last_error ());
1369 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
1372 info->parent = mono_type_get_object (domain, &method->klass->byval_arg);
1373 info->ret = mono_type_get_object (domain, sig->ret);
1374 info->attrs = method->flags;
1375 info->implattrs = method->iflags;
1376 if (sig->call_convention == MONO_CALL_DEFAULT)
1379 if (sig->call_convention == MONO_CALL_VARARG)
1384 info->callconv |= (sig->hasthis << 5) | (sig->explicit_this << 6);
1388 ves_icall_get_parameter_info (MonoMethod *method)
1390 MonoDomain *domain = mono_domain_get ();
1392 return mono_param_get_objects (domain, method);
1395 static MonoReflectionMarshal*
1396 ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod *method)
1398 MonoDomain *domain = mono_domain_get ();
1399 MonoReflectionMarshal* res = NULL;
1400 MonoMarshalSpec **mspecs;
1403 mspecs = g_new (MonoMarshalSpec*, mono_method_signature (method)->param_count + 1);
1404 mono_method_get_marshal_info (method, mspecs);
1407 res = mono_reflection_marshal_from_marshal_spec (domain, method->klass, mspecs [0]);
1409 for (i = mono_method_signature (method)->param_count; i >= 0; i--)
1411 mono_metadata_free_marshal_spec (mspecs [i]);
1418 ves_icall_MonoField_GetFieldOffset (MonoReflectionField *field)
1420 return field->field->offset - sizeof (MonoObject);
1423 static MonoReflectionType*
1424 ves_icall_MonoField_GetParentType (MonoReflectionField *field, MonoBoolean declaring)
1427 MONO_ARCH_SAVE_REGS;
1429 parent = declaring? field->field->parent: field->klass;
1431 return mono_type_get_object (mono_object_domain (field), &parent->byval_arg);
1435 ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj)
1438 MonoClassField *cf = field->field;
1442 MonoDomain *domain = mono_object_domain (field);
1444 gboolean is_static = FALSE;
1445 gboolean is_ref = FALSE;
1447 MONO_ARCH_SAVE_REGS;
1449 if (field->klass->image->assembly->ref_only)
1450 mono_raise_exception (mono_get_exception_invalid_operation (
1451 "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
1453 mono_class_init (field->klass);
1455 t = mono_type_get_underlying_type (cf->type);
1457 case MONO_TYPE_STRING:
1458 case MONO_TYPE_OBJECT:
1459 case MONO_TYPE_CLASS:
1460 case MONO_TYPE_ARRAY:
1461 case MONO_TYPE_SZARRAY:
1466 case MONO_TYPE_BOOLEAN:
1469 case MONO_TYPE_CHAR:
1478 case MONO_TYPE_VALUETYPE:
1481 case MONO_TYPE_GENERICINST:
1482 if (mono_type_generic_inst_is_valuetype (t)) {
1489 g_error ("type 0x%x not handled in "
1490 "ves_icall_Monofield_GetValue", t->type);
1495 if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) {
1497 vtable = mono_class_vtable (domain, cf->parent);
1498 if (!vtable->initialized && !(cf->type->attrs & FIELD_ATTRIBUTE_LITERAL))
1499 mono_runtime_class_init (vtable);
1504 mono_field_static_get_value (vtable, cf, &o);
1506 mono_field_get_value (obj, cf, &o);
1511 if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) {
1512 MonoClass *nklass = mono_class_from_mono_type (cf->type);
1515 /* Convert the Nullable structure into a boxed vtype */
1517 buf = (guint8*)vtable->data + cf->offset;
1519 buf = (guint8*)obj + cf->offset;
1521 return mono_nullable_box (buf, nklass);
1524 /* boxed value type */
1525 klass = mono_class_from_mono_type (cf->type);
1526 o = mono_object_new (domain, klass);
1527 v = ((gchar *) o) + sizeof (MonoObject);
1529 mono_field_static_get_value (vtable, cf, v);
1531 mono_field_get_value (obj, cf, v);
1538 ves_icall_FieldInfo_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value)
1540 MonoClassField *cf = field->field;
1543 MONO_ARCH_SAVE_REGS;
1545 if (field->klass->image->assembly->ref_only)
1546 mono_raise_exception (mono_get_exception_invalid_operation (
1547 "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
1549 v = (gchar *) value;
1550 if (!cf->type->byref) {
1551 switch (cf->type->type) {
1554 case MONO_TYPE_BOOLEAN:
1557 case MONO_TYPE_CHAR:
1566 case MONO_TYPE_VALUETYPE:
1568 v += sizeof (MonoObject);
1570 case MONO_TYPE_STRING:
1571 case MONO_TYPE_OBJECT:
1572 case MONO_TYPE_CLASS:
1573 case MONO_TYPE_ARRAY:
1574 case MONO_TYPE_SZARRAY:
1577 case MONO_TYPE_GENERICINST: {
1578 MonoGenericClass *gclass = cf->type->data.generic_class;
1579 g_assert (!gclass->context.class_inst->is_open);
1581 if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) {
1582 MonoClass *nklass = mono_class_from_mono_type (cf->type);
1586 * Convert the boxed vtype into a Nullable structure.
1587 * This is complicated by the fact that Nullables have
1588 * a variable structure.
1590 /* Allocate using alloca so it gets GC tracking */
1591 buf = alloca (nklass->instance_size);
1593 mono_nullable_init (buf, value, nklass);
1598 if (gclass->container_class->valuetype && (v != NULL))
1599 v += sizeof (MonoObject);
1603 g_error ("type 0x%x not handled in "
1604 "ves_icall_FieldInfo_SetValueInternal", cf->type->type);
1609 if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) {
1610 MonoVTable *vtable = mono_class_vtable (mono_object_domain (field), cf->parent);
1611 if (!vtable->initialized)
1612 mono_runtime_class_init (vtable);
1613 mono_field_static_set_value (vtable, cf, v);
1615 mono_field_set_value (obj, cf, v);
1619 static MonoReflectionType*
1620 ves_icall_MonoGenericMethod_get_ReflectedType (MonoReflectionGenericMethod *rmethod)
1622 MonoMethod *method = rmethod->method.method;
1624 return mono_type_get_object (mono_object_domain (rmethod), &method->klass->byval_arg);
1627 /* From MonoProperty.cs */
1629 PInfo_Attributes = 1,
1630 PInfo_GetMethod = 1 << 1,
1631 PInfo_SetMethod = 1 << 2,
1632 PInfo_ReflectedType = 1 << 3,
1633 PInfo_DeclaringType = 1 << 4,
1638 ves_icall_get_property_info (MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
1640 MonoDomain *domain = mono_object_domain (property);
1642 MONO_ARCH_SAVE_REGS;
1644 if ((req_info & PInfo_ReflectedType) != 0)
1645 info->parent = mono_type_get_object (domain, &property->klass->byval_arg);
1646 else if ((req_info & PInfo_DeclaringType) != 0)
1647 info->parent = mono_type_get_object (domain, &property->property->parent->byval_arg);
1649 if ((req_info & PInfo_Name) != 0)
1650 info->name = mono_string_new (domain, property->property->name);
1652 if ((req_info & PInfo_Attributes) != 0)
1653 info->attrs = property->property->attrs;
1655 if ((req_info & PInfo_GetMethod) != 0)
1656 info->get = property->property->get ?
1657 mono_method_get_object (domain, property->property->get, NULL): NULL;
1659 if ((req_info & PInfo_SetMethod) != 0)
1660 info->set = property->property->set ?
1661 mono_method_get_object (domain, property->property->set, NULL): NULL;
1663 * There may be other methods defined for properties, though, it seems they are not exposed
1664 * in the reflection API
1669 ves_icall_get_event_info (MonoReflectionEvent *event, MonoEventInfo *info)
1671 MonoDomain *domain = mono_object_domain (event);
1673 MONO_ARCH_SAVE_REGS;
1675 info->reflected_type = mono_type_get_object (domain, &event->klass->byval_arg);
1676 info->declaring_type = mono_type_get_object (domain, &event->event->parent->byval_arg);
1678 info->name = mono_string_new (domain, event->event->name);
1679 info->attrs = event->event->attrs;
1680 info->add_method = event->event->add ? mono_method_get_object (domain, event->event->add, NULL): NULL;
1681 info->remove_method = event->event->remove ? mono_method_get_object (domain, event->event->remove, NULL): NULL;
1682 info->raise_method = event->event->raise ? mono_method_get_object (domain, event->event->raise, NULL): NULL;
1684 if (event->event->other) {
1686 while (event->event->other [n])
1688 info->other_methods = mono_array_new (domain, mono_defaults.method_info_class, n);
1690 for (i = 0; i < n; i++)
1691 mono_array_setref (info->other_methods, i, mono_method_get_object (domain, event->event->other [i], NULL));
1696 ves_icall_Type_GetInterfaces (MonoReflectionType* type)
1698 MonoDomain *domain = mono_object_domain (type);
1700 GPtrArray *ifaces = NULL;
1702 MonoClass *class = mono_class_from_mono_type (type->type);
1705 MonoGenericContext *context = NULL;
1707 MONO_ARCH_SAVE_REGS;
1709 if (class->generic_class && class->generic_class->context.class_inst->is_open) {
1710 context = mono_class_get_context (class);
1711 class = class->generic_class->container_class;
1714 mono_class_setup_vtable (class);
1716 slots = mono_bitset_new (class->max_interface_id + 1, 0);
1718 for (parent = class; parent; parent = parent->parent) {
1719 GPtrArray *tmp_ifaces = mono_class_get_implemented_interfaces (parent);
1721 for (i = 0; i < tmp_ifaces->len; ++i) {
1722 MonoClass *ic = g_ptr_array_index (tmp_ifaces, i);
1724 if (mono_bitset_test (slots, ic->interface_id))
1727 mono_bitset_set (slots, ic->interface_id);
1729 ifaces = g_ptr_array_new ();
1730 g_ptr_array_add (ifaces, ic);
1732 g_ptr_array_free (tmp_ifaces, TRUE);
1735 mono_bitset_free (slots);
1738 return mono_array_new (domain, mono_defaults.monotype_class, 0);
1740 intf = mono_array_new (domain, mono_defaults.monotype_class, ifaces->len);
1741 for (i = 0; i < ifaces->len; ++i) {
1742 MonoClass *ic = g_ptr_array_index (ifaces, i);
1743 MonoType *ret = &ic->byval_arg;
1744 if (context && ic->generic_class && ic->generic_class->context.class_inst->is_open)
1745 ret = mono_class_inflate_generic_type (ret, context);
1747 mono_array_setref (intf, i, mono_type_get_object (domain, ret));
1749 g_ptr_array_free (ifaces, TRUE);
1755 ves_icall_Type_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType *iface, MonoArray **targets, MonoArray **methods)
1757 MonoClass *class = mono_class_from_mono_type (type->type);
1758 MonoClass *iclass = mono_class_from_mono_type (iface->type);
1759 MonoReflectionMethod *member;
1762 int i = 0, len, ioffset;
1765 MONO_ARCH_SAVE_REGS;
1767 mono_class_setup_vtable (class);
1769 /* type doesn't implement iface: the exception is thrown in managed code */
1770 if (! MONO_CLASS_IMPLEMENTS_INTERFACE (class, iclass->interface_id))
1773 len = mono_class_num_methods (iclass);
1774 ioffset = mono_class_interface_offset (class, iclass);
1775 domain = mono_object_domain (type);
1776 *targets = mono_array_new (domain, mono_defaults.method_info_class, len);
1777 *methods = mono_array_new (domain, mono_defaults.method_info_class, len);
1780 while ((method = mono_class_get_methods (iclass, &iter))) {
1781 member = mono_method_get_object (domain, method, iclass);
1782 mono_array_setref (*methods, i, member);
1783 member = mono_method_get_object (domain, class->vtable [i + ioffset], class);
1784 mono_array_setref (*targets, i, member);
1791 ves_icall_Type_GetPacking (MonoReflectionType *type, guint32 *packing, guint32 *size)
1793 MonoClass *klass = mono_class_from_mono_type (type->type);
1795 g_assert (!klass->image->dynamic);
1797 mono_metadata_packing_from_typedef (klass->image, klass->type_token, packing, size);
1800 static MonoReflectionType*
1801 ves_icall_MonoType_GetElementType (MonoReflectionType *type)
1803 MonoClass *class = mono_class_from_mono_type (type->type);
1805 MONO_ARCH_SAVE_REGS;
1807 // GelElementType should only return a type for:
1808 // Array Pointer PassedByRef
1809 if (type->type->byref)
1810 return mono_type_get_object (mono_object_domain (type), &class->byval_arg);
1811 if (class->enumtype && class->enum_basetype) /* types that are modifierd typebuilkders may not have enum_basetype set */
1812 return mono_type_get_object (mono_object_domain (type), class->enum_basetype);
1813 else if (class->element_class && MONO_CLASS_IS_ARRAY (class))
1814 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
1815 else if (class->element_class && type->type->type == MONO_TYPE_PTR)
1816 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
1821 static MonoReflectionType*
1822 ves_icall_get_type_parent (MonoReflectionType *type)
1824 MonoClass *class = mono_class_from_mono_type (type->type);
1826 MONO_ARCH_SAVE_REGS;
1828 return class->parent ? mono_type_get_object (mono_object_domain (type), &class->parent->byval_arg): NULL;
1832 ves_icall_type_ispointer (MonoReflectionType *type)
1834 MONO_ARCH_SAVE_REGS;
1836 return type->type->type == MONO_TYPE_PTR;
1840 ves_icall_type_isprimitive (MonoReflectionType *type)
1842 MONO_ARCH_SAVE_REGS;
1844 return (!type->type->byref && (((type->type->type >= MONO_TYPE_BOOLEAN) && (type->type->type <= MONO_TYPE_R8)) || (type->type->type == MONO_TYPE_I) || (type->type->type == MONO_TYPE_U)));
1848 ves_icall_type_isbyref (MonoReflectionType *type)
1850 MONO_ARCH_SAVE_REGS;
1852 return type->type->byref;
1856 ves_icall_type_iscomobject (MonoReflectionType *type)
1858 MonoClass *klass = mono_class_from_mono_type (type->type);
1859 MONO_ARCH_SAVE_REGS;
1861 return (klass && klass->is_com_object);
1864 static MonoReflectionModule*
1865 ves_icall_MonoType_get_Module (MonoReflectionType *type)
1867 MonoClass *class = mono_class_from_mono_type (type->type);
1869 MONO_ARCH_SAVE_REGS;
1871 return mono_module_get_object (mono_object_domain (type), class->image);
1874 static MonoReflectionAssembly*
1875 ves_icall_MonoType_get_Assembly (MonoReflectionType *type)
1877 MonoDomain *domain = mono_domain_get ();
1878 MonoClass *class = mono_class_from_mono_type (type->type);
1880 MONO_ARCH_SAVE_REGS;
1882 return mono_assembly_get_object (domain, class->image->assembly);
1885 static MonoReflectionType*
1886 ves_icall_MonoType_get_DeclaringType (MonoReflectionType *type)
1888 MonoDomain *domain = mono_domain_get ();
1891 MONO_ARCH_SAVE_REGS;
1893 if (type->type->byref)
1895 if (type->type->type == MONO_TYPE_VAR)
1896 class = type->type->data.generic_param->owner->owner.klass;
1897 else if (type->type->type == MONO_TYPE_MVAR)
1898 class = type->type->data.generic_param->owner->owner.method->klass;
1900 class = mono_class_from_mono_type (type->type)->nested_in;
1902 return class ? mono_type_get_object (domain, &class->byval_arg) : NULL;
1905 static MonoReflectionType*
1906 ves_icall_MonoType_get_UnderlyingSystemType (MonoReflectionType *type)
1908 MonoDomain *domain = mono_domain_get ();
1909 MonoClass *class = mono_class_from_mono_type (type->type);
1911 MONO_ARCH_SAVE_REGS;
1913 if (class->enumtype && class->enum_basetype) /* types that are modified typebuilders may not have enum_basetype set */
1914 return mono_type_get_object (domain, class->enum_basetype);
1915 else if (class->element_class)
1916 return mono_type_get_object (domain, &class->element_class->byval_arg);
1922 ves_icall_MonoType_get_Name (MonoReflectionType *type)
1924 MonoDomain *domain = mono_domain_get ();
1925 MonoClass *class = mono_class_from_mono_type (type->type);
1927 MONO_ARCH_SAVE_REGS;
1929 if (type->type->byref) {
1930 char *n = g_strdup_printf ("%s&", class->name);
1931 MonoString *res = mono_string_new (domain, n);
1937 return mono_string_new (domain, class->name);
1942 ves_icall_MonoType_get_Namespace (MonoReflectionType *type)
1944 MonoDomain *domain = mono_domain_get ();
1945 MonoClass *class = mono_class_from_mono_type (type->type);
1947 MONO_ARCH_SAVE_REGS;
1949 while (class->nested_in)
1950 class = class->nested_in;
1952 if (class->name_space [0] == '\0')
1955 return mono_string_new (domain, class->name_space);
1959 ves_icall_MonoType_GetArrayRank (MonoReflectionType *type)
1961 MonoClass *class = mono_class_from_mono_type (type->type);
1963 MONO_ARCH_SAVE_REGS;
1969 ves_icall_MonoType_GetGenericArguments (MonoReflectionType *type)
1972 MonoClass *klass, *pklass;
1974 MONO_ARCH_SAVE_REGS;
1976 klass = mono_class_from_mono_type (type->type);
1978 if (klass->generic_container) {
1979 MonoGenericContainer *container = klass->generic_container;
1980 res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, container->type_argc);
1981 for (i = 0; i < container->type_argc; ++i) {
1982 pklass = mono_class_from_generic_parameter (&container->type_params [i], klass->image, FALSE);
1983 mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), &pklass->byval_arg));
1985 } else if (klass->generic_class) {
1986 MonoGenericInst *inst = klass->generic_class->context.class_inst;
1987 res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, inst->type_argc);
1988 for (i = 0; i < inst->type_argc; ++i)
1989 mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), inst->type_argv [i]));
1991 res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, 0);
1997 ves_icall_Type_get_IsGenericTypeDefinition (MonoReflectionType *type)
2000 MONO_ARCH_SAVE_REGS;
2002 if (type->type->byref)
2005 klass = mono_class_from_mono_type (type->type);
2007 return klass->generic_container != NULL;
2010 static MonoReflectionType*
2011 ves_icall_Type_GetGenericTypeDefinition_impl (MonoReflectionType *type)
2014 MONO_ARCH_SAVE_REGS;
2016 if (type->type->byref)
2019 klass = mono_class_from_mono_type (type->type);
2020 if (klass->generic_container) {
2021 return type; /* check this one */
2023 if (klass->generic_class) {
2024 MonoClass *generic_class = klass->generic_class->container_class;
2026 if (generic_class->wastypebuilder && generic_class->reflection_info)
2027 return generic_class->reflection_info;
2029 return mono_type_get_object (mono_object_domain (type), &generic_class->byval_arg);
2034 static MonoReflectionType*
2035 ves_icall_Type_MakeGenericType (MonoReflectionType *type, MonoArray *type_array)
2037 MonoType *geninst, **types;
2040 MONO_ARCH_SAVE_REGS;
2042 count = mono_array_length (type_array);
2043 types = g_new0 (MonoType *, count);
2045 for (i = 0; i < count; i++) {
2046 MonoReflectionType *t = mono_array_get (type_array, gpointer, i);
2047 types [i] = t->type;
2050 geninst = mono_reflection_bind_generic_parameters (type, count, types);
2055 return mono_type_get_object (mono_object_domain (type), geninst);
2059 ves_icall_Type_get_IsGenericInstance (MonoReflectionType *type)
2062 MONO_ARCH_SAVE_REGS;
2064 if (type->type->byref)
2067 klass = mono_class_from_mono_type (type->type);
2068 return klass->generic_class != NULL;
2072 ves_icall_Type_get_IsGenericType (MonoReflectionType *type)
2075 MONO_ARCH_SAVE_REGS;
2077 if (type->type->byref)
2080 klass = mono_class_from_mono_type (type->type);
2081 return klass->generic_class != NULL || klass->generic_container != NULL;
2085 ves_icall_Type_GetGenericParameterPosition (MonoReflectionType *type)
2087 MONO_ARCH_SAVE_REGS;
2089 if (is_generic_parameter (type->type))
2090 return type->type->data.generic_param->num;
2094 static GenericParameterAttributes
2095 ves_icall_Type_GetGenericParameterAttributes (MonoReflectionType *type)
2097 MONO_ARCH_SAVE_REGS;
2098 g_assert (is_generic_parameter (type->type));
2099 return type->type->data.generic_param->flags;
2103 ves_icall_Type_GetGenericParameterConstraints (MonoReflectionType *type)
2105 MonoGenericParam *param;
2111 MONO_ARCH_SAVE_REGS;
2113 domain = mono_object_domain (type);
2114 param = type->type->data.generic_param;
2115 for (count = 0, ptr = param->constraints; ptr && *ptr; ptr++, count++)
2118 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2119 for (i = 0; i < count; i++)
2120 mono_array_setref (res, i, mono_type_get_object (domain, ¶m->constraints [i]->byval_arg));
2127 ves_icall_MonoType_get_IsGenericParameter (MonoReflectionType *type)
2129 MONO_ARCH_SAVE_REGS;
2130 return is_generic_parameter (type->type);
2134 ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder *tb)
2136 MONO_ARCH_SAVE_REGS;
2137 return is_generic_parameter (tb->type.type);
2141 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
2142 MonoReflectionType *t)
2144 enumtype->type = t->type;
2147 static MonoReflectionType*
2148 ves_icall_MonoGenericClass_GetParentType (MonoReflectionGenericClass *type)
2150 MonoDynamicGenericClass *gclass;
2151 MonoReflectionType *parent = NULL;
2156 MONO_ARCH_SAVE_REGS;
2158 g_assert (type->type.type->data.generic_class->is_dynamic);
2159 gclass = (MonoDynamicGenericClass *) type->type.type->data.generic_class;
2161 domain = mono_object_domain (type);
2162 klass = mono_class_from_mono_type (type->generic_type->type);
2164 if (!klass->generic_class && !klass->generic_container)
2167 if (!strcmp (type->generic_type->object.vtable->klass->name, "TypeBuilder")) {
2168 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *) type->generic_type;
2169 parent = tb->parent;
2170 } else if (klass->wastypebuilder) {
2171 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *) type->generic_type;
2172 parent = tb->parent;
2174 MonoClass *pklass = klass->parent;
2176 parent = mono_type_get_object (domain, &pklass->byval_arg);
2179 if (!parent || (parent->type->type != MONO_TYPE_GENERICINST))
2182 inflated = mono_class_inflate_generic_type (
2183 parent->type, mono_generic_class_get_context ((MonoGenericClass *) gclass));
2185 return mono_type_get_object (domain, inflated);
2189 ves_icall_MonoGenericClass_GetInterfaces (MonoReflectionGenericClass *type)
2191 static MonoClass *System_Reflection_MonoGenericClass;
2192 MonoGenericClass *gclass;
2193 MonoReflectionTypeBuilder *tb = NULL;
2194 MonoClass *klass = NULL;
2199 MONO_ARCH_SAVE_REGS;
2201 if (!System_Reflection_MonoGenericClass) {
2202 System_Reflection_MonoGenericClass = mono_class_from_name (
2203 mono_defaults.corlib, "System.Reflection", "MonoGenericClass");
2204 g_assert (System_Reflection_MonoGenericClass);
2207 domain = mono_object_domain (type);
2209 gclass = type->type.type->data.generic_class;
2210 g_assert (gclass->is_dynamic);
2212 if (!strcmp (type->generic_type->object.vtable->klass->name, "TypeBuilder")) {
2213 tb = (MonoReflectionTypeBuilder *) type->generic_type;
2214 icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
2216 klass = gclass->container_class;
2217 mono_class_init (klass);
2218 icount = klass->interface_count;
2221 res = mono_array_new (domain, System_Reflection_MonoGenericClass, icount);
2223 for (i = 0; i < icount; i++) {
2224 MonoReflectionType *iface;
2228 iface = mono_array_get (tb->interfaces, MonoReflectionType *, i);
2231 it = &klass->interfaces [i]->byval_arg;
2233 it = mono_class_inflate_generic_type (it, mono_generic_class_get_context (gclass));
2235 iface = mono_type_get_object (domain, it);
2236 mono_array_setref (res, i, iface);
2242 static MonoReflectionMethod*
2243 ves_icall_MonoGenericClass_GetCorrespondingInflatedMethod (MonoReflectionGenericClass *type,
2244 MonoReflectionMethod* generic)
2246 MonoGenericClass *gclass;
2247 MonoDynamicGenericClass *dgclass;
2251 MONO_ARCH_SAVE_REGS;
2253 gclass = type->type.type->data.generic_class;
2254 g_assert (gclass->is_dynamic);
2256 dgclass = (MonoDynamicGenericClass *) gclass;
2258 domain = mono_object_domain (type);
2260 for (i = 0; i < dgclass->count_methods; i++)
2261 if (generic->method->token == dgclass->methods [i]->token)
2262 return mono_method_get_object (domain, dgclass->methods [i], NULL);
2267 static MonoReflectionMethod*
2268 ves_icall_MonoGenericClass_GetCorrespondingInflatedConstructor (MonoReflectionGenericClass *type,
2269 MonoReflectionMethod* generic)
2271 MonoGenericClass *gclass;
2272 MonoDynamicGenericClass *dgclass;
2276 MONO_ARCH_SAVE_REGS;
2278 gclass = type->type.type->data.generic_class;
2279 g_assert (gclass->is_dynamic);
2281 dgclass = (MonoDynamicGenericClass *) gclass;
2283 domain = mono_object_domain (type);
2285 for (i = 0; i < dgclass->count_ctors; i++)
2286 if (generic->method->token == dgclass->ctors [i]->token)
2287 return mono_method_get_object (domain, dgclass->ctors [i], NULL);
2293 static MonoReflectionField*
2294 ves_icall_MonoGenericClass_GetCorrespondingInflatedField (MonoReflectionGenericClass *type,
2295 MonoString* generic_name)
2297 MonoGenericClass *gclass;
2298 MonoDynamicGenericClass *dgclass;
2300 MonoClass *refclass;
2301 char *utf8_name = mono_string_to_utf8 (generic_name);
2304 MONO_ARCH_SAVE_REGS;
2306 gclass = type->type.type->data.generic_class;
2307 g_assert (gclass->is_dynamic);
2309 dgclass = (MonoDynamicGenericClass *) gclass;
2311 refclass = mono_class_from_mono_type (type->type.type);
2313 domain = mono_object_domain (type);
2315 for (i = 0; i < dgclass->count_fields; i++)
2316 if (strcmp (utf8_name, dgclass->fields [i].name) == 0) {
2318 return mono_field_get_object (domain, refclass, &dgclass->fields [i]);
2327 static MonoReflectionMethod*
2328 ves_icall_MonoType_GetCorrespondingInflatedMethod (MonoReflectionType *type,
2329 MonoReflectionMethod* generic)
2336 MONO_ARCH_SAVE_REGS;
2338 domain = ((MonoObject *)type)->vtable->domain;
2340 klass = mono_class_from_mono_type (type->type);
2343 while ((method = mono_class_get_methods (klass, &iter))) {
2344 if (method->token == generic->method->token)
2345 return mono_method_get_object (domain, method, klass);
2352 ves_icall_MonoGenericClass_GetMethods (MonoReflectionGenericClass *type,
2353 MonoReflectionType *reflected_type)
2355 MonoGenericClass *gclass;
2356 MonoDynamicGenericClass *dgclass;
2358 MonoClass *refclass;
2362 MONO_ARCH_SAVE_REGS;
2364 gclass = type->type.type->data.generic_class;
2365 g_assert (gclass->is_dynamic);
2366 dgclass = (MonoDynamicGenericClass *) gclass;
2368 refclass = mono_class_from_mono_type (reflected_type->type);
2370 domain = mono_object_domain (type);
2371 res = mono_array_new (domain, mono_defaults.method_info_class, dgclass->count_methods);
2373 for (i = 0; i < dgclass->count_methods; i++)
2374 mono_array_setref (res, i, mono_method_get_object (domain, dgclass->methods [i], refclass));
2380 ves_icall_MonoGenericClass_GetConstructors (MonoReflectionGenericClass *type,
2381 MonoReflectionType *reflected_type)
2383 static MonoClass *System_Reflection_ConstructorInfo;
2384 MonoGenericClass *gclass;
2385 MonoDynamicGenericClass *dgclass;
2387 MonoClass *refclass;
2391 MONO_ARCH_SAVE_REGS;
2393 if (!System_Reflection_ConstructorInfo)
2394 System_Reflection_ConstructorInfo = mono_class_from_name (
2395 mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
2397 gclass = type->type.type->data.generic_class;
2398 g_assert (gclass->is_dynamic);
2399 dgclass = (MonoDynamicGenericClass *) gclass;
2401 refclass = mono_class_from_mono_type (reflected_type->type);
2403 domain = mono_object_domain (type);
2404 res = mono_array_new (domain, System_Reflection_ConstructorInfo, dgclass->count_ctors);
2406 for (i = 0; i < dgclass->count_ctors; i++)
2407 mono_array_setref (res, i, mono_method_get_object (domain, dgclass->ctors [i], refclass));
2413 ves_icall_MonoGenericClass_GetFields (MonoReflectionGenericClass *type,
2414 MonoReflectionType *reflected_type)
2416 MonoGenericClass *gclass;
2417 MonoDynamicGenericClass *dgclass;
2419 MonoClass *refclass;
2423 MONO_ARCH_SAVE_REGS;
2425 gclass = type->type.type->data.generic_class;
2426 g_assert (gclass->is_dynamic);
2427 dgclass = (MonoDynamicGenericClass *) gclass;
2429 refclass = mono_class_from_mono_type (reflected_type->type);
2431 domain = mono_object_domain (type);
2432 res = mono_array_new (domain, mono_defaults.field_info_class, dgclass->count_fields);
2434 for (i = 0; i < dgclass->count_fields; i++)
2435 mono_array_setref (res, i, mono_field_get_object (domain, refclass, &dgclass->fields [i]));
2441 ves_icall_MonoGenericClass_GetProperties (MonoReflectionGenericClass *type,
2442 MonoReflectionType *reflected_type)
2444 static MonoClass *System_Reflection_PropertyInfo;
2445 MonoGenericClass *gclass;
2446 MonoDynamicGenericClass *dgclass;
2448 MonoClass *refclass;
2452 MONO_ARCH_SAVE_REGS;
2454 if (!System_Reflection_PropertyInfo)
2455 System_Reflection_PropertyInfo = mono_class_from_name (
2456 mono_defaults.corlib, "System.Reflection", "PropertyInfo");
2458 gclass = type->type.type->data.generic_class;
2459 g_assert (gclass->is_dynamic);
2460 dgclass = (MonoDynamicGenericClass *) gclass;
2462 refclass = mono_class_from_mono_type (reflected_type->type);
2464 domain = mono_object_domain (type);
2465 res = mono_array_new (domain, System_Reflection_PropertyInfo, dgclass->count_properties);
2467 for (i = 0; i < dgclass->count_properties; i++)
2468 mono_array_setref (res, i, mono_property_get_object (domain, refclass, &dgclass->properties [i]));
2474 ves_icall_MonoGenericClass_GetEvents (MonoReflectionGenericClass *type,
2475 MonoReflectionType *reflected_type)
2477 static MonoClass *System_Reflection_EventInfo;
2478 MonoGenericClass *gclass;
2479 MonoDynamicGenericClass *dgclass;
2481 MonoClass *refclass;
2485 MONO_ARCH_SAVE_REGS;
2487 if (!System_Reflection_EventInfo)
2488 System_Reflection_EventInfo = mono_class_from_name (
2489 mono_defaults.corlib, "System.Reflection", "EventInfo");
2491 gclass = type->type.type->data.generic_class;
2492 g_assert (gclass->is_dynamic);
2493 dgclass = (MonoDynamicGenericClass *) gclass;
2495 refclass = mono_class_from_mono_type (reflected_type->type);
2497 domain = mono_object_domain (type);
2498 res = mono_array_new (domain, System_Reflection_EventInfo, dgclass->count_events);
2500 for (i = 0; i < dgclass->count_events; i++)
2501 mono_array_setref (res, i, mono_event_get_object (domain, refclass, &dgclass->events [i]));
2506 static MonoReflectionMethod *
2507 ves_icall_MonoType_get_DeclaringMethod (MonoReflectionType *type)
2512 MONO_ARCH_SAVE_REGS;
2514 if (type->type->byref || type->type->type != MONO_TYPE_MVAR)
2517 method = type->type->data.generic_param->owner->owner.method;
2519 klass = mono_class_from_mono_type (type->type);
2520 return mono_method_get_object (mono_object_domain (type), method, klass);
2523 static MonoReflectionDllImportAttribute*
2524 ves_icall_MonoMethod_GetDllImportAttribute (MonoMethod *method)
2526 static MonoClass *DllImportAttributeClass = NULL;
2527 MonoDomain *domain = mono_domain_get ();
2528 MonoReflectionDllImportAttribute *attr;
2529 MonoImage *image = method->klass->image;
2530 MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method;
2531 MonoTableInfo *tables = image->tables;
2532 MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
2533 MonoTableInfo *mr = &tables [MONO_TABLE_MODULEREF];
2534 guint32 im_cols [MONO_IMPLMAP_SIZE];
2535 guint32 scope_token;
2536 const char *import = NULL;
2537 const char *scope = NULL;
2540 if (!method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)
2543 if (!DllImportAttributeClass) {
2544 DllImportAttributeClass =
2545 mono_class_from_name (mono_defaults.corlib,
2546 "System.Runtime.InteropServices", "DllImportAttribute");
2547 g_assert (DllImportAttributeClass);
2550 if (method->klass->image->dynamic) {
2551 MonoReflectionMethodAux *method_aux =
2552 g_hash_table_lookup (
2553 ((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
2555 import = method_aux->dllentry;
2556 scope = method_aux->dll;
2560 if (piinfo->implmap_idx) {
2561 mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
2563 piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
2564 import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
2565 scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
2566 scope = mono_metadata_string_heap (image, scope_token);
2569 flags = piinfo->piflags;
2571 attr = (MonoReflectionDllImportAttribute*)mono_object_new (domain, DllImportAttributeClass);
2573 MONO_OBJECT_SETREF (attr, dll, mono_string_new (domain, scope));
2574 MONO_OBJECT_SETREF (attr, entry_point, mono_string_new (domain, import));
2575 attr->call_conv = (flags & 0x700) >> 8;
2576 attr->charset = ((flags & 0x6) >> 1) + 1;
2577 if (attr->charset == 1)
2579 attr->exact_spelling = (flags & 0x1) != 0;
2580 attr->set_last_error = (flags & 0x40) != 0;
2581 attr->best_fit_mapping = (flags & 0x30) == 0x10;
2582 attr->throw_on_unmappable = (flags & 0x3000) == 0x1000;
2583 attr->preserve_sig = FALSE;
2588 static MonoReflectionMethod *
2589 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
2591 MonoMethodInflated *imethod;
2593 MONO_ARCH_SAVE_REGS;
2595 if (method->method->generic_container)
2598 if (!method->method->is_inflated)
2601 imethod = (MonoMethodInflated *) method->method;
2603 if (imethod->reflection_info)
2604 return imethod->reflection_info;
2606 return mono_method_get_object (
2607 mono_object_domain (method), imethod->declaring, NULL);
2611 ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethod *method)
2613 MONO_ARCH_SAVE_REGS;
2615 return mono_method_signature (method->method)->generic_param_count != 0;
2619 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method)
2621 MONO_ARCH_SAVE_REGS;
2623 return method->method->generic_container != NULL;
2627 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
2632 MONO_ARCH_SAVE_REGS;
2634 domain = mono_object_domain (method);
2636 if (method->method->is_inflated) {
2637 MonoGenericInst *inst = mono_method_get_context (method->method)->method_inst;
2640 count = inst->type_argc;
2641 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2643 for (i = 0; i < count; i++)
2644 mono_array_setref (res, i, mono_type_get_object (domain, inst->type_argv [i]));
2650 count = mono_method_signature (method->method)->generic_param_count;
2651 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2653 for (i = 0; i < count; i++) {
2654 MonoGenericParam *param = &method->method->generic_container->type_params [i];
2655 MonoClass *pklass = mono_class_from_generic_parameter (
2656 param, method->method->klass->image, TRUE);
2657 mono_array_setref (res, i,
2658 mono_type_get_object (domain, &pklass->byval_arg));
2665 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoArray *params)
2668 * Invoke from reflection is supposed to always be a virtual call (the API
2669 * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
2670 * greater flexibility.
2672 MonoMethod *m = method->method;
2676 MONO_ARCH_SAVE_REGS;
2678 if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
2680 if (!mono_object_isinst (this, m->klass))
2681 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
2682 m = mono_object_get_virtual_method (this, m);
2683 /* must pass the pointer to the value for valuetype methods */
2684 if (m->klass->valuetype)
2685 obj = mono_object_unbox (this);
2686 } else if (strcmp (m->name, ".ctor") && !m->wrapper_type)
2687 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
2690 pcount = params? mono_array_length (params): 0;
2691 if (pcount != mono_method_signature (m)->param_count)
2692 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
2694 if ((m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) && !strcmp (m->name, ".ctor") && !this)
2695 mono_raise_exception (mono_exception_from_name_msg (mono_defaults.corlib, "System", "MethodAccessException", "Cannot invoke constructor of an abstract class."));
2697 if (m->klass->image->assembly->ref_only)
2698 mono_raise_exception (mono_get_exception_invalid_operation ("It is illegal to invoke a method on a type loaded using the ReflectionOnly api."));
2700 if (m->klass->rank && !strcmp (m->name, ".ctor")) {
2703 guint32 *lower_bounds;
2704 pcount = mono_array_length (params);
2705 lengths = alloca (sizeof (guint32) * pcount);
2706 for (i = 0; i < pcount; ++i)
2707 lengths [i] = *(gint32*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
2709 if (m->klass->rank == pcount) {
2710 /* Only lengths provided. */
2711 lower_bounds = NULL;
2713 g_assert (pcount == (m->klass->rank * 2));
2714 /* lower bounds are first. */
2715 lower_bounds = lengths;
2716 lengths += m->klass->rank;
2719 return (MonoObject*)mono_array_new_full (mono_object_domain (params), m->klass, lengths, lower_bounds);
2721 return mono_runtime_invoke_array (m, obj, params, NULL);
2725 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this, MonoArray *params, MonoArray **outArgs)
2727 MonoDomain *domain = mono_object_domain (method);
2728 MonoMethod *m = method->method;
2729 MonoMethodSignature *sig = mono_method_signature (m);
2730 MonoArray *out_args;
2732 int i, j, outarg_count = 0;
2734 MONO_ARCH_SAVE_REGS;
2736 if (m->klass == mono_defaults.object_class) {
2738 if (!strcmp (m->name, "FieldGetter")) {
2739 MonoClass *k = this->vtable->klass;
2743 /* If this is a proxy, then it must be a CBO */
2744 if (k == mono_defaults.transparent_proxy_class) {
2745 MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
2746 this = tp->rp->unwrapped_server;
2748 k = this->vtable->klass;
2751 name = mono_array_get (params, MonoString *, 1);
2752 str = mono_string_to_utf8 (name);
2755 MonoClassField* field = mono_class_get_field_from_name (k, str);
2757 MonoClass *field_klass = mono_class_from_mono_type (field->type);
2758 if (field_klass->valuetype)
2759 result = mono_value_box (domain, field_klass, (char *)this + field->offset);
2761 result = *((gpointer *)((char *)this + field->offset));
2763 out_args = mono_array_new (domain, mono_defaults.object_class, 1);
2764 *outArgs = out_args;
2765 mono_array_setref (out_args, 0, result);
2773 g_assert_not_reached ();
2775 } else if (!strcmp (m->name, "FieldSetter")) {
2776 MonoClass *k = this->vtable->klass;
2782 /* If this is a proxy, then it must be a CBO */
2783 if (k == mono_defaults.transparent_proxy_class) {
2784 MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
2785 this = tp->rp->unwrapped_server;
2787 k = this->vtable->klass;
2790 name = mono_array_get (params, MonoString *, 1);
2791 str = mono_string_to_utf8 (name);
2794 MonoClassField* field = mono_class_get_field_from_name (k, str);
2796 MonoClass *field_klass = mono_class_from_mono_type (field->type);
2797 MonoObject *val = mono_array_get (params, gpointer, 2);
2799 if (field_klass->valuetype) {
2800 size = mono_type_size (field->type, &align);
2801 memcpy ((char *)this + field->offset,
2802 ((char *)val) + sizeof (MonoObject), size);
2804 *(MonoObject**)((char *)this + field->offset) = val;
2806 out_args = mono_array_new (domain, mono_defaults.object_class, 0);
2807 *outArgs = out_args;
2817 g_assert_not_reached ();
2822 for (i = 0; i < mono_array_length (params); i++) {
2823 if (sig->params [i]->byref)
2827 out_args = mono_array_new (domain, mono_defaults.object_class, outarg_count);
2829 /* handle constructors only for objects already allocated */
2830 if (!strcmp (method->method->name, ".ctor"))
2833 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
2834 g_assert (!method->method->klass->valuetype);
2835 result = mono_runtime_invoke_array (method->method, this, params, NULL);
2837 for (i = 0, j = 0; i < mono_array_length (params); i++) {
2838 if (sig->params [i]->byref) {
2840 arg = mono_array_get (params, gpointer, i);
2841 mono_array_setref (out_args, j, arg);
2846 *outArgs = out_args;
2852 read_enum_value (char *mem, int type)
2856 return *(guint8*)mem;
2858 return *(gint8*)mem;
2860 return *(guint16*)mem;
2862 return *(gint16*)mem;
2864 return *(guint32*)mem;
2866 return *(gint32*)mem;
2868 return *(guint64*)mem;
2870 return *(gint64*)mem;
2872 g_assert_not_reached ();
2878 write_enum_value (char *mem, int type, guint64 value)
2882 case MONO_TYPE_I1: {
2883 guint8 *p = (guint8*)mem;
2888 case MONO_TYPE_I2: {
2889 guint16 *p = (void*)mem;
2894 case MONO_TYPE_I4: {
2895 guint32 *p = (void*)mem;
2900 case MONO_TYPE_I8: {
2901 guint64 *p = (void*)mem;
2906 g_assert_not_reached ();
2912 ves_icall_System_Enum_ToObject (MonoReflectionType *type, MonoObject *obj)
2915 MonoClass *enumc, *objc;
2919 MONO_ARCH_SAVE_REGS;
2921 MONO_CHECK_ARG_NULL (type);
2922 MONO_CHECK_ARG_NULL (obj);
2924 domain = mono_object_domain (type);
2925 enumc = mono_class_from_mono_type (type->type);
2926 objc = obj->vtable->klass;
2928 if (!enumc->enumtype)
2929 mono_raise_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
2930 if (!((objc->enumtype) || (objc->byval_arg.type >= MONO_TYPE_I1 && objc->byval_arg.type <= MONO_TYPE_U8)))
2931 mono_raise_exception (mono_get_exception_argument ("value", "The value passed in must be an enum base or an underlying type for an enum, such as an Int32."));
2933 res = mono_object_new (domain, enumc);
2934 val = read_enum_value ((char *)obj + sizeof (MonoObject), objc->enumtype? objc->enum_basetype->type: objc->byval_arg.type);
2935 write_enum_value ((char *)res + sizeof (MonoObject), enumc->enum_basetype->type, val);
2941 ves_icall_System_Enum_get_value (MonoObject *this)
2949 MONO_ARCH_SAVE_REGS;
2954 g_assert (this->vtable->klass->enumtype);
2956 enumc = mono_class_from_mono_type (this->vtable->klass->enum_basetype);
2957 res = mono_object_new (mono_object_domain (this), enumc);
2958 dst = (char *)res + sizeof (MonoObject);
2959 src = (char *)this + sizeof (MonoObject);
2960 size = mono_class_value_size (enumc, NULL);
2962 memcpy (dst, src, size);
2968 ves_icall_get_enum_info (MonoReflectionType *type, MonoEnumInfo *info)
2970 MonoDomain *domain = mono_object_domain (type);
2971 MonoClass *enumc = mono_class_from_mono_type (type->type);
2972 guint j = 0, nvalues, crow;
2974 MonoClassField *field;
2976 MONO_ARCH_SAVE_REGS;
2978 info->utype = mono_type_get_object (domain, enumc->enum_basetype);
2979 nvalues = mono_class_num_fields (enumc) ? mono_class_num_fields (enumc) - 1 : 0;
2980 info->names = mono_array_new (domain, mono_defaults.string_class, nvalues);
2981 info->values = mono_array_new (domain, enumc, nvalues);
2985 while ((field = mono_class_get_fields (enumc, &iter))) {
2989 if (strcmp ("value__", field->name) == 0)
2991 if (mono_field_is_deleted (field))
2993 mono_array_setref (info->names, j, mono_string_new (domain, field->name));
2996 crow = mono_metadata_get_constant_index (enumc->image, mono_class_get_field_token (field), crow + 1);
2997 field->def_type = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_TYPE);
2998 crow = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_VALUE);
2999 field->data = (gpointer)mono_metadata_blob_heap (enumc->image, crow);
3003 len = mono_metadata_decode_blob_size (p, &p);
3004 switch (enumc->enum_basetype->type) {
3007 mono_array_set (info->values, gchar, j, *p);
3009 case MONO_TYPE_CHAR:
3012 mono_array_set (info->values, gint16, j, read16 (p));
3016 mono_array_set (info->values, gint32, j, read32 (p));
3020 mono_array_set (info->values, gint64, j, read64 (p));
3023 g_error ("Implement type 0x%02x in get_enum_info", enumc->enum_basetype->type);
3030 BFLAGS_IgnoreCase = 1,
3031 BFLAGS_DeclaredOnly = 2,
3032 BFLAGS_Instance = 4,
3034 BFLAGS_Public = 0x10,
3035 BFLAGS_NonPublic = 0x20,
3036 BFLAGS_FlattenHierarchy = 0x40,
3037 BFLAGS_InvokeMethod = 0x100,
3038 BFLAGS_CreateInstance = 0x200,
3039 BFLAGS_GetField = 0x400,
3040 BFLAGS_SetField = 0x800,
3041 BFLAGS_GetProperty = 0x1000,
3042 BFLAGS_SetProperty = 0x2000,
3043 BFLAGS_ExactBinding = 0x10000,
3044 BFLAGS_SuppressChangeType = 0x20000,
3045 BFLAGS_OptionalParamBinding = 0x40000
3048 static MonoReflectionField *
3049 ves_icall_Type_GetField (MonoReflectionType *type, MonoString *name, guint32 bflags)
3052 MonoClass *startklass, *klass;
3054 MonoClassField *field;
3057 int (*compare_func) (const char *s1, const char *s2) = NULL;
3058 domain = ((MonoObject *)type)->vtable->domain;
3059 klass = startklass = mono_class_from_mono_type (type->type);
3061 MONO_ARCH_SAVE_REGS;
3064 mono_raise_exception (mono_get_exception_argument_null ("name"));
3065 if (type->type->byref)
3068 compare_func = (bflags & BFLAGS_IgnoreCase) ? g_strcasecmp : strcmp;
3071 if (klass->exception_type != MONO_EXCEPTION_NONE)
3072 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3075 while ((field = mono_class_get_fields (klass, &iter))) {
3078 if (field->type == NULL)
3080 if (mono_field_is_deleted (field))
3082 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3083 if (bflags & BFLAGS_Public)
3086 if (bflags & BFLAGS_NonPublic)
3092 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
3093 if (bflags & BFLAGS_Static)
3094 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3097 if (bflags & BFLAGS_Instance)
3104 utf8_name = mono_string_to_utf8 (name);
3106 if (compare_func (field->name, utf8_name)) {
3112 return mono_field_get_object (domain, klass, field);
3114 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3121 ves_icall_Type_GetFields_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3124 MonoClass *startklass, *klass, *refklass;
3129 MonoClassField *field;
3131 MONO_ARCH_SAVE_REGS;
3133 domain = ((MonoObject *)type)->vtable->domain;
3134 if (type->type->byref)
3135 return mono_array_new (domain, mono_defaults.field_info_class, 0);
3136 klass = startklass = mono_class_from_mono_type (type->type);
3137 refklass = mono_class_from_mono_type (reftype->type);
3141 res = mono_array_new (domain, mono_defaults.field_info_class, len);
3143 if (klass->exception_type != MONO_EXCEPTION_NONE)
3144 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3147 while ((field = mono_class_get_fields (klass, &iter))) {
3149 if (mono_field_is_deleted (field))
3151 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3152 if (bflags & BFLAGS_Public)
3155 if (bflags & BFLAGS_NonPublic) {
3156 /* Serialization currently depends on the old behavior.
3157 * if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE || startklass == klass)*/
3164 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
3165 if (bflags & BFLAGS_Static)
3166 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3169 if (bflags & BFLAGS_Instance)
3175 member = (MonoObject*)mono_field_get_object (domain, refklass, field);
3177 MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, len * 2);
3178 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3182 mono_array_setref (res, i, member);
3185 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3188 MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, i);
3189 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3192 * Better solution for the new GC.
3193 * res->max_length = i;
3200 ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
3203 MonoClass *startklass, *klass, *refklass;
3208 int i, len, match, nslots;
3209 guint32 method_slots_default [8];
3210 guint32 *method_slots;
3211 gchar *mname = NULL;
3212 int (*compare_func) (const char *s1, const char *s2) = NULL;
3214 MONO_ARCH_SAVE_REGS;
3216 domain = ((MonoObject *)type)->vtable->domain;
3217 if (type->type->byref)
3218 return mono_array_new (domain, mono_defaults.method_info_class, 0);
3219 klass = startklass = mono_class_from_mono_type (type->type);
3220 refklass = mono_class_from_mono_type (reftype->type);
3223 mname = mono_string_to_utf8 (name);
3224 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
3227 mono_class_setup_vtable (klass);
3229 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : klass->vtable_size;
3230 if (nslots >= sizeof (method_slots_default) * 8) {
3231 method_slots = g_new0 (guint32, nslots / 32 + 1);
3233 method_slots = method_slots_default;
3234 memset (method_slots, 0, sizeof (method_slots_default));
3238 res = mono_array_new (domain, mono_defaults.method_info_class, len);
3240 mono_class_setup_vtable (klass);
3241 if (klass->exception_type != MONO_EXCEPTION_NONE)
3242 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3245 while ((method = mono_class_get_methods (klass, &iter))) {
3247 if (method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
3249 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3250 if (bflags & BFLAGS_Public)
3253 if (bflags & BFLAGS_NonPublic)
3259 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3260 if (bflags & BFLAGS_Static)
3261 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3264 if (bflags & BFLAGS_Instance)
3272 if (compare_func (mname, method->name))
3277 if (method->slot != -1) {
3278 g_assert (method->slot < nslots);
3279 if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
3281 method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
3284 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
3287 MonoArray *new_res = mono_array_new (domain, mono_defaults.method_info_class, len * 2);
3288 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3292 mono_array_setref (res, i, member);
3295 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3299 if (method_slots != method_slots_default)
3300 g_free (method_slots);
3302 MonoArray *new_res = mono_array_new (domain, mono_defaults.method_info_class, i);
3303 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3306 * Better solution for the new GC.
3307 * res->max_length = i;
3314 ves_icall_Type_GetConstructors_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3317 static MonoClass *System_Reflection_ConstructorInfo;
3318 MonoClass *startklass, *klass, *refklass;
3323 gpointer iter = NULL;
3325 MONO_ARCH_SAVE_REGS;
3327 domain = ((MonoObject *)type)->vtable->domain;
3328 if (type->type->byref)
3329 return mono_array_new (domain, mono_defaults.method_info_class, 0);
3330 klass = startklass = mono_class_from_mono_type (type->type);
3331 refklass = mono_class_from_mono_type (reftype->type);
3333 if (klass->exception_type != MONO_EXCEPTION_NONE)
3334 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3336 if (!System_Reflection_ConstructorInfo)
3337 System_Reflection_ConstructorInfo = mono_class_from_name (
3338 mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
3342 res = mono_array_new (domain, System_Reflection_ConstructorInfo, len);
3344 while ((method = mono_class_get_methods (klass, &iter))) {
3346 if (strcmp (method->name, ".ctor") && strcmp (method->name, ".cctor"))
3348 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3349 if (bflags & BFLAGS_Public)
3352 if (bflags & BFLAGS_NonPublic)
3358 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3359 if (bflags & BFLAGS_Static)
3360 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3363 if (bflags & BFLAGS_Instance)
3369 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
3372 MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, len * 2);
3373 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3377 mono_array_setref (res, i, member);
3381 MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, i);
3382 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3385 * Better solution for the new GC.
3386 * res->max_length = i;
3393 ves_icall_Type_GetPropertiesByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
3396 static MonoClass *System_Reflection_PropertyInfo;
3397 MonoClass *startklass, *klass;
3401 int i, match, nslots;
3404 guint32 method_slots_default [8];
3405 guint32 *method_slots;
3406 gchar *propname = NULL;
3407 int (*compare_func) (const char *s1, const char *s2) = NULL;
3410 MONO_ARCH_SAVE_REGS;
3412 if (!System_Reflection_PropertyInfo)
3413 System_Reflection_PropertyInfo = mono_class_from_name (
3414 mono_defaults.corlib, "System.Reflection", "PropertyInfo");
3416 domain = ((MonoObject *)type)->vtable->domain;
3417 if (type->type->byref)
3418 return mono_array_new (domain, System_Reflection_PropertyInfo, 0);
3419 klass = startklass = mono_class_from_mono_type (type->type);
3421 propname = mono_string_to_utf8 (name);
3422 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
3425 mono_class_setup_vtable (klass);
3427 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : klass->vtable_size;
3428 if (nslots >= sizeof (method_slots_default) * 8) {
3429 method_slots = g_new0 (guint32, nslots / 32 + 1);
3431 method_slots = method_slots_default;
3432 memset (method_slots, 0, sizeof (method_slots_default));
3436 res = mono_array_new (domain, System_Reflection_PropertyInfo, len);
3438 mono_class_setup_vtable (klass);
3439 if (klass->exception_type != MONO_EXCEPTION_NONE) {
3440 if (method_slots != method_slots_default)
3441 g_free (method_slots);
3444 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3448 while ((prop = mono_class_get_properties (klass, &iter))) {
3454 flags = method->flags;
3457 if ((prop->get && ((prop->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC)) ||
3458 (prop->set && ((prop->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC))) {
3459 if (bflags & BFLAGS_Public)
3462 if (bflags & BFLAGS_NonPublic)
3468 if (flags & METHOD_ATTRIBUTE_STATIC) {
3469 if (bflags & BFLAGS_Static)
3470 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3473 if (bflags & BFLAGS_Instance)
3482 if (compare_func (propname, prop->name))
3486 if (prop->get && prop->get->slot != -1) {
3487 if (method_slots [prop->get->slot >> 5] & (1 << (prop->get->slot & 0x1f)))
3489 method_slots [prop->get->slot >> 5] |= 1 << (prop->get->slot & 0x1f);
3491 if (prop->set && prop->set->slot != -1) {
3492 if (method_slots [prop->set->slot >> 5] & (1 << (prop->set->slot & 0x1f)))
3494 method_slots [prop->set->slot >> 5] |= 1 << (prop->set->slot & 0x1f);
3498 MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, len * 2);
3499 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3503 mono_array_setref (res, i, mono_property_get_object (domain, startklass, prop));
3506 if ((!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent)))
3510 if (method_slots != method_slots_default)
3511 g_free (method_slots);
3513 MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, i);
3514 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3517 * Better solution for the new GC.
3518 * res->max_length = i;
3524 static MonoReflectionEvent *
3525 ves_icall_MonoType_GetEvent (MonoReflectionType *type, MonoString *name, guint32 bflags)
3528 MonoClass *klass, *startklass;
3534 MONO_ARCH_SAVE_REGS;
3536 event_name = mono_string_to_utf8 (name);
3537 if (type->type->byref)
3539 klass = startklass = mono_class_from_mono_type (type->type);
3540 domain = mono_object_domain (type);
3543 if (klass->exception_type != MONO_EXCEPTION_NONE)
3544 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3547 while ((event = mono_class_get_events (klass, &iter))) {
3548 if (strcmp (event->name, event_name))
3551 method = event->add;
3553 method = event->remove;
3555 method = event->raise;
3557 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3558 if (!(bflags & BFLAGS_Public))
3561 if (!(bflags & BFLAGS_NonPublic))
3566 if (!(bflags & BFLAGS_NonPublic))
3569 g_free (event_name);
3570 return mono_event_get_object (domain, startklass, event);
3573 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3576 g_free (event_name);
3581 ves_icall_Type_GetEvents_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3584 static MonoClass *System_Reflection_EventInfo;
3585 MonoClass *startklass, *klass;
3592 MONO_ARCH_SAVE_REGS;
3594 if (!System_Reflection_EventInfo)
3595 System_Reflection_EventInfo = mono_class_from_name (
3596 mono_defaults.corlib, "System.Reflection", "EventInfo");
3598 domain = mono_object_domain (type);
3599 if (type->type->byref)
3600 return mono_array_new (domain, System_Reflection_EventInfo, 0);
3601 klass = startklass = mono_class_from_mono_type (type->type);
3605 res = mono_array_new (domain, System_Reflection_EventInfo, len);
3607 if (klass->exception_type != MONO_EXCEPTION_NONE)
3608 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3611 while ((event = mono_class_get_events (klass, &iter))) {
3613 method = event->add;
3615 method = event->remove;
3617 method = event->raise;
3619 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3620 if (bflags & BFLAGS_Public)
3623 if (bflags & BFLAGS_NonPublic)
3628 if (bflags & BFLAGS_NonPublic)
3634 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3635 if (bflags & BFLAGS_Static)
3636 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3639 if (bflags & BFLAGS_Instance)
3644 if (bflags & BFLAGS_Instance)
3650 MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, len * 2);
3651 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3655 mono_array_setref (res, i, mono_event_get_object (domain, startklass, event));
3658 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3661 MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, i);
3662 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3665 * Better solution for the new GC.
3666 * res->max_length = i;
3672 static MonoReflectionType *
3673 ves_icall_Type_GetNestedType (MonoReflectionType *type, MonoString *name, guint32 bflags)
3681 MONO_ARCH_SAVE_REGS;
3683 domain = ((MonoObject *)type)->vtable->domain;
3684 if (type->type->byref)
3686 klass = mono_class_from_mono_type (type->type);
3687 str = mono_string_to_utf8 (name);
3690 if (klass->exception_type != MONO_EXCEPTION_NONE)
3691 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3694 * If a nested type is generic, return its generic type definition.
3695 * Note that this means that the return value is essentially a
3696 * nested type of the generic type definition of @klass.
3698 * A note in MSDN claims that a generic type definition can have
3699 * nested types that aren't generic. In any case, the container of that
3700 * nested type would be the generic type definition.
3702 if (klass->generic_class)
3703 klass = klass->generic_class->container_class;
3705 for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
3707 nested = tmpn->data;
3708 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
3709 if (bflags & BFLAGS_Public)
3712 if (bflags & BFLAGS_NonPublic)
3717 if (strcmp (nested->name, str) == 0){
3719 return mono_type_get_object (domain, &nested->byval_arg);
3722 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3729 ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags)
3739 MONO_ARCH_SAVE_REGS;
3741 domain = ((MonoObject *)type)->vtable->domain;
3742 if (type->type->byref)
3743 return mono_array_new (domain, mono_defaults.monotype_class, 0);
3744 klass = mono_class_from_mono_type (type->type);
3745 if (klass->exception_type != MONO_EXCEPTION_NONE)
3746 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3749 * If a nested type is generic, return its generic type definition.
3750 * Note that this means that the return value is essentially the set
3751 * of nested types of the generic type definition of @klass.
3753 * A note in MSDN claims that a generic type definition can have
3754 * nested types that aren't generic. In any case, the container of that
3755 * nested type would be the generic type definition.
3757 if (klass->generic_class)
3758 klass = klass->generic_class->container_class;
3762 res = mono_array_new (domain, mono_defaults.monotype_class, len);
3763 for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
3765 nested = tmpn->data;
3766 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
3767 if (bflags & BFLAGS_Public)
3770 if (bflags & BFLAGS_NonPublic)
3775 member = (MonoObject*)mono_type_get_object (domain, &nested->byval_arg);
3777 MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, len * 2);
3778 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3782 mono_array_setref (res, i, member);
3786 MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, i);
3787 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3790 * Better solution for the new GC.
3791 * res->max_length = i;
3797 static MonoReflectionType*
3798 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *assembly, MonoReflectionModule *module, MonoString *name, MonoBoolean throwOnError, MonoBoolean ignoreCase)
3801 MonoType *type = NULL;
3802 MonoTypeNameParse info;
3803 gboolean type_resolve;
3805 MONO_ARCH_SAVE_REGS;
3807 /* On MS.NET, this does not fire a TypeResolve event */
3808 type_resolve = TRUE;
3809 str = mono_string_to_utf8 (name);
3810 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
3811 if (!mono_reflection_parse_type (str, &info)) {
3813 g_list_free (info.modifiers);
3814 g_list_free (info.nested);
3815 if (throwOnError) /* uhm: this is a parse error, though... */
3816 mono_raise_exception (mono_get_exception_type_load (name, NULL));
3817 /*g_print ("failed parse\n");*/
3821 if (module != NULL) {
3823 type = mono_reflection_get_type (module->image, &info, ignoreCase, &type_resolve);
3828 if (assembly->assembly->dynamic) {
3829 /* Enumerate all modules */
3830 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
3834 if (abuilder->modules) {
3835 for (i = 0; i < mono_array_length (abuilder->modules); ++i) {
3836 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
3837 type = mono_reflection_get_type (&mb->dynamic_image->image, &info, ignoreCase, &type_resolve);
3843 if (!type && abuilder->loaded_modules) {
3844 for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) {
3845 MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
3846 type = mono_reflection_get_type (mod->image, &info, ignoreCase, &type_resolve);
3853 type = mono_reflection_get_type (assembly->assembly->image, &info, ignoreCase, &type_resolve);
3855 g_list_free (info.modifiers);
3856 g_list_free (info.nested);
3858 MonoException *e = NULL;
3861 e = mono_get_exception_type_load (name, NULL);
3863 mono_loader_clear_error ();
3866 mono_raise_exception (e);
3871 if (type->type == MONO_TYPE_CLASS) {
3872 MonoClass *klass = mono_type_get_class (type);
3873 /* need to report exceptions ? */
3874 if (throwOnError && klass->exception_type) {
3875 /* report SecurityException (or others) that occured when loading the assembly */
3876 MonoException *exc = mono_class_get_exception_for_failure (klass);
3877 mono_loader_clear_error ();
3878 mono_raise_exception (exc);
3879 } else if (klass->exception_type == MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND) {
3884 /* g_print ("got it\n"); */
3885 return mono_type_get_object (mono_object_domain (assembly), type);
3889 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *assembly, MonoBoolean escaped)
3891 MonoDomain *domain = mono_object_domain (assembly);
3892 MonoAssembly *mass = assembly->assembly;
3893 MonoString *res = NULL;
3897 MONO_ARCH_SAVE_REGS;
3899 if (g_path_is_absolute (mass->image->name))
3900 absolute = g_strdup (mass->image->name);
3902 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
3906 for (i = strlen (absolute) - 1; i >= 0; i--)
3907 if (absolute [i] == '\\')
3912 uri = g_filename_to_uri (absolute, NULL, NULL);
3914 uri = g_strconcat ("file://", absolute, NULL);
3918 res = mono_string_new (domain, uri);
3926 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssembly *assembly)
3928 MonoAssembly *mass = assembly->assembly;
3930 MONO_ARCH_SAVE_REGS;
3932 return mass->in_gac;
3935 static MonoReflectionAssembly*
3936 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoString *mname, MonoObject *evidence)
3940 MonoImageOpenStatus status;
3942 MONO_ARCH_SAVE_REGS;
3944 name = mono_string_to_utf8 (mname);
3945 res = mono_assembly_load_with_partial_name (name, &status);
3951 return mono_assembly_get_object (mono_domain_get (), res);
3955 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssembly *assembly)
3957 MonoDomain *domain = mono_object_domain (assembly);
3960 MONO_ARCH_SAVE_REGS;
3962 res = mono_string_new (domain, mono_image_get_filename (assembly->assembly->image));
3968 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssembly *assembly)
3970 MONO_ARCH_SAVE_REGS;
3972 return assembly->assembly->ref_only;
3976 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssembly *assembly)
3978 MonoDomain *domain = mono_object_domain (assembly);
3980 MONO_ARCH_SAVE_REGS;
3982 return mono_string_new (domain, assembly->assembly->image->version);
3985 static MonoReflectionMethod*
3986 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssembly *assembly)
3988 guint32 token = mono_image_get_entry_point (assembly->assembly->image);
3990 MONO_ARCH_SAVE_REGS;
3994 return mono_method_get_object (mono_object_domain (assembly), mono_get_method (assembly->assembly->image, token, NULL), NULL);
3997 static MonoReflectionModule*
3998 ves_icall_System_Reflection_Assembly_get_ManifestModule (MonoReflectionAssembly *assembly)
4000 return mono_module_get_object (mono_object_domain (assembly), assembly->assembly->image);
4004 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssembly *assembly)
4006 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4007 MonoArray *result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, table->rows);
4011 MONO_ARCH_SAVE_REGS;
4013 for (i = 0; i < table->rows; ++i) {
4014 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_MANIFEST_NAME));
4015 mono_array_setref (result, i, mono_string_new (mono_object_domain (assembly), val));
4021 create_version (MonoDomain *domain, guint32 major, guint32 minor, guint32 build, guint32 revision)
4023 static MonoClass *System_Version = NULL;
4024 static MonoMethod *create_version = NULL;
4028 if (!System_Version) {
4029 System_Version = mono_class_from_name (mono_defaults.corlib, "System", "Version");
4030 g_assert (System_Version);
4033 if (!create_version) {
4034 MonoMethodDesc *desc = mono_method_desc_new (":.ctor(int,int,int,int)", FALSE);
4035 create_version = mono_method_desc_search_in_class (desc, System_Version);
4036 g_assert (create_version);
4037 mono_method_desc_free (desc);
4043 args [3] = &revision;
4044 result = mono_object_new (domain, System_Version);
4045 mono_runtime_invoke (create_version, result, args, NULL);
4051 ves_icall_System_Reflection_Assembly_GetReferencedAssemblies (MonoReflectionAssembly *assembly)
4053 static MonoClass *System_Reflection_AssemblyName;
4055 MonoDomain *domain = mono_object_domain (assembly);
4057 static MonoMethod *create_culture = NULL;
4058 MonoImage *image = assembly->assembly->image;
4061 MONO_ARCH_SAVE_REGS;
4063 if (!System_Reflection_AssemblyName)
4064 System_Reflection_AssemblyName = mono_class_from_name (
4065 mono_defaults.corlib, "System.Reflection", "AssemblyName");
4067 t = &assembly->assembly->image->tables [MONO_TABLE_ASSEMBLYREF];
4070 result = mono_array_new (domain, System_Reflection_AssemblyName, count);
4073 MonoMethodDesc *desc = mono_method_desc_new (
4074 "System.Globalization.CultureInfo:CreateSpecificCulture(string)", TRUE);
4075 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4076 g_assert (create_culture);
4077 mono_method_desc_free (desc);
4080 for (i = 0; i < count; i++) {
4081 MonoReflectionAssemblyName *aname;
4082 guint32 cols [MONO_ASSEMBLYREF_SIZE];
4084 mono_metadata_decode_row (t, i, cols, MONO_ASSEMBLYREF_SIZE);
4086 aname = (MonoReflectionAssemblyName *) mono_object_new (
4087 domain, System_Reflection_AssemblyName);
4089 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_NAME])));
4091 aname->major = cols [MONO_ASSEMBLYREF_MAJOR_VERSION];
4092 aname->minor = cols [MONO_ASSEMBLYREF_MINOR_VERSION];
4093 aname->build = cols [MONO_ASSEMBLYREF_BUILD_NUMBER];
4094 aname->revision = cols [MONO_ASSEMBLYREF_REV_NUMBER];
4095 aname->flags = cols [MONO_ASSEMBLYREF_FLAGS];
4096 aname->versioncompat = 1; /* SameMachine (default) */
4097 aname->hashalg = ASSEMBLY_HASH_SHA1; /* SHA1 (default) */
4098 MONO_OBJECT_SETREF (aname, version, create_version (domain, aname->major, aname->minor, aname->build, aname->revision));
4100 if (create_culture) {
4102 args [0] = mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_CULTURE]));
4103 MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
4106 if (cols [MONO_ASSEMBLYREF_PUBLIC_KEY]) {
4107 const gchar *pkey_ptr = mono_metadata_blob_heap (image, cols [MONO_ASSEMBLYREF_PUBLIC_KEY]);
4108 guint32 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
4110 if ((cols [MONO_ASSEMBLYREF_FLAGS] & ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG)) {
4111 /* public key token isn't copied - the class library will
4112 automatically generate it from the public key if required */
4113 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4114 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
4116 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4117 memcpy (mono_array_addr (aname->keyToken, guint8, 0), pkey_ptr, pkey_len);
4121 /* note: this function doesn't return the codebase on purpose (i.e. it can
4122 be used under partial trust as path information isn't present). */
4124 mono_array_setref (result, i, aname);
4135 foreach_namespace (const char* key, gconstpointer val, NameSpaceInfo *info)
4137 MonoString *name = mono_string_new (mono_object_domain (info->res), key);
4139 mono_array_setref (info->res, info->idx, name);
4144 ves_icall_System_Reflection_Assembly_GetNamespaces (MonoReflectionAssembly *assembly)
4146 MonoImage *img = assembly->assembly->image;
4150 MONO_ARCH_SAVE_REGS;
4152 if (!img->name_cache)
4153 mono_image_init_name_cache (img);
4155 res = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, g_hash_table_size (img->name_cache));
4158 g_hash_table_foreach (img->name_cache, (GHFunc)foreach_namespace, &info);
4163 /* move this in some file in mono/util/ */
4165 g_concat_dir_and_file (const char *dir, const char *file)
4167 g_return_val_if_fail (dir != NULL, NULL);
4168 g_return_val_if_fail (file != NULL, NULL);
4171 * If the directory name doesn't have a / on the end, we need
4172 * to add one so we get a proper path to the file
4174 if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
4175 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
4177 return g_strconcat (dir, file, NULL);
4181 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssembly *assembly, MonoString *name, gint32 *size, MonoReflectionModule **ref_module)
4183 char *n = mono_string_to_utf8 (name);
4184 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4186 guint32 cols [MONO_MANIFEST_SIZE];
4187 guint32 impl, file_idx;
4191 MONO_ARCH_SAVE_REGS;
4193 for (i = 0; i < table->rows; ++i) {
4194 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4195 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4196 if (strcmp (val, n) == 0)
4200 if (i == table->rows)
4203 impl = cols [MONO_MANIFEST_IMPLEMENTATION];
4206 * this code should only be called after obtaining the
4207 * ResourceInfo and handling the other cases.
4209 g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
4210 file_idx = impl >> MONO_IMPLEMENTATION_BITS;
4212 module = mono_image_load_file_for_image (assembly->assembly->image, file_idx);
4217 module = assembly->assembly->image;
4219 *ref_module = mono_module_get_object (mono_domain_get (), module);
4221 return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
4225 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoManifestResourceInfo *info)
4227 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4229 guint32 cols [MONO_MANIFEST_SIZE];
4230 guint32 file_cols [MONO_FILE_SIZE];
4234 MONO_ARCH_SAVE_REGS;
4236 n = mono_string_to_utf8 (name);
4237 for (i = 0; i < table->rows; ++i) {
4238 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4239 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4240 if (strcmp (val, n) == 0)
4244 if (i == table->rows)
4247 if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
4248 info->location = RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST;
4251 switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
4252 case MONO_IMPLEMENTATION_FILE:
4253 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4254 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4255 mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
4256 val = mono_metadata_string_heap (assembly->assembly->image, file_cols [MONO_FILE_NAME]);
4257 MONO_OBJECT_SETREF (info, filename, mono_string_new (mono_object_domain (assembly), val));
4258 if (file_cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA)
4261 info->location = RESOURCE_LOCATION_EMBEDDED;
4264 case MONO_IMPLEMENTATION_ASSEMBLYREF:
4265 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4266 mono_assembly_load_reference (assembly->assembly->image, i - 1);
4267 if (assembly->assembly->image->references [i - 1] == (gpointer)-1) {
4268 char *msg = g_strdup_printf ("Assembly %d referenced from assembly %s not found ", i - 1, assembly->assembly->image->name);
4269 MonoException *ex = mono_get_exception_file_not_found2 (msg, NULL);
4271 mono_raise_exception (ex);
4273 MONO_OBJECT_SETREF (info, assembly, mono_assembly_get_object (mono_domain_get (), assembly->assembly->image->references [i - 1]));
4275 /* Obtain info recursively */
4276 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (info->assembly, name, info);
4277 info->location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
4280 case MONO_IMPLEMENTATION_EXP_TYPE:
4281 g_assert_not_reached ();
4290 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoBoolean resource_modules)
4292 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4293 MonoArray *result = NULL;
4298 MONO_ARCH_SAVE_REGS;
4300 /* check hash if needed */
4302 n = mono_string_to_utf8 (name);
4303 for (i = 0; i < table->rows; ++i) {
4304 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4305 if (strcmp (val, n) == 0) {
4308 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4309 fn = mono_string_new (mono_object_domain (assembly), n);
4311 return (MonoObject*)fn;
4319 for (i = 0; i < table->rows; ++i) {
4320 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA))
4324 result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, count);
4327 for (i = 0; i < table->rows; ++i) {
4328 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4329 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4330 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4331 mono_array_setref (result, count, mono_string_new (mono_object_domain (assembly), n));
4336 return (MonoObject*)result;
4340 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly *assembly)
4342 MonoDomain *domain = mono_domain_get();
4345 int i, j, file_count = 0;
4346 MonoImage **modules;
4347 guint32 module_count, real_module_count;
4348 MonoTableInfo *table;
4350 g_assert (assembly->assembly->image != NULL);
4352 if (assembly->assembly->dynamic) {
4353 MonoReflectionAssemblyBuilder *assemblyb = (MonoReflectionAssemblyBuilder*)assembly;
4355 if (assemblyb->modules)
4356 module_count = mono_array_length (assemblyb->modules);
4359 real_module_count = module_count;
4361 modules = g_new0 (MonoImage*, module_count);
4362 if (assemblyb->modules) {
4363 for (i = 0; i < mono_array_length (assemblyb->modules); ++i) {
4365 mono_array_get (assemblyb->modules, MonoReflectionModuleBuilder*, i)->module.image;
4370 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4371 file_count = table->rows;
4373 modules = assembly->assembly->image->modules;
4374 module_count = assembly->assembly->image->module_count;
4376 real_module_count = 0;
4377 for (i = 0; i < module_count; ++i)
4379 real_module_count ++;
4382 klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "Module");
4383 res = mono_array_new (domain, klass, 1 + real_module_count + file_count);
4385 mono_array_setref (res, 0, mono_module_get_object (domain, assembly->assembly->image));
4387 for (i = 0; i < module_count; ++i)
4389 mono_array_setref (res, j, mono_module_get_object (domain, modules[i]));
4393 for (i = 0; i < file_count; ++i, ++j)
4394 mono_array_setref (res, j, mono_module_file_get_object (domain, assembly->assembly->image, i));
4396 if (assembly->assembly->dynamic)
4402 static MonoReflectionMethod*
4403 ves_icall_GetCurrentMethod (void)
4405 MonoMethod *m = mono_method_get_last_managed ();
4407 MONO_ARCH_SAVE_REGS;
4409 return mono_method_get_object (mono_domain_get (), m, NULL);
4412 static MonoReflectionMethod*
4413 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType (MonoMethod *method, MonoType *type)
4415 /* FIXME check that method belongs to klass or a parent */
4418 klass = mono_class_from_mono_type (type);
4420 klass = method->klass;
4421 return mono_method_get_object (mono_domain_get (), method, klass);
4424 static MonoReflectionMethod*
4425 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternal (MonoMethod *method)
4427 return mono_method_get_object (mono_domain_get (), method, NULL);
4430 static MonoReflectionMethodBody*
4431 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod *method)
4433 return mono_method_body_get_object (mono_domain_get (), method);
4436 static MonoReflectionAssembly*
4437 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (void)
4439 MonoMethod *m = mono_method_get_last_managed ();
4441 MONO_ARCH_SAVE_REGS;
4443 return mono_assembly_get_object (mono_domain_get (), m->klass->image->assembly);
4447 static MonoReflectionAssembly*
4448 ves_icall_System_Reflection_Assembly_GetEntryAssembly (void)
4450 MonoDomain* domain = mono_domain_get ();
4452 MONO_ARCH_SAVE_REGS;
4454 if (!domain->entry_assembly)
4457 return mono_assembly_get_object (domain, domain->entry_assembly);
4460 static MonoReflectionAssembly*
4461 ves_icall_System_Reflection_Assembly_GetCallingAssembly (void)
4463 MonoMethod *m = mono_method_get_last_managed ();
4464 MonoMethod *dest = m;
4466 MONO_ARCH_SAVE_REGS;
4468 mono_stack_walk_no_il (get_caller, &dest);
4471 return mono_assembly_get_object (mono_domain_get (), dest->klass->image->assembly);
4475 ves_icall_System_MonoType_getFullName (MonoReflectionType *object, gboolean full_name,
4476 gboolean assembly_qualified)
4478 MonoDomain *domain = mono_object_domain (object);
4479 MonoTypeNameFormat format;
4483 MONO_ARCH_SAVE_REGS;
4485 format = assembly_qualified ?
4486 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
4487 MONO_TYPE_NAME_FORMAT_FULL_NAME;
4489 format = MONO_TYPE_NAME_FORMAT_REFLECTION;
4491 name = mono_type_get_name_full (object->type, format);
4495 if (full_name && (object->type->type == MONO_TYPE_VAR || object->type->type == MONO_TYPE_MVAR)) {
4500 res = mono_string_new (domain, name);
4507 fill_reflection_assembly_name (MonoDomain *domain, MonoReflectionAssemblyName *aname, MonoAssemblyName *name, const char *absolute, gboolean by_default_version)
4509 static MonoMethod *create_culture = NULL;
4512 const char *pkey_ptr;
4515 MONO_ARCH_SAVE_REGS;
4517 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, name->name));
4518 aname->major = name->major;
4519 aname->minor = name->minor;
4520 aname->build = name->build;
4521 aname->revision = name->revision;
4522 aname->hashalg = name->hash_alg;
4523 if (by_default_version)
4524 MONO_OBJECT_SETREF (aname, version, create_version (domain, name->major, name->minor, name->build, name->revision));
4526 codebase = g_filename_to_uri (absolute, NULL, NULL);
4528 MONO_OBJECT_SETREF (aname, codebase, mono_string_new (domain, codebase));
4532 if (!create_culture) {
4533 MonoMethodDesc *desc = mono_method_desc_new ("System.Globalization.CultureInfo:CreateSpecificCulture(string)", TRUE);
4534 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4535 g_assert (create_culture);
4536 mono_method_desc_free (desc);
4539 if (name->culture) {
4540 args [0] = mono_string_new (domain, name->culture);
4541 MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
4544 if (name->public_key) {
4545 pkey_ptr = (char*)name->public_key;
4546 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
4548 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4549 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
4552 /* MonoAssemblyName keeps the public key token as an hexadecimal string */
4553 if (name->public_key_token [0]) {
4557 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, 8));
4558 p = mono_array_addr (aname->keyToken, char, 0);
4560 for (i = 0, j = 0; i < 8; i++) {
4561 *p = g_ascii_xdigit_value (name->public_key_token [j++]) << 4;
4562 *p |= g_ascii_xdigit_value (name->public_key_token [j++]);
4569 ves_icall_System_Reflection_Assembly_FillName (MonoReflectionAssembly *assembly, MonoReflectionAssemblyName *aname)
4572 MonoAssembly *mass = assembly->assembly;
4574 MONO_ARCH_SAVE_REGS;
4576 if (g_path_is_absolute (mass->image->name)) {
4577 fill_reflection_assembly_name (mono_object_domain (assembly),
4578 aname, &mass->aname, mass->image->name, TRUE);
4581 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4583 fill_reflection_assembly_name (mono_object_domain (assembly),
4584 aname, &mass->aname, absolute, TRUE);
4590 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoString *fname, MonoReflectionAssemblyName *aname)
4593 MonoImageOpenStatus status = MONO_IMAGE_OK;
4596 MonoAssemblyName name;
4598 MONO_ARCH_SAVE_REGS;
4600 filename = mono_string_to_utf8 (fname);
4602 image = mono_image_open (filename, &status);
4608 if (status == MONO_IMAGE_IMAGE_INVALID)
4609 exc = mono_get_exception_bad_image_format2 (NULL, fname);
4611 exc = mono_get_exception_file_not_found2 (NULL, fname);
4612 mono_raise_exception (exc);
4615 res = mono_assembly_fill_assembly_name (image, &name);
4617 mono_image_close (image);
4619 mono_raise_exception (mono_get_exception_argument ("assemblyFile", "The file does not contain a manifest"));
4622 fill_reflection_assembly_name (mono_domain_get (), aname, &name, filename, TRUE);
4625 mono_image_close (image);
4629 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssembly *assembly,
4630 char **minimum, guint32 *minLength, char **optional, guint32 *optLength, char **refused, guint32 *refLength)
4632 MonoBoolean result = FALSE;
4633 MonoDeclSecurityEntry entry;
4635 /* SecurityAction.RequestMinimum */
4636 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQMIN, &entry)) {
4637 *minimum = entry.blob;
4638 *minLength = entry.size;
4641 /* SecurityAction.RequestOptional */
4642 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQOPT, &entry)) {
4643 *optional = entry.blob;
4644 *optLength = entry.size;
4647 /* SecurityAction.RequestRefuse */
4648 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQREFUSE, &entry)) {
4649 *refused = entry.blob;
4650 *refLength = entry.size;
4658 mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoBoolean exportedOnly)
4662 MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
4664 guint32 attrs, visibility;
4666 /* we start the count from 1 because we skip the special type <Module> */
4669 for (i = 1; i < tdef->rows; ++i) {
4670 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
4671 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
4672 if (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)
4676 count = tdef->rows - 1;
4678 res = mono_array_new (domain, mono_defaults.monotype_class, count);
4680 for (i = 1; i < tdef->rows; ++i) {
4681 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
4682 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
4683 if (!exportedOnly || (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)) {
4684 klass = mono_class_get_throw (image, (i + 1) | MONO_TOKEN_TYPE_DEF);
4685 if (mono_loader_get_last_error ())
4686 mono_loader_clear_error ();
4687 mono_array_setref (res, count, mono_type_get_object (domain, &klass->byval_arg));
4696 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly, MonoBoolean exportedOnly)
4698 MonoArray *res = NULL;
4699 MonoImage *image = NULL;
4700 MonoTableInfo *table = NULL;
4705 MONO_ARCH_SAVE_REGS;
4707 domain = mono_object_domain (assembly);
4709 if (assembly->assembly->dynamic) {
4710 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
4711 if (abuilder->modules) {
4712 for (i = 0; i < mono_array_length(abuilder->modules); i++) {
4713 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
4714 MonoArray *append = mb->types;
4715 /* The types array might not be fully filled up */
4716 if (append && mb->num_types > 0) {
4719 len1 = res ? mono_array_length (res) : 0;
4720 len2 = mb->num_types;
4721 new = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4723 mono_array_memcpy_refs (new, 0, res, 0, len1);
4724 mono_array_memcpy_refs (new, len1, append, 0, len2);
4730 * Replace TypeBuilders with the created types to be compatible
4734 for (i = 0; i < mono_array_length (res); ++i) {
4735 MonoReflectionTypeBuilder *tb = mono_array_get (res, MonoReflectionTypeBuilder*, i);
4737 mono_array_setref (res, i, tb->created);
4742 if (abuilder->loaded_modules)
4743 for (i = 0; i < mono_array_length(abuilder->loaded_modules); i++) {
4744 MonoReflectionModule *rm = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
4745 MonoArray *append = mono_module_get_types (domain, rm->image, exportedOnly);
4746 if (append && mono_array_length (append) > 0) {
4749 len1 = res ? mono_array_length (res) : 0;
4750 len2 = mono_array_length (append);
4751 new = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4753 mono_array_memcpy_refs (new, 0, res, 0, len1);
4754 mono_array_memcpy_refs (new, len1, append, 0, len2);
4761 return mono_array_new (domain, mono_defaults.monotype_class, 0);
4763 image = assembly->assembly->image;
4764 table = &image->tables [MONO_TABLE_FILE];
4765 res = mono_module_get_types (domain, image, exportedOnly);
4767 /* Append data from all modules in the assembly */
4768 for (i = 0; i < table->rows; ++i) {
4769 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4770 MonoImage *loaded_image = mono_assembly_load_module (image->assembly, i + 1);
4772 MonoArray *res2 = mono_module_get_types (domain, loaded_image, exportedOnly);
4773 /* Append the new types to the end of the array */
4774 if (mono_array_length (res2) > 0) {
4778 len1 = mono_array_length (res);
4779 len2 = mono_array_length (res2);
4780 res3 = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4781 mono_array_memcpy_refs (res3, 0, res, 0, len1);
4782 mono_array_memcpy_refs (res3, len1, res2, 0, len2);
4789 /* the ReflectionTypeLoadException must have all the types (Types property),
4790 * NULL replacing types which throws an exception. The LoaderException must
4791 * contain all exceptions for NULL items.
4794 len = mono_array_length (res);
4796 for (i = 0; i < len; i++) {
4797 MonoReflectionType *t = mono_array_get (res, gpointer, i);
4798 MonoClass *klass = mono_type_get_class (t->type);
4799 if ((klass != NULL) && klass->exception_type) {
4800 /* keep the class in the list */
4801 list = g_list_append (list, klass);
4802 /* and replace Type with NULL */
4803 mono_array_setref (res, i, NULL);
4809 MonoException *exc = NULL;
4810 MonoArray *exl = NULL;
4811 int length = g_list_length (list);
4813 mono_loader_clear_error ();
4815 exl = mono_array_new (domain, mono_defaults.exception_class, length);
4816 for (i = 0, tmp = list; i < length; i++, tmp = tmp->next) {
4817 MonoException *exc = mono_class_get_exception_for_failure (tmp->data);
4818 mono_array_setref (exl, i, exc);
4823 exc = mono_get_exception_reflection_type_load (res, exl);
4824 mono_loader_clear_error ();
4825 mono_raise_exception (exc);
4832 ves_icall_System_Reflection_AssemblyName_ParseName (MonoReflectionAssemblyName *name, MonoString *assname)
4834 MonoAssemblyName aname;
4835 MonoDomain *domain = mono_object_domain (name);
4837 gboolean is_version_defined;
4839 val = mono_string_to_utf8 (assname);
4840 if (!mono_assembly_name_parse_full (val, &aname, TRUE, &is_version_defined))
4843 fill_reflection_assembly_name (domain, name, &aname, "", is_version_defined);
4845 mono_assembly_name_free (&aname);
4846 g_free ((guint8*) aname.public_key);
4852 static MonoReflectionType*
4853 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModule *module)
4855 MonoDomain *domain = mono_object_domain (module);
4858 MONO_ARCH_SAVE_REGS;
4860 g_assert (module->image);
4862 if (module->image->dynamic && ((MonoDynamicImage*)(module->image))->initial_image)
4863 /* These images do not have a global type */
4866 klass = mono_class_get (module->image, 1 | MONO_TOKEN_TYPE_DEF);
4867 return mono_type_get_object (domain, &klass->byval_arg);
4871 ves_icall_System_Reflection_Module_Close (MonoReflectionModule *module)
4873 /*if (module->image)
4874 mono_image_close (module->image);*/
4878 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModule *module)
4880 MonoDomain *domain = mono_object_domain (module);
4882 MONO_ARCH_SAVE_REGS;
4884 g_assert (module->image);
4885 return mono_string_new (domain, module->image->guid);
4889 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine)
4891 if (image->dynamic) {
4892 MonoDynamicImage *dyn = (MonoDynamicImage*)image;
4893 *pe_kind = dyn->pe_kind;
4894 *machine = dyn->machine;
4897 *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
4898 *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
4903 ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage *image)
4905 return (image->md_version_major << 16) | (image->md_version_minor);
4909 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModule *module)
4911 MONO_ARCH_SAVE_REGS;
4914 return mono_array_new (mono_object_domain (module), mono_defaults.monotype_class, 0);
4916 return mono_module_get_types (mono_object_domain (module), module->image, FALSE);
4920 mono_metadata_memberref_is_method (MonoImage *image, guint32 token)
4922 guint32 cols [MONO_MEMBERREF_SIZE];
4924 mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
4925 sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
4926 mono_metadata_decode_blob_size (sig, &sig);
4927 return (*sig != 0x6);
4931 init_generic_context_from_args (MonoGenericContext *context, MonoArray *type_args, MonoArray *method_args)
4934 context->class_inst = mono_metadata_get_generic_inst (mono_array_length (type_args),
4935 mono_array_addr (type_args, MonoType*, 0));
4937 context->class_inst = NULL;
4939 context->method_inst = mono_metadata_get_generic_inst (mono_array_length (method_args),
4940 mono_array_addr (method_args, MonoType*, 0));
4942 context->method_inst = NULL;
4946 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
4949 int table = mono_metadata_token_table (token);
4950 int index = mono_metadata_token_index (token);
4951 MonoGenericContext context;
4953 *error = ResolveTokenError_Other;
4955 /* Validate token */
4956 if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) &&
4957 (table != MONO_TABLE_TYPESPEC)) {
4958 *error = ResolveTokenError_BadTable;
4962 if (image->dynamic) {
4963 if (type_args || method_args)
4964 mono_raise_exception (mono_get_exception_not_implemented (NULL));
4965 return mono_lookup_dynamic_token (image, token);
4968 if ((index <= 0) || (index > image->tables [table].rows)) {
4969 *error = ResolveTokenError_OutOfRange;
4973 init_generic_context_from_args (&context, type_args, method_args);
4974 klass = mono_class_get_full (image, token, &context);
4977 return &klass->byval_arg;
4983 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
4985 int table = mono_metadata_token_table (token);
4986 int index = mono_metadata_token_index (token);
4987 MonoGenericContext context;
4990 *error = ResolveTokenError_Other;
4992 /* Validate token */
4993 if ((table != MONO_TABLE_METHOD) && (table != MONO_TABLE_METHODSPEC) &&
4994 (table != MONO_TABLE_MEMBERREF)) {
4995 *error = ResolveTokenError_BadTable;
4999 if (image->dynamic) {
5000 if (type_args || method_args)
5001 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5002 /* FIXME: validate memberref token type */
5003 return mono_lookup_dynamic_token (image, token);
5006 if ((index <= 0) || (index > image->tables [table].rows)) {
5007 *error = ResolveTokenError_OutOfRange;
5010 if ((table == MONO_TABLE_MEMBERREF) && (!mono_metadata_memberref_is_method (image, token))) {
5011 *error = ResolveTokenError_BadTable;
5015 init_generic_context_from_args (&context, type_args, method_args);
5016 method = mono_get_method_full (image, token, NULL, &context);
5022 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
5024 int index = mono_metadata_token_index (token);
5026 *error = ResolveTokenError_Other;
5028 /* Validate token */
5029 if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
5030 *error = ResolveTokenError_BadTable;
5035 return mono_lookup_dynamic_token (image, token);
5037 if ((index <= 0) || (index >= image->heap_us.size)) {
5038 *error = ResolveTokenError_OutOfRange;
5042 /* FIXME: What to do if the index points into the middle of a string ? */
5044 return mono_ldstr (mono_domain_get (), image, index);
5047 static MonoClassField*
5048 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5051 int table = mono_metadata_token_table (token);
5052 int index = mono_metadata_token_index (token);
5053 MonoGenericContext context;
5054 MonoClassField *field;
5056 *error = ResolveTokenError_Other;
5058 /* Validate token */
5059 if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
5060 *error = ResolveTokenError_BadTable;
5064 if (image->dynamic) {
5065 if (type_args || method_args)
5066 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5067 /* FIXME: validate memberref token type */
5068 return mono_lookup_dynamic_token (image, token);
5071 if ((index <= 0) || (index > image->tables [table].rows)) {
5072 *error = ResolveTokenError_OutOfRange;
5075 if ((table == MONO_TABLE_MEMBERREF) && (mono_metadata_memberref_is_method (image, token))) {
5076 *error = ResolveTokenError_BadTable;
5080 init_generic_context_from_args (&context, type_args, method_args);
5081 field = mono_field_from_token (image, token, &klass, &context);
5088 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5090 int table = mono_metadata_token_table (token);
5092 *error = ResolveTokenError_Other;
5095 case MONO_TABLE_TYPEDEF:
5096 case MONO_TABLE_TYPEREF:
5097 case MONO_TABLE_TYPESPEC: {
5098 MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, type_args, method_args, error);
5100 return (MonoObject*)mono_type_get_object (mono_domain_get (), t);
5104 case MONO_TABLE_METHOD:
5105 case MONO_TABLE_METHODSPEC: {
5106 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5108 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
5112 case MONO_TABLE_FIELD: {
5113 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5115 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
5119 case MONO_TABLE_MEMBERREF:
5120 if (mono_metadata_memberref_is_method (image, token)) {
5121 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5123 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
5128 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5130 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
5137 *error = ResolveTokenError_BadTable;
5144 ves_icall_System_Reflection_Module_ResolveSignature (MonoImage *image, guint32 token, MonoResolveTokenError *error)
5146 int table = mono_metadata_token_table (token);
5147 int idx = mono_metadata_token_index (token);
5148 MonoTableInfo *tables = image->tables;
5153 *error = ResolveTokenError_OutOfRange;
5155 /* FIXME: Support other tables ? */
5156 if (table != MONO_TABLE_STANDALONESIG)
5162 if ((idx == 0) || (idx > tables [MONO_TABLE_STANDALONESIG].rows))
5165 sig = mono_metadata_decode_row_col (&tables [MONO_TABLE_STANDALONESIG], idx - 1, 0);
5167 ptr = mono_metadata_blob_heap (image, sig);
5168 len = mono_metadata_decode_blob_size (ptr, &ptr);
5170 res = mono_array_new (mono_domain_get (), mono_defaults.byte_class, len);
5171 memcpy (mono_array_addr (res, guint8, 0), ptr, len);
5175 static MonoReflectionType*
5176 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
5179 int isbyref = 0, rank;
5180 char *str = mono_string_to_utf8 (smodifiers);
5183 MONO_ARCH_SAVE_REGS;
5185 klass = mono_class_from_mono_type (tb->type.type);
5187 /* logic taken from mono_reflection_parse_type(): keep in sync */
5191 if (isbyref) { /* only one level allowed by the spec */
5198 return mono_type_get_object (mono_object_domain (tb), &klass->this_arg);
5201 klass = mono_ptr_class_get (&klass->byval_arg);
5202 mono_class_init (klass);
5213 else if (*p != '*') { /* '*' means unknown lower bound */
5224 klass = mono_array_class_get (klass, rank);
5225 mono_class_init (klass);
5232 return mono_type_get_object (mono_object_domain (tb), &klass->byval_arg);
5236 ves_icall_Type_IsArrayImpl (MonoReflectionType *t)
5241 MONO_ARCH_SAVE_REGS;
5244 res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
5249 static MonoReflectionType *
5250 ves_icall_Type_make_array_type (MonoReflectionType *type, int rank)
5252 MonoClass *klass, *aklass;
5254 MONO_ARCH_SAVE_REGS;
5256 klass = mono_class_from_mono_type (type->type);
5257 aklass = mono_array_class_get (klass, rank);
5259 return mono_type_get_object (mono_object_domain (type), &aklass->byval_arg);
5262 static MonoReflectionType *
5263 ves_icall_Type_make_byref_type (MonoReflectionType *type)
5267 MONO_ARCH_SAVE_REGS;
5269 klass = mono_class_from_mono_type (type->type);
5271 return mono_type_get_object (mono_object_domain (type), &klass->this_arg);
5274 static MonoReflectionType *
5275 ves_icall_Type_MakePointerType (MonoReflectionType *type)
5279 MONO_ARCH_SAVE_REGS;
5281 pklass = mono_ptr_class_get (type->type);
5283 return mono_type_get_object (mono_object_domain (type), &pklass->byval_arg);
5287 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
5288 MonoReflectionMethod *info)
5290 MonoClass *delegate_class = mono_class_from_mono_type (type->type);
5291 MonoObject *delegate;
5294 MONO_ARCH_SAVE_REGS;
5296 mono_assert (delegate_class->parent == mono_defaults.multicastdelegate_class);
5298 delegate = mono_object_new (mono_object_domain (type), delegate_class);
5300 func = mono_compile_method (info->method);
5302 mono_delegate_ctor (delegate, target, func);
5308 ves_icall_System_Delegate_SetMulticastInvoke (MonoDelegate *this)
5313 /* Find the Invoke method */
5315 while ((invoke = mono_class_get_methods (this->object.vtable->klass, &iter))) {
5316 if (!strcmp (invoke->name, "Invoke"))
5321 this->invoke_impl = mono_compile_method (mono_marshal_get_delegate_invoke (invoke));
5325 * Magic number to convert a time which is relative to
5326 * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
5328 #define EPOCH_ADJUST ((guint64)62135596800LL)
5331 * Magic number to convert FILETIME base Jan 1, 1601 to DateTime - base Jan, 1, 0001
5333 #define FILETIME_ADJUST ((guint64)504911232000000000LL)
5336 * This returns Now in UTC
5339 ves_icall_System_DateTime_GetNow (void)
5341 #ifdef PLATFORM_WIN32
5345 GetSystemTime (&st);
5346 SystemTimeToFileTime (&st, &ft);
5347 return (gint64) FILETIME_ADJUST + ((((gint64)ft.dwHighDateTime)<<32) | ft.dwLowDateTime);
5349 /* FIXME: put this in io-layer and call it GetLocalTime */
5353 MONO_ARCH_SAVE_REGS;
5355 if (gettimeofday (&tv, NULL) == 0) {
5356 res = (((gint64)tv.tv_sec + EPOCH_ADJUST)* 1000000 + tv.tv_usec)*10;
5359 /* fixme: raise exception */
5364 #ifdef PLATFORM_WIN32
5365 /* convert a SYSTEMTIME which is of the form "last thursday in october" to a real date */
5367 convert_to_absolute_date(SYSTEMTIME *date)
5369 #define IS_LEAP(y) ((y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0))
5370 static int days_in_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5371 static int leap_days_in_month[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5372 /* from the calendar FAQ */
5373 int a = (14 - date->wMonth) / 12;
5374 int y = date->wYear - a;
5375 int m = date->wMonth + 12 * a - 2;
5376 int d = (1 + y + y/4 - y/100 + y/400 + (31*m)/12) % 7;
5378 /* d is now the day of the week for the first of the month (0 == Sunday) */
5380 int day_of_week = date->wDayOfWeek;
5382 /* set day_in_month to the first day in the month which falls on day_of_week */
5383 int day_in_month = 1 + (day_of_week - d);
5384 if (day_in_month <= 0)
5387 /* wDay is 1 for first weekday in month, 2 for 2nd ... 5 means last - so work that out allowing for days in the month */
5388 date->wDay = day_in_month + (date->wDay - 1) * 7;
5389 if (date->wDay > (IS_LEAP(date->wYear) ? leap_days_in_month[date->wMonth - 1] : days_in_month[date->wMonth - 1]))
5394 #ifndef PLATFORM_WIN32
5396 * Return's the offset from GMT of a local time.
5398 * tm is a local time
5399 * t is the same local time as seconds.
5402 gmt_offset(struct tm *tm, time_t t)
5404 #if defined (HAVE_TM_GMTOFF)
5405 return tm->tm_gmtoff;
5410 g.tm_isdst = tm->tm_isdst;
5412 return (int)difftime(t, t2);
5417 * This is heavily based on zdump.c from glibc 2.2.
5419 * * data[0]: start of daylight saving time (in DateTime ticks).
5420 * * data[1]: end of daylight saving time (in DateTime ticks).
5421 * * data[2]: utcoffset (in TimeSpan ticks).
5422 * * data[3]: additional offset when daylight saving (in TimeSpan ticks).
5423 * * name[0]: name of this timezone when not daylight saving.
5424 * * name[1]: name of this timezone when daylight saving.
5426 * FIXME: This only works with "standard" Unix dates (years between 1900 and 2100) while
5427 * the class library allows years between 1 and 9999.
5429 * Returns true on success and zero on failure.
5432 ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year, MonoArray **data, MonoArray **names)
5434 #ifndef PLATFORM_WIN32
5435 MonoDomain *domain = mono_domain_get ();
5436 struct tm start, tt;
5440 int is_daylight = 0, day;
5443 MONO_ARCH_SAVE_REGS;
5445 MONO_CHECK_ARG_NULL (data);
5446 MONO_CHECK_ARG_NULL (names);
5448 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5449 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5452 * no info is better than crashing: we'll need our own tz data
5453 * to make this work properly, anyway. The range is probably
5454 * reduced to 1970 .. 2037 because that is what mktime is
5455 * guaranteed to support (we get into an infinite loop
5459 memset (&start, 0, sizeof (start));
5462 start.tm_year = year-1900;
5464 t = mktime (&start);
5466 if ((year < 1970) || (year > 2037) || (t == -1)) {
5468 tt = *localtime (&t);
5469 strftime (tzone, sizeof (tzone), "%Z", &tt);
5470 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5471 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5475 gmtoff = gmt_offset (&start, t);
5477 /* For each day of the year, calculate the tm_gmtoff. */
5478 for (day = 0; day < 365; day++) {
5481 tt = *localtime (&t);
5483 /* Daylight saving starts or ends here. */
5484 if (gmt_offset (&tt, t) != gmtoff) {
5488 /* Try to find the exact hour when daylight saving starts/ends. */
5492 tt1 = *localtime (&t1);
5493 } while (gmt_offset (&tt1, t1) != gmtoff);
5495 /* Try to find the exact minute when daylight saving starts/ends. */
5498 tt1 = *localtime (&t1);
5499 } while (gmt_offset (&tt1, t1) == gmtoff);
5501 strftime (tzone, sizeof (tzone), "%Z", &tt);
5503 /* Write data, if we're already in daylight saving, we're done. */
5505 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5506 mono_array_set ((*data), gint64, 1, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
5509 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5510 mono_array_set ((*data), gint64, 0, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
5514 /* This is only set once when we enter daylight saving. */
5515 mono_array_set ((*data), gint64, 2, (gint64)gmtoff * 10000000L);
5516 mono_array_set ((*data), gint64, 3, (gint64)(gmt_offset (&tt, t) - gmtoff) * 10000000L);
5518 gmtoff = gmt_offset (&tt, t);
5523 strftime (tzone, sizeof (tzone), "%Z", &tt);
5524 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5525 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5526 mono_array_set ((*data), gint64, 0, 0);
5527 mono_array_set ((*data), gint64, 1, 0);
5528 mono_array_set ((*data), gint64, 2, (gint64) gmtoff * 10000000L);
5529 mono_array_set ((*data), gint64, 3, 0);
5534 MonoDomain *domain = mono_domain_get ();
5535 TIME_ZONE_INFORMATION tz_info;
5540 tz_id = GetTimeZoneInformation (&tz_info);
5541 if (tz_id == TIME_ZONE_ID_INVALID)
5544 MONO_CHECK_ARG_NULL (data);
5545 MONO_CHECK_ARG_NULL (names);
5547 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5548 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5550 for (i = 0; i < 32; ++i)
5551 if (!tz_info.DaylightName [i])
5553 mono_array_setref ((*names), 1, mono_string_new_utf16 (domain, tz_info.DaylightName, i));
5554 for (i = 0; i < 32; ++i)
5555 if (!tz_info.StandardName [i])
5557 mono_array_setref ((*names), 0, mono_string_new_utf16 (domain, tz_info.StandardName, i));
5559 if ((year <= 1601) || (year > 30827)) {
5561 * According to MSDN, the MS time functions can't handle dates outside
5567 /* even if the timezone has no daylight savings it may have Bias (e.g. GMT+13 it seems) */
5568 if (tz_id != TIME_ZONE_ID_UNKNOWN) {
5569 tz_info.StandardDate.wYear = year;
5570 convert_to_absolute_date(&tz_info.StandardDate);
5571 err = SystemTimeToFileTime (&tz_info.StandardDate, &ft);
5573 mono_array_set ((*data), gint64, 1, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
5574 tz_info.DaylightDate.wYear = year;
5575 convert_to_absolute_date(&tz_info.DaylightDate);
5576 err = SystemTimeToFileTime (&tz_info.DaylightDate, &ft);
5578 mono_array_set ((*data), gint64, 0, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
5580 mono_array_set ((*data), gint64, 2, (tz_info.Bias + tz_info.StandardBias) * -600000000LL);
5581 mono_array_set ((*data), gint64, 3, (tz_info.DaylightBias - tz_info.StandardBias) * -600000000LL);
5588 ves_icall_System_Object_obj_address (MonoObject *this)
5590 MONO_ARCH_SAVE_REGS;
5597 static inline gint32
5598 mono_array_get_byte_length (MonoArray *array)
5604 klass = array->obj.vtable->klass;
5606 if (array->bounds == NULL)
5607 length = array->max_length;
5610 for (i = 0; i < klass->rank; ++ i)
5611 length *= array->bounds [i].length;
5614 switch (klass->element_class->byval_arg.type) {
5617 case MONO_TYPE_BOOLEAN:
5621 case MONO_TYPE_CHAR:
5629 return length * sizeof (gpointer);
5640 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array)
5642 MONO_ARCH_SAVE_REGS;
5644 return mono_array_get_byte_length (array);
5648 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx)
5650 MONO_ARCH_SAVE_REGS;
5652 return mono_array_get (array, gint8, idx);
5656 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value)
5658 MONO_ARCH_SAVE_REGS;
5660 mono_array_set (array, gint8, idx, value);
5664 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count)
5666 guint8 *src_buf, *dest_buf;
5668 MONO_ARCH_SAVE_REGS;
5670 /* watch out for integer overflow */
5671 if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count))
5674 src_buf = (guint8 *)src->vector + src_offset;
5675 dest_buf = (guint8 *)dest->vector + dest_offset;
5678 memcpy (dest_buf, src_buf, count);
5680 memmove (dest_buf, src_buf, count); /* Source and dest are the same array */
5686 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this, MonoString *class_name)
5688 MonoDomain *domain = mono_object_domain (this);
5690 MonoRealProxy *rp = ((MonoRealProxy *)this);
5691 MonoTransparentProxy *tp;
5695 MONO_ARCH_SAVE_REGS;
5697 res = mono_object_new (domain, mono_defaults.transparent_proxy_class);
5698 tp = (MonoTransparentProxy*) res;
5700 MONO_OBJECT_SETREF (tp, rp, rp);
5701 type = ((MonoReflectionType *)rp->class_to_proxy)->type;
5702 klass = mono_class_from_mono_type (type);
5704 tp->custom_type_info = (mono_object_isinst (this, mono_defaults.iremotingtypeinfo_class) != NULL);
5705 tp->remote_class = mono_remote_class (domain, class_name, klass);
5707 res->vtable = mono_remote_class_vtable (domain, tp->remote_class, rp);
5711 static MonoReflectionType *
5712 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
5714 return mono_type_get_object (mono_object_domain (tp), &tp->remote_class->proxy_class->byval_arg);
5717 /* System.Environment */
5720 ves_icall_System_Environment_get_MachineName (void)
5722 #if defined (PLATFORM_WIN32)
5727 len = MAX_COMPUTERNAME_LENGTH + 1;
5728 buf = g_new (gunichar2, len);
5731 if (GetComputerName (buf, (PDWORD) &len))
5732 result = mono_string_new_utf16 (mono_domain_get (), buf, len);
5740 if (gethostname (buf, sizeof (buf)) == 0)
5741 result = mono_string_new (mono_domain_get (), buf);
5750 ves_icall_System_Environment_get_Platform (void)
5752 MONO_ARCH_SAVE_REGS;
5754 #if defined (PLATFORM_WIN32)
5764 ves_icall_System_Environment_get_NewLine (void)
5766 MONO_ARCH_SAVE_REGS;
5768 #if defined (PLATFORM_WIN32)
5769 return mono_string_new (mono_domain_get (), "\r\n");
5771 return mono_string_new (mono_domain_get (), "\n");
5776 ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name)
5781 MONO_ARCH_SAVE_REGS;
5786 utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
5787 value = g_getenv (utf8_name);
5794 return mono_string_new (mono_domain_get (), value);
5798 * There is no standard way to get at environ.
5801 #ifndef __MINGW32_VERSION
5808 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
5816 MONO_ARCH_SAVE_REGS;
5819 for (e = environ; *e != 0; ++ e)
5822 domain = mono_domain_get ();
5823 names = mono_array_new (domain, mono_defaults.string_class, n);
5826 for (e = environ; *e != 0; ++ e) {
5827 parts = g_strsplit (*e, "=", 2);
5829 str = mono_string_new (domain, *parts);
5830 mono_array_setref (names, n, str);
5842 * If your platform lacks setenv/unsetenv, you must upgrade your glib.
5844 #if !GLIB_CHECK_VERSION(2,4,0)
5845 #define g_setenv(a,b,c) setenv(a,b,c)
5846 #define g_unsetenv(a) unsetenv(a)
5850 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
5852 #ifdef PLATFORM_WIN32
5853 gunichar2 *utf16_name, *utf16_value;
5855 gchar *utf8_name, *utf8_value;
5858 MONO_ARCH_SAVE_REGS;
5860 #ifdef PLATFORM_WIN32
5861 utf16_name = mono_string_to_utf16 (name);
5862 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
5863 SetEnvironmentVariable (utf16_name, NULL);
5864 g_free (utf16_name);
5868 utf16_value = mono_string_to_utf16 (value);
5870 SetEnvironmentVariable (utf16_name, utf16_value);
5872 g_free (utf16_name);
5873 g_free (utf16_value);
5875 utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
5877 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
5878 g_unsetenv (utf8_name);
5883 utf8_value = mono_string_to_utf8 (value);
5884 g_setenv (utf8_name, utf8_value, TRUE);
5887 g_free (utf8_value);
5892 * Returns: the number of milliseconds elapsed since the system started.
5895 ves_icall_System_Environment_get_TickCount (void)
5897 return GetTickCount ();
5902 ves_icall_System_Environment_Exit (int result)
5904 MONO_ARCH_SAVE_REGS;
5906 mono_runtime_set_shutting_down ();
5908 /* Suspend all managed threads since the runtime is going away */
5909 mono_thread_suspend_all_other_threads ();
5911 mono_runtime_quit ();
5913 /* we may need to do some cleanup here... */
5918 ves_icall_System_Environment_GetGacPath (void)
5920 return mono_string_new (mono_domain_get (), mono_assembly_getrootdir ());
5924 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
5926 #if defined (PLATFORM_WIN32)
5927 #ifndef CSIDL_FLAG_CREATE
5928 #define CSIDL_FLAG_CREATE 0x8000
5931 WCHAR path [MAX_PATH];
5932 /* Create directory if no existing */
5933 if (SUCCEEDED (SHGetFolderPathW (NULL, folder | CSIDL_FLAG_CREATE, NULL, 0, path))) {
5937 return mono_string_new_utf16 (mono_domain_get (), path, len);
5940 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
5942 return mono_string_new (mono_domain_get (), "");
5946 ves_icall_System_Environment_GetLogicalDrives (void)
5948 gunichar2 buf [128], *ptr, *dname;
5950 gint initial_size = 127, size = 128;
5953 MonoString *drivestr;
5954 MonoDomain *domain = mono_domain_get ();
5957 MONO_ARCH_SAVE_REGS;
5962 while (size > initial_size) {
5963 size = GetLogicalDriveStrings (initial_size, ptr);
5964 if (size > initial_size) {
5967 ptr = g_malloc0 ((size + 1) * sizeof (gunichar2));
5968 initial_size = size;
5982 result = mono_array_new (domain, mono_defaults.string_class, ndrives);
5987 while (*u16) { u16++; len ++; }
5988 drivestr = mono_string_new_utf16 (domain, dname, len);
5989 mono_array_setref (result, ndrives++, drivestr);
6000 ves_icall_System_Environment_InternalGetHome (void)
6002 MONO_ARCH_SAVE_REGS;
6004 return mono_string_new (mono_domain_get (), g_get_home_dir ());
6007 static const char *encodings [] = {
6009 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
6010 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
6011 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
6013 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
6014 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
6015 "x_unicode_2_0_utf_7",
6017 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
6018 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
6020 "utf_16", "UTF_16LE", "ucs_2", "unicode",
6023 "unicodefffe", "utf_16be",
6030 * Returns the internal codepage, if the value of "int_code_page" is
6031 * 1 at entry, and we can not compute a suitable code page number,
6032 * returns the code page as a string
6035 ves_icall_System_Text_Encoding_InternalCodePage (gint32 *int_code_page)
6040 char *codepage = NULL;
6042 int want_name = *int_code_page;
6045 *int_code_page = -1;
6046 MONO_ARCH_SAVE_REGS;
6048 g_get_charset (&cset);
6049 c = codepage = strdup (cset);
6050 for (c = codepage; *c; c++){
6051 if (isascii (*c) && isalpha (*c))
6056 /* g_print ("charset: %s\n", cset); */
6058 /* handle some common aliases */
6061 for (i = 0; p != 0; ){
6062 if ((gssize) p < 7){
6064 p = encodings [++i];
6067 if (strcmp (p, codepage) == 0){
6068 *int_code_page = code;
6071 p = encodings [++i];
6074 if (strstr (codepage, "utf_8") != NULL)
6075 *int_code_page |= 0x10000000;
6078 if (want_name && *int_code_page == -1)
6079 return mono_string_new (mono_domain_get (), cset);
6085 ves_icall_System_Environment_get_HasShutdownStarted (void)
6087 if (mono_runtime_is_shutting_down ())
6090 if (mono_domain_is_unloading (mono_domain_get ()))
6097 ves_icall_MonoMethodMessage_InitMessage (MonoMethodMessage *this,
6098 MonoReflectionMethod *method,
6099 MonoArray *out_args)
6101 MONO_ARCH_SAVE_REGS;
6103 mono_message_init (mono_object_domain (this), this, method, out_args);
6107 ves_icall_IsTransparentProxy (MonoObject *proxy)
6109 MONO_ARCH_SAVE_REGS;
6114 if (proxy->vtable->klass == mono_defaults.transparent_proxy_class)
6121 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6126 MONO_ARCH_SAVE_REGS;
6128 klass = mono_class_from_mono_type (type->type);
6129 vtable = mono_class_vtable (mono_domain_get (), klass);
6131 if (enable) vtable->remote = 1;
6132 else vtable->remote = 0;
6136 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type)
6141 MONO_ARCH_SAVE_REGS;
6143 domain = mono_object_domain (type);
6144 klass = mono_class_from_mono_type (type->type);
6146 if (klass->rank >= 1) {
6147 g_assert (klass->rank == 1);
6148 return (MonoObject *) mono_array_new (domain, klass->element_class, 0);
6150 /* Bypass remoting object creation check */
6151 return mono_object_new_alloc_specific (mono_class_vtable (domain, klass));
6156 ves_icall_System_IO_get_temp_path (void)
6158 MONO_ARCH_SAVE_REGS;
6160 return mono_string_new (mono_domain_get (), g_get_tmp_dir ());
6164 ves_icall_RuntimeMethod_GetFunctionPointer (MonoMethod *method)
6166 MONO_ARCH_SAVE_REGS;
6168 return mono_compile_method (method);
6172 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
6177 MONO_ARCH_SAVE_REGS;
6179 path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
6181 #if defined (PLATFORM_WIN32)
6182 /* Avoid mixing '/' and '\\' */
6185 for (i = strlen (path) - 1; i >= 0; i--)
6186 if (path [i] == '/')
6190 mcpath = mono_string_new (mono_domain_get (), path);
6197 ves_icall_System_Configuration_DefaultConfig_get_bundled_machine_config (void)
6199 const gchar *machine_config;
6201 MONO_ARCH_SAVE_REGS;
6203 machine_config = mono_get_machine_config ();
6205 if (!machine_config)
6208 return mono_string_new (mono_domain_get (), machine_config);
6212 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
6217 MONO_ARCH_SAVE_REGS;
6219 path = g_path_get_dirname (mono_get_config_dir ());
6221 #if defined (PLATFORM_WIN32)
6222 /* Avoid mixing '/' and '\\' */
6225 for (i = strlen (path) - 1; i >= 0; i--)
6226 if (path [i] == '/')
6230 ipath = mono_string_new (mono_domain_get (), path);
6237 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
6239 #if defined (PLATFORM_WIN32)
6240 OutputDebugString (mono_string_chars (message));
6242 g_warning ("WriteWindowsDebugString called and PLATFORM_WIN32 not defined!\n");
6246 /* Only used for value types */
6248 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
6253 MONO_ARCH_SAVE_REGS;
6255 domain = mono_object_domain (type);
6256 klass = mono_class_from_mono_type (type->type);
6258 if (mono_class_is_nullable (klass))
6259 /* No arguments -> null */
6262 return mono_object_new (domain, klass);
6265 static MonoReflectionMethod *
6266 ves_icall_MonoMethod_get_base_definition (MonoReflectionMethod *m)
6268 MonoClass *klass, *parent;
6269 MonoMethod *method = m->method;
6270 MonoMethod *result = NULL;
6272 MONO_ARCH_SAVE_REGS;
6274 if (method->klass == NULL)
6277 if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
6278 MONO_CLASS_IS_INTERFACE (method->klass) ||
6279 method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
6282 klass = method->klass;
6283 if (klass->generic_class)
6284 klass = klass->generic_class->container_class;
6286 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
6287 for (parent = klass->parent; parent != NULL; parent = parent->parent) {
6288 mono_class_setup_vtable (parent);
6289 if (parent->vtable_size <= method->slot)
6294 if (klass == method->klass)
6297 result = klass->vtable [method->slot];
6298 if (result == NULL) {
6299 /* It is an abstract method */
6300 gpointer iter = NULL;
6301 while ((result = mono_class_get_methods (klass, &iter)))
6302 if (result->slot == method->slot)
6309 return mono_method_get_object (mono_domain_get (), result, NULL);
6313 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
6315 MONO_ARCH_SAVE_REGS;
6317 iter->sig = *(MonoMethodSignature**)argsp;
6319 g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
6320 g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
6323 /* FIXME: it's not documented what start is exactly... */
6327 guint32 i, arg_size;
6329 iter->args = argsp + sizeof (gpointer);
6330 #ifndef MONO_ARCH_REGPARMS
6331 for (i = 0; i < iter->sig->sentinelpos; ++i) {
6332 arg_size = mono_type_stack_size (iter->sig->params [i], &align);
6333 iter->args = (char*)iter->args + arg_size;
6337 iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
6339 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
6343 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
6345 guint32 i, arg_size;
6348 MONO_ARCH_SAVE_REGS;
6350 i = iter->sig->sentinelpos + iter->next_arg;
6352 g_assert (i < iter->sig->param_count);
6354 res.type = iter->sig->params [i];
6355 res.klass = mono_class_from_mono_type (res.type);
6356 /* FIXME: endianess issue... */
6357 res.value = iter->args;
6358 arg_size = mono_type_stack_size (res.type, &align);
6359 iter->args = (char*)iter->args + arg_size;
6362 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6368 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
6370 guint32 i, arg_size;
6373 MONO_ARCH_SAVE_REGS;
6375 i = iter->sig->sentinelpos + iter->next_arg;
6377 g_assert (i < iter->sig->param_count);
6379 while (i < iter->sig->param_count) {
6380 if (!mono_metadata_type_equal (type, iter->sig->params [i]))
6382 res.type = iter->sig->params [i];
6383 res.klass = mono_class_from_mono_type (res.type);
6384 /* FIXME: endianess issue... */
6385 res.value = iter->args;
6386 arg_size = mono_type_stack_size (res.type, &align);
6387 iter->args = (char*)iter->args + arg_size;
6389 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6392 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
6401 mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
6404 MONO_ARCH_SAVE_REGS;
6406 i = iter->sig->sentinelpos + iter->next_arg;
6408 g_assert (i < iter->sig->param_count);
6410 return iter->sig->params [i];
6414 mono_TypedReference_ToObject (MonoTypedRef tref)
6416 MONO_ARCH_SAVE_REGS;
6418 if (MONO_TYPE_IS_REFERENCE (tref.type)) {
6419 MonoObject** objp = tref.value;
6423 return mono_value_box (mono_domain_get (), tref.klass, tref.value);
6427 mono_TypedReference_ToObjectInternal (MonoType *type, gpointer value, MonoClass *klass)
6429 MONO_ARCH_SAVE_REGS;
6431 if (MONO_TYPE_IS_REFERENCE (type)) {
6432 MonoObject** objp = value;
6436 return mono_value_box (mono_domain_get (), klass, value);
6440 prelink_method (MonoMethod *method)
6442 const char *exc_class, *exc_arg;
6443 if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
6445 mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
6447 mono_raise_exception(
6448 mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg ) );
6450 /* create the wrapper, too? */
6454 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
6456 MONO_ARCH_SAVE_REGS;
6457 prelink_method (method->method);
6461 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
6463 MonoClass *klass = mono_class_from_mono_type (type->type);
6465 gpointer iter = NULL;
6466 MONO_ARCH_SAVE_REGS;
6468 while ((m = mono_class_get_methods (klass, &iter)))
6472 /* These parameters are "readonly" in corlib/System/Char.cs */
6474 ves_icall_System_Char_GetDataTablePointers (guint8 const **category_data,
6475 guint8 const **numeric_data,
6476 gdouble const **numeric_data_values,
6477 guint16 const **to_lower_data_low,
6478 guint16 const **to_lower_data_high,
6479 guint16 const **to_upper_data_low,
6480 guint16 const **to_upper_data_high)
6482 *category_data = CategoryData;
6483 *numeric_data = NumericData;
6484 *numeric_data_values = NumericDataValues;
6485 *to_lower_data_low = ToLowerDataLow;
6486 *to_lower_data_high = ToLowerDataHigh;
6487 *to_upper_data_low = ToUpperDataLow;
6488 *to_upper_data_high = ToUpperDataHigh;
6492 ves_icall_MonoDebugger_GetMethodToken (MonoReflectionMethod *method)
6494 return method->method->token;
6498 * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
6499 * and avoid useless allocations.
6502 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional)
6506 for (i = 0; i < type->num_mods; ++i) {
6507 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
6512 res = mono_array_new (mono_domain_get (), mono_defaults.systemtype_class, count);
6514 for (i = 0; i < type->num_mods; ++i) {
6515 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
6516 MonoClass *klass = mono_class_get (image, type->modifiers [i].token);
6517 mono_array_setref (res, count, mono_type_get_object (mono_domain_get (), &klass->byval_arg));
6525 param_info_get_type_modifiers (MonoReflectionParameter *param, MonoBoolean optional)
6527 MonoType *type = param->ClassImpl->type;
6528 MonoReflectionMethod *method = (MonoReflectionMethod*)param->MemberImpl;
6529 MonoImage *image = method->method->klass->image;
6530 int pos = param->PositionImpl;
6531 MonoMethodSignature *sig = mono_method_signature (method->method);
6535 type = sig->params [pos];
6537 return type_array_from_modifiers (image, type, optional);
6541 get_property_type (MonoProperty *prop)
6543 MonoMethodSignature *sig;
6545 sig = mono_method_signature (prop->get);
6547 } else if (prop->set) {
6548 sig = mono_method_signature (prop->set);
6549 return sig->params [sig->param_count - 1];
6555 property_info_get_type_modifiers (MonoReflectionProperty *property, MonoBoolean optional)
6557 MonoType *type = get_property_type (property->property);
6558 MonoImage *image = property->klass->image;
6562 return type_array_from_modifiers (image, type, optional);
6566 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
6568 MonoCustomAttrInfo *cinfo;
6571 cinfo = mono_reflection_get_custom_attrs_info (obj);
6574 found = mono_custom_attrs_has_attr (cinfo, mono_class_from_mono_type (attr_type->type));
6576 mono_custom_attrs_free (cinfo);
6581 custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
6583 MonoArray *res = mono_reflection_get_custom_attrs_by_type (obj, attr_type ? mono_class_from_mono_type (attr_type->type) : NULL);
6585 if (mono_loader_get_last_error ()) {
6586 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
6587 g_assert_not_reached ();
6594 GCHandle_CheckCurrentDomain (guint32 gchandle)
6596 return mono_gchandle_is_in_domain (gchandle, mono_domain_get ());
6600 ves_icall_Mono_Runtime_GetDisplayName (void)
6602 static const char display_name_str [] = "Mono " VERSION;
6603 MonoString *display_name = mono_string_new (mono_domain_get (), display_name_str);
6604 return display_name;
6609 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
6610 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
6611 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 62, 128, 128, 128, 63,
6612 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 0, 128, 128,
6613 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
6614 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 128, 128, 128, 128, 128,
6615 128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
6616 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
6620 base64_to_byte_array (gunichar2 *start, gint ilength, MonoBoolean allowWhitespaceOnly)
6625 gunichar2 last, prev_last;
6633 last = prev_last = 0;
6634 for (i = 0; i < ilength; i++) {
6636 if (c >= sizeof (dbase64)) {
6637 exc = mono_exception_from_name_msg (mono_get_corlib (),
6638 "System", "FormatException",
6639 "Invalid character found.");
6640 mono_raise_exception (exc);
6641 } else if (isspace (c)) {
6649 olength = ilength - ignored;
6651 if (allowWhitespaceOnly && olength == 0) {
6652 return mono_array_new (mono_domain_get (), mono_defaults.byte_class, 0);
6655 if ((olength & 3) != 0 || olength <= 0) {
6656 exc = mono_exception_from_name_msg (mono_get_corlib (), "System",
6657 "FormatException", "Invalid length.");
6658 mono_raise_exception (exc);
6661 olength = (olength * 3) / 4;
6665 if (prev_last == '=')
6668 result = mono_array_new (mono_domain_get (), mono_defaults.byte_class, olength);
6669 res_ptr = mono_array_addr (result, guchar, 0);
6670 for (i = 0; i < ilength; ) {
6673 for (k = 0; k < 4 && i < ilength;) {
6679 if (((b [k] = dbase64 [c]) & 0x80) != 0) {
6680 exc = mono_exception_from_name_msg (mono_get_corlib (),
6681 "System", "FormatException",
6682 "Invalid character found.");
6683 mono_raise_exception (exc);
6688 *res_ptr++ = (b [0] << 2) | (b [1] >> 4);
6690 *res_ptr++ = (b [1] << 4) | (b [2] >> 2);
6692 *res_ptr++ = (b [2] << 6) | b [3];
6694 while (i < ilength && isspace (start [i]))
6702 InternalFromBase64String (MonoString *str, MonoBoolean allowWhitespaceOnly)
6704 MONO_ARCH_SAVE_REGS;
6706 return base64_to_byte_array (mono_string_chars (str),
6707 mono_string_length (str), allowWhitespaceOnly);
6711 InternalFromBase64CharArray (MonoArray *input, gint offset, gint length)
6713 MONO_ARCH_SAVE_REGS;
6715 return base64_to_byte_array (mono_array_addr (input, gunichar2, offset),
6719 #define ICALL_TYPE(id,name,first)
6720 #define ICALL(id,name,func) Icall_ ## id,
6723 #include "metadata/icall-def.h"
6729 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
6730 #define ICALL(id,name,func)
6732 #include "metadata/icall-def.h"
6738 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
6739 #define ICALL(id,name,func)
6741 guint16 first_icall;
6744 static const IcallTypeDesc
6745 icall_type_descs [] = {
6746 #include "metadata/icall-def.h"
6750 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
6753 #define ICALL_TYPE(id,name,first)
6756 #ifdef HAVE_ARRAY_ELEM_INIT
6757 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
6758 #define MSGSTRFIELD1(line) str##line
6760 static const struct msgstrtn_t {
6761 #define ICALL(id,name,func)
6763 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
6764 #include "metadata/icall-def.h"
6766 } icall_type_names_str = {
6767 #define ICALL_TYPE(id,name,first) (name),
6768 #include "metadata/icall-def.h"
6771 static const guint16 icall_type_names_idx [] = {
6772 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
6773 #include "metadata/icall-def.h"
6776 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
6778 static const struct msgstr_t {
6780 #define ICALL_TYPE(id,name,first)
6781 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
6782 #include "metadata/icall-def.h"
6784 } icall_names_str = {
6785 #define ICALL(id,name,func) (name),
6786 #include "metadata/icall-def.h"
6789 static const guint16 icall_names_idx [] = {
6790 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
6791 #include "metadata/icall-def.h"
6794 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
6800 #define ICALL_TYPE(id,name,first) name,
6801 #define ICALL(id,name,func)
6802 static const char* const
6803 icall_type_names [] = {
6804 #include "metadata/icall-def.h"
6808 #define icall_type_name_get(id) (icall_type_names [(id)])
6812 #define ICALL_TYPE(id,name,first)
6813 #define ICALL(id,name,func) name,
6814 static const char* const
6816 #include "metadata/icall-def.h"
6819 #define icall_name_get(id) icall_names [(id)]
6821 #endif /* !HAVE_ARRAY_ELEM_INIT */
6825 #define ICALL_TYPE(id,name,first)
6826 #define ICALL(id,name,func) func,
6827 static const gconstpointer
6828 icall_functions [] = {
6829 #include "metadata/icall-def.h"
6833 static GHashTable *icall_hash = NULL;
6834 static GHashTable *jit_icall_hash_name = NULL;
6835 static GHashTable *jit_icall_hash_addr = NULL;
6838 mono_icall_init (void)
6842 /* check that tables are sorted: disable in release */
6845 const char *prev_class = NULL;
6846 const char *prev_method;
6848 for (i = 0; i < Icall_type_num; ++i) {
6849 const IcallTypeDesc *desc;
6852 if (prev_class && strcmp (prev_class, icall_type_name_get (i)) >= 0)
6853 g_print ("class %s should come before class %s\n", icall_type_name_get (i), prev_class);
6854 prev_class = icall_type_name_get (i);
6855 desc = &icall_type_descs [i];
6856 num_icalls = icall_desc_num_icalls (desc);
6857 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
6858 for (j = 0; j < num_icalls; ++j) {
6859 const char *methodn = icall_name_get (desc->first_icall + j);
6860 if (prev_method && strcmp (prev_method, methodn) >= 0)
6861 g_print ("method %s should come before method %s\n", methodn, prev_method);
6862 prev_method = methodn;
6867 icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
6871 mono_icall_cleanup (void)
6873 g_hash_table_destroy (icall_hash);
6874 g_hash_table_destroy (jit_icall_hash_name);
6875 g_hash_table_destroy (jit_icall_hash_addr);
6879 mono_add_internal_call (const char *name, gconstpointer method)
6881 mono_loader_lock ();
6883 g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
6885 mono_loader_unlock ();
6888 #ifdef HAVE_ARRAY_ELEM_INIT
6890 compare_method_imap (const void *key, const void *elem)
6892 const char* method_name = (const char*)&icall_names_str + (*(guint16*)elem);
6893 return strcmp (key, method_name);
6897 find_method_icall (const IcallTypeDesc *imap, const char *name)
6899 const guint16 *nameslot = bsearch (name, icall_names_idx + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names_idx [0]), compare_method_imap);
6902 return (gpointer)icall_functions [(nameslot - &icall_names_idx [0])];
6906 compare_class_imap (const void *key, const void *elem)
6908 const char* class_name = (const char*)&icall_type_names_str + (*(guint16*)elem);
6909 return strcmp (key, class_name);
6912 static const IcallTypeDesc*
6913 find_class_icalls (const char *name)
6915 const guint16 *nameslot = bsearch (name, icall_type_names_idx, Icall_type_num, sizeof (icall_type_names_idx [0]), compare_class_imap);
6918 return &icall_type_descs [nameslot - &icall_type_names_idx [0]];
6923 compare_method_imap (const void *key, const void *elem)
6925 const char** method_name = (const char**)elem;
6926 return strcmp (key, *method_name);
6930 find_method_icall (const IcallTypeDesc *imap, const char *name)
6932 const char **nameslot = bsearch (name, icall_names + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names [0]), compare_method_imap);
6935 return (gpointer)icall_functions [(nameslot - icall_names)];
6939 compare_class_imap (const void *key, const void *elem)
6941 const char** class_name = (const char**)elem;
6942 return strcmp (key, *class_name);
6945 static const IcallTypeDesc*
6946 find_class_icalls (const char *name)
6948 const char **nameslot = bsearch (name, icall_type_names, Icall_type_num, sizeof (icall_type_names [0]), compare_class_imap);
6951 return &icall_type_descs [nameslot - icall_type_names];
6957 * we should probably export this as an helper (handle nested types).
6958 * Returns the number of chars written in buf.
6961 concat_class_name (char *buf, int bufsize, MonoClass *klass)
6963 int nspacelen, cnamelen;
6964 nspacelen = strlen (klass->name_space);
6965 cnamelen = strlen (klass->name);
6966 if (nspacelen + cnamelen + 2 > bufsize)
6969 memcpy (buf, klass->name_space, nspacelen);
6970 buf [nspacelen ++] = '.';
6972 memcpy (buf + nspacelen, klass->name, cnamelen);
6973 buf [nspacelen + cnamelen] = 0;
6974 return nspacelen + cnamelen;
6978 mono_lookup_internal_call (MonoMethod *method)
6983 int typelen = 0, mlen, siglen;
6985 const IcallTypeDesc *imap;
6987 g_assert (method != NULL);
6989 if (method->is_inflated)
6990 method = ((MonoMethodInflated *) method)->declaring;
6992 if (method->klass->nested_in) {
6993 int pos = concat_class_name (mname, sizeof (mname)-2, method->klass->nested_in);
6997 mname [pos++] = '/';
7000 typelen = concat_class_name (mname+pos, sizeof (mname)-pos-1, method->klass);
7006 typelen = concat_class_name (mname, sizeof (mname), method->klass);
7011 imap = find_class_icalls (mname);
7013 mname [typelen] = ':';
7014 mname [typelen + 1] = ':';
7016 mlen = strlen (method->name);
7017 memcpy (mname + typelen + 2, method->name, mlen);
7018 sigstart = mname + typelen + 2 + mlen;
7021 tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
7022 siglen = strlen (tmpsig);
7023 if (typelen + mlen + siglen + 6 > sizeof (mname))
7026 memcpy (sigstart + 1, tmpsig, siglen);
7027 sigstart [siglen + 1] = ')';
7028 sigstart [siglen + 2] = 0;
7031 mono_loader_lock ();
7033 res = g_hash_table_lookup (icall_hash, mname);
7035 mono_loader_unlock ();
7038 /* try without signature */
7040 res = g_hash_table_lookup (icall_hash, mname);
7042 mono_loader_unlock ();
7046 /* it wasn't found in the static call tables */
7048 mono_loader_unlock ();
7051 res = find_method_icall (imap, sigstart - mlen);
7053 mono_loader_unlock ();
7056 /* try _with_ signature */
7058 res = find_method_icall (imap, sigstart - mlen);
7060 mono_loader_unlock ();
7064 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname);
7065 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
7066 g_print ("The out of sync library is: %s\n", method->klass->image->name);
7067 g_print ("\nWhen you update one from cvs you need to update, compile and install\nthe other too.\n");
7068 g_print ("Do not report this as a bug unless you're sure you have updated correctly:\nyou probably have a broken mono install.\n");
7069 g_print ("If you see other errors or faults after this message they are probably related\n");
7070 g_print ("and you need to fix your mono install first.\n");
7072 mono_loader_unlock ();
7078 type_from_typename (char *typename)
7080 MonoClass *klass = NULL; /* assignment to shut GCC warning up */
7082 if (!strcmp (typename, "int"))
7083 klass = mono_defaults.int_class;
7084 else if (!strcmp (typename, "ptr"))
7085 klass = mono_defaults.int_class;
7086 else if (!strcmp (typename, "void"))
7087 klass = mono_defaults.void_class;
7088 else if (!strcmp (typename, "int32"))
7089 klass = mono_defaults.int32_class;
7090 else if (!strcmp (typename, "uint32"))
7091 klass = mono_defaults.uint32_class;
7092 else if (!strcmp (typename, "int8"))
7093 klass = mono_defaults.sbyte_class;
7094 else if (!strcmp (typename, "uint8"))
7095 klass = mono_defaults.byte_class;
7096 else if (!strcmp (typename, "int16"))
7097 klass = mono_defaults.int16_class;
7098 else if (!strcmp (typename, "uint16"))
7099 klass = mono_defaults.uint16_class;
7100 else if (!strcmp (typename, "long"))
7101 klass = mono_defaults.int64_class;
7102 else if (!strcmp (typename, "ulong"))
7103 klass = mono_defaults.uint64_class;
7104 else if (!strcmp (typename, "float"))
7105 klass = mono_defaults.single_class;
7106 else if (!strcmp (typename, "double"))
7107 klass = mono_defaults.double_class;
7108 else if (!strcmp (typename, "object"))
7109 klass = mono_defaults.object_class;
7110 else if (!strcmp (typename, "obj"))
7111 klass = mono_defaults.object_class;
7114 g_assert_not_reached ();
7116 return &klass->byval_arg;
7119 MonoMethodSignature*
7120 mono_create_icall_signature (const char *sigstr)
7125 MonoMethodSignature *res;
7127 mono_loader_lock ();
7128 res = g_hash_table_lookup (mono_defaults.corlib->helper_signatures, sigstr);
7130 mono_loader_unlock ();
7134 parts = g_strsplit (sigstr, " ", 256);
7143 res = mono_metadata_signature_alloc (mono_defaults.corlib, len - 1);
7146 #ifdef PLATFORM_WIN32
7148 * Under windows, the default pinvoke calling convention is STDCALL but
7151 res->call_convention = MONO_CALL_C;
7154 res->ret = type_from_typename (parts [0]);
7155 for (i = 1; i < len; ++i) {
7156 res->params [i - 1] = type_from_typename (parts [i]);
7161 g_hash_table_insert (mono_defaults.corlib->helper_signatures, (gpointer)sigstr, res);
7163 mono_loader_unlock ();
7169 mono_find_jit_icall_by_name (const char *name)
7171 MonoJitICallInfo *info;
7172 g_assert (jit_icall_hash_name);
7174 mono_loader_lock ();
7175 info = g_hash_table_lookup (jit_icall_hash_name, name);
7176 mono_loader_unlock ();
7181 mono_find_jit_icall_by_addr (gconstpointer addr)
7183 MonoJitICallInfo *info;
7184 g_assert (jit_icall_hash_addr);
7186 mono_loader_lock ();
7187 info = g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
7188 mono_loader_unlock ();
7194 mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
7196 mono_loader_lock ();
7197 g_hash_table_insert (jit_icall_hash_addr, (gpointer)wrapper, info);
7198 mono_loader_unlock ();
7202 mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
7204 MonoJitICallInfo *info;
7209 mono_loader_lock ();
7211 if (!jit_icall_hash_name) {
7212 jit_icall_hash_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
7213 jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
7216 if (g_hash_table_lookup (jit_icall_hash_name, name)) {
7217 g_warning ("jit icall already defined \"%s\"\n", name);
7218 g_assert_not_reached ();
7221 info = g_new0 (MonoJitICallInfo, 1);
7228 info->wrapper = func;
7230 info->wrapper = NULL;
7233 g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
7234 g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
7236 mono_loader_unlock ();