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/metadata/security-core-clr.h>
62 #include <mono/io-layer/io-layer.h>
63 #include <mono/utils/strtod.h>
64 #include <mono/utils/monobitset.h>
66 #if defined (PLATFORM_WIN32)
72 static MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void);
75 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional);
77 static inline MonoBoolean
78 is_generic_parameter (MonoType *type)
80 return !type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR);
84 * We expect a pointer to a char, not a string
87 mono_double_ParseImpl (char *ptr, double *result)
96 *result = strtod (ptr, &endptr);
99 *result = mono_strtod (ptr, &endptr);
102 if (!*ptr || (endptr && *endptr))
109 mono_class_get_throw (MonoImage *image, guint32 type_token)
111 MonoClass *class = mono_class_get (image, type_token);
112 MonoLoaderError *error;
118 error = mono_loader_get_last_error ();
119 g_assert (error != NULL);
121 ex = mono_loader_error_prepare_exception (error);
122 mono_raise_exception (ex);
127 ves_icall_System_Array_GetValueImpl (MonoObject *this, guint32 pos)
136 ao = (MonoArray *)this;
137 ac = (MonoClass *)ao->obj.vtable->klass;
139 esize = mono_array_element_size (ac);
140 ea = (gpointer*)((char*)ao->vector + (pos * esize));
142 if (ac->element_class->valuetype)
143 return mono_value_box (this->vtable->domain, ac->element_class, ea);
149 ves_icall_System_Array_GetValue (MonoObject *this, MonoObject *idxs)
157 MONO_CHECK_ARG_NULL (idxs);
159 io = (MonoArray *)idxs;
160 ic = (MonoClass *)io->obj.vtable->klass;
162 ao = (MonoArray *)this;
163 ac = (MonoClass *)ao->obj.vtable->klass;
165 g_assert (ic->rank == 1);
166 if (io->bounds != NULL || io->max_length != ac->rank)
167 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
169 ind = (gint32 *)io->vector;
171 if (ao->bounds == NULL) {
172 if (*ind < 0 || *ind >= ao->max_length)
173 mono_raise_exception (mono_get_exception_index_out_of_range ());
175 return ves_icall_System_Array_GetValueImpl (this, *ind);
178 for (i = 0; i < ac->rank; i++)
179 if ((ind [i] < ao->bounds [i].lower_bound) ||
180 (ind [i] >= ao->bounds [i].length + ao->bounds [i].lower_bound))
181 mono_raise_exception (mono_get_exception_index_out_of_range ());
183 pos = ind [0] - ao->bounds [0].lower_bound;
184 for (i = 1; i < ac->rank; i++)
185 pos = pos*ao->bounds [i].length + ind [i] -
186 ao->bounds [i].lower_bound;
188 return ves_icall_System_Array_GetValueImpl (this, pos);
192 ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32 pos)
194 MonoClass *ac, *vc, *ec;
206 vc = value->vtable->klass;
210 ac = this->obj.vtable->klass;
211 ec = ac->element_class;
213 esize = mono_array_element_size (ac);
214 ea = (gpointer*)((char*)this->vector + (pos * esize));
215 va = (gpointer*)((char*)value + sizeof (MonoObject));
218 memset (ea, 0, esize);
222 #define NO_WIDENING_CONVERSION G_STMT_START{\
223 mono_raise_exception (mono_get_exception_argument ( \
224 "value", "not a widening conversion")); \
227 #define CHECK_WIDENING_CONVERSION(extra) G_STMT_START{\
228 if (esize < vsize + (extra)) \
229 mono_raise_exception (mono_get_exception_argument ( \
230 "value", "not a widening conversion")); \
233 #define INVALID_CAST G_STMT_START{\
234 mono_raise_exception (mono_get_exception_invalid_cast ()); \
237 /* Check element (destination) type. */
238 switch (ec->byval_arg.type) {
239 case MONO_TYPE_STRING:
240 switch (vc->byval_arg.type) {
241 case MONO_TYPE_STRING:
247 case MONO_TYPE_BOOLEAN:
248 switch (vc->byval_arg.type) {
249 case MONO_TYPE_BOOLEAN:
262 NO_WIDENING_CONVERSION;
269 if (!ec->valuetype) {
270 if (!mono_object_isinst (value, ec))
272 *ea = (gpointer)value;
276 if (mono_object_isinst (value, ec)) {
277 memcpy (ea, (char *)value + sizeof (MonoObject), esize);
284 vsize = mono_class_instance_size (vc) - sizeof (MonoObject);
286 et = ec->byval_arg.type;
287 if (et == MONO_TYPE_VALUETYPE && ec->byval_arg.data.klass->enumtype)
288 et = ec->byval_arg.data.klass->enum_basetype->type;
290 vt = vc->byval_arg.type;
291 if (vt == MONO_TYPE_VALUETYPE && vc->byval_arg.data.klass->enumtype)
292 vt = vc->byval_arg.data.klass->enum_basetype->type;
294 #define ASSIGN_UNSIGNED(etype) G_STMT_START{\
300 case MONO_TYPE_CHAR: \
301 CHECK_WIDENING_CONVERSION(0); \
302 *(etype *) ea = (etype) u64; \
304 /* You can't assign a signed value to an unsigned array. */ \
309 /* You can't assign a floating point number to an integer array. */ \
312 NO_WIDENING_CONVERSION; \
316 #define ASSIGN_SIGNED(etype) G_STMT_START{\
322 CHECK_WIDENING_CONVERSION(0); \
323 *(etype *) ea = (etype) i64; \
325 /* You can assign an unsigned value to a signed array if the array's */ \
326 /* element size is larger than the value size. */ \
331 case MONO_TYPE_CHAR: \
332 CHECK_WIDENING_CONVERSION(1); \
333 *(etype *) ea = (etype) u64; \
335 /* You can't assign a floating point number to an integer array. */ \
338 NO_WIDENING_CONVERSION; \
342 #define ASSIGN_REAL(etype) G_STMT_START{\
346 CHECK_WIDENING_CONVERSION(0); \
347 *(etype *) ea = (etype) r64; \
349 /* All integer values fit into a floating point array, so we don't */ \
350 /* need to CHECK_WIDENING_CONVERSION here. */ \
355 *(etype *) ea = (etype) i64; \
361 case MONO_TYPE_CHAR: \
362 *(etype *) ea = (etype) u64; \
369 u64 = *(guint8 *) va;
372 u64 = *(guint16 *) va;
375 u64 = *(guint32 *) va;
378 u64 = *(guint64 *) va;
384 i64 = *(gint16 *) va;
387 i64 = *(gint32 *) va;
390 i64 = *(gint64 *) va;
393 r64 = *(gfloat *) va;
396 r64 = *(gdouble *) va;
399 u64 = *(guint16 *) va;
401 case MONO_TYPE_BOOLEAN:
402 /* Boolean is only compatible with itself. */
415 NO_WIDENING_CONVERSION;
422 /* If we can't do a direct copy, let's try a widening conversion. */
425 ASSIGN_UNSIGNED (guint16);
427 ASSIGN_UNSIGNED (guint8);
429 ASSIGN_UNSIGNED (guint16);
431 ASSIGN_UNSIGNED (guint32);
433 ASSIGN_UNSIGNED (guint64);
435 ASSIGN_SIGNED (gint8);
437 ASSIGN_SIGNED (gint16);
439 ASSIGN_SIGNED (gint32);
441 ASSIGN_SIGNED (gint64);
443 ASSIGN_REAL (gfloat);
445 ASSIGN_REAL (gdouble);
449 /* Not reached, INVALID_CAST does not return. Just to avoid a compiler warning ... */
453 #undef NO_WIDENING_CONVERSION
454 #undef CHECK_WIDENING_CONVERSION
455 #undef ASSIGN_UNSIGNED
461 ves_icall_System_Array_SetValue (MonoArray *this, MonoObject *value,
469 MONO_CHECK_ARG_NULL (idxs);
471 ic = idxs->obj.vtable->klass;
472 ac = this->obj.vtable->klass;
474 g_assert (ic->rank == 1);
475 if (idxs->bounds != NULL || idxs->max_length != ac->rank)
476 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
478 ind = (gint32 *)idxs->vector;
480 if (this->bounds == NULL) {
481 if (*ind < 0 || *ind >= this->max_length)
482 mono_raise_exception (mono_get_exception_index_out_of_range ());
484 ves_icall_System_Array_SetValueImpl (this, value, *ind);
488 for (i = 0; i < ac->rank; i++)
489 if ((ind [i] < this->bounds [i].lower_bound) ||
490 (ind [i] >= this->bounds [i].length + this->bounds [i].lower_bound))
491 mono_raise_exception (mono_get_exception_index_out_of_range ());
493 pos = ind [0] - this->bounds [0].lower_bound;
494 for (i = 1; i < ac->rank; i++)
495 pos = pos * this->bounds [i].length + ind [i] -
496 this->bounds [i].lower_bound;
498 ves_icall_System_Array_SetValueImpl (this, value, pos);
502 ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
507 gboolean bounded = FALSE;
511 MONO_CHECK_ARG_NULL (type);
512 MONO_CHECK_ARG_NULL (lengths);
514 MONO_CHECK_ARG (lengths, mono_array_length (lengths) > 0);
516 MONO_CHECK_ARG (bounds, mono_array_length (lengths) == mono_array_length (bounds));
518 for (i = 0; i < mono_array_length (lengths); i++)
519 if (mono_array_get (lengths, gint32, i) < 0)
520 mono_raise_exception (mono_get_exception_argument_out_of_range (NULL));
522 if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint32, 0) != 0))
523 /* vectors are not the same as one dimensional arrays with no-zero bounds */
528 aklass = mono_bounded_array_class_get (mono_class_from_mono_type (type->type), mono_array_length (lengths), bounded);
530 sizes = alloca (aklass->rank * sizeof(guint32) * 2);
531 for (i = 0; i < aklass->rank; ++i) {
532 sizes [i] = mono_array_get (lengths, guint32, i);
534 sizes [i + aklass->rank] = mono_array_get (bounds, guint32, i);
536 sizes [i + aklass->rank] = 0;
539 array = mono_array_new_full (mono_object_domain (type), aklass, sizes, sizes + aklass->rank);
545 ves_icall_System_Array_GetRank (MonoObject *this)
549 return this->vtable->klass->rank;
553 ves_icall_System_Array_GetLength (MonoArray *this, gint32 dimension)
555 gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
559 if ((dimension < 0) || (dimension >= rank))
560 mono_raise_exception (mono_get_exception_index_out_of_range ());
562 if (this->bounds == NULL)
563 return this->max_length;
565 return this->bounds [dimension].length;
569 ves_icall_System_Array_GetLowerBound (MonoArray *this, gint32 dimension)
571 gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
575 if ((dimension < 0) || (dimension >= rank))
576 mono_raise_exception (mono_get_exception_index_out_of_range ());
578 if (this->bounds == NULL)
581 return this->bounds [dimension].lower_bound;
585 ves_icall_System_Array_ClearInternal (MonoArray *arr, int idx, int length)
587 int sz = mono_array_element_size (mono_object_class (arr));
588 memset (mono_array_addr_with_size (arr, sz, idx), 0, length * sz);
592 ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* dest, int dest_idx, int length)
597 MonoClass *src_class;
598 MonoClass *dest_class;
603 if (source->obj.vtable->klass->rank != dest->obj.vtable->klass->rank)
606 if (source->bounds || dest->bounds)
609 if ((dest_idx + length > mono_array_length (dest)) ||
610 (source_idx + length > mono_array_length (source)))
613 src_class = source->obj.vtable->klass->element_class;
614 dest_class = dest->obj.vtable->klass->element_class;
617 * Handle common cases.
620 /* Case1: object[] -> valuetype[] (ArrayList::ToArray) */
621 if (src_class == mono_defaults.object_class && dest_class->valuetype) {
622 int has_refs = dest_class->has_references;
623 for (i = source_idx; i < source_idx + length; ++i) {
624 MonoObject *elem = mono_array_get (source, MonoObject*, i);
625 if (elem && !mono_object_isinst (elem, dest_class))
629 element_size = mono_array_element_size (dest->obj.vtable->klass);
630 memset (mono_array_addr_with_size (dest, element_size, dest_idx), 0, element_size * length);
631 for (i = 0; i < length; ++i) {
632 MonoObject *elem = mono_array_get (source, MonoObject*, source_idx + i);
633 void *addr = mono_array_addr_with_size (dest, element_size, dest_idx + i);
637 mono_value_copy (addr, (char *)elem + sizeof (MonoObject), dest_class);
639 memcpy (addr, (char *)elem + sizeof (MonoObject), element_size);
644 /* Check if we're copying a char[] <==> (u)short[] */
645 if (src_class != dest_class) {
646 if (dest_class->valuetype || dest_class->enumtype || src_class->valuetype || src_class->enumtype)
649 if (mono_class_is_subclass_of (src_class, dest_class, FALSE))
651 /* Case2: object[] -> reftype[] (ArrayList::ToArray) */
652 else if (mono_class_is_subclass_of (dest_class, src_class, FALSE))
653 for (i = source_idx; i < source_idx + length; ++i) {
654 MonoObject *elem = mono_array_get (source, MonoObject*, i);
655 if (elem && !mono_object_isinst (elem, dest_class))
662 if (dest_class->valuetype) {
663 element_size = mono_array_element_size (source->obj.vtable->klass);
664 source_addr = mono_array_addr_with_size (source, element_size, source_idx);
665 if (dest_class->has_references) {
666 mono_value_copy_array (dest, dest_idx, source_addr, length);
668 dest_addr = mono_array_addr_with_size (dest, element_size, dest_idx);
669 memmove (dest_addr, source_addr, element_size * length);
672 mono_array_memcpy_refs (dest, dest_idx, source, source_idx, length);
679 ves_icall_System_Array_GetGenericValueImpl (MonoObject *this, guint32 pos, gpointer value)
688 ao = (MonoArray *)this;
689 ac = (MonoClass *)ao->obj.vtable->klass;
691 esize = mono_array_element_size (ac);
692 ea = (gpointer*)((char*)ao->vector + (pos * esize));
694 memcpy (value, ea, esize);
698 ves_icall_System_Array_SetGenericValueImpl (MonoObject *this, guint32 pos, gpointer value)
707 ao = (MonoArray *)this;
708 ac = (MonoClass *)ao->obj.vtable->klass;
710 esize = mono_array_element_size (ac);
711 ea = (gpointer*)((char*)ao->vector + (pos * esize));
713 memcpy (ea, value, esize);
717 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoArray *array, MonoClassField *field_handle)
719 MonoClass *klass = array->obj.vtable->klass;
720 guint32 size = mono_array_element_size (klass);
722 size *= array->max_length;
724 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
726 guint ## n *data = (guint ## n *) mono_array_addr (array, char, 0); \
727 guint ## n *src = (guint ## n *) field_handle->data; \
728 guint ## n *end = (guint ## n *)((char*)src + size); \
730 for (; src < end; data++, src++) { \
731 *data = read ## n (src); \
735 /* printf ("Initialize array with elements of %s type\n", klass->element_class->name); */
737 switch (mono_type_get_underlying_type (&klass->element_class->byval_arg)->type) {
754 memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
758 memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
760 if (klass->element_class->byval_arg.type == MONO_TYPE_R8) {
763 double *data = (double*)mono_array_addr (array, double, 0);
765 for (i = 0; i < size; i++, data++) {
775 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData (void)
779 return offsetof (MonoString, chars);
783 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue (MonoObject *obj)
787 if ((obj == NULL) || (! (obj->vtable->klass->valuetype)))
790 return mono_object_clone (obj);
794 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (MonoType *handle)
800 MONO_CHECK_ARG_NULL (handle);
802 klass = mono_class_from_mono_type (handle);
803 MONO_CHECK_ARG (handle, klass);
805 /* This will call the type constructor */
806 if (! (klass->flags & TYPE_ATTRIBUTE_INTERFACE))
807 mono_runtime_class_init (mono_class_vtable (mono_domain_get (), klass));
811 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunModuleConstructor (MonoImage *image)
815 mono_image_check_for_module_cctor (image);
816 if (image->has_module_cctor) {
817 MonoClass *module_klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | 1);
818 mono_runtime_class_init (mono_class_vtable (mono_domain_get (), module_klass));
823 ves_icall_System_Object_MemberwiseClone (MonoObject *this)
827 return mono_object_clone (this);
831 ves_icall_System_ValueType_InternalGetHashCode (MonoObject *this, MonoArray **fields)
834 MonoObject **values = NULL;
838 MonoClassField* field;
843 klass = mono_object_class (this);
845 if (mono_class_num_fields (klass) == 0)
846 return mono_object_hash (this);
849 * Compute the starting value of the hashcode for fields of primitive
850 * types, and return the remaining fields in an array to the managed side.
851 * This way, we can avoid costly reflection operations in managed code.
854 while ((field = mono_class_get_fields (klass, &iter))) {
855 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
857 if (mono_field_is_deleted (field))
859 /* FIXME: Add more types */
860 switch (field->type->type) {
862 result ^= *(gint32*)((guint8*)this + field->offset);
864 case MONO_TYPE_STRING: {
866 s = *(MonoString**)((guint8*)this + field->offset);
868 result ^= mono_string_hash (s);
873 values = g_newa (MonoObject*, mono_class_num_fields (klass));
874 o = mono_field_get_value_object (mono_object_domain (this), field, this);
875 values [count++] = o;
881 *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
882 for (i = 0; i < count; ++i)
883 mono_array_setref (*fields, i, values [i]);
891 ves_icall_System_ValueType_Equals (MonoObject *this, MonoObject *that, MonoArray **fields)
894 MonoObject **values = NULL;
896 MonoClassField* field;
902 MONO_CHECK_ARG_NULL (that);
904 if (this->vtable != that->vtable)
907 klass = mono_object_class (this);
910 * Do the comparison for fields of primitive type and return a result if
911 * possible. Otherwise, return the remaining fields in an array to the
912 * managed side. This way, we can avoid costly reflection operations in
917 while ((field = mono_class_get_fields (klass, &iter))) {
918 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
920 if (mono_field_is_deleted (field))
922 /* FIXME: Add more types */
923 switch (field->type->type) {
925 if (*(gint32*)((guint8*)this + field->offset) != *(gint32*)((guint8*)that + field->offset))
928 case MONO_TYPE_STRING: {
930 guint32 s1len, s2len;
931 s1 = *(MonoString**)((guint8*)this + field->offset);
932 s2 = *(MonoString**)((guint8*)that + field->offset);
935 if ((s1 == NULL) || (s2 == NULL))
937 s1len = mono_string_length (s1);
938 s2len = mono_string_length (s2);
942 if (memcmp (mono_string_chars (s1), mono_string_chars (s2), s1len * sizeof (gunichar2)) != 0)
948 values = g_newa (MonoObject*, mono_class_num_fields (klass) * 2);
949 o = mono_field_get_value_object (mono_object_domain (this), field, this);
950 values [count++] = o;
951 o = mono_field_get_value_object (mono_object_domain (this), field, that);
952 values [count++] = o;
958 *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
959 for (i = 0; i < count; ++i)
960 mono_array_setref (*fields, i, values [i]);
967 static MonoReflectionType *
968 ves_icall_System_Object_GetType (MonoObject *obj)
972 if (obj->vtable->klass != mono_defaults.transparent_proxy_class)
973 return mono_type_get_object (mono_object_domain (obj), &obj->vtable->klass->byval_arg);
975 return mono_type_get_object (mono_object_domain (obj), &((MonoTransparentProxy*)obj)->remote_class->proxy_class->byval_arg);
979 mono_type_type_from_obj (MonoReflectionType *mtype, MonoObject *obj)
983 mtype->type = &obj->vtable->klass->byval_arg;
984 g_assert (mtype->type->type);
988 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj)
992 MONO_CHECK_ARG_NULL (obj);
994 return mono_image_create_token (mb->dynamic_image, obj, TRUE);
998 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder *mb,
999 MonoReflectionMethod *method,
1000 MonoArray *opt_param_types)
1002 MONO_ARCH_SAVE_REGS;
1004 MONO_CHECK_ARG_NULL (method);
1006 return mono_image_create_method_token (
1007 mb->dynamic_image, (MonoObject *) method, opt_param_types);
1011 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder *mb, HANDLE file)
1013 MONO_ARCH_SAVE_REGS;
1015 mono_image_create_pefile (mb, file);
1019 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
1021 MONO_ARCH_SAVE_REGS;
1023 mono_image_build_metadata (mb);
1027 get_caller (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1029 MonoMethod **dest = data;
1031 /* skip unmanaged frames */
1046 static MonoReflectionType *
1047 type_from_name (const char *str, MonoBoolean ignoreCase)
1049 MonoType *type = NULL;
1050 MonoAssembly *assembly = NULL;
1051 MonoTypeNameParse info;
1052 char *temp_str = g_strdup (str);
1053 gboolean type_resolve = FALSE;
1055 MONO_ARCH_SAVE_REGS;
1057 /* mono_reflection_parse_type() mangles the string */
1058 if (!mono_reflection_parse_type (temp_str, &info)) {
1059 mono_reflection_free_type_info (&info);
1064 if (info.assembly.name) {
1065 assembly = mono_assembly_load (&info.assembly, NULL, NULL);
1067 MonoMethod *m = mono_method_get_last_managed ();
1068 MonoMethod *dest = m;
1070 mono_stack_walk_no_il (get_caller, &dest);
1075 * FIXME: mono_method_get_last_managed() sometimes returns NULL, thus
1076 * causing ves_icall_System_Reflection_Assembly_GetCallingAssembly()
1077 * to crash. This only seems to happen in some strange remoting
1078 * scenarios and I was unable to figure out what's happening there.
1079 * Dec 10, 2005 - Martin.
1083 assembly = dest->klass->image->assembly;
1085 g_warning (G_STRLOC);
1090 type = mono_reflection_get_type (assembly->image, &info, ignoreCase, &type_resolve);
1092 if (!info.assembly.name && !type) /* try mscorlib */
1093 type = mono_reflection_get_type (NULL, &info, ignoreCase, &type_resolve);
1095 mono_reflection_free_type_info (&info);
1101 return mono_type_get_object (mono_domain_get (), type);
1105 MonoReflectionType *
1106 mono_type_get (const char *str)
1108 char *copy = g_strdup (str);
1109 MonoReflectionType *type = type_from_name (copy, FALSE);
1116 static MonoReflectionType*
1117 ves_icall_type_from_name (MonoString *name,
1118 MonoBoolean throwOnError,
1119 MonoBoolean ignoreCase)
1121 char *str = mono_string_to_utf8 (name);
1122 MonoReflectionType *type;
1124 type = type_from_name (str, ignoreCase);
1127 MonoException *e = NULL;
1130 e = mono_get_exception_type_load (name, NULL);
1132 mono_loader_clear_error ();
1134 mono_raise_exception (e);
1141 static MonoReflectionType*
1142 ves_icall_type_from_handle (MonoType *handle)
1144 MonoDomain *domain = mono_domain_get ();
1145 MonoClass *klass = mono_class_from_mono_type (handle);
1147 MONO_ARCH_SAVE_REGS;
1149 mono_class_init (klass);
1150 return mono_type_get_object (domain, handle);
1154 ves_icall_System_Type_EqualsInternal (MonoReflectionType *type, MonoReflectionType *c)
1156 MONO_ARCH_SAVE_REGS;
1158 if (c && type->type && c->type)
1159 return mono_metadata_type_equal (type->type, c->type);
1164 /* System.TypeCode */
1183 TYPECODE_STRING = 18
1187 ves_icall_type_GetTypeCodeInternal (MonoReflectionType *type)
1189 int t = type->type->type;
1191 MONO_ARCH_SAVE_REGS;
1193 if (type->type->byref)
1194 return TYPECODE_OBJECT;
1198 case MONO_TYPE_VOID:
1199 return TYPECODE_OBJECT;
1200 case MONO_TYPE_BOOLEAN:
1201 return TYPECODE_BOOLEAN;
1203 return TYPECODE_BYTE;
1205 return TYPECODE_SBYTE;
1207 return TYPECODE_UINT16;
1209 return TYPECODE_INT16;
1210 case MONO_TYPE_CHAR:
1211 return TYPECODE_CHAR;
1215 return TYPECODE_OBJECT;
1217 return TYPECODE_UINT32;
1219 return TYPECODE_INT32;
1221 return TYPECODE_UINT64;
1223 return TYPECODE_INT64;
1225 return TYPECODE_SINGLE;
1227 return TYPECODE_DOUBLE;
1228 case MONO_TYPE_VALUETYPE:
1229 if (type->type->data.klass->enumtype) {
1230 t = type->type->data.klass->enum_basetype->type;
1233 MonoClass *k = type->type->data.klass;
1234 if (strcmp (k->name_space, "System") == 0) {
1235 if (strcmp (k->name, "Decimal") == 0)
1236 return TYPECODE_DECIMAL;
1237 else if (strcmp (k->name, "DateTime") == 0)
1238 return TYPECODE_DATETIME;
1241 return TYPECODE_OBJECT;
1242 case MONO_TYPE_STRING:
1243 return TYPECODE_STRING;
1244 case MONO_TYPE_SZARRAY:
1245 case MONO_TYPE_ARRAY:
1246 case MONO_TYPE_OBJECT:
1248 case MONO_TYPE_MVAR:
1249 case MONO_TYPE_TYPEDBYREF:
1250 return TYPECODE_OBJECT;
1251 case MONO_TYPE_CLASS:
1253 MonoClass *k = type->type->data.klass;
1254 if (strcmp (k->name_space, "System") == 0) {
1255 if (strcmp (k->name, "DBNull") == 0)
1256 return TYPECODE_DBNULL;
1259 return TYPECODE_OBJECT;
1260 case MONO_TYPE_GENERICINST:
1261 return TYPECODE_OBJECT;
1263 g_error ("type 0x%02x not handled in GetTypeCode()", t);
1269 ves_icall_type_is_subtype_of (MonoReflectionType *type, MonoReflectionType *c, MonoBoolean check_interfaces)
1275 MONO_ARCH_SAVE_REGS;
1277 g_assert (type != NULL);
1279 domain = ((MonoObject *)type)->vtable->domain;
1281 if (!c) /* FIXME: dont know what do do here */
1284 klass = mono_class_from_mono_type (type->type);
1285 klassc = mono_class_from_mono_type (c->type);
1287 if (type->type->byref)
1288 return klassc == mono_defaults.object_class;
1290 return mono_class_is_subclass_of (klass, klassc, check_interfaces);
1294 ves_icall_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType *c)
1300 MONO_ARCH_SAVE_REGS;
1302 g_assert (type != NULL);
1304 domain = ((MonoObject *)type)->vtable->domain;
1306 klass = mono_class_from_mono_type (type->type);
1307 klassc = mono_class_from_mono_type (c->type);
1309 if (type->type->byref && !c->type->byref)
1312 return mono_class_is_assignable_from (klass, klassc);
1316 ves_icall_type_IsInstanceOfType (MonoReflectionType *type, MonoObject *obj)
1318 MonoClass *klass = mono_class_from_mono_type (type->type);
1319 return mono_object_isinst (obj, klass) != NULL;
1323 ves_icall_get_attributes (MonoReflectionType *type)
1325 MonoClass *klass = mono_class_from_mono_type (type->type);
1327 MONO_ARCH_SAVE_REGS;
1329 return klass->flags;
1332 static MonoReflectionMarshal*
1333 ves_icall_System_Reflection_FieldInfo_GetUnmanagedMarshal (MonoReflectionField *field)
1335 MonoClass *klass = field->field->parent;
1336 MonoMarshalType *info;
1339 if (klass->generic_container ||
1340 (klass->generic_class && klass->generic_class->context.class_inst->is_open))
1343 info = mono_marshal_load_type_info (klass);
1345 for (i = 0; i < info->num_fields; ++i) {
1346 if (info->fields [i].field == field->field) {
1347 if (!info->fields [i].mspec)
1350 return mono_reflection_marshal_from_marshal_spec (field->object.vtable->domain, klass, info->fields [i].mspec);
1357 static MonoReflectionField*
1358 ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoClass *klass)
1363 klass = handle->parent;
1365 /* FIXME: check that handle is a field of klass or of a parent: return null
1366 * and throw the exception in managed code.
1368 return mono_field_get_object (mono_domain_get (), klass, handle);
1371 static MonoReflectionField*
1372 ves_icall_System_Reflection_FieldInfo_internal_from_handle (MonoClassField *handle)
1374 MONO_ARCH_SAVE_REGS;
1378 return mono_field_get_object (mono_domain_get (), handle->parent, handle);
1382 ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionField *field, MonoBoolean optional)
1384 MonoType *type = field->field->type;
1386 return type_array_from_modifiers (field->field->parent->image, type, optional);
1390 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
1392 MonoDomain *domain = mono_domain_get ();
1393 MonoMethodSignature* sig;
1394 MONO_ARCH_SAVE_REGS;
1396 sig = mono_method_signature (method);
1398 g_assert (mono_loader_get_last_error ());
1399 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
1402 info->parent = mono_type_get_object (domain, &method->klass->byval_arg);
1403 info->ret = mono_type_get_object (domain, sig->ret);
1404 info->attrs = method->flags;
1405 info->implattrs = method->iflags;
1406 if (sig->call_convention == MONO_CALL_DEFAULT)
1409 if (sig->call_convention == MONO_CALL_VARARG)
1414 info->callconv |= (sig->hasthis << 5) | (sig->explicit_this << 6);
1418 ves_icall_get_parameter_info (MonoMethod *method)
1420 MonoDomain *domain = mono_domain_get ();
1422 return mono_param_get_objects (domain, method);
1425 static MonoReflectionMarshal*
1426 ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod *method)
1428 MonoDomain *domain = mono_domain_get ();
1429 MonoReflectionMarshal* res = NULL;
1430 MonoMarshalSpec **mspecs;
1433 mspecs = g_new (MonoMarshalSpec*, mono_method_signature (method)->param_count + 1);
1434 mono_method_get_marshal_info (method, mspecs);
1437 res = mono_reflection_marshal_from_marshal_spec (domain, method->klass, mspecs [0]);
1439 for (i = mono_method_signature (method)->param_count; i >= 0; i--)
1441 mono_metadata_free_marshal_spec (mspecs [i]);
1448 ves_icall_MonoField_GetFieldOffset (MonoReflectionField *field)
1450 return field->field->offset - sizeof (MonoObject);
1453 static MonoReflectionType*
1454 ves_icall_MonoField_GetParentType (MonoReflectionField *field, MonoBoolean declaring)
1457 MONO_ARCH_SAVE_REGS;
1459 parent = declaring? field->field->parent: field->klass;
1461 return mono_type_get_object (mono_object_domain (field), &parent->byval_arg);
1465 ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj)
1468 MonoClassField *cf = field->field;
1472 MonoDomain *domain = mono_object_domain (field);
1474 gboolean is_static = FALSE;
1475 gboolean is_ref = FALSE;
1477 MONO_ARCH_SAVE_REGS;
1479 if (field->klass->image->assembly->ref_only)
1480 mono_raise_exception (mono_get_exception_invalid_operation (
1481 "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
1483 mono_class_init (field->klass);
1485 t = mono_type_get_underlying_type (cf->type);
1487 case MONO_TYPE_STRING:
1488 case MONO_TYPE_OBJECT:
1489 case MONO_TYPE_CLASS:
1490 case MONO_TYPE_ARRAY:
1491 case MONO_TYPE_SZARRAY:
1496 case MONO_TYPE_BOOLEAN:
1499 case MONO_TYPE_CHAR:
1508 case MONO_TYPE_VALUETYPE:
1511 case MONO_TYPE_GENERICINST:
1512 if (mono_type_generic_inst_is_valuetype (t)) {
1519 g_error ("type 0x%x not handled in "
1520 "ves_icall_Monofield_GetValue", t->type);
1525 if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) {
1527 vtable = mono_class_vtable (domain, cf->parent);
1528 if (!vtable->initialized && !(cf->type->attrs & FIELD_ATTRIBUTE_LITERAL))
1529 mono_runtime_class_init (vtable);
1534 mono_field_static_get_value (vtable, cf, &o);
1536 mono_field_get_value (obj, cf, &o);
1541 if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) {
1542 MonoClass *nklass = mono_class_from_mono_type (cf->type);
1545 /* Convert the Nullable structure into a boxed vtype */
1547 buf = (guint8*)vtable->data + cf->offset;
1549 buf = (guint8*)obj + cf->offset;
1551 return mono_nullable_box (buf, nklass);
1554 /* boxed value type */
1555 klass = mono_class_from_mono_type (cf->type);
1556 o = mono_object_new (domain, klass);
1557 v = ((gchar *) o) + sizeof (MonoObject);
1559 mono_field_static_get_value (vtable, cf, v);
1561 mono_field_get_value (obj, cf, v);
1568 ves_icall_FieldInfo_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value)
1570 MonoClassField *cf = field->field;
1573 MONO_ARCH_SAVE_REGS;
1575 if (field->klass->image->assembly->ref_only)
1576 mono_raise_exception (mono_get_exception_invalid_operation (
1577 "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
1579 v = (gchar *) value;
1580 if (!cf->type->byref) {
1581 switch (cf->type->type) {
1584 case MONO_TYPE_BOOLEAN:
1587 case MONO_TYPE_CHAR:
1596 case MONO_TYPE_VALUETYPE:
1598 v += sizeof (MonoObject);
1600 case MONO_TYPE_STRING:
1601 case MONO_TYPE_OBJECT:
1602 case MONO_TYPE_CLASS:
1603 case MONO_TYPE_ARRAY:
1604 case MONO_TYPE_SZARRAY:
1607 case MONO_TYPE_GENERICINST: {
1608 MonoGenericClass *gclass = cf->type->data.generic_class;
1609 g_assert (!gclass->context.class_inst->is_open);
1611 if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) {
1612 MonoClass *nklass = mono_class_from_mono_type (cf->type);
1613 MonoObject *nullable;
1616 * Convert the boxed vtype into a Nullable structure.
1617 * This is complicated by the fact that Nullables have
1618 * a variable structure.
1620 nullable = mono_object_new (mono_domain_get (), nklass);
1622 mono_nullable_init (mono_object_unbox (nullable), value, nklass);
1624 v = mono_object_unbox (nullable);
1627 if (gclass->container_class->valuetype && (v != NULL))
1628 v += sizeof (MonoObject);
1632 g_error ("type 0x%x not handled in "
1633 "ves_icall_FieldInfo_SetValueInternal", cf->type->type);
1638 if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) {
1639 MonoVTable *vtable = mono_class_vtable (mono_object_domain (field), cf->parent);
1640 if (!vtable->initialized)
1641 mono_runtime_class_init (vtable);
1642 mono_field_static_set_value (vtable, cf, v);
1644 mono_field_set_value (obj, cf, v);
1648 static MonoReflectionType*
1649 ves_icall_MonoGenericMethod_get_ReflectedType (MonoReflectionGenericMethod *rmethod)
1651 MonoMethod *method = rmethod->method.method;
1653 return mono_type_get_object (mono_object_domain (rmethod), &method->klass->byval_arg);
1656 /* From MonoProperty.cs */
1658 PInfo_Attributes = 1,
1659 PInfo_GetMethod = 1 << 1,
1660 PInfo_SetMethod = 1 << 2,
1661 PInfo_ReflectedType = 1 << 3,
1662 PInfo_DeclaringType = 1 << 4,
1667 ves_icall_get_property_info (MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
1669 MonoDomain *domain = mono_object_domain (property);
1671 MONO_ARCH_SAVE_REGS;
1673 if ((req_info & PInfo_ReflectedType) != 0)
1674 info->parent = mono_type_get_object (domain, &property->klass->byval_arg);
1675 else if ((req_info & PInfo_DeclaringType) != 0)
1676 info->parent = mono_type_get_object (domain, &property->property->parent->byval_arg);
1678 if ((req_info & PInfo_Name) != 0)
1679 info->name = mono_string_new (domain, property->property->name);
1681 if ((req_info & PInfo_Attributes) != 0)
1682 info->attrs = property->property->attrs;
1684 if ((req_info & PInfo_GetMethod) != 0)
1685 info->get = property->property->get ?
1686 mono_method_get_object (domain, property->property->get, property->klass): NULL;
1688 if ((req_info & PInfo_SetMethod) != 0)
1689 info->set = property->property->set ?
1690 mono_method_get_object (domain, property->property->set, property->klass): NULL;
1692 * There may be other methods defined for properties, though, it seems they are not exposed
1693 * in the reflection API
1698 ves_icall_get_event_info (MonoReflectionEvent *event, MonoEventInfo *info)
1700 MonoDomain *domain = mono_object_domain (event);
1702 MONO_ARCH_SAVE_REGS;
1704 info->reflected_type = mono_type_get_object (domain, &event->klass->byval_arg);
1705 info->declaring_type = mono_type_get_object (domain, &event->event->parent->byval_arg);
1707 info->name = mono_string_new (domain, event->event->name);
1708 info->attrs = event->event->attrs;
1709 info->add_method = event->event->add ? mono_method_get_object (domain, event->event->add, NULL): NULL;
1710 info->remove_method = event->event->remove ? mono_method_get_object (domain, event->event->remove, NULL): NULL;
1711 info->raise_method = event->event->raise ? mono_method_get_object (domain, event->event->raise, NULL): NULL;
1713 if (event->event->other) {
1715 while (event->event->other [n])
1717 info->other_methods = mono_array_new (domain, mono_defaults.method_info_class, n);
1719 for (i = 0; i < n; i++)
1720 mono_array_setref (info->other_methods, i, mono_method_get_object (domain, event->event->other [i], NULL));
1725 ves_icall_Type_GetInterfaces (MonoReflectionType* type)
1727 MonoDomain *domain = mono_object_domain (type);
1729 GPtrArray *ifaces = NULL;
1731 MonoClass *class = mono_class_from_mono_type (type->type);
1734 MonoGenericContext *context = NULL;
1736 MONO_ARCH_SAVE_REGS;
1738 if (class->generic_class && class->generic_class->context.class_inst->is_open) {
1739 context = mono_class_get_context (class);
1740 class = class->generic_class->container_class;
1743 mono_class_setup_vtable (class);
1745 slots = mono_bitset_new (class->max_interface_id + 1, 0);
1747 for (parent = class; parent; parent = parent->parent) {
1748 GPtrArray *tmp_ifaces = mono_class_get_implemented_interfaces (parent);
1750 for (i = 0; i < tmp_ifaces->len; ++i) {
1751 MonoClass *ic = g_ptr_array_index (tmp_ifaces, i);
1753 if (mono_bitset_test (slots, ic->interface_id))
1756 mono_bitset_set (slots, ic->interface_id);
1758 ifaces = g_ptr_array_new ();
1759 g_ptr_array_add (ifaces, ic);
1761 g_ptr_array_free (tmp_ifaces, TRUE);
1764 mono_bitset_free (slots);
1767 return mono_array_new (domain, mono_defaults.monotype_class, 0);
1769 intf = mono_array_new (domain, mono_defaults.monotype_class, ifaces->len);
1770 for (i = 0; i < ifaces->len; ++i) {
1771 MonoClass *ic = g_ptr_array_index (ifaces, i);
1772 MonoType *ret = &ic->byval_arg;
1773 if (context && ic->generic_class && ic->generic_class->context.class_inst->is_open)
1774 ret = mono_class_inflate_generic_type (ret, context);
1776 mono_array_setref (intf, i, mono_type_get_object (domain, ret));
1778 g_ptr_array_free (ifaces, TRUE);
1784 ves_icall_Type_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType *iface, MonoArray **targets, MonoArray **methods)
1786 MonoClass *class = mono_class_from_mono_type (type->type);
1787 MonoClass *iclass = mono_class_from_mono_type (iface->type);
1788 MonoReflectionMethod *member;
1791 int i = 0, len, ioffset;
1794 MONO_ARCH_SAVE_REGS;
1796 mono_class_setup_vtable (class);
1798 /* type doesn't implement iface: the exception is thrown in managed code */
1799 if (! MONO_CLASS_IMPLEMENTS_INTERFACE (class, iclass->interface_id))
1802 len = mono_class_num_methods (iclass);
1803 ioffset = mono_class_interface_offset (class, iclass);
1804 domain = mono_object_domain (type);
1805 *targets = mono_array_new (domain, mono_defaults.method_info_class, len);
1806 *methods = mono_array_new (domain, mono_defaults.method_info_class, len);
1809 while ((method = mono_class_get_methods (iclass, &iter))) {
1810 member = mono_method_get_object (domain, method, iclass);
1811 mono_array_setref (*methods, i, member);
1812 member = mono_method_get_object (domain, class->vtable [i + ioffset], class);
1813 mono_array_setref (*targets, i, member);
1820 ves_icall_Type_GetPacking (MonoReflectionType *type, guint32 *packing, guint32 *size)
1822 MonoClass *klass = mono_class_from_mono_type (type->type);
1824 g_assert (!klass->image->dynamic);
1826 mono_metadata_packing_from_typedef (klass->image, klass->type_token, packing, size);
1829 static MonoReflectionType*
1830 ves_icall_MonoType_GetElementType (MonoReflectionType *type)
1832 MonoClass *class = mono_class_from_mono_type (type->type);
1834 MONO_ARCH_SAVE_REGS;
1836 // GetElementType should only return a type for:
1837 // Array Pointer PassedByRef
1838 if (type->type->byref)
1839 return mono_type_get_object (mono_object_domain (type), &class->byval_arg);
1840 else if (class->element_class && MONO_CLASS_IS_ARRAY (class))
1841 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
1842 else if (class->element_class && type->type->type == MONO_TYPE_PTR)
1843 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
1848 static MonoReflectionType*
1849 ves_icall_get_type_parent (MonoReflectionType *type)
1851 MonoClass *class = mono_class_from_mono_type (type->type);
1853 MONO_ARCH_SAVE_REGS;
1855 return class->parent ? mono_type_get_object (mono_object_domain (type), &class->parent->byval_arg): NULL;
1859 ves_icall_type_ispointer (MonoReflectionType *type)
1861 MONO_ARCH_SAVE_REGS;
1863 return type->type->type == MONO_TYPE_PTR;
1867 ves_icall_type_isprimitive (MonoReflectionType *type)
1869 MONO_ARCH_SAVE_REGS;
1871 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)));
1875 ves_icall_type_isbyref (MonoReflectionType *type)
1877 MONO_ARCH_SAVE_REGS;
1879 return type->type->byref;
1883 ves_icall_type_iscomobject (MonoReflectionType *type)
1885 MonoClass *klass = mono_class_from_mono_type (type->type);
1886 MONO_ARCH_SAVE_REGS;
1888 return (klass && klass->is_com_object);
1891 static MonoReflectionModule*
1892 ves_icall_MonoType_get_Module (MonoReflectionType *type)
1894 MonoClass *class = mono_class_from_mono_type (type->type);
1896 MONO_ARCH_SAVE_REGS;
1898 return mono_module_get_object (mono_object_domain (type), class->image);
1901 static MonoReflectionAssembly*
1902 ves_icall_MonoType_get_Assembly (MonoReflectionType *type)
1904 MonoDomain *domain = mono_domain_get ();
1905 MonoClass *class = mono_class_from_mono_type (type->type);
1907 MONO_ARCH_SAVE_REGS;
1909 return mono_assembly_get_object (domain, class->image->assembly);
1912 static MonoReflectionType*
1913 ves_icall_MonoType_get_DeclaringType (MonoReflectionType *type)
1915 MonoDomain *domain = mono_domain_get ();
1918 MONO_ARCH_SAVE_REGS;
1920 if (type->type->byref)
1922 if (type->type->type == MONO_TYPE_VAR)
1923 class = type->type->data.generic_param->owner->owner.klass;
1924 else if (type->type->type == MONO_TYPE_MVAR)
1925 class = type->type->data.generic_param->owner->owner.method->klass;
1927 class = mono_class_from_mono_type (type->type)->nested_in;
1929 return class ? mono_type_get_object (domain, &class->byval_arg) : NULL;
1932 static MonoReflectionType*
1933 ves_icall_MonoType_get_UnderlyingSystemType (MonoReflectionType *type)
1935 MonoDomain *domain = mono_domain_get ();
1936 MonoClass *class = mono_class_from_mono_type (type->type);
1938 MONO_ARCH_SAVE_REGS;
1940 if (class->enumtype && class->enum_basetype) /* types that are modified typebuilders may not have enum_basetype set */
1941 return mono_type_get_object (domain, class->enum_basetype);
1942 else if (class->element_class)
1943 return mono_type_get_object (domain, &class->element_class->byval_arg);
1949 ves_icall_MonoType_get_Name (MonoReflectionType *type)
1951 MonoDomain *domain = mono_domain_get ();
1952 MonoClass *class = mono_class_from_mono_type (type->type);
1954 MONO_ARCH_SAVE_REGS;
1956 if (type->type->byref) {
1957 char *n = g_strdup_printf ("%s&", class->name);
1958 MonoString *res = mono_string_new (domain, n);
1964 return mono_string_new (domain, class->name);
1969 ves_icall_MonoType_get_Namespace (MonoReflectionType *type)
1971 MonoDomain *domain = mono_domain_get ();
1972 MonoClass *class = mono_class_from_mono_type (type->type);
1974 MONO_ARCH_SAVE_REGS;
1976 while (class->nested_in)
1977 class = class->nested_in;
1979 if (class->name_space [0] == '\0')
1982 return mono_string_new (domain, class->name_space);
1986 ves_icall_MonoType_GetArrayRank (MonoReflectionType *type)
1988 MonoClass *class = mono_class_from_mono_type (type->type);
1990 MONO_ARCH_SAVE_REGS;
1996 ves_icall_MonoType_GetGenericArguments (MonoReflectionType *type)
1999 MonoClass *klass, *pklass;
2001 MONO_ARCH_SAVE_REGS;
2003 klass = mono_class_from_mono_type (type->type);
2005 if (klass->generic_container) {
2006 MonoGenericContainer *container = klass->generic_container;
2007 res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, container->type_argc);
2008 for (i = 0; i < container->type_argc; ++i) {
2009 pklass = mono_class_from_generic_parameter (&container->type_params [i], klass->image, FALSE);
2010 mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), &pklass->byval_arg));
2012 } else if (klass->generic_class) {
2013 MonoGenericInst *inst = klass->generic_class->context.class_inst;
2014 res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, inst->type_argc);
2015 for (i = 0; i < inst->type_argc; ++i)
2016 mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), inst->type_argv [i]));
2018 res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, 0);
2024 ves_icall_Type_get_IsGenericTypeDefinition (MonoReflectionType *type)
2027 MONO_ARCH_SAVE_REGS;
2029 if (type->type->byref)
2032 klass = mono_class_from_mono_type (type->type);
2034 return klass->generic_container != NULL;
2037 static MonoReflectionType*
2038 ves_icall_Type_GetGenericTypeDefinition_impl (MonoReflectionType *type)
2041 MONO_ARCH_SAVE_REGS;
2043 if (type->type->byref)
2046 klass = mono_class_from_mono_type (type->type);
2047 if (klass->generic_container) {
2048 return type; /* check this one */
2050 if (klass->generic_class) {
2051 MonoClass *generic_class = klass->generic_class->container_class;
2053 if (generic_class->wastypebuilder && generic_class->reflection_info)
2054 return generic_class->reflection_info;
2056 return mono_type_get_object (mono_object_domain (type), &generic_class->byval_arg);
2061 static MonoReflectionType*
2062 ves_icall_Type_MakeGenericType (MonoReflectionType *type, MonoArray *type_array)
2064 MonoType *geninst, **types;
2067 MONO_ARCH_SAVE_REGS;
2069 count = mono_array_length (type_array);
2070 types = g_new0 (MonoType *, count);
2072 for (i = 0; i < count; i++) {
2073 MonoReflectionType *t = mono_array_get (type_array, gpointer, i);
2074 types [i] = t->type;
2077 geninst = mono_reflection_bind_generic_parameters (type, count, types);
2082 return mono_type_get_object (mono_object_domain (type), geninst);
2086 ves_icall_Type_get_IsGenericInstance (MonoReflectionType *type)
2089 MONO_ARCH_SAVE_REGS;
2091 if (type->type->byref)
2094 klass = mono_class_from_mono_type (type->type);
2095 return klass->generic_class != NULL;
2099 ves_icall_Type_get_IsGenericType (MonoReflectionType *type)
2102 MONO_ARCH_SAVE_REGS;
2104 if (type->type->byref)
2107 klass = mono_class_from_mono_type (type->type);
2108 return klass->generic_class != NULL || klass->generic_container != NULL;
2112 ves_icall_Type_GetGenericParameterPosition (MonoReflectionType *type)
2114 MONO_ARCH_SAVE_REGS;
2116 if (is_generic_parameter (type->type))
2117 return type->type->data.generic_param->num;
2121 static GenericParameterAttributes
2122 ves_icall_Type_GetGenericParameterAttributes (MonoReflectionType *type)
2124 MONO_ARCH_SAVE_REGS;
2125 g_assert (is_generic_parameter (type->type));
2126 return type->type->data.generic_param->flags;
2130 ves_icall_Type_GetGenericParameterConstraints (MonoReflectionType *type)
2132 MonoGenericParam *param;
2138 MONO_ARCH_SAVE_REGS;
2140 domain = mono_object_domain (type);
2141 param = type->type->data.generic_param;
2142 for (count = 0, ptr = param->constraints; ptr && *ptr; ptr++, count++)
2145 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2146 for (i = 0; i < count; i++)
2147 mono_array_setref (res, i, mono_type_get_object (domain, ¶m->constraints [i]->byval_arg));
2154 ves_icall_MonoType_get_IsGenericParameter (MonoReflectionType *type)
2156 MONO_ARCH_SAVE_REGS;
2157 return is_generic_parameter (type->type);
2161 ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder *tb)
2163 MONO_ARCH_SAVE_REGS;
2164 return is_generic_parameter (tb->type.type);
2168 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
2169 MonoReflectionType *t)
2171 enumtype->type = t->type;
2174 static MonoReflectionType*
2175 ves_icall_MonoGenericClass_GetParentType (MonoReflectionGenericClass *type)
2177 MonoDynamicGenericClass *gclass;
2178 MonoReflectionType *parent = NULL;
2183 MONO_ARCH_SAVE_REGS;
2185 g_assert (type->type.type->data.generic_class->is_dynamic);
2186 gclass = (MonoDynamicGenericClass *) type->type.type->data.generic_class;
2188 domain = mono_object_domain (type);
2189 klass = mono_class_from_mono_type (type->generic_type->type);
2191 if (!klass->generic_class && !klass->generic_container)
2194 if (!strcmp (type->generic_type->object.vtable->klass->name, "TypeBuilder")) {
2195 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *) type->generic_type;
2196 parent = tb->parent;
2197 } else if (klass->wastypebuilder) {
2198 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *) type->generic_type;
2199 parent = tb->parent;
2201 MonoClass *pklass = klass->parent;
2203 parent = mono_type_get_object (domain, &pklass->byval_arg);
2206 if (!parent || (parent->type->type != MONO_TYPE_GENERICINST))
2209 inflated = mono_class_inflate_generic_type (
2210 parent->type, mono_generic_class_get_context ((MonoGenericClass *) gclass));
2212 return mono_type_get_object (domain, inflated);
2216 ves_icall_MonoGenericClass_GetInterfaces (MonoReflectionGenericClass *type)
2218 static MonoClass *System_Reflection_MonoGenericClass;
2219 MonoGenericClass *gclass;
2220 MonoReflectionTypeBuilder *tb = NULL;
2221 MonoClass *klass = NULL;
2226 MONO_ARCH_SAVE_REGS;
2228 if (!System_Reflection_MonoGenericClass) {
2229 System_Reflection_MonoGenericClass = mono_class_from_name (
2230 mono_defaults.corlib, "System.Reflection", "MonoGenericClass");
2231 g_assert (System_Reflection_MonoGenericClass);
2234 domain = mono_object_domain (type);
2236 gclass = type->type.type->data.generic_class;
2237 g_assert (gclass->is_dynamic);
2239 if (!strcmp (type->generic_type->object.vtable->klass->name, "TypeBuilder")) {
2240 tb = (MonoReflectionTypeBuilder *) type->generic_type;
2241 icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
2243 klass = gclass->container_class;
2244 mono_class_init (klass);
2245 icount = klass->interface_count;
2248 res = mono_array_new (domain, System_Reflection_MonoGenericClass, icount);
2250 for (i = 0; i < icount; i++) {
2251 MonoReflectionType *iface;
2255 iface = mono_array_get (tb->interfaces, MonoReflectionType *, i);
2258 it = &klass->interfaces [i]->byval_arg;
2260 it = mono_class_inflate_generic_type (it, mono_generic_class_get_context (gclass));
2262 iface = mono_type_get_object (domain, it);
2263 mono_array_setref (res, i, iface);
2269 static MonoReflectionMethod*
2270 ves_icall_MonoGenericClass_GetCorrespondingInflatedMethod (MonoReflectionGenericClass *type,
2271 MonoReflectionMethod* generic)
2273 MonoGenericClass *gclass;
2274 MonoDynamicGenericClass *dgclass;
2278 MONO_ARCH_SAVE_REGS;
2280 gclass = type->type.type->data.generic_class;
2281 g_assert (gclass->is_dynamic);
2283 dgclass = (MonoDynamicGenericClass *) gclass;
2285 domain = mono_object_domain (type);
2287 for (i = 0; i < dgclass->count_methods; i++)
2288 if (generic->method->token == dgclass->methods [i]->token)
2289 return mono_method_get_object (domain, dgclass->methods [i], NULL);
2294 static MonoReflectionMethod*
2295 ves_icall_MonoGenericClass_GetCorrespondingInflatedConstructor (MonoReflectionGenericClass *type,
2296 MonoReflectionMethod* generic)
2298 MonoGenericClass *gclass;
2299 MonoDynamicGenericClass *dgclass;
2303 MONO_ARCH_SAVE_REGS;
2305 gclass = type->type.type->data.generic_class;
2306 g_assert (gclass->is_dynamic);
2308 dgclass = (MonoDynamicGenericClass *) gclass;
2310 domain = mono_object_domain (type);
2312 for (i = 0; i < dgclass->count_ctors; i++)
2313 if (generic->method->token == dgclass->ctors [i]->token)
2314 return mono_method_get_object (domain, dgclass->ctors [i], NULL);
2320 static MonoReflectionField*
2321 ves_icall_MonoGenericClass_GetCorrespondingInflatedField (MonoReflectionGenericClass *type,
2322 MonoString* generic_name)
2324 MonoGenericClass *gclass;
2325 MonoDynamicGenericClass *dgclass;
2327 MonoClass *refclass;
2328 char *utf8_name = mono_string_to_utf8 (generic_name);
2331 MONO_ARCH_SAVE_REGS;
2333 gclass = type->type.type->data.generic_class;
2334 g_assert (gclass->is_dynamic);
2336 dgclass = (MonoDynamicGenericClass *) gclass;
2338 refclass = mono_class_from_mono_type (type->type.type);
2340 domain = mono_object_domain (type);
2342 for (i = 0; i < dgclass->count_fields; i++)
2343 if (strcmp (utf8_name, dgclass->fields [i].name) == 0) {
2345 return mono_field_get_object (domain, refclass, &dgclass->fields [i]);
2354 static MonoReflectionMethod*
2355 ves_icall_MonoType_GetCorrespondingInflatedMethod (MonoReflectionType *type,
2356 MonoReflectionMethod* generic)
2363 MONO_ARCH_SAVE_REGS;
2365 domain = ((MonoObject *)type)->vtable->domain;
2367 klass = mono_class_from_mono_type (type->type);
2370 while ((method = mono_class_get_methods (klass, &iter))) {
2371 if (method->token == generic->method->token)
2372 return mono_method_get_object (domain, method, klass);
2379 ves_icall_MonoGenericClass_GetMethods (MonoReflectionGenericClass *type,
2380 MonoReflectionType *reflected_type)
2382 MonoGenericClass *gclass;
2383 MonoDynamicGenericClass *dgclass;
2385 MonoClass *refclass;
2389 MONO_ARCH_SAVE_REGS;
2391 gclass = type->type.type->data.generic_class;
2392 g_assert (gclass->is_dynamic);
2393 dgclass = (MonoDynamicGenericClass *) gclass;
2395 refclass = mono_class_from_mono_type (reflected_type->type);
2397 domain = mono_object_domain (type);
2398 res = mono_array_new (domain, mono_defaults.method_info_class, dgclass->count_methods);
2400 for (i = 0; i < dgclass->count_methods; i++)
2401 mono_array_setref (res, i, mono_method_get_object (domain, dgclass->methods [i], refclass));
2407 ves_icall_MonoGenericClass_GetConstructors (MonoReflectionGenericClass *type,
2408 MonoReflectionType *reflected_type)
2410 static MonoClass *System_Reflection_ConstructorInfo;
2411 MonoGenericClass *gclass;
2412 MonoDynamicGenericClass *dgclass;
2414 MonoClass *refclass;
2418 MONO_ARCH_SAVE_REGS;
2420 if (!System_Reflection_ConstructorInfo)
2421 System_Reflection_ConstructorInfo = mono_class_from_name (
2422 mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
2424 gclass = type->type.type->data.generic_class;
2425 g_assert (gclass->is_dynamic);
2426 dgclass = (MonoDynamicGenericClass *) gclass;
2428 refclass = mono_class_from_mono_type (reflected_type->type);
2430 domain = mono_object_domain (type);
2431 res = mono_array_new (domain, System_Reflection_ConstructorInfo, dgclass->count_ctors);
2433 for (i = 0; i < dgclass->count_ctors; i++)
2434 mono_array_setref (res, i, mono_method_get_object (domain, dgclass->ctors [i], refclass));
2440 ves_icall_MonoGenericClass_GetFields (MonoReflectionGenericClass *type,
2441 MonoReflectionType *reflected_type)
2443 MonoGenericClass *gclass;
2444 MonoDynamicGenericClass *dgclass;
2446 MonoClass *refclass;
2450 MONO_ARCH_SAVE_REGS;
2452 gclass = type->type.type->data.generic_class;
2453 g_assert (gclass->is_dynamic);
2454 dgclass = (MonoDynamicGenericClass *) gclass;
2456 refclass = mono_class_from_mono_type (reflected_type->type);
2458 domain = mono_object_domain (type);
2459 res = mono_array_new (domain, mono_defaults.field_info_class, dgclass->count_fields);
2461 for (i = 0; i < dgclass->count_fields; i++)
2462 mono_array_setref (res, i, mono_field_get_object (domain, refclass, &dgclass->fields [i]));
2468 ves_icall_MonoGenericClass_GetProperties (MonoReflectionGenericClass *type,
2469 MonoReflectionType *reflected_type)
2471 static MonoClass *System_Reflection_PropertyInfo;
2472 MonoGenericClass *gclass;
2473 MonoDynamicGenericClass *dgclass;
2475 MonoClass *refclass;
2479 MONO_ARCH_SAVE_REGS;
2481 if (!System_Reflection_PropertyInfo)
2482 System_Reflection_PropertyInfo = mono_class_from_name (
2483 mono_defaults.corlib, "System.Reflection", "PropertyInfo");
2485 gclass = type->type.type->data.generic_class;
2486 g_assert (gclass->is_dynamic);
2487 dgclass = (MonoDynamicGenericClass *) gclass;
2489 refclass = mono_class_from_mono_type (reflected_type->type);
2491 domain = mono_object_domain (type);
2492 res = mono_array_new (domain, System_Reflection_PropertyInfo, dgclass->count_properties);
2494 for (i = 0; i < dgclass->count_properties; i++)
2495 mono_array_setref (res, i, mono_property_get_object (domain, refclass, &dgclass->properties [i]));
2501 ves_icall_MonoGenericClass_GetEvents (MonoReflectionGenericClass *type,
2502 MonoReflectionType *reflected_type)
2504 static MonoClass *System_Reflection_EventInfo;
2505 MonoGenericClass *gclass;
2506 MonoDynamicGenericClass *dgclass;
2508 MonoClass *refclass;
2512 MONO_ARCH_SAVE_REGS;
2514 if (!System_Reflection_EventInfo)
2515 System_Reflection_EventInfo = mono_class_from_name (
2516 mono_defaults.corlib, "System.Reflection", "EventInfo");
2518 gclass = type->type.type->data.generic_class;
2519 g_assert (gclass->is_dynamic);
2520 dgclass = (MonoDynamicGenericClass *) gclass;
2522 refclass = mono_class_from_mono_type (reflected_type->type);
2524 domain = mono_object_domain (type);
2525 res = mono_array_new (domain, System_Reflection_EventInfo, dgclass->count_events);
2527 for (i = 0; i < dgclass->count_events; i++)
2528 mono_array_setref (res, i, mono_event_get_object (domain, refclass, &dgclass->events [i]));
2533 static MonoReflectionMethod *
2534 ves_icall_MonoType_get_DeclaringMethod (MonoReflectionType *type)
2539 MONO_ARCH_SAVE_REGS;
2541 if (type->type->byref || type->type->type != MONO_TYPE_MVAR)
2544 method = type->type->data.generic_param->owner->owner.method;
2546 klass = mono_class_from_mono_type (type->type);
2547 return mono_method_get_object (mono_object_domain (type), method, klass);
2550 static MonoReflectionDllImportAttribute*
2551 ves_icall_MonoMethod_GetDllImportAttribute (MonoMethod *method)
2553 static MonoClass *DllImportAttributeClass = NULL;
2554 MonoDomain *domain = mono_domain_get ();
2555 MonoReflectionDllImportAttribute *attr;
2556 MonoImage *image = method->klass->image;
2557 MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method;
2558 MonoTableInfo *tables = image->tables;
2559 MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
2560 MonoTableInfo *mr = &tables [MONO_TABLE_MODULEREF];
2561 guint32 im_cols [MONO_IMPLMAP_SIZE];
2562 guint32 scope_token;
2563 const char *import = NULL;
2564 const char *scope = NULL;
2567 if (!method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)
2570 if (!DllImportAttributeClass) {
2571 DllImportAttributeClass =
2572 mono_class_from_name (mono_defaults.corlib,
2573 "System.Runtime.InteropServices", "DllImportAttribute");
2574 g_assert (DllImportAttributeClass);
2577 if (method->klass->image->dynamic) {
2578 MonoReflectionMethodAux *method_aux =
2579 g_hash_table_lookup (
2580 ((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
2582 import = method_aux->dllentry;
2583 scope = method_aux->dll;
2587 if (piinfo->implmap_idx) {
2588 mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
2590 piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
2591 import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
2592 scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
2593 scope = mono_metadata_string_heap (image, scope_token);
2596 flags = piinfo->piflags;
2598 attr = (MonoReflectionDllImportAttribute*)mono_object_new (domain, DllImportAttributeClass);
2600 MONO_OBJECT_SETREF (attr, dll, mono_string_new (domain, scope));
2601 MONO_OBJECT_SETREF (attr, entry_point, mono_string_new (domain, import));
2602 attr->call_conv = (flags & 0x700) >> 8;
2603 attr->charset = ((flags & 0x6) >> 1) + 1;
2604 if (attr->charset == 1)
2606 attr->exact_spelling = (flags & 0x1) != 0;
2607 attr->set_last_error = (flags & 0x40) != 0;
2608 attr->best_fit_mapping = (flags & 0x30) == 0x10;
2609 attr->throw_on_unmappable = (flags & 0x3000) == 0x1000;
2610 attr->preserve_sig = FALSE;
2615 static MonoReflectionMethod *
2616 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
2618 MonoMethodInflated *imethod;
2620 MONO_ARCH_SAVE_REGS;
2622 if (method->method->generic_container)
2625 if (!method->method->is_inflated)
2628 imethod = (MonoMethodInflated *) method->method;
2630 if (imethod->reflection_info)
2631 return imethod->reflection_info;
2633 return mono_method_get_object (
2634 mono_object_domain (method), imethod->declaring, NULL);
2638 ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethod *method)
2640 MONO_ARCH_SAVE_REGS;
2642 return mono_method_signature (method->method)->generic_param_count != 0;
2646 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method)
2648 MONO_ARCH_SAVE_REGS;
2650 return method->method->generic_container != NULL;
2654 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
2659 MONO_ARCH_SAVE_REGS;
2661 domain = mono_object_domain (method);
2663 if (method->method->is_inflated) {
2664 MonoGenericInst *inst = mono_method_get_context (method->method)->method_inst;
2667 count = inst->type_argc;
2668 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2670 for (i = 0; i < count; i++)
2671 mono_array_setref (res, i, mono_type_get_object (domain, inst->type_argv [i]));
2677 count = mono_method_signature (method->method)->generic_param_count;
2678 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2680 for (i = 0; i < count; i++) {
2681 MonoGenericParam *param = &method->method->generic_container->type_params [i];
2682 MonoClass *pklass = mono_class_from_generic_parameter (
2683 param, method->method->klass->image, TRUE);
2684 mono_array_setref (res, i,
2685 mono_type_get_object (domain, &pklass->byval_arg));
2692 ensure_reflection_security (void)
2694 MonoMethod *m = mono_method_get_last_managed ();
2698 g_print ("method %s.%s.%s in image %s\n",
2699 m->klass->name_space, m->klass->name, m->name, m->klass->image->name);
2702 /* We stop at the first method which is not in
2703 System.Reflection or which is not in a platform
2705 if (strcmp (m->klass->name_space, "System.Reflection") != 0 ||
2706 !mono_security_core_clr_is_platform_image (m->klass->image)) {
2707 /* If the method is transparent we throw an exception. */
2708 if (mono_security_core_clr_method_level (m, TRUE) == MONO_SECURITY_CORE_CLR_TRANSPARENT ) {
2709 MonoException *ex = mono_exception_from_name_msg (mono_defaults.corlib, "System", "MethodAccessException", "Reflection called from transparent code");
2711 mono_raise_exception (ex);
2716 mono_stack_walk_no_il (get_caller, &m);
2721 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoArray *params)
2724 * Invoke from reflection is supposed to always be a virtual call (the API
2725 * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
2726 * greater flexibility.
2728 MonoMethod *m = method->method;
2732 MONO_ARCH_SAVE_REGS;
2734 if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR &&
2735 mono_security_core_clr_method_level (m, TRUE) == MONO_SECURITY_CORE_CLR_CRITICAL)
2736 ensure_reflection_security ();
2738 if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
2740 if (!mono_object_isinst (this, m->klass))
2741 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
2742 m = mono_object_get_virtual_method (this, m);
2743 /* must pass the pointer to the value for valuetype methods */
2744 if (m->klass->valuetype)
2745 obj = mono_object_unbox (this);
2746 } else if (strcmp (m->name, ".ctor") && !m->wrapper_type)
2747 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
2750 pcount = params? mono_array_length (params): 0;
2751 if (pcount != mono_method_signature (m)->param_count)
2752 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
2754 if ((m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) && !strcmp (m->name, ".ctor") && !this)
2755 mono_raise_exception (mono_exception_from_name_msg (mono_defaults.corlib, "System", "MethodAccessException", "Cannot invoke constructor of an abstract class."));
2757 if (m->klass->image->assembly->ref_only)
2758 mono_raise_exception (mono_get_exception_invalid_operation ("It is illegal to invoke a method on a type loaded using the ReflectionOnly api."));
2760 if (m->klass->rank && !strcmp (m->name, ".ctor")) {
2763 guint32 *lower_bounds;
2764 pcount = mono_array_length (params);
2765 lengths = alloca (sizeof (guint32) * pcount);
2766 for (i = 0; i < pcount; ++i)
2767 lengths [i] = *(gint32*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
2769 if (m->klass->rank == pcount) {
2770 /* Only lengths provided. */
2771 lower_bounds = NULL;
2773 g_assert (pcount == (m->klass->rank * 2));
2774 /* lower bounds are first. */
2775 lower_bounds = lengths;
2776 lengths += m->klass->rank;
2779 return (MonoObject*)mono_array_new_full (mono_object_domain (params), m->klass, lengths, lower_bounds);
2781 return mono_runtime_invoke_array (m, obj, params, NULL);
2785 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this, MonoArray *params, MonoArray **outArgs)
2787 MonoDomain *domain = mono_object_domain (method);
2788 MonoMethod *m = method->method;
2789 MonoMethodSignature *sig = mono_method_signature (m);
2790 MonoArray *out_args;
2792 int i, j, outarg_count = 0;
2794 MONO_ARCH_SAVE_REGS;
2796 if (m->klass == mono_defaults.object_class) {
2798 if (!strcmp (m->name, "FieldGetter")) {
2799 MonoClass *k = this->vtable->klass;
2803 /* If this is a proxy, then it must be a CBO */
2804 if (k == mono_defaults.transparent_proxy_class) {
2805 MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
2806 this = tp->rp->unwrapped_server;
2808 k = this->vtable->klass;
2811 name = mono_array_get (params, MonoString *, 1);
2812 str = mono_string_to_utf8 (name);
2815 MonoClassField* field = mono_class_get_field_from_name (k, str);
2817 MonoClass *field_klass = mono_class_from_mono_type (field->type);
2818 if (field_klass->valuetype)
2819 result = mono_value_box (domain, field_klass, (char *)this + field->offset);
2821 result = *((gpointer *)((char *)this + field->offset));
2823 out_args = mono_array_new (domain, mono_defaults.object_class, 1);
2824 *outArgs = out_args;
2825 mono_array_setref (out_args, 0, result);
2833 g_assert_not_reached ();
2835 } else if (!strcmp (m->name, "FieldSetter")) {
2836 MonoClass *k = this->vtable->klass;
2842 /* If this is a proxy, then it must be a CBO */
2843 if (k == mono_defaults.transparent_proxy_class) {
2844 MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
2845 this = tp->rp->unwrapped_server;
2847 k = this->vtable->klass;
2850 name = mono_array_get (params, MonoString *, 1);
2851 str = mono_string_to_utf8 (name);
2854 MonoClassField* field = mono_class_get_field_from_name (k, str);
2856 MonoClass *field_klass = mono_class_from_mono_type (field->type);
2857 MonoObject *val = mono_array_get (params, gpointer, 2);
2859 if (field_klass->valuetype) {
2860 size = mono_type_size (field->type, &align);
2861 memcpy ((char *)this + field->offset,
2862 ((char *)val) + sizeof (MonoObject), size);
2864 *(MonoObject**)((char *)this + field->offset) = val;
2866 out_args = mono_array_new (domain, mono_defaults.object_class, 0);
2867 *outArgs = out_args;
2877 g_assert_not_reached ();
2882 for (i = 0; i < mono_array_length (params); i++) {
2883 if (sig->params [i]->byref)
2887 out_args = mono_array_new (domain, mono_defaults.object_class, outarg_count);
2889 /* handle constructors only for objects already allocated */
2890 if (!strcmp (method->method->name, ".ctor"))
2893 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
2894 g_assert (!method->method->klass->valuetype);
2895 result = mono_runtime_invoke_array (method->method, this, params, NULL);
2897 for (i = 0, j = 0; i < mono_array_length (params); i++) {
2898 if (sig->params [i]->byref) {
2900 arg = mono_array_get (params, gpointer, i);
2901 mono_array_setref (out_args, j, arg);
2906 *outArgs = out_args;
2912 read_enum_value (char *mem, int type)
2916 return *(guint8*)mem;
2918 return *(gint8*)mem;
2920 return *(guint16*)mem;
2922 return *(gint16*)mem;
2924 return *(guint32*)mem;
2926 return *(gint32*)mem;
2928 return *(guint64*)mem;
2930 return *(gint64*)mem;
2932 g_assert_not_reached ();
2938 write_enum_value (char *mem, int type, guint64 value)
2942 case MONO_TYPE_I1: {
2943 guint8 *p = (guint8*)mem;
2948 case MONO_TYPE_I2: {
2949 guint16 *p = (void*)mem;
2954 case MONO_TYPE_I4: {
2955 guint32 *p = (void*)mem;
2960 case MONO_TYPE_I8: {
2961 guint64 *p = (void*)mem;
2966 g_assert_not_reached ();
2972 ves_icall_System_Enum_ToObject (MonoReflectionType *type, MonoObject *obj)
2975 MonoClass *enumc, *objc;
2979 MONO_ARCH_SAVE_REGS;
2981 MONO_CHECK_ARG_NULL (type);
2982 MONO_CHECK_ARG_NULL (obj);
2984 domain = mono_object_domain (type);
2985 enumc = mono_class_from_mono_type (type->type);
2986 objc = obj->vtable->klass;
2988 if (!enumc->enumtype)
2989 mono_raise_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
2990 if (!((objc->enumtype) || (objc->byval_arg.type >= MONO_TYPE_I1 && objc->byval_arg.type <= MONO_TYPE_U8)))
2991 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."));
2993 res = mono_object_new (domain, enumc);
2994 val = read_enum_value ((char *)obj + sizeof (MonoObject), objc->enumtype? objc->enum_basetype->type: objc->byval_arg.type);
2995 write_enum_value ((char *)res + sizeof (MonoObject), enumc->enum_basetype->type, val);
3001 ves_icall_System_Enum_get_value (MonoObject *this)
3009 MONO_ARCH_SAVE_REGS;
3014 g_assert (this->vtable->klass->enumtype);
3016 enumc = mono_class_from_mono_type (this->vtable->klass->enum_basetype);
3017 res = mono_object_new (mono_object_domain (this), enumc);
3018 dst = (char *)res + sizeof (MonoObject);
3019 src = (char *)this + sizeof (MonoObject);
3020 size = mono_class_value_size (enumc, NULL);
3022 memcpy (dst, src, size);
3028 ves_icall_get_enum_info (MonoReflectionType *type, MonoEnumInfo *info)
3030 MonoDomain *domain = mono_object_domain (type);
3031 MonoClass *enumc = mono_class_from_mono_type (type->type);
3032 guint j = 0, nvalues, crow;
3034 MonoClassField *field;
3036 MONO_ARCH_SAVE_REGS;
3038 info->utype = mono_type_get_object (domain, enumc->enum_basetype);
3039 nvalues = mono_class_num_fields (enumc) ? mono_class_num_fields (enumc) - 1 : 0;
3040 info->names = mono_array_new (domain, mono_defaults.string_class, nvalues);
3041 info->values = mono_array_new (domain, enumc, nvalues);
3045 while ((field = mono_class_get_fields (enumc, &iter))) {
3049 if (strcmp ("value__", field->name) == 0)
3051 if (mono_field_is_deleted (field))
3053 mono_array_setref (info->names, j, mono_string_new (domain, field->name));
3056 crow = mono_metadata_get_constant_index (enumc->image, mono_class_get_field_token (field), crow + 1);
3057 field->def_type = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_TYPE);
3058 crow = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_VALUE);
3059 field->data = (gpointer)mono_metadata_blob_heap (enumc->image, crow);
3063 len = mono_metadata_decode_blob_size (p, &p);
3064 switch (enumc->enum_basetype->type) {
3067 mono_array_set (info->values, gchar, j, *p);
3069 case MONO_TYPE_CHAR:
3072 mono_array_set (info->values, gint16, j, read16 (p));
3076 mono_array_set (info->values, gint32, j, read32 (p));
3080 mono_array_set (info->values, gint64, j, read64 (p));
3083 g_error ("Implement type 0x%02x in get_enum_info", enumc->enum_basetype->type);
3090 BFLAGS_IgnoreCase = 1,
3091 BFLAGS_DeclaredOnly = 2,
3092 BFLAGS_Instance = 4,
3094 BFLAGS_Public = 0x10,
3095 BFLAGS_NonPublic = 0x20,
3096 BFLAGS_FlattenHierarchy = 0x40,
3097 BFLAGS_InvokeMethod = 0x100,
3098 BFLAGS_CreateInstance = 0x200,
3099 BFLAGS_GetField = 0x400,
3100 BFLAGS_SetField = 0x800,
3101 BFLAGS_GetProperty = 0x1000,
3102 BFLAGS_SetProperty = 0x2000,
3103 BFLAGS_ExactBinding = 0x10000,
3104 BFLAGS_SuppressChangeType = 0x20000,
3105 BFLAGS_OptionalParamBinding = 0x40000
3108 static MonoReflectionField *
3109 ves_icall_Type_GetField (MonoReflectionType *type, MonoString *name, guint32 bflags)
3112 MonoClass *startklass, *klass;
3114 MonoClassField *field;
3117 int (*compare_func) (const char *s1, const char *s2) = NULL;
3118 domain = ((MonoObject *)type)->vtable->domain;
3119 klass = startklass = mono_class_from_mono_type (type->type);
3121 MONO_ARCH_SAVE_REGS;
3124 mono_raise_exception (mono_get_exception_argument_null ("name"));
3125 if (type->type->byref)
3128 compare_func = (bflags & BFLAGS_IgnoreCase) ? g_strcasecmp : strcmp;
3131 if (klass->exception_type != MONO_EXCEPTION_NONE)
3132 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3135 while ((field = mono_class_get_fields (klass, &iter))) {
3138 if (field->type == NULL)
3140 if (mono_field_is_deleted (field))
3142 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3143 if (bflags & BFLAGS_Public)
3146 if (bflags & BFLAGS_NonPublic)
3152 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
3153 if (bflags & BFLAGS_Static)
3154 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3157 if (bflags & BFLAGS_Instance)
3164 utf8_name = mono_string_to_utf8 (name);
3166 if (compare_func (field->name, utf8_name)) {
3172 return mono_field_get_object (domain, klass, field);
3174 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3181 ves_icall_Type_GetFields_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3184 MonoClass *startklass, *klass, *refklass;
3189 MonoClassField *field;
3191 MONO_ARCH_SAVE_REGS;
3193 domain = ((MonoObject *)type)->vtable->domain;
3194 if (type->type->byref)
3195 return mono_array_new (domain, mono_defaults.field_info_class, 0);
3196 klass = startklass = mono_class_from_mono_type (type->type);
3197 refklass = mono_class_from_mono_type (reftype->type);
3201 res = mono_array_new (domain, mono_defaults.field_info_class, len);
3203 if (klass->exception_type != MONO_EXCEPTION_NONE)
3204 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3207 while ((field = mono_class_get_fields (klass, &iter))) {
3209 if (mono_field_is_deleted (field))
3211 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3212 if (bflags & BFLAGS_Public)
3215 if (bflags & BFLAGS_NonPublic) {
3216 /* Serialization currently depends on the old behavior.
3217 * if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE || startklass == klass)*/
3224 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
3225 if (bflags & BFLAGS_Static)
3226 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3229 if (bflags & BFLAGS_Instance)
3235 member = (MonoObject*)mono_field_get_object (domain, refklass, field);
3237 MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, len * 2);
3238 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3242 mono_array_setref (res, i, member);
3245 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3248 MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, i);
3249 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3252 * Better solution for the new GC.
3253 * res->max_length = i;
3260 ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
3263 MonoClass *startklass, *klass, *refklass;
3268 int i, len, match, nslots;
3269 guint32 method_slots_default [8];
3270 guint32 *method_slots;
3271 gchar *mname = NULL;
3272 int (*compare_func) (const char *s1, const char *s2) = NULL;
3274 MONO_ARCH_SAVE_REGS;
3276 domain = ((MonoObject *)type)->vtable->domain;
3277 if (type->type->byref)
3278 return mono_array_new (domain, mono_defaults.method_info_class, 0);
3279 klass = startklass = mono_class_from_mono_type (type->type);
3280 refklass = mono_class_from_mono_type (reftype->type);
3283 mname = mono_string_to_utf8 (name);
3284 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
3287 mono_class_setup_vtable (klass);
3289 if (is_generic_parameter (type->type))
3290 nslots = klass->parent->vtable_size;
3292 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : klass->vtable_size;
3293 if (nslots >= sizeof (method_slots_default) * 8) {
3294 method_slots = g_new0 (guint32, nslots / 32 + 1);
3296 method_slots = method_slots_default;
3297 memset (method_slots, 0, sizeof (method_slots_default));
3301 res = mono_array_new (domain, mono_defaults.method_info_class, len);
3303 mono_class_setup_vtable (klass);
3304 if (klass->exception_type != MONO_EXCEPTION_NONE)
3305 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3308 while ((method = mono_class_get_methods (klass, &iter))) {
3310 if (method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
3312 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3313 if (bflags & BFLAGS_Public)
3316 if (bflags & BFLAGS_NonPublic)
3322 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3323 if (bflags & BFLAGS_Static)
3324 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3327 if (bflags & BFLAGS_Instance)
3335 if (compare_func (mname, method->name))
3340 if (method->slot != -1) {
3341 g_assert (method->slot < nslots);
3342 if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
3344 method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
3347 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
3350 MonoArray *new_res = mono_array_new (domain, mono_defaults.method_info_class, len * 2);
3351 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3355 mono_array_setref (res, i, member);
3358 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3362 if (method_slots != method_slots_default)
3363 g_free (method_slots);
3365 MonoArray *new_res = mono_array_new (domain, mono_defaults.method_info_class, i);
3366 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3369 * Better solution for the new GC.
3370 * res->max_length = i;
3377 ves_icall_Type_GetConstructors_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3380 static MonoClass *System_Reflection_ConstructorInfo;
3381 MonoClass *startklass, *klass, *refklass;
3386 gpointer iter = NULL;
3388 MONO_ARCH_SAVE_REGS;
3390 domain = ((MonoObject *)type)->vtable->domain;
3391 if (type->type->byref)
3392 return mono_array_new (domain, mono_defaults.method_info_class, 0);
3393 klass = startklass = mono_class_from_mono_type (type->type);
3394 refklass = mono_class_from_mono_type (reftype->type);
3396 if (klass->exception_type != MONO_EXCEPTION_NONE)
3397 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3399 if (!System_Reflection_ConstructorInfo)
3400 System_Reflection_ConstructorInfo = mono_class_from_name (
3401 mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
3405 res = mono_array_new (domain, System_Reflection_ConstructorInfo, len);
3407 while ((method = mono_class_get_methods (klass, &iter))) {
3409 if (strcmp (method->name, ".ctor") && strcmp (method->name, ".cctor"))
3411 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3412 if (bflags & BFLAGS_Public)
3415 if (bflags & BFLAGS_NonPublic)
3421 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3422 if (bflags & BFLAGS_Static)
3423 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3426 if (bflags & BFLAGS_Instance)
3432 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
3435 MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, len * 2);
3436 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3440 mono_array_setref (res, i, member);
3444 MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, i);
3445 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3448 * Better solution for the new GC.
3449 * res->max_length = i;
3456 ves_icall_Type_GetPropertiesByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
3459 static MonoClass *System_Reflection_PropertyInfo;
3460 MonoClass *startklass, *klass;
3464 int i, match, nslots;
3467 guint32 method_slots_default [8];
3468 guint32 *method_slots;
3469 gchar *propname = NULL;
3470 int (*compare_func) (const char *s1, const char *s2) = NULL;
3473 MONO_ARCH_SAVE_REGS;
3475 if (!System_Reflection_PropertyInfo)
3476 System_Reflection_PropertyInfo = mono_class_from_name (
3477 mono_defaults.corlib, "System.Reflection", "PropertyInfo");
3479 domain = ((MonoObject *)type)->vtable->domain;
3480 if (type->type->byref)
3481 return mono_array_new (domain, System_Reflection_PropertyInfo, 0);
3482 klass = startklass = mono_class_from_mono_type (type->type);
3484 propname = mono_string_to_utf8 (name);
3485 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
3488 mono_class_setup_vtable (klass);
3490 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : klass->vtable_size;
3491 if (nslots >= sizeof (method_slots_default) * 8) {
3492 method_slots = g_new0 (guint32, nslots / 32 + 1);
3494 method_slots = method_slots_default;
3495 memset (method_slots, 0, sizeof (method_slots_default));
3499 res = mono_array_new (domain, System_Reflection_PropertyInfo, len);
3501 mono_class_setup_vtable (klass);
3502 if (klass->exception_type != MONO_EXCEPTION_NONE) {
3503 if (method_slots != method_slots_default)
3504 g_free (method_slots);
3507 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3511 while ((prop = mono_class_get_properties (klass, &iter))) {
3517 flags = method->flags;
3520 if ((prop->get && ((prop->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC)) ||
3521 (prop->set && ((prop->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC))) {
3522 if (bflags & BFLAGS_Public)
3525 if (bflags & BFLAGS_NonPublic)
3531 if (flags & METHOD_ATTRIBUTE_STATIC) {
3532 if (bflags & BFLAGS_Static)
3533 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3536 if (bflags & BFLAGS_Instance)
3545 if (compare_func (propname, prop->name))
3549 if (prop->get && prop->get->slot != -1) {
3550 if (method_slots [prop->get->slot >> 5] & (1 << (prop->get->slot & 0x1f)))
3552 method_slots [prop->get->slot >> 5] |= 1 << (prop->get->slot & 0x1f);
3554 if (prop->set && prop->set->slot != -1) {
3555 if (method_slots [prop->set->slot >> 5] & (1 << (prop->set->slot & 0x1f)))
3557 method_slots [prop->set->slot >> 5] |= 1 << (prop->set->slot & 0x1f);
3561 MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, len * 2);
3562 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3566 mono_array_setref (res, i, mono_property_get_object (domain, startklass, prop));
3569 if ((!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent)))
3573 if (method_slots != method_slots_default)
3574 g_free (method_slots);
3576 MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, i);
3577 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3580 * Better solution for the new GC.
3581 * res->max_length = i;
3587 static MonoReflectionEvent *
3588 ves_icall_MonoType_GetEvent (MonoReflectionType *type, MonoString *name, guint32 bflags)
3591 MonoClass *klass, *startklass;
3597 MONO_ARCH_SAVE_REGS;
3599 event_name = mono_string_to_utf8 (name);
3600 if (type->type->byref)
3602 klass = startklass = mono_class_from_mono_type (type->type);
3603 domain = mono_object_domain (type);
3606 if (klass->exception_type != MONO_EXCEPTION_NONE)
3607 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3610 while ((event = mono_class_get_events (klass, &iter))) {
3611 if (strcmp (event->name, event_name))
3614 method = event->add;
3616 method = event->remove;
3618 method = event->raise;
3620 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3621 if (!(bflags & BFLAGS_Public))
3624 if (!(bflags & BFLAGS_NonPublic))
3629 if (!(bflags & BFLAGS_NonPublic))
3632 g_free (event_name);
3633 return mono_event_get_object (domain, startklass, event);
3636 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3639 g_free (event_name);
3644 ves_icall_Type_GetEvents_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3647 static MonoClass *System_Reflection_EventInfo;
3648 MonoClass *startklass, *klass;
3655 MONO_ARCH_SAVE_REGS;
3657 if (!System_Reflection_EventInfo)
3658 System_Reflection_EventInfo = mono_class_from_name (
3659 mono_defaults.corlib, "System.Reflection", "EventInfo");
3661 domain = mono_object_domain (type);
3662 if (type->type->byref)
3663 return mono_array_new (domain, System_Reflection_EventInfo, 0);
3664 klass = startklass = mono_class_from_mono_type (type->type);
3668 res = mono_array_new (domain, System_Reflection_EventInfo, len);
3670 if (klass->exception_type != MONO_EXCEPTION_NONE)
3671 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3674 while ((event = mono_class_get_events (klass, &iter))) {
3676 method = event->add;
3678 method = event->remove;
3680 method = event->raise;
3682 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3683 if (bflags & BFLAGS_Public)
3686 if (bflags & BFLAGS_NonPublic)
3691 if (bflags & BFLAGS_NonPublic)
3697 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3698 if (bflags & BFLAGS_Static)
3699 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3702 if (bflags & BFLAGS_Instance)
3707 if (bflags & BFLAGS_Instance)
3713 MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, len * 2);
3714 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3718 mono_array_setref (res, i, mono_event_get_object (domain, startklass, event));
3721 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3724 MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, i);
3725 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3728 * Better solution for the new GC.
3729 * res->max_length = i;
3735 static MonoReflectionType *
3736 ves_icall_Type_GetNestedType (MonoReflectionType *type, MonoString *name, guint32 bflags)
3744 MONO_ARCH_SAVE_REGS;
3746 domain = ((MonoObject *)type)->vtable->domain;
3747 if (type->type->byref)
3749 klass = mono_class_from_mono_type (type->type);
3750 str = mono_string_to_utf8 (name);
3753 if (klass->exception_type != MONO_EXCEPTION_NONE)
3754 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3757 * If a nested type is generic, return its generic type definition.
3758 * Note that this means that the return value is essentially a
3759 * nested type of the generic type definition of @klass.
3761 * A note in MSDN claims that a generic type definition can have
3762 * nested types that aren't generic. In any case, the container of that
3763 * nested type would be the generic type definition.
3765 if (klass->generic_class)
3766 klass = klass->generic_class->container_class;
3768 for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
3770 nested = tmpn->data;
3771 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
3772 if (bflags & BFLAGS_Public)
3775 if (bflags & BFLAGS_NonPublic)
3780 if (strcmp (nested->name, str) == 0){
3782 return mono_type_get_object (domain, &nested->byval_arg);
3785 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3792 ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags)
3802 MONO_ARCH_SAVE_REGS;
3804 domain = ((MonoObject *)type)->vtable->domain;
3805 if (type->type->byref)
3806 return mono_array_new (domain, mono_defaults.monotype_class, 0);
3807 klass = mono_class_from_mono_type (type->type);
3808 if (klass->exception_type != MONO_EXCEPTION_NONE)
3809 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3812 * If a nested type is generic, return its generic type definition.
3813 * Note that this means that the return value is essentially the set
3814 * of nested types of the generic type definition of @klass.
3816 * A note in MSDN claims that a generic type definition can have
3817 * nested types that aren't generic. In any case, the container of that
3818 * nested type would be the generic type definition.
3820 if (klass->generic_class)
3821 klass = klass->generic_class->container_class;
3825 res = mono_array_new (domain, mono_defaults.monotype_class, len);
3826 for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
3828 nested = tmpn->data;
3829 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
3830 if (bflags & BFLAGS_Public)
3833 if (bflags & BFLAGS_NonPublic)
3838 member = (MonoObject*)mono_type_get_object (domain, &nested->byval_arg);
3840 MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, len * 2);
3841 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3845 mono_array_setref (res, i, member);
3849 MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, i);
3850 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3853 * Better solution for the new GC.
3854 * res->max_length = i;
3860 static MonoReflectionType*
3861 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *assembly, MonoReflectionModule *module, MonoString *name, MonoBoolean throwOnError, MonoBoolean ignoreCase)
3864 MonoType *type = NULL;
3865 MonoTypeNameParse info;
3866 gboolean type_resolve;
3868 MONO_ARCH_SAVE_REGS;
3870 /* On MS.NET, this does not fire a TypeResolve event */
3871 type_resolve = TRUE;
3872 str = mono_string_to_utf8 (name);
3873 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
3874 if (!mono_reflection_parse_type (str, &info)) {
3876 mono_reflection_free_type_info (&info);
3877 if (throwOnError) /* uhm: this is a parse error, though... */
3878 mono_raise_exception (mono_get_exception_type_load (name, NULL));
3879 /*g_print ("failed parse\n");*/
3883 if (module != NULL) {
3885 type = mono_reflection_get_type (module->image, &info, ignoreCase, &type_resolve);
3890 if (assembly->assembly->dynamic) {
3891 /* Enumerate all modules */
3892 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
3896 if (abuilder->modules) {
3897 for (i = 0; i < mono_array_length (abuilder->modules); ++i) {
3898 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
3899 type = mono_reflection_get_type (&mb->dynamic_image->image, &info, ignoreCase, &type_resolve);
3905 if (!type && abuilder->loaded_modules) {
3906 for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) {
3907 MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
3908 type = mono_reflection_get_type (mod->image, &info, ignoreCase, &type_resolve);
3915 type = mono_reflection_get_type (assembly->assembly->image, &info, ignoreCase, &type_resolve);
3917 mono_reflection_free_type_info (&info);
3919 MonoException *e = NULL;
3922 e = mono_get_exception_type_load (name, NULL);
3924 mono_loader_clear_error ();
3927 mono_raise_exception (e);
3932 if (type->type == MONO_TYPE_CLASS) {
3933 MonoClass *klass = mono_type_get_class (type);
3934 /* need to report exceptions ? */
3935 if (throwOnError && klass->exception_type) {
3936 /* report SecurityException (or others) that occured when loading the assembly */
3937 MonoException *exc = mono_class_get_exception_for_failure (klass);
3938 mono_loader_clear_error ();
3939 mono_raise_exception (exc);
3940 } else if (klass->exception_type == MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND) {
3945 /* g_print ("got it\n"); */
3946 return mono_type_get_object (mono_object_domain (assembly), type);
3950 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *assembly, MonoBoolean escaped)
3952 MonoDomain *domain = mono_object_domain (assembly);
3953 MonoAssembly *mass = assembly->assembly;
3954 MonoString *res = NULL;
3958 MONO_ARCH_SAVE_REGS;
3960 if (g_path_is_absolute (mass->image->name))
3961 absolute = g_strdup (mass->image->name);
3963 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
3967 for (i = strlen (absolute) - 1; i >= 0; i--)
3968 if (absolute [i] == '\\')
3973 uri = g_filename_to_uri (absolute, NULL, NULL);
3975 uri = g_strconcat ("file://", absolute, NULL);
3979 res = mono_string_new (domain, uri);
3987 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssembly *assembly)
3989 MonoAssembly *mass = assembly->assembly;
3991 MONO_ARCH_SAVE_REGS;
3993 return mass->in_gac;
3996 static MonoReflectionAssembly*
3997 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoString *mname, MonoObject *evidence)
4001 MonoImageOpenStatus status;
4003 MONO_ARCH_SAVE_REGS;
4005 name = mono_string_to_utf8 (mname);
4006 res = mono_assembly_load_with_partial_name (name, &status);
4012 return mono_assembly_get_object (mono_domain_get (), res);
4016 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssembly *assembly)
4018 MonoDomain *domain = mono_object_domain (assembly);
4021 MONO_ARCH_SAVE_REGS;
4023 res = mono_string_new (domain, mono_image_get_filename (assembly->assembly->image));
4029 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssembly *assembly)
4031 MONO_ARCH_SAVE_REGS;
4033 return assembly->assembly->ref_only;
4037 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssembly *assembly)
4039 MonoDomain *domain = mono_object_domain (assembly);
4041 MONO_ARCH_SAVE_REGS;
4043 return mono_string_new (domain, assembly->assembly->image->version);
4046 static MonoReflectionMethod*
4047 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssembly *assembly)
4049 guint32 token = mono_image_get_entry_point (assembly->assembly->image);
4051 MONO_ARCH_SAVE_REGS;
4055 return mono_method_get_object (mono_object_domain (assembly), mono_get_method (assembly->assembly->image, token, NULL), NULL);
4058 static MonoReflectionModule*
4059 ves_icall_System_Reflection_Assembly_GetManifestModuleInternal (MonoReflectionAssembly *assembly)
4061 return mono_module_get_object (mono_object_domain (assembly), assembly->assembly->image);
4065 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssembly *assembly)
4067 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4068 MonoArray *result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, table->rows);
4072 MONO_ARCH_SAVE_REGS;
4074 for (i = 0; i < table->rows; ++i) {
4075 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_MANIFEST_NAME));
4076 mono_array_setref (result, i, mono_string_new (mono_object_domain (assembly), val));
4082 create_version (MonoDomain *domain, guint32 major, guint32 minor, guint32 build, guint32 revision)
4084 static MonoClass *System_Version = NULL;
4085 static MonoMethod *create_version = NULL;
4089 if (!System_Version) {
4090 System_Version = mono_class_from_name (mono_defaults.corlib, "System", "Version");
4091 g_assert (System_Version);
4094 if (!create_version) {
4095 MonoMethodDesc *desc = mono_method_desc_new (":.ctor(int,int,int,int)", FALSE);
4096 create_version = mono_method_desc_search_in_class (desc, System_Version);
4097 g_assert (create_version);
4098 mono_method_desc_free (desc);
4104 args [3] = &revision;
4105 result = mono_object_new (domain, System_Version);
4106 mono_runtime_invoke (create_version, result, args, NULL);
4112 ves_icall_System_Reflection_Assembly_GetReferencedAssemblies (MonoReflectionAssembly *assembly)
4114 static MonoClass *System_Reflection_AssemblyName;
4116 MonoDomain *domain = mono_object_domain (assembly);
4118 static MonoMethod *create_culture = NULL;
4119 MonoImage *image = assembly->assembly->image;
4122 MONO_ARCH_SAVE_REGS;
4124 if (!System_Reflection_AssemblyName)
4125 System_Reflection_AssemblyName = mono_class_from_name (
4126 mono_defaults.corlib, "System.Reflection", "AssemblyName");
4128 t = &assembly->assembly->image->tables [MONO_TABLE_ASSEMBLYREF];
4131 result = mono_array_new (domain, System_Reflection_AssemblyName, count);
4134 MonoMethodDesc *desc = mono_method_desc_new (
4135 "System.Globalization.CultureInfo:CreateSpecificCulture(string)", TRUE);
4136 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4137 g_assert (create_culture);
4138 mono_method_desc_free (desc);
4141 for (i = 0; i < count; i++) {
4142 MonoReflectionAssemblyName *aname;
4143 guint32 cols [MONO_ASSEMBLYREF_SIZE];
4145 mono_metadata_decode_row (t, i, cols, MONO_ASSEMBLYREF_SIZE);
4147 aname = (MonoReflectionAssemblyName *) mono_object_new (
4148 domain, System_Reflection_AssemblyName);
4150 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_NAME])));
4152 aname->major = cols [MONO_ASSEMBLYREF_MAJOR_VERSION];
4153 aname->minor = cols [MONO_ASSEMBLYREF_MINOR_VERSION];
4154 aname->build = cols [MONO_ASSEMBLYREF_BUILD_NUMBER];
4155 aname->revision = cols [MONO_ASSEMBLYREF_REV_NUMBER];
4156 aname->flags = cols [MONO_ASSEMBLYREF_FLAGS];
4157 aname->versioncompat = 1; /* SameMachine (default) */
4158 aname->hashalg = ASSEMBLY_HASH_SHA1; /* SHA1 (default) */
4159 MONO_OBJECT_SETREF (aname, version, create_version (domain, aname->major, aname->minor, aname->build, aname->revision));
4161 if (create_culture) {
4163 args [0] = mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_CULTURE]));
4164 MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
4167 if (cols [MONO_ASSEMBLYREF_PUBLIC_KEY]) {
4168 const gchar *pkey_ptr = mono_metadata_blob_heap (image, cols [MONO_ASSEMBLYREF_PUBLIC_KEY]);
4169 guint32 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
4171 if ((cols [MONO_ASSEMBLYREF_FLAGS] & ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG)) {
4172 /* public key token isn't copied - the class library will
4173 automatically generate it from the public key if required */
4174 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4175 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
4177 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4178 memcpy (mono_array_addr (aname->keyToken, guint8, 0), pkey_ptr, pkey_len);
4182 /* note: this function doesn't return the codebase on purpose (i.e. it can
4183 be used under partial trust as path information isn't present). */
4185 mono_array_setref (result, i, aname);
4196 foreach_namespace (const char* key, gconstpointer val, NameSpaceInfo *info)
4198 MonoString *name = mono_string_new (mono_object_domain (info->res), key);
4200 mono_array_setref (info->res, info->idx, name);
4205 ves_icall_System_Reflection_Assembly_GetNamespaces (MonoReflectionAssembly *assembly)
4207 MonoImage *img = assembly->assembly->image;
4211 MONO_ARCH_SAVE_REGS;
4213 if (!img->name_cache)
4214 mono_image_init_name_cache (img);
4216 res = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, g_hash_table_size (img->name_cache));
4219 g_hash_table_foreach (img->name_cache, (GHFunc)foreach_namespace, &info);
4224 /* move this in some file in mono/util/ */
4226 g_concat_dir_and_file (const char *dir, const char *file)
4228 g_return_val_if_fail (dir != NULL, NULL);
4229 g_return_val_if_fail (file != NULL, NULL);
4232 * If the directory name doesn't have a / on the end, we need
4233 * to add one so we get a proper path to the file
4235 if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
4236 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
4238 return g_strconcat (dir, file, NULL);
4242 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssembly *assembly, MonoString *name, gint32 *size, MonoReflectionModule **ref_module)
4244 char *n = mono_string_to_utf8 (name);
4245 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4247 guint32 cols [MONO_MANIFEST_SIZE];
4248 guint32 impl, file_idx;
4252 MONO_ARCH_SAVE_REGS;
4254 for (i = 0; i < table->rows; ++i) {
4255 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4256 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4257 if (strcmp (val, n) == 0)
4261 if (i == table->rows)
4264 impl = cols [MONO_MANIFEST_IMPLEMENTATION];
4267 * this code should only be called after obtaining the
4268 * ResourceInfo and handling the other cases.
4270 g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
4271 file_idx = impl >> MONO_IMPLEMENTATION_BITS;
4273 module = mono_image_load_file_for_image (assembly->assembly->image, file_idx);
4278 module = assembly->assembly->image;
4280 *ref_module = mono_module_get_object (mono_domain_get (), module);
4282 return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
4286 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoManifestResourceInfo *info)
4288 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4290 guint32 cols [MONO_MANIFEST_SIZE];
4291 guint32 file_cols [MONO_FILE_SIZE];
4295 MONO_ARCH_SAVE_REGS;
4297 n = mono_string_to_utf8 (name);
4298 for (i = 0; i < table->rows; ++i) {
4299 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4300 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4301 if (strcmp (val, n) == 0)
4305 if (i == table->rows)
4308 if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
4309 info->location = RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST;
4312 switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
4313 case MONO_IMPLEMENTATION_FILE:
4314 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4315 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4316 mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
4317 val = mono_metadata_string_heap (assembly->assembly->image, file_cols [MONO_FILE_NAME]);
4318 MONO_OBJECT_SETREF (info, filename, mono_string_new (mono_object_domain (assembly), val));
4319 if (file_cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA)
4322 info->location = RESOURCE_LOCATION_EMBEDDED;
4325 case MONO_IMPLEMENTATION_ASSEMBLYREF:
4326 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4327 mono_assembly_load_reference (assembly->assembly->image, i - 1);
4328 if (assembly->assembly->image->references [i - 1] == (gpointer)-1) {
4329 char *msg = g_strdup_printf ("Assembly %d referenced from assembly %s not found ", i - 1, assembly->assembly->image->name);
4330 MonoException *ex = mono_get_exception_file_not_found2 (msg, NULL);
4332 mono_raise_exception (ex);
4334 MONO_OBJECT_SETREF (info, assembly, mono_assembly_get_object (mono_domain_get (), assembly->assembly->image->references [i - 1]));
4336 /* Obtain info recursively */
4337 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (info->assembly, name, info);
4338 info->location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
4341 case MONO_IMPLEMENTATION_EXP_TYPE:
4342 g_assert_not_reached ();
4351 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoBoolean resource_modules)
4353 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4354 MonoArray *result = NULL;
4359 MONO_ARCH_SAVE_REGS;
4361 /* check hash if needed */
4363 n = mono_string_to_utf8 (name);
4364 for (i = 0; i < table->rows; ++i) {
4365 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4366 if (strcmp (val, n) == 0) {
4369 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4370 fn = mono_string_new (mono_object_domain (assembly), n);
4372 return (MonoObject*)fn;
4380 for (i = 0; i < table->rows; ++i) {
4381 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA))
4385 result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, count);
4388 for (i = 0; i < table->rows; ++i) {
4389 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4390 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4391 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4392 mono_array_setref (result, count, mono_string_new (mono_object_domain (assembly), n));
4397 return (MonoObject*)result;
4401 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly *assembly)
4403 MonoDomain *domain = mono_domain_get();
4406 int i, j, file_count = 0;
4407 MonoImage **modules;
4408 guint32 module_count, real_module_count;
4409 MonoTableInfo *table;
4411 g_assert (assembly->assembly->image != NULL);
4413 if (assembly->assembly->dynamic) {
4414 MonoReflectionAssemblyBuilder *assemblyb = (MonoReflectionAssemblyBuilder*)assembly;
4416 if (assemblyb->modules)
4417 module_count = mono_array_length (assemblyb->modules);
4420 real_module_count = module_count;
4422 modules = g_new0 (MonoImage*, module_count);
4423 if (assemblyb->modules) {
4424 for (i = 0; i < mono_array_length (assemblyb->modules); ++i) {
4426 mono_array_get (assemblyb->modules, MonoReflectionModuleBuilder*, i)->module.image;
4431 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4432 file_count = table->rows;
4434 modules = assembly->assembly->image->modules;
4435 module_count = assembly->assembly->image->module_count;
4437 real_module_count = 0;
4438 for (i = 0; i < module_count; ++i)
4440 real_module_count ++;
4443 klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "Module");
4444 res = mono_array_new (domain, klass, 1 + real_module_count + file_count);
4446 mono_array_setref (res, 0, mono_module_get_object (domain, assembly->assembly->image));
4448 for (i = 0; i < module_count; ++i)
4450 mono_array_setref (res, j, mono_module_get_object (domain, modules[i]));
4454 for (i = 0; i < file_count; ++i, ++j)
4455 mono_array_setref (res, j, mono_module_file_get_object (domain, assembly->assembly->image, i));
4457 if (assembly->assembly->dynamic)
4463 static MonoReflectionMethod*
4464 ves_icall_GetCurrentMethod (void)
4466 MonoMethod *m = mono_method_get_last_managed ();
4468 MONO_ARCH_SAVE_REGS;
4470 return mono_method_get_object (mono_domain_get (), m, NULL);
4473 static MonoReflectionMethod*
4474 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType (MonoMethod *method, MonoType *type)
4476 /* FIXME check that method belongs to klass or a parent */
4479 klass = mono_class_from_mono_type (type);
4481 klass = method->klass;
4482 return mono_method_get_object (mono_domain_get (), method, klass);
4485 static MonoReflectionMethod*
4486 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternal (MonoMethod *method)
4488 return mono_method_get_object (mono_domain_get (), method, NULL);
4491 static MonoReflectionMethodBody*
4492 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod *method)
4494 return mono_method_body_get_object (mono_domain_get (), method);
4497 static MonoReflectionAssembly*
4498 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (void)
4500 MonoMethod *m = mono_method_get_last_managed ();
4502 MONO_ARCH_SAVE_REGS;
4504 return mono_assembly_get_object (mono_domain_get (), m->klass->image->assembly);
4508 static MonoReflectionAssembly*
4509 ves_icall_System_Reflection_Assembly_GetEntryAssembly (void)
4511 MonoDomain* domain = mono_domain_get ();
4513 MONO_ARCH_SAVE_REGS;
4515 if (!domain->entry_assembly)
4518 return mono_assembly_get_object (domain, domain->entry_assembly);
4521 static MonoReflectionAssembly*
4522 ves_icall_System_Reflection_Assembly_GetCallingAssembly (void)
4524 MonoMethod *m = mono_method_get_last_managed ();
4525 MonoMethod *dest = m;
4527 MONO_ARCH_SAVE_REGS;
4529 mono_stack_walk_no_il (get_caller, &dest);
4532 return mono_assembly_get_object (mono_domain_get (), dest->klass->image->assembly);
4536 ves_icall_System_MonoType_getFullName (MonoReflectionType *object, gboolean full_name,
4537 gboolean assembly_qualified)
4539 MonoDomain *domain = mono_object_domain (object);
4540 MonoTypeNameFormat format;
4544 MONO_ARCH_SAVE_REGS;
4546 format = assembly_qualified ?
4547 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
4548 MONO_TYPE_NAME_FORMAT_FULL_NAME;
4550 format = MONO_TYPE_NAME_FORMAT_REFLECTION;
4552 name = mono_type_get_name_full (object->type, format);
4556 if (full_name && (object->type->type == MONO_TYPE_VAR || object->type->type == MONO_TYPE_MVAR)) {
4561 res = mono_string_new (domain, name);
4568 fill_reflection_assembly_name (MonoDomain *domain, MonoReflectionAssemblyName *aname, MonoAssemblyName *name, const char *absolute, gboolean by_default_version)
4570 static MonoMethod *create_culture = NULL;
4573 const char *pkey_ptr;
4576 MONO_ARCH_SAVE_REGS;
4578 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, name->name));
4579 aname->major = name->major;
4580 aname->minor = name->minor;
4581 aname->build = name->build;
4582 aname->revision = name->revision;
4583 aname->hashalg = name->hash_alg;
4584 if (by_default_version)
4585 MONO_OBJECT_SETREF (aname, version, create_version (domain, name->major, name->minor, name->build, name->revision));
4587 codebase = g_filename_to_uri (absolute, NULL, NULL);
4589 MONO_OBJECT_SETREF (aname, codebase, mono_string_new (domain, codebase));
4593 if (!create_culture) {
4594 MonoMethodDesc *desc = mono_method_desc_new ("System.Globalization.CultureInfo:CreateSpecificCulture(string)", TRUE);
4595 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4596 g_assert (create_culture);
4597 mono_method_desc_free (desc);
4600 if (name->culture) {
4601 args [0] = mono_string_new (domain, name->culture);
4602 MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
4605 if (name->public_key) {
4606 pkey_ptr = (char*)name->public_key;
4607 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
4609 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4610 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
4613 /* MonoAssemblyName keeps the public key token as an hexadecimal string */
4614 if (name->public_key_token [0]) {
4618 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, 8));
4619 p = mono_array_addr (aname->keyToken, char, 0);
4621 for (i = 0, j = 0; i < 8; i++) {
4622 *p = g_ascii_xdigit_value (name->public_key_token [j++]) << 4;
4623 *p |= g_ascii_xdigit_value (name->public_key_token [j++]);
4630 ves_icall_System_Reflection_Assembly_FillName (MonoReflectionAssembly *assembly, MonoReflectionAssemblyName *aname)
4633 MonoAssembly *mass = assembly->assembly;
4635 MONO_ARCH_SAVE_REGS;
4637 if (g_path_is_absolute (mass->image->name)) {
4638 fill_reflection_assembly_name (mono_object_domain (assembly),
4639 aname, &mass->aname, mass->image->name, TRUE);
4642 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4644 fill_reflection_assembly_name (mono_object_domain (assembly),
4645 aname, &mass->aname, absolute, TRUE);
4651 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoString *fname, MonoReflectionAssemblyName *aname)
4654 MonoImageOpenStatus status = MONO_IMAGE_OK;
4657 MonoAssemblyName name;
4659 MONO_ARCH_SAVE_REGS;
4661 filename = mono_string_to_utf8 (fname);
4663 image = mono_image_open (filename, &status);
4669 if (status == MONO_IMAGE_IMAGE_INVALID)
4670 exc = mono_get_exception_bad_image_format2 (NULL, fname);
4672 exc = mono_get_exception_file_not_found2 (NULL, fname);
4673 mono_raise_exception (exc);
4676 res = mono_assembly_fill_assembly_name (image, &name);
4678 mono_image_close (image);
4680 mono_raise_exception (mono_get_exception_argument ("assemblyFile", "The file does not contain a manifest"));
4683 fill_reflection_assembly_name (mono_domain_get (), aname, &name, filename, TRUE);
4686 mono_image_close (image);
4690 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssembly *assembly,
4691 char **minimum, guint32 *minLength, char **optional, guint32 *optLength, char **refused, guint32 *refLength)
4693 MonoBoolean result = FALSE;
4694 MonoDeclSecurityEntry entry;
4696 /* SecurityAction.RequestMinimum */
4697 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQMIN, &entry)) {
4698 *minimum = entry.blob;
4699 *minLength = entry.size;
4702 /* SecurityAction.RequestOptional */
4703 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQOPT, &entry)) {
4704 *optional = entry.blob;
4705 *optLength = entry.size;
4708 /* SecurityAction.RequestRefuse */
4709 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQREFUSE, &entry)) {
4710 *refused = entry.blob;
4711 *refLength = entry.size;
4719 mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoBoolean exportedOnly)
4723 MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
4725 guint32 attrs, visibility;
4727 /* we start the count from 1 because we skip the special type <Module> */
4730 for (i = 1; i < tdef->rows; ++i) {
4731 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
4732 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
4733 if (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)
4737 count = tdef->rows - 1;
4739 res = mono_array_new (domain, mono_defaults.monotype_class, count);
4741 for (i = 1; i < tdef->rows; ++i) {
4742 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
4743 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
4744 if (!exportedOnly || (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)) {
4745 klass = mono_class_get_throw (image, (i + 1) | MONO_TOKEN_TYPE_DEF);
4746 if (mono_loader_get_last_error ())
4747 mono_loader_clear_error ();
4748 mono_array_setref (res, count, mono_type_get_object (domain, &klass->byval_arg));
4757 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly, MonoBoolean exportedOnly)
4759 MonoArray *res = NULL;
4760 MonoImage *image = NULL;
4761 MonoTableInfo *table = NULL;
4766 MONO_ARCH_SAVE_REGS;
4768 domain = mono_object_domain (assembly);
4770 if (assembly->assembly->dynamic) {
4771 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
4772 if (abuilder->modules) {
4773 for (i = 0; i < mono_array_length(abuilder->modules); i++) {
4774 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
4775 MonoArray *append = mb->types;
4776 /* The types array might not be fully filled up */
4777 if (append && mb->num_types > 0) {
4780 len1 = res ? mono_array_length (res) : 0;
4781 len2 = mb->num_types;
4782 new = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4784 mono_array_memcpy_refs (new, 0, res, 0, len1);
4785 mono_array_memcpy_refs (new, len1, append, 0, len2);
4791 * Replace TypeBuilders with the created types to be compatible
4795 for (i = 0; i < mono_array_length (res); ++i) {
4796 MonoReflectionTypeBuilder *tb = mono_array_get (res, MonoReflectionTypeBuilder*, i);
4798 mono_array_setref (res, i, tb->created);
4803 if (abuilder->loaded_modules)
4804 for (i = 0; i < mono_array_length(abuilder->loaded_modules); i++) {
4805 MonoReflectionModule *rm = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
4806 MonoArray *append = mono_module_get_types (domain, rm->image, exportedOnly);
4807 if (append && mono_array_length (append) > 0) {
4810 len1 = res ? mono_array_length (res) : 0;
4811 len2 = mono_array_length (append);
4812 new = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4814 mono_array_memcpy_refs (new, 0, res, 0, len1);
4815 mono_array_memcpy_refs (new, len1, append, 0, len2);
4822 return mono_array_new (domain, mono_defaults.monotype_class, 0);
4824 image = assembly->assembly->image;
4825 table = &image->tables [MONO_TABLE_FILE];
4826 res = mono_module_get_types (domain, image, exportedOnly);
4828 /* Append data from all modules in the assembly */
4829 for (i = 0; i < table->rows; ++i) {
4830 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4831 MonoImage *loaded_image = mono_assembly_load_module (image->assembly, i + 1);
4833 MonoArray *res2 = mono_module_get_types (domain, loaded_image, exportedOnly);
4834 /* Append the new types to the end of the array */
4835 if (mono_array_length (res2) > 0) {
4839 len1 = mono_array_length (res);
4840 len2 = mono_array_length (res2);
4841 res3 = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4842 mono_array_memcpy_refs (res3, 0, res, 0, len1);
4843 mono_array_memcpy_refs (res3, len1, res2, 0, len2);
4850 /* the ReflectionTypeLoadException must have all the types (Types property),
4851 * NULL replacing types which throws an exception. The LoaderException must
4852 * contain all exceptions for NULL items.
4855 len = mono_array_length (res);
4857 for (i = 0; i < len; i++) {
4858 MonoReflectionType *t = mono_array_get (res, gpointer, i);
4859 MonoClass *klass = mono_type_get_class (t->type);
4860 if ((klass != NULL) && klass->exception_type) {
4861 /* keep the class in the list */
4862 list = g_list_append (list, klass);
4863 /* and replace Type with NULL */
4864 mono_array_setref (res, i, NULL);
4870 MonoException *exc = NULL;
4871 MonoArray *exl = NULL;
4872 int length = g_list_length (list);
4874 mono_loader_clear_error ();
4876 exl = mono_array_new (domain, mono_defaults.exception_class, length);
4877 for (i = 0, tmp = list; i < length; i++, tmp = tmp->next) {
4878 MonoException *exc = mono_class_get_exception_for_failure (tmp->data);
4879 mono_array_setref (exl, i, exc);
4884 exc = mono_get_exception_reflection_type_load (res, exl);
4885 mono_loader_clear_error ();
4886 mono_raise_exception (exc);
4893 ves_icall_System_Reflection_AssemblyName_ParseName (MonoReflectionAssemblyName *name, MonoString *assname)
4895 MonoAssemblyName aname;
4896 MonoDomain *domain = mono_object_domain (name);
4898 gboolean is_version_defined;
4900 val = mono_string_to_utf8 (assname);
4901 if (!mono_assembly_name_parse_full (val, &aname, TRUE, &is_version_defined))
4904 fill_reflection_assembly_name (domain, name, &aname, "", is_version_defined);
4906 mono_assembly_name_free (&aname);
4907 g_free ((guint8*) aname.public_key);
4913 static MonoReflectionType*
4914 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModule *module)
4916 MonoDomain *domain = mono_object_domain (module);
4919 MONO_ARCH_SAVE_REGS;
4921 g_assert (module->image);
4923 if (module->image->dynamic && ((MonoDynamicImage*)(module->image))->initial_image)
4924 /* These images do not have a global type */
4927 klass = mono_class_get (module->image, 1 | MONO_TOKEN_TYPE_DEF);
4928 return mono_type_get_object (domain, &klass->byval_arg);
4932 ves_icall_System_Reflection_Module_Close (MonoReflectionModule *module)
4934 /*if (module->image)
4935 mono_image_close (module->image);*/
4939 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModule *module)
4941 MonoDomain *domain = mono_object_domain (module);
4943 MONO_ARCH_SAVE_REGS;
4945 g_assert (module->image);
4946 return mono_string_new (domain, module->image->guid);
4950 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine)
4952 if (image->dynamic) {
4953 MonoDynamicImage *dyn = (MonoDynamicImage*)image;
4954 *pe_kind = dyn->pe_kind;
4955 *machine = dyn->machine;
4958 *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
4959 *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
4964 ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage *image)
4966 return (image->md_version_major << 16) | (image->md_version_minor);
4970 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModule *module)
4972 MONO_ARCH_SAVE_REGS;
4975 return mono_array_new (mono_object_domain (module), mono_defaults.monotype_class, 0);
4977 return mono_module_get_types (mono_object_domain (module), module->image, FALSE);
4981 mono_metadata_memberref_is_method (MonoImage *image, guint32 token)
4983 guint32 cols [MONO_MEMBERREF_SIZE];
4985 mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
4986 sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
4987 mono_metadata_decode_blob_size (sig, &sig);
4988 return (*sig != 0x6);
4992 init_generic_context_from_args (MonoGenericContext *context, MonoArray *type_args, MonoArray *method_args)
4995 context->class_inst = mono_metadata_get_generic_inst (mono_array_length (type_args),
4996 mono_array_addr (type_args, MonoType*, 0));
4998 context->class_inst = NULL;
5000 context->method_inst = mono_metadata_get_generic_inst (mono_array_length (method_args),
5001 mono_array_addr (method_args, MonoType*, 0));
5003 context->method_inst = NULL;
5007 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5010 int table = mono_metadata_token_table (token);
5011 int index = mono_metadata_token_index (token);
5012 MonoGenericContext context;
5014 *error = ResolveTokenError_Other;
5016 /* Validate token */
5017 if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) &&
5018 (table != MONO_TABLE_TYPESPEC)) {
5019 *error = ResolveTokenError_BadTable;
5023 if (image->dynamic) {
5024 if (type_args || method_args)
5025 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5026 return mono_lookup_dynamic_token (image, token, NULL);
5029 if ((index <= 0) || (index > image->tables [table].rows)) {
5030 *error = ResolveTokenError_OutOfRange;
5034 init_generic_context_from_args (&context, type_args, method_args);
5035 klass = mono_class_get_full (image, token, &context);
5038 return &klass->byval_arg;
5044 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5046 int table = mono_metadata_token_table (token);
5047 int index = mono_metadata_token_index (token);
5048 MonoGenericContext context;
5051 *error = ResolveTokenError_Other;
5053 /* Validate token */
5054 if ((table != MONO_TABLE_METHOD) && (table != MONO_TABLE_METHODSPEC) &&
5055 (table != MONO_TABLE_MEMBERREF)) {
5056 *error = ResolveTokenError_BadTable;
5060 if (image->dynamic) {
5061 if (type_args || method_args)
5062 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5063 /* FIXME: validate memberref token type */
5064 return mono_lookup_dynamic_token (image, token, NULL);
5067 if ((index <= 0) || (index > image->tables [table].rows)) {
5068 *error = ResolveTokenError_OutOfRange;
5071 if ((table == MONO_TABLE_MEMBERREF) && (!mono_metadata_memberref_is_method (image, token))) {
5072 *error = ResolveTokenError_BadTable;
5076 init_generic_context_from_args (&context, type_args, method_args);
5077 method = mono_get_method_full (image, token, NULL, &context);
5083 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
5085 int index = mono_metadata_token_index (token);
5087 *error = ResolveTokenError_Other;
5089 /* Validate token */
5090 if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
5091 *error = ResolveTokenError_BadTable;
5096 return mono_lookup_dynamic_token (image, token, NULL);
5098 if ((index <= 0) || (index >= image->heap_us.size)) {
5099 *error = ResolveTokenError_OutOfRange;
5103 /* FIXME: What to do if the index points into the middle of a string ? */
5105 return mono_ldstr (mono_domain_get (), image, index);
5108 static MonoClassField*
5109 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5112 int table = mono_metadata_token_table (token);
5113 int index = mono_metadata_token_index (token);
5114 MonoGenericContext context;
5115 MonoClassField *field;
5117 *error = ResolveTokenError_Other;
5119 /* Validate token */
5120 if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
5121 *error = ResolveTokenError_BadTable;
5125 if (image->dynamic) {
5126 if (type_args || method_args)
5127 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5128 /* FIXME: validate memberref token type */
5129 return mono_lookup_dynamic_token (image, token, NULL);
5132 if ((index <= 0) || (index > image->tables [table].rows)) {
5133 *error = ResolveTokenError_OutOfRange;
5136 if ((table == MONO_TABLE_MEMBERREF) && (mono_metadata_memberref_is_method (image, token))) {
5137 *error = ResolveTokenError_BadTable;
5141 init_generic_context_from_args (&context, type_args, method_args);
5142 field = mono_field_from_token (image, token, &klass, &context);
5149 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5151 int table = mono_metadata_token_table (token);
5153 *error = ResolveTokenError_Other;
5156 case MONO_TABLE_TYPEDEF:
5157 case MONO_TABLE_TYPEREF:
5158 case MONO_TABLE_TYPESPEC: {
5159 MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, type_args, method_args, error);
5161 return (MonoObject*)mono_type_get_object (mono_domain_get (), t);
5165 case MONO_TABLE_METHOD:
5166 case MONO_TABLE_METHODSPEC: {
5167 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5169 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
5173 case MONO_TABLE_FIELD: {
5174 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5176 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
5180 case MONO_TABLE_MEMBERREF:
5181 if (mono_metadata_memberref_is_method (image, token)) {
5182 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5184 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
5189 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5191 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
5198 *error = ResolveTokenError_BadTable;
5205 ves_icall_System_Reflection_Module_ResolveSignature (MonoImage *image, guint32 token, MonoResolveTokenError *error)
5207 int table = mono_metadata_token_table (token);
5208 int idx = mono_metadata_token_index (token);
5209 MonoTableInfo *tables = image->tables;
5214 *error = ResolveTokenError_OutOfRange;
5216 /* FIXME: Support other tables ? */
5217 if (table != MONO_TABLE_STANDALONESIG)
5223 if ((idx == 0) || (idx > tables [MONO_TABLE_STANDALONESIG].rows))
5226 sig = mono_metadata_decode_row_col (&tables [MONO_TABLE_STANDALONESIG], idx - 1, 0);
5228 ptr = mono_metadata_blob_heap (image, sig);
5229 len = mono_metadata_decode_blob_size (ptr, &ptr);
5231 res = mono_array_new (mono_domain_get (), mono_defaults.byte_class, len);
5232 memcpy (mono_array_addr (res, guint8, 0), ptr, len);
5236 static MonoReflectionType*
5237 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
5240 int isbyref = 0, rank;
5241 char *str = mono_string_to_utf8 (smodifiers);
5244 MONO_ARCH_SAVE_REGS;
5246 klass = mono_class_from_mono_type (tb->type.type);
5248 /* logic taken from mono_reflection_parse_type(): keep in sync */
5252 if (isbyref) { /* only one level allowed by the spec */
5259 return mono_type_get_object (mono_object_domain (tb), &klass->this_arg);
5262 klass = mono_ptr_class_get (&klass->byval_arg);
5263 mono_class_init (klass);
5274 else if (*p != '*') { /* '*' means unknown lower bound */
5285 klass = mono_array_class_get (klass, rank);
5286 mono_class_init (klass);
5293 return mono_type_get_object (mono_object_domain (tb), &klass->byval_arg);
5297 ves_icall_Type_IsArrayImpl (MonoReflectionType *t)
5302 MONO_ARCH_SAVE_REGS;
5305 res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
5310 static MonoReflectionType *
5311 ves_icall_Type_make_array_type (MonoReflectionType *type, int rank)
5313 MonoClass *klass, *aklass;
5315 MONO_ARCH_SAVE_REGS;
5317 klass = mono_class_from_mono_type (type->type);
5318 aklass = mono_array_class_get (klass, rank);
5320 return mono_type_get_object (mono_object_domain (type), &aklass->byval_arg);
5323 static MonoReflectionType *
5324 ves_icall_Type_make_byref_type (MonoReflectionType *type)
5328 MONO_ARCH_SAVE_REGS;
5330 klass = mono_class_from_mono_type (type->type);
5332 return mono_type_get_object (mono_object_domain (type), &klass->this_arg);
5335 static MonoReflectionType *
5336 ves_icall_Type_MakePointerType (MonoReflectionType *type)
5340 MONO_ARCH_SAVE_REGS;
5342 pklass = mono_ptr_class_get (type->type);
5344 return mono_type_get_object (mono_object_domain (type), &pklass->byval_arg);
5348 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
5349 MonoReflectionMethod *info)
5351 MonoClass *delegate_class = mono_class_from_mono_type (type->type);
5352 MonoObject *delegate;
5355 MONO_ARCH_SAVE_REGS;
5357 mono_assert (delegate_class->parent == mono_defaults.multicastdelegate_class);
5359 delegate = mono_object_new (mono_object_domain (type), delegate_class);
5361 func = mono_compile_method (info->method);
5363 mono_delegate_ctor (delegate, target, func);
5369 ves_icall_System_Delegate_SetMulticastInvoke (MonoDelegate *this)
5374 /* Find the Invoke method */
5376 while ((invoke = mono_class_get_methods (this->object.vtable->klass, &iter))) {
5377 if (!strcmp (invoke->name, "Invoke"))
5382 this->invoke_impl = mono_compile_method (mono_marshal_get_delegate_invoke (invoke));
5386 * Magic number to convert a time which is relative to
5387 * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
5389 #define EPOCH_ADJUST ((guint64)62135596800LL)
5392 * Magic number to convert FILETIME base Jan 1, 1601 to DateTime - base Jan, 1, 0001
5394 #define FILETIME_ADJUST ((guint64)504911232000000000LL)
5397 * This returns Now in UTC
5400 ves_icall_System_DateTime_GetNow (void)
5402 #ifdef PLATFORM_WIN32
5406 GetSystemTime (&st);
5407 SystemTimeToFileTime (&st, &ft);
5408 return (gint64) FILETIME_ADJUST + ((((gint64)ft.dwHighDateTime)<<32) | ft.dwLowDateTime);
5410 /* FIXME: put this in io-layer and call it GetLocalTime */
5414 MONO_ARCH_SAVE_REGS;
5416 if (gettimeofday (&tv, NULL) == 0) {
5417 res = (((gint64)tv.tv_sec + EPOCH_ADJUST)* 1000000 + tv.tv_usec)*10;
5420 /* fixme: raise exception */
5425 #ifdef PLATFORM_WIN32
5426 /* convert a SYSTEMTIME which is of the form "last thursday in october" to a real date */
5428 convert_to_absolute_date(SYSTEMTIME *date)
5430 #define IS_LEAP(y) ((y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0))
5431 static int days_in_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5432 static int leap_days_in_month[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5433 /* from the calendar FAQ */
5434 int a = (14 - date->wMonth) / 12;
5435 int y = date->wYear - a;
5436 int m = date->wMonth + 12 * a - 2;
5437 int d = (1 + y + y/4 - y/100 + y/400 + (31*m)/12) % 7;
5439 /* d is now the day of the week for the first of the month (0 == Sunday) */
5441 int day_of_week = date->wDayOfWeek;
5443 /* set day_in_month to the first day in the month which falls on day_of_week */
5444 int day_in_month = 1 + (day_of_week - d);
5445 if (day_in_month <= 0)
5448 /* wDay is 1 for first weekday in month, 2 for 2nd ... 5 means last - so work that out allowing for days in the month */
5449 date->wDay = day_in_month + (date->wDay - 1) * 7;
5450 if (date->wDay > (IS_LEAP(date->wYear) ? leap_days_in_month[date->wMonth - 1] : days_in_month[date->wMonth - 1]))
5455 #ifndef PLATFORM_WIN32
5457 * Return's the offset from GMT of a local time.
5459 * tm is a local time
5460 * t is the same local time as seconds.
5463 gmt_offset(struct tm *tm, time_t t)
5465 #if defined (HAVE_TM_GMTOFF)
5466 return tm->tm_gmtoff;
5471 g.tm_isdst = tm->tm_isdst;
5473 return (int)difftime(t, t2);
5478 * This is heavily based on zdump.c from glibc 2.2.
5480 * * data[0]: start of daylight saving time (in DateTime ticks).
5481 * * data[1]: end of daylight saving time (in DateTime ticks).
5482 * * data[2]: utcoffset (in TimeSpan ticks).
5483 * * data[3]: additional offset when daylight saving (in TimeSpan ticks).
5484 * * name[0]: name of this timezone when not daylight saving.
5485 * * name[1]: name of this timezone when daylight saving.
5487 * FIXME: This only works with "standard" Unix dates (years between 1900 and 2100) while
5488 * the class library allows years between 1 and 9999.
5490 * Returns true on success and zero on failure.
5493 ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year, MonoArray **data, MonoArray **names)
5495 #ifndef PLATFORM_WIN32
5496 MonoDomain *domain = mono_domain_get ();
5497 struct tm start, tt;
5501 int is_daylight = 0, day;
5504 MONO_ARCH_SAVE_REGS;
5506 MONO_CHECK_ARG_NULL (data);
5507 MONO_CHECK_ARG_NULL (names);
5509 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5510 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5513 * no info is better than crashing: we'll need our own tz data
5514 * to make this work properly, anyway. The range is probably
5515 * reduced to 1970 .. 2037 because that is what mktime is
5516 * guaranteed to support (we get into an infinite loop
5520 memset (&start, 0, sizeof (start));
5523 start.tm_year = year-1900;
5525 t = mktime (&start);
5527 if ((year < 1970) || (year > 2037) || (t == -1)) {
5529 tt = *localtime (&t);
5530 strftime (tzone, sizeof (tzone), "%Z", &tt);
5531 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5532 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5536 gmtoff = gmt_offset (&start, t);
5538 /* For each day of the year, calculate the tm_gmtoff. */
5539 for (day = 0; day < 365; day++) {
5542 tt = *localtime (&t);
5544 /* Daylight saving starts or ends here. */
5545 if (gmt_offset (&tt, t) != gmtoff) {
5549 /* Try to find the exact hour when daylight saving starts/ends. */
5553 tt1 = *localtime (&t1);
5554 } while (gmt_offset (&tt1, t1) != gmtoff);
5556 /* Try to find the exact minute when daylight saving starts/ends. */
5559 tt1 = *localtime (&t1);
5560 } while (gmt_offset (&tt1, t1) == gmtoff);
5562 strftime (tzone, sizeof (tzone), "%Z", &tt);
5564 /* Write data, if we're already in daylight saving, we're done. */
5566 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5567 mono_array_set ((*data), gint64, 1, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
5570 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5571 mono_array_set ((*data), gint64, 0, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
5575 /* This is only set once when we enter daylight saving. */
5576 mono_array_set ((*data), gint64, 2, (gint64)gmtoff * 10000000L);
5577 mono_array_set ((*data), gint64, 3, (gint64)(gmt_offset (&tt, t) - gmtoff) * 10000000L);
5579 gmtoff = gmt_offset (&tt, t);
5584 strftime (tzone, sizeof (tzone), "%Z", &tt);
5585 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5586 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5587 mono_array_set ((*data), gint64, 0, 0);
5588 mono_array_set ((*data), gint64, 1, 0);
5589 mono_array_set ((*data), gint64, 2, (gint64) gmtoff * 10000000L);
5590 mono_array_set ((*data), gint64, 3, 0);
5595 MonoDomain *domain = mono_domain_get ();
5596 TIME_ZONE_INFORMATION tz_info;
5601 tz_id = GetTimeZoneInformation (&tz_info);
5602 if (tz_id == TIME_ZONE_ID_INVALID)
5605 MONO_CHECK_ARG_NULL (data);
5606 MONO_CHECK_ARG_NULL (names);
5608 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5609 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5611 for (i = 0; i < 32; ++i)
5612 if (!tz_info.DaylightName [i])
5614 mono_array_setref ((*names), 1, mono_string_new_utf16 (domain, tz_info.DaylightName, i));
5615 for (i = 0; i < 32; ++i)
5616 if (!tz_info.StandardName [i])
5618 mono_array_setref ((*names), 0, mono_string_new_utf16 (domain, tz_info.StandardName, i));
5620 if ((year <= 1601) || (year > 30827)) {
5622 * According to MSDN, the MS time functions can't handle dates outside
5628 /* even if the timezone has no daylight savings it may have Bias (e.g. GMT+13 it seems) */
5629 if (tz_id != TIME_ZONE_ID_UNKNOWN) {
5630 tz_info.StandardDate.wYear = year;
5631 convert_to_absolute_date(&tz_info.StandardDate);
5632 err = SystemTimeToFileTime (&tz_info.StandardDate, &ft);
5634 mono_array_set ((*data), gint64, 1, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
5635 tz_info.DaylightDate.wYear = year;
5636 convert_to_absolute_date(&tz_info.DaylightDate);
5637 err = SystemTimeToFileTime (&tz_info.DaylightDate, &ft);
5639 mono_array_set ((*data), gint64, 0, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
5641 mono_array_set ((*data), gint64, 2, (tz_info.Bias + tz_info.StandardBias) * -600000000LL);
5642 mono_array_set ((*data), gint64, 3, (tz_info.DaylightBias - tz_info.StandardBias) * -600000000LL);
5649 ves_icall_System_Object_obj_address (MonoObject *this)
5651 MONO_ARCH_SAVE_REGS;
5658 static inline gint32
5659 mono_array_get_byte_length (MonoArray *array)
5665 klass = array->obj.vtable->klass;
5667 if (array->bounds == NULL)
5668 length = array->max_length;
5671 for (i = 0; i < klass->rank; ++ i)
5672 length *= array->bounds [i].length;
5675 switch (klass->element_class->byval_arg.type) {
5678 case MONO_TYPE_BOOLEAN:
5682 case MONO_TYPE_CHAR:
5690 return length * sizeof (gpointer);
5701 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array)
5703 MONO_ARCH_SAVE_REGS;
5705 return mono_array_get_byte_length (array);
5709 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx)
5711 MONO_ARCH_SAVE_REGS;
5713 return mono_array_get (array, gint8, idx);
5717 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value)
5719 MONO_ARCH_SAVE_REGS;
5721 mono_array_set (array, gint8, idx, value);
5725 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count)
5727 guint8 *src_buf, *dest_buf;
5729 MONO_ARCH_SAVE_REGS;
5731 /* watch out for integer overflow */
5732 if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count))
5735 src_buf = (guint8 *)src->vector + src_offset;
5736 dest_buf = (guint8 *)dest->vector + dest_offset;
5739 memcpy (dest_buf, src_buf, count);
5741 memmove (dest_buf, src_buf, count); /* Source and dest are the same array */
5747 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this, MonoString *class_name)
5749 MonoDomain *domain = mono_object_domain (this);
5751 MonoRealProxy *rp = ((MonoRealProxy *)this);
5752 MonoTransparentProxy *tp;
5756 MONO_ARCH_SAVE_REGS;
5758 res = mono_object_new (domain, mono_defaults.transparent_proxy_class);
5759 tp = (MonoTransparentProxy*) res;
5761 MONO_OBJECT_SETREF (tp, rp, rp);
5762 type = ((MonoReflectionType *)rp->class_to_proxy)->type;
5763 klass = mono_class_from_mono_type (type);
5765 tp->custom_type_info = (mono_object_isinst (this, mono_defaults.iremotingtypeinfo_class) != NULL);
5766 tp->remote_class = mono_remote_class (domain, class_name, klass);
5768 res->vtable = mono_remote_class_vtable (domain, tp->remote_class, rp);
5772 static MonoReflectionType *
5773 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
5775 return mono_type_get_object (mono_object_domain (tp), &tp->remote_class->proxy_class->byval_arg);
5778 /* System.Environment */
5781 ves_icall_System_Environment_get_MachineName (void)
5783 #if defined (PLATFORM_WIN32)
5788 len = MAX_COMPUTERNAME_LENGTH + 1;
5789 buf = g_new (gunichar2, len);
5792 if (GetComputerName (buf, (PDWORD) &len))
5793 result = mono_string_new_utf16 (mono_domain_get (), buf, len);
5801 if (gethostname (buf, sizeof (buf)) == 0)
5802 result = mono_string_new (mono_domain_get (), buf);
5811 ves_icall_System_Environment_get_Platform (void)
5813 MONO_ARCH_SAVE_REGS;
5815 #if defined (PLATFORM_WIN32)
5825 ves_icall_System_Environment_get_NewLine (void)
5827 MONO_ARCH_SAVE_REGS;
5829 #if defined (PLATFORM_WIN32)
5830 return mono_string_new (mono_domain_get (), "\r\n");
5832 return mono_string_new (mono_domain_get (), "\n");
5837 ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name)
5842 MONO_ARCH_SAVE_REGS;
5847 utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
5848 value = g_getenv (utf8_name);
5855 return mono_string_new (mono_domain_get (), value);
5859 * There is no standard way to get at environ.
5862 #ifndef __MINGW32_VERSION
5869 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
5877 MONO_ARCH_SAVE_REGS;
5880 for (e = environ; *e != 0; ++ e)
5883 domain = mono_domain_get ();
5884 names = mono_array_new (domain, mono_defaults.string_class, n);
5887 for (e = environ; *e != 0; ++ e) {
5888 parts = g_strsplit (*e, "=", 2);
5890 str = mono_string_new (domain, *parts);
5891 mono_array_setref (names, n, str);
5903 * If your platform lacks setenv/unsetenv, you must upgrade your glib.
5905 #if !GLIB_CHECK_VERSION(2,4,0)
5906 #define g_setenv(a,b,c) setenv(a,b,c)
5907 #define g_unsetenv(a) unsetenv(a)
5911 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
5913 #ifdef PLATFORM_WIN32
5914 gunichar2 *utf16_name, *utf16_value;
5916 gchar *utf8_name, *utf8_value;
5919 MONO_ARCH_SAVE_REGS;
5921 #ifdef PLATFORM_WIN32
5922 utf16_name = mono_string_to_utf16 (name);
5923 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
5924 SetEnvironmentVariable (utf16_name, NULL);
5925 g_free (utf16_name);
5929 utf16_value = mono_string_to_utf16 (value);
5931 SetEnvironmentVariable (utf16_name, utf16_value);
5933 g_free (utf16_name);
5934 g_free (utf16_value);
5936 utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
5938 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
5939 g_unsetenv (utf8_name);
5944 utf8_value = mono_string_to_utf8 (value);
5945 g_setenv (utf8_name, utf8_value, TRUE);
5948 g_free (utf8_value);
5953 * Returns: the number of milliseconds elapsed since the system started.
5956 ves_icall_System_Environment_get_TickCount (void)
5958 return GetTickCount ();
5963 ves_icall_System_Environment_Exit (int result)
5965 MONO_ARCH_SAVE_REGS;
5967 mono_runtime_set_shutting_down ();
5969 /* Suspend all managed threads since the runtime is going away */
5970 mono_thread_suspend_all_other_threads ();
5972 mono_runtime_quit ();
5974 /* we may need to do some cleanup here... */
5979 ves_icall_System_Environment_GetGacPath (void)
5981 return mono_string_new (mono_domain_get (), mono_assembly_getrootdir ());
5985 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
5987 #if defined (PLATFORM_WIN32)
5988 #ifndef CSIDL_FLAG_CREATE
5989 #define CSIDL_FLAG_CREATE 0x8000
5992 WCHAR path [MAX_PATH];
5993 /* Create directory if no existing */
5994 if (SUCCEEDED (SHGetFolderPathW (NULL, folder | CSIDL_FLAG_CREATE, NULL, 0, path))) {
5998 return mono_string_new_utf16 (mono_domain_get (), path, len);
6001 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
6003 return mono_string_new (mono_domain_get (), "");
6007 ves_icall_System_Environment_GetLogicalDrives (void)
6009 gunichar2 buf [128], *ptr, *dname;
6011 gint initial_size = 127, size = 128;
6014 MonoString *drivestr;
6015 MonoDomain *domain = mono_domain_get ();
6018 MONO_ARCH_SAVE_REGS;
6023 while (size > initial_size) {
6024 size = GetLogicalDriveStrings (initial_size, ptr);
6025 if (size > initial_size) {
6028 ptr = g_malloc0 ((size + 1) * sizeof (gunichar2));
6029 initial_size = size;
6043 result = mono_array_new (domain, mono_defaults.string_class, ndrives);
6048 while (*u16) { u16++; len ++; }
6049 drivestr = mono_string_new_utf16 (domain, dname, len);
6050 mono_array_setref (result, ndrives++, drivestr);
6061 ves_icall_System_Environment_InternalGetHome (void)
6063 MONO_ARCH_SAVE_REGS;
6065 return mono_string_new (mono_domain_get (), g_get_home_dir ());
6068 static const char *encodings [] = {
6070 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
6071 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
6072 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
6074 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
6075 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
6076 "x_unicode_2_0_utf_7",
6078 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
6079 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
6081 "utf_16", "UTF_16LE", "ucs_2", "unicode",
6084 "unicodefffe", "utf_16be",
6091 * Returns the internal codepage, if the value of "int_code_page" is
6092 * 1 at entry, and we can not compute a suitable code page number,
6093 * returns the code page as a string
6096 ves_icall_System_Text_Encoding_InternalCodePage (gint32 *int_code_page)
6101 char *codepage = NULL;
6103 int want_name = *int_code_page;
6106 *int_code_page = -1;
6107 MONO_ARCH_SAVE_REGS;
6109 g_get_charset (&cset);
6110 c = codepage = strdup (cset);
6111 for (c = codepage; *c; c++){
6112 if (isascii (*c) && isalpha (*c))
6117 /* g_print ("charset: %s\n", cset); */
6119 /* handle some common aliases */
6122 for (i = 0; p != 0; ){
6123 if ((gssize) p < 7){
6125 p = encodings [++i];
6128 if (strcmp (p, codepage) == 0){
6129 *int_code_page = code;
6132 p = encodings [++i];
6135 if (strstr (codepage, "utf_8") != NULL)
6136 *int_code_page |= 0x10000000;
6139 if (want_name && *int_code_page == -1)
6140 return mono_string_new (mono_domain_get (), cset);
6146 ves_icall_System_Environment_get_HasShutdownStarted (void)
6148 if (mono_runtime_is_shutting_down ())
6151 if (mono_domain_is_unloading (mono_domain_get ()))
6158 ves_icall_MonoMethodMessage_InitMessage (MonoMethodMessage *this,
6159 MonoReflectionMethod *method,
6160 MonoArray *out_args)
6162 MONO_ARCH_SAVE_REGS;
6164 mono_message_init (mono_object_domain (this), this, method, out_args);
6168 ves_icall_IsTransparentProxy (MonoObject *proxy)
6170 MONO_ARCH_SAVE_REGS;
6175 if (proxy->vtable->klass == mono_defaults.transparent_proxy_class)
6182 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6187 MONO_ARCH_SAVE_REGS;
6189 klass = mono_class_from_mono_type (type->type);
6190 vtable = mono_class_vtable (mono_domain_get (), klass);
6192 if (enable) vtable->remote = 1;
6193 else vtable->remote = 0;
6197 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type)
6202 MONO_ARCH_SAVE_REGS;
6204 domain = mono_object_domain (type);
6205 klass = mono_class_from_mono_type (type->type);
6207 if (klass->rank >= 1) {
6208 g_assert (klass->rank == 1);
6209 return (MonoObject *) mono_array_new (domain, klass->element_class, 0);
6211 /* Bypass remoting object creation check */
6212 return mono_object_new_alloc_specific (mono_class_vtable (domain, klass));
6217 ves_icall_System_IO_get_temp_path (void)
6219 MONO_ARCH_SAVE_REGS;
6221 return mono_string_new (mono_domain_get (), g_get_tmp_dir ());
6225 ves_icall_RuntimeMethod_GetFunctionPointer (MonoMethod *method)
6227 MONO_ARCH_SAVE_REGS;
6229 return mono_compile_method (method);
6233 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
6238 MONO_ARCH_SAVE_REGS;
6240 path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
6242 #if defined (PLATFORM_WIN32)
6243 /* Avoid mixing '/' and '\\' */
6246 for (i = strlen (path) - 1; i >= 0; i--)
6247 if (path [i] == '/')
6251 mcpath = mono_string_new (mono_domain_get (), path);
6258 get_bundled_machine_config (void)
6260 const gchar *machine_config;
6262 MONO_ARCH_SAVE_REGS;
6264 machine_config = mono_get_machine_config ();
6266 if (!machine_config)
6269 return mono_string_new (mono_domain_get (), machine_config);
6273 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
6278 MONO_ARCH_SAVE_REGS;
6280 path = g_path_get_dirname (mono_get_config_dir ());
6282 #if defined (PLATFORM_WIN32)
6283 /* Avoid mixing '/' and '\\' */
6286 for (i = strlen (path) - 1; i >= 0; i--)
6287 if (path [i] == '/')
6291 ipath = mono_string_new (mono_domain_get (), path);
6298 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
6300 #if defined (PLATFORM_WIN32)
6301 OutputDebugString (mono_string_chars (message));
6303 g_warning ("WriteWindowsDebugString called and PLATFORM_WIN32 not defined!\n");
6307 /* Only used for value types */
6309 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
6314 MONO_ARCH_SAVE_REGS;
6316 domain = mono_object_domain (type);
6317 klass = mono_class_from_mono_type (type->type);
6319 if (mono_class_is_nullable (klass))
6320 /* No arguments -> null */
6323 return mono_object_new (domain, klass);
6326 static MonoReflectionMethod *
6327 ves_icall_MonoMethod_get_base_definition (MonoReflectionMethod *m)
6329 MonoClass *klass, *parent;
6330 MonoMethod *method = m->method;
6331 MonoMethod *result = NULL;
6333 MONO_ARCH_SAVE_REGS;
6335 if (method->klass == NULL)
6338 if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
6339 MONO_CLASS_IS_INTERFACE (method->klass) ||
6340 method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
6343 klass = method->klass;
6344 if (klass->generic_class)
6345 klass = klass->generic_class->container_class;
6347 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
6348 for (parent = klass->parent; parent != NULL; parent = parent->parent) {
6349 mono_class_setup_vtable (parent);
6350 if (parent->vtable_size <= method->slot)
6355 if (klass == method->klass)
6358 result = klass->vtable [method->slot];
6359 if (result == NULL) {
6360 /* It is an abstract method */
6361 gpointer iter = NULL;
6362 while ((result = mono_class_get_methods (klass, &iter)))
6363 if (result->slot == method->slot)
6370 return mono_method_get_object (mono_domain_get (), result, NULL);
6374 ves_icall_MonoMethod_get_name (MonoReflectionMethod *m)
6376 MonoMethod *method = m->method;
6378 MONO_OBJECT_SETREF (m, name, mono_string_new (mono_object_domain (m), method->name));
6383 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
6385 MONO_ARCH_SAVE_REGS;
6387 iter->sig = *(MonoMethodSignature**)argsp;
6389 g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
6390 g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
6393 /* FIXME: it's not documented what start is exactly... */
6397 guint32 i, arg_size;
6399 iter->args = argsp + sizeof (gpointer);
6400 #ifndef MONO_ARCH_REGPARMS
6401 for (i = 0; i < iter->sig->sentinelpos; ++i) {
6402 arg_size = mono_type_stack_size (iter->sig->params [i], &align);
6403 iter->args = (char*)iter->args + arg_size;
6407 iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
6409 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
6413 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
6415 guint32 i, arg_size;
6418 MONO_ARCH_SAVE_REGS;
6420 i = iter->sig->sentinelpos + iter->next_arg;
6422 g_assert (i < iter->sig->param_count);
6424 res.type = iter->sig->params [i];
6425 res.klass = mono_class_from_mono_type (res.type);
6426 /* FIXME: endianess issue... */
6427 res.value = iter->args;
6428 arg_size = mono_type_stack_size (res.type, &align);
6429 iter->args = (char*)iter->args + arg_size;
6432 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6438 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
6440 guint32 i, arg_size;
6443 MONO_ARCH_SAVE_REGS;
6445 i = iter->sig->sentinelpos + iter->next_arg;
6447 g_assert (i < iter->sig->param_count);
6449 while (i < iter->sig->param_count) {
6450 if (!mono_metadata_type_equal (type, iter->sig->params [i]))
6452 res.type = iter->sig->params [i];
6453 res.klass = mono_class_from_mono_type (res.type);
6454 /* FIXME: endianess issue... */
6455 res.value = iter->args;
6456 arg_size = mono_type_stack_size (res.type, &align);
6457 iter->args = (char*)iter->args + arg_size;
6459 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6462 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
6471 mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
6474 MONO_ARCH_SAVE_REGS;
6476 i = iter->sig->sentinelpos + iter->next_arg;
6478 g_assert (i < iter->sig->param_count);
6480 return iter->sig->params [i];
6484 mono_TypedReference_ToObject (MonoTypedRef tref)
6486 MONO_ARCH_SAVE_REGS;
6488 if (MONO_TYPE_IS_REFERENCE (tref.type)) {
6489 MonoObject** objp = tref.value;
6493 return mono_value_box (mono_domain_get (), tref.klass, tref.value);
6497 mono_TypedReference_ToObjectInternal (MonoType *type, gpointer value, MonoClass *klass)
6499 MONO_ARCH_SAVE_REGS;
6501 if (MONO_TYPE_IS_REFERENCE (type)) {
6502 MonoObject** objp = value;
6506 return mono_value_box (mono_domain_get (), klass, value);
6510 prelink_method (MonoMethod *method)
6512 const char *exc_class, *exc_arg;
6513 if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
6515 mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
6517 mono_raise_exception(
6518 mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg ) );
6520 /* create the wrapper, too? */
6524 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
6526 MONO_ARCH_SAVE_REGS;
6527 prelink_method (method->method);
6531 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
6533 MonoClass *klass = mono_class_from_mono_type (type->type);
6535 gpointer iter = NULL;
6536 MONO_ARCH_SAVE_REGS;
6538 while ((m = mono_class_get_methods (klass, &iter)))
6542 /* These parameters are "readonly" in corlib/System/Char.cs */
6544 ves_icall_System_Char_GetDataTablePointers (guint8 const **category_data,
6545 guint8 const **numeric_data,
6546 gdouble const **numeric_data_values,
6547 guint16 const **to_lower_data_low,
6548 guint16 const **to_lower_data_high,
6549 guint16 const **to_upper_data_low,
6550 guint16 const **to_upper_data_high)
6552 *category_data = CategoryData;
6553 *numeric_data = NumericData;
6554 *numeric_data_values = NumericDataValues;
6555 *to_lower_data_low = ToLowerDataLow;
6556 *to_lower_data_high = ToLowerDataHigh;
6557 *to_upper_data_low = ToUpperDataLow;
6558 *to_upper_data_high = ToUpperDataHigh;
6562 ves_icall_MonoDebugger_GetMethodToken (MonoReflectionMethod *method)
6564 return method->method->token;
6568 * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
6569 * and avoid useless allocations.
6572 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional)
6576 for (i = 0; i < type->num_mods; ++i) {
6577 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
6582 res = mono_array_new (mono_domain_get (), mono_defaults.systemtype_class, count);
6584 for (i = 0; i < type->num_mods; ++i) {
6585 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
6586 MonoClass *klass = mono_class_get (image, type->modifiers [i].token);
6587 mono_array_setref (res, count, mono_type_get_object (mono_domain_get (), &klass->byval_arg));
6595 param_info_get_type_modifiers (MonoReflectionParameter *param, MonoBoolean optional)
6597 MonoType *type = param->ClassImpl->type;
6598 MonoReflectionMethod *method = (MonoReflectionMethod*)param->MemberImpl;
6599 MonoImage *image = method->method->klass->image;
6600 int pos = param->PositionImpl;
6601 MonoMethodSignature *sig = mono_method_signature (method->method);
6605 type = sig->params [pos];
6607 return type_array_from_modifiers (image, type, optional);
6611 get_property_type (MonoProperty *prop)
6613 MonoMethodSignature *sig;
6615 sig = mono_method_signature (prop->get);
6617 } else if (prop->set) {
6618 sig = mono_method_signature (prop->set);
6619 return sig->params [sig->param_count - 1];
6625 property_info_get_type_modifiers (MonoReflectionProperty *property, MonoBoolean optional)
6627 MonoType *type = get_property_type (property->property);
6628 MonoImage *image = property->klass->image;
6632 return type_array_from_modifiers (image, type, optional);
6636 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
6638 MonoCustomAttrInfo *cinfo;
6641 cinfo = mono_reflection_get_custom_attrs_info (obj);
6644 found = mono_custom_attrs_has_attr (cinfo, mono_class_from_mono_type (attr_type->type));
6646 mono_custom_attrs_free (cinfo);
6651 custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
6653 MonoArray *res = mono_reflection_get_custom_attrs_by_type (obj, attr_type ? mono_class_from_mono_type (attr_type->type) : NULL);
6655 if (mono_loader_get_last_error ()) {
6656 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
6657 g_assert_not_reached ();
6664 GCHandle_CheckCurrentDomain (guint32 gchandle)
6666 return mono_gchandle_is_in_domain (gchandle, mono_domain_get ());
6670 ves_icall_Mono_Runtime_GetDisplayName (void)
6672 static const char display_name_str [] = "Mono " VERSION;
6673 MonoString *display_name = mono_string_new (mono_domain_get (), display_name_str);
6674 return display_name;
6679 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
6680 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
6681 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 62, 128, 128, 128, 63,
6682 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 0, 128, 128,
6683 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
6684 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 128, 128, 128, 128, 128,
6685 128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
6686 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
6690 base64_to_byte_array (gunichar2 *start, gint ilength, MonoBoolean allowWhitespaceOnly)
6695 gunichar2 last, prev_last;
6703 last = prev_last = 0;
6704 for (i = 0; i < ilength; i++) {
6706 if (c >= sizeof (dbase64)) {
6707 exc = mono_exception_from_name_msg (mono_get_corlib (),
6708 "System", "FormatException",
6709 "Invalid character found.");
6710 mono_raise_exception (exc);
6711 } else if (isspace (c)) {
6719 olength = ilength - ignored;
6721 if (allowWhitespaceOnly && olength == 0) {
6722 return mono_array_new (mono_domain_get (), mono_defaults.byte_class, 0);
6725 if ((olength & 3) != 0 || olength <= 0) {
6726 exc = mono_exception_from_name_msg (mono_get_corlib (), "System",
6727 "FormatException", "Invalid length.");
6728 mono_raise_exception (exc);
6731 olength = (olength * 3) / 4;
6735 if (prev_last == '=')
6738 result = mono_array_new (mono_domain_get (), mono_defaults.byte_class, olength);
6739 res_ptr = mono_array_addr (result, guchar, 0);
6740 for (i = 0; i < ilength; ) {
6743 for (k = 0; k < 4 && i < ilength;) {
6749 if (((b [k] = dbase64 [c]) & 0x80) != 0) {
6750 exc = mono_exception_from_name_msg (mono_get_corlib (),
6751 "System", "FormatException",
6752 "Invalid character found.");
6753 mono_raise_exception (exc);
6758 *res_ptr++ = (b [0] << 2) | (b [1] >> 4);
6760 *res_ptr++ = (b [1] << 4) | (b [2] >> 2);
6762 *res_ptr++ = (b [2] << 6) | b [3];
6764 while (i < ilength && isspace (start [i]))
6772 InternalFromBase64String (MonoString *str, MonoBoolean allowWhitespaceOnly)
6774 MONO_ARCH_SAVE_REGS;
6776 return base64_to_byte_array (mono_string_chars (str),
6777 mono_string_length (str), allowWhitespaceOnly);
6781 InternalFromBase64CharArray (MonoArray *input, gint offset, gint length)
6783 MONO_ARCH_SAVE_REGS;
6785 return base64_to_byte_array (mono_array_addr (input, gunichar2, offset),
6789 #define ICALL_TYPE(id,name,first)
6790 #define ICALL(id,name,func) Icall_ ## id,
6793 #include "metadata/icall-def.h"
6799 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
6800 #define ICALL(id,name,func)
6802 #include "metadata/icall-def.h"
6808 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
6809 #define ICALL(id,name,func)
6811 guint16 first_icall;
6814 static const IcallTypeDesc
6815 icall_type_descs [] = {
6816 #include "metadata/icall-def.h"
6820 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
6823 #define ICALL_TYPE(id,name,first)
6826 #ifdef HAVE_ARRAY_ELEM_INIT
6827 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
6828 #define MSGSTRFIELD1(line) str##line
6830 static const struct msgstrtn_t {
6831 #define ICALL(id,name,func)
6833 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
6834 #include "metadata/icall-def.h"
6836 } icall_type_names_str = {
6837 #define ICALL_TYPE(id,name,first) (name),
6838 #include "metadata/icall-def.h"
6841 static const guint16 icall_type_names_idx [] = {
6842 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
6843 #include "metadata/icall-def.h"
6846 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
6848 static const struct msgstr_t {
6850 #define ICALL_TYPE(id,name,first)
6851 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
6852 #include "metadata/icall-def.h"
6854 } icall_names_str = {
6855 #define ICALL(id,name,func) (name),
6856 #include "metadata/icall-def.h"
6859 static const guint16 icall_names_idx [] = {
6860 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
6861 #include "metadata/icall-def.h"
6864 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
6870 #define ICALL_TYPE(id,name,first) name,
6871 #define ICALL(id,name,func)
6872 static const char* const
6873 icall_type_names [] = {
6874 #include "metadata/icall-def.h"
6878 #define icall_type_name_get(id) (icall_type_names [(id)])
6882 #define ICALL_TYPE(id,name,first)
6883 #define ICALL(id,name,func) name,
6884 static const char* const
6886 #include "metadata/icall-def.h"
6889 #define icall_name_get(id) icall_names [(id)]
6891 #endif /* !HAVE_ARRAY_ELEM_INIT */
6895 #define ICALL_TYPE(id,name,first)
6896 #define ICALL(id,name,func) func,
6897 static const gconstpointer
6898 icall_functions [] = {
6899 #include "metadata/icall-def.h"
6903 static GHashTable *icall_hash = NULL;
6904 static GHashTable *jit_icall_hash_name = NULL;
6905 static GHashTable *jit_icall_hash_addr = NULL;
6908 mono_icall_init (void)
6912 /* check that tables are sorted: disable in release */
6915 const char *prev_class = NULL;
6916 const char *prev_method;
6918 for (i = 0; i < Icall_type_num; ++i) {
6919 const IcallTypeDesc *desc;
6922 if (prev_class && strcmp (prev_class, icall_type_name_get (i)) >= 0)
6923 g_print ("class %s should come before class %s\n", icall_type_name_get (i), prev_class);
6924 prev_class = icall_type_name_get (i);
6925 desc = &icall_type_descs [i];
6926 num_icalls = icall_desc_num_icalls (desc);
6927 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
6928 for (j = 0; j < num_icalls; ++j) {
6929 const char *methodn = icall_name_get (desc->first_icall + j);
6930 if (prev_method && strcmp (prev_method, methodn) >= 0)
6931 g_print ("method %s should come before method %s\n", methodn, prev_method);
6932 prev_method = methodn;
6937 icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
6941 mono_icall_cleanup (void)
6943 g_hash_table_destroy (icall_hash);
6944 g_hash_table_destroy (jit_icall_hash_name);
6945 g_hash_table_destroy (jit_icall_hash_addr);
6949 mono_add_internal_call (const char *name, gconstpointer method)
6951 mono_loader_lock ();
6953 g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
6955 mono_loader_unlock ();
6958 #ifdef HAVE_ARRAY_ELEM_INIT
6960 compare_method_imap (const void *key, const void *elem)
6962 const char* method_name = (const char*)&icall_names_str + (*(guint16*)elem);
6963 return strcmp (key, method_name);
6967 find_method_icall (const IcallTypeDesc *imap, const char *name)
6969 const guint16 *nameslot = bsearch (name, icall_names_idx + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names_idx [0]), compare_method_imap);
6972 return (gpointer)icall_functions [(nameslot - &icall_names_idx [0])];
6976 compare_class_imap (const void *key, const void *elem)
6978 const char* class_name = (const char*)&icall_type_names_str + (*(guint16*)elem);
6979 return strcmp (key, class_name);
6982 static const IcallTypeDesc*
6983 find_class_icalls (const char *name)
6985 const guint16 *nameslot = bsearch (name, icall_type_names_idx, Icall_type_num, sizeof (icall_type_names_idx [0]), compare_class_imap);
6988 return &icall_type_descs [nameslot - &icall_type_names_idx [0]];
6993 compare_method_imap (const void *key, const void *elem)
6995 const char** method_name = (const char**)elem;
6996 return strcmp (key, *method_name);
7000 find_method_icall (const IcallTypeDesc *imap, const char *name)
7002 const char **nameslot = bsearch (name, icall_names + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names [0]), compare_method_imap);
7005 return (gpointer)icall_functions [(nameslot - icall_names)];
7009 compare_class_imap (const void *key, const void *elem)
7011 const char** class_name = (const char**)elem;
7012 return strcmp (key, *class_name);
7015 static const IcallTypeDesc*
7016 find_class_icalls (const char *name)
7018 const char **nameslot = bsearch (name, icall_type_names, Icall_type_num, sizeof (icall_type_names [0]), compare_class_imap);
7021 return &icall_type_descs [nameslot - icall_type_names];
7027 * we should probably export this as an helper (handle nested types).
7028 * Returns the number of chars written in buf.
7031 concat_class_name (char *buf, int bufsize, MonoClass *klass)
7033 int nspacelen, cnamelen;
7034 nspacelen = strlen (klass->name_space);
7035 cnamelen = strlen (klass->name);
7036 if (nspacelen + cnamelen + 2 > bufsize)
7039 memcpy (buf, klass->name_space, nspacelen);
7040 buf [nspacelen ++] = '.';
7042 memcpy (buf + nspacelen, klass->name, cnamelen);
7043 buf [nspacelen + cnamelen] = 0;
7044 return nspacelen + cnamelen;
7048 mono_lookup_internal_call (MonoMethod *method)
7053 int typelen = 0, mlen, siglen;
7055 const IcallTypeDesc *imap;
7057 g_assert (method != NULL);
7059 if (method->is_inflated)
7060 method = ((MonoMethodInflated *) method)->declaring;
7062 if (method->klass->nested_in) {
7063 int pos = concat_class_name (mname, sizeof (mname)-2, method->klass->nested_in);
7067 mname [pos++] = '/';
7070 typelen = concat_class_name (mname+pos, sizeof (mname)-pos-1, method->klass);
7076 typelen = concat_class_name (mname, sizeof (mname), method->klass);
7081 imap = find_class_icalls (mname);
7083 mname [typelen] = ':';
7084 mname [typelen + 1] = ':';
7086 mlen = strlen (method->name);
7087 memcpy (mname + typelen + 2, method->name, mlen);
7088 sigstart = mname + typelen + 2 + mlen;
7091 tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
7092 siglen = strlen (tmpsig);
7093 if (typelen + mlen + siglen + 6 > sizeof (mname))
7096 memcpy (sigstart + 1, tmpsig, siglen);
7097 sigstart [siglen + 1] = ')';
7098 sigstart [siglen + 2] = 0;
7101 mono_loader_lock ();
7103 res = g_hash_table_lookup (icall_hash, mname);
7105 mono_loader_unlock ();
7108 /* try without signature */
7110 res = g_hash_table_lookup (icall_hash, mname);
7112 mono_loader_unlock ();
7116 /* it wasn't found in the static call tables */
7118 mono_loader_unlock ();
7121 res = find_method_icall (imap, sigstart - mlen);
7123 mono_loader_unlock ();
7126 /* try _with_ signature */
7128 res = find_method_icall (imap, sigstart - mlen);
7130 mono_loader_unlock ();
7134 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname);
7135 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
7136 g_print ("The out of sync library is: %s\n", method->klass->image->name);
7137 g_print ("\nWhen you update one from cvs you need to update, compile and install\nthe other too.\n");
7138 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");
7139 g_print ("If you see other errors or faults after this message they are probably related\n");
7140 g_print ("and you need to fix your mono install first.\n");
7142 mono_loader_unlock ();
7148 type_from_typename (char *typename)
7150 MonoClass *klass = NULL; /* assignment to shut GCC warning up */
7152 if (!strcmp (typename, "int"))
7153 klass = mono_defaults.int_class;
7154 else if (!strcmp (typename, "ptr"))
7155 klass = mono_defaults.int_class;
7156 else if (!strcmp (typename, "void"))
7157 klass = mono_defaults.void_class;
7158 else if (!strcmp (typename, "int32"))
7159 klass = mono_defaults.int32_class;
7160 else if (!strcmp (typename, "uint32"))
7161 klass = mono_defaults.uint32_class;
7162 else if (!strcmp (typename, "int8"))
7163 klass = mono_defaults.sbyte_class;
7164 else if (!strcmp (typename, "uint8"))
7165 klass = mono_defaults.byte_class;
7166 else if (!strcmp (typename, "int16"))
7167 klass = mono_defaults.int16_class;
7168 else if (!strcmp (typename, "uint16"))
7169 klass = mono_defaults.uint16_class;
7170 else if (!strcmp (typename, "long"))
7171 klass = mono_defaults.int64_class;
7172 else if (!strcmp (typename, "ulong"))
7173 klass = mono_defaults.uint64_class;
7174 else if (!strcmp (typename, "float"))
7175 klass = mono_defaults.single_class;
7176 else if (!strcmp (typename, "double"))
7177 klass = mono_defaults.double_class;
7178 else if (!strcmp (typename, "object"))
7179 klass = mono_defaults.object_class;
7180 else if (!strcmp (typename, "obj"))
7181 klass = mono_defaults.object_class;
7184 g_assert_not_reached ();
7186 return &klass->byval_arg;
7189 MonoMethodSignature*
7190 mono_create_icall_signature (const char *sigstr)
7195 MonoMethodSignature *res;
7197 mono_loader_lock ();
7198 res = g_hash_table_lookup (mono_defaults.corlib->helper_signatures, sigstr);
7200 mono_loader_unlock ();
7204 parts = g_strsplit (sigstr, " ", 256);
7213 res = mono_metadata_signature_alloc (mono_defaults.corlib, len - 1);
7216 #ifdef PLATFORM_WIN32
7218 * Under windows, the default pinvoke calling convention is STDCALL but
7221 res->call_convention = MONO_CALL_C;
7224 res->ret = type_from_typename (parts [0]);
7225 for (i = 1; i < len; ++i) {
7226 res->params [i - 1] = type_from_typename (parts [i]);
7231 g_hash_table_insert (mono_defaults.corlib->helper_signatures, (gpointer)sigstr, res);
7233 mono_loader_unlock ();
7239 mono_find_jit_icall_by_name (const char *name)
7241 MonoJitICallInfo *info;
7242 g_assert (jit_icall_hash_name);
7244 mono_loader_lock ();
7245 info = g_hash_table_lookup (jit_icall_hash_name, name);
7246 mono_loader_unlock ();
7251 mono_find_jit_icall_by_addr (gconstpointer addr)
7253 MonoJitICallInfo *info;
7254 g_assert (jit_icall_hash_addr);
7256 mono_loader_lock ();
7257 info = g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
7258 mono_loader_unlock ();
7264 mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
7266 mono_loader_lock ();
7267 g_hash_table_insert (jit_icall_hash_addr, (gpointer)wrapper, info);
7268 mono_loader_unlock ();
7272 mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
7274 MonoJitICallInfo *info;
7279 mono_loader_lock ();
7281 if (!jit_icall_hash_name) {
7282 jit_icall_hash_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
7283 jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
7286 if (g_hash_table_lookup (jit_icall_hash_name, name)) {
7287 g_warning ("jit icall already defined \"%s\"\n", name);
7288 g_assert_not_reached ();
7291 info = g_new0 (MonoJitICallInfo, 1);
7298 info->wrapper = func;
7300 info->wrapper = NULL;
7303 g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
7304 g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
7306 mono_loader_unlock ();