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 = bsd_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, NULL): NULL;
1688 if ((req_info & PInfo_SetMethod) != 0)
1689 info->set = property->property->set ?
1690 mono_method_get_object (domain, property->property->set, NULL): 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 // GelElementType 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 if (class->enumtype && class->enum_basetype) /* types that are modifierd typebuilkders may not have enum_basetype set */
1841 return mono_type_get_object (mono_object_domain (type), class->enum_basetype);
1842 else if (class->element_class && MONO_CLASS_IS_ARRAY (class))
1843 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
1844 else if (class->element_class && type->type->type == MONO_TYPE_PTR)
1845 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
1850 static MonoReflectionType*
1851 ves_icall_get_type_parent (MonoReflectionType *type)
1853 MonoClass *class = mono_class_from_mono_type (type->type);
1855 MONO_ARCH_SAVE_REGS;
1857 return class->parent ? mono_type_get_object (mono_object_domain (type), &class->parent->byval_arg): NULL;
1861 ves_icall_type_ispointer (MonoReflectionType *type)
1863 MONO_ARCH_SAVE_REGS;
1865 return type->type->type == MONO_TYPE_PTR;
1869 ves_icall_type_isprimitive (MonoReflectionType *type)
1871 MONO_ARCH_SAVE_REGS;
1873 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)));
1877 ves_icall_type_isbyref (MonoReflectionType *type)
1879 MONO_ARCH_SAVE_REGS;
1881 return type->type->byref;
1885 ves_icall_type_iscomobject (MonoReflectionType *type)
1887 MonoClass *klass = mono_class_from_mono_type (type->type);
1888 MONO_ARCH_SAVE_REGS;
1890 return (klass && klass->is_com_object);
1893 static MonoReflectionModule*
1894 ves_icall_MonoType_get_Module (MonoReflectionType *type)
1896 MonoClass *class = mono_class_from_mono_type (type->type);
1898 MONO_ARCH_SAVE_REGS;
1900 return mono_module_get_object (mono_object_domain (type), class->image);
1903 static MonoReflectionAssembly*
1904 ves_icall_MonoType_get_Assembly (MonoReflectionType *type)
1906 MonoDomain *domain = mono_domain_get ();
1907 MonoClass *class = mono_class_from_mono_type (type->type);
1909 MONO_ARCH_SAVE_REGS;
1911 return mono_assembly_get_object (domain, class->image->assembly);
1914 static MonoReflectionType*
1915 ves_icall_MonoType_get_DeclaringType (MonoReflectionType *type)
1917 MonoDomain *domain = mono_domain_get ();
1920 MONO_ARCH_SAVE_REGS;
1922 if (type->type->byref)
1924 if (type->type->type == MONO_TYPE_VAR)
1925 class = type->type->data.generic_param->owner->owner.klass;
1926 else if (type->type->type == MONO_TYPE_MVAR)
1927 class = type->type->data.generic_param->owner->owner.method->klass;
1929 class = mono_class_from_mono_type (type->type)->nested_in;
1931 return class ? mono_type_get_object (domain, &class->byval_arg) : NULL;
1934 static MonoReflectionType*
1935 ves_icall_MonoType_get_UnderlyingSystemType (MonoReflectionType *type)
1937 MonoDomain *domain = mono_domain_get ();
1938 MonoClass *class = mono_class_from_mono_type (type->type);
1940 MONO_ARCH_SAVE_REGS;
1942 if (class->enumtype && class->enum_basetype) /* types that are modified typebuilders may not have enum_basetype set */
1943 return mono_type_get_object (domain, class->enum_basetype);
1944 else if (class->element_class)
1945 return mono_type_get_object (domain, &class->element_class->byval_arg);
1951 ves_icall_MonoType_get_Name (MonoReflectionType *type)
1953 MonoDomain *domain = mono_domain_get ();
1954 MonoClass *class = mono_class_from_mono_type (type->type);
1956 MONO_ARCH_SAVE_REGS;
1958 if (type->type->byref) {
1959 char *n = g_strdup_printf ("%s&", class->name);
1960 MonoString *res = mono_string_new (domain, n);
1966 return mono_string_new (domain, class->name);
1971 ves_icall_MonoType_get_Namespace (MonoReflectionType *type)
1973 MonoDomain *domain = mono_domain_get ();
1974 MonoClass *class = mono_class_from_mono_type (type->type);
1976 MONO_ARCH_SAVE_REGS;
1978 while (class->nested_in)
1979 class = class->nested_in;
1981 if (class->name_space [0] == '\0')
1984 return mono_string_new (domain, class->name_space);
1988 ves_icall_MonoType_GetArrayRank (MonoReflectionType *type)
1990 MonoClass *class = mono_class_from_mono_type (type->type);
1992 MONO_ARCH_SAVE_REGS;
1998 ves_icall_MonoType_GetGenericArguments (MonoReflectionType *type)
2001 MonoClass *klass, *pklass;
2003 MONO_ARCH_SAVE_REGS;
2005 klass = mono_class_from_mono_type (type->type);
2007 if (klass->generic_container) {
2008 MonoGenericContainer *container = klass->generic_container;
2009 res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, container->type_argc);
2010 for (i = 0; i < container->type_argc; ++i) {
2011 pklass = mono_class_from_generic_parameter (&container->type_params [i], klass->image, FALSE);
2012 mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), &pklass->byval_arg));
2014 } else if (klass->generic_class) {
2015 MonoGenericInst *inst = klass->generic_class->context.class_inst;
2016 res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, inst->type_argc);
2017 for (i = 0; i < inst->type_argc; ++i)
2018 mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), inst->type_argv [i]));
2020 res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, 0);
2026 ves_icall_Type_get_IsGenericTypeDefinition (MonoReflectionType *type)
2029 MONO_ARCH_SAVE_REGS;
2031 if (type->type->byref)
2034 klass = mono_class_from_mono_type (type->type);
2036 return klass->generic_container != NULL;
2039 static MonoReflectionType*
2040 ves_icall_Type_GetGenericTypeDefinition_impl (MonoReflectionType *type)
2043 MONO_ARCH_SAVE_REGS;
2045 if (type->type->byref)
2048 klass = mono_class_from_mono_type (type->type);
2049 if (klass->generic_container) {
2050 return type; /* check this one */
2052 if (klass->generic_class) {
2053 MonoClass *generic_class = klass->generic_class->container_class;
2055 if (generic_class->wastypebuilder && generic_class->reflection_info)
2056 return generic_class->reflection_info;
2058 return mono_type_get_object (mono_object_domain (type), &generic_class->byval_arg);
2063 static MonoReflectionType*
2064 ves_icall_Type_MakeGenericType (MonoReflectionType *type, MonoArray *type_array)
2066 MonoType *geninst, **types;
2069 MONO_ARCH_SAVE_REGS;
2071 count = mono_array_length (type_array);
2072 types = g_new0 (MonoType *, count);
2074 for (i = 0; i < count; i++) {
2075 MonoReflectionType *t = mono_array_get (type_array, gpointer, i);
2076 types [i] = t->type;
2079 geninst = mono_reflection_bind_generic_parameters (type, count, types);
2084 return mono_type_get_object (mono_object_domain (type), geninst);
2088 ves_icall_Type_get_IsGenericInstance (MonoReflectionType *type)
2091 MONO_ARCH_SAVE_REGS;
2093 if (type->type->byref)
2096 klass = mono_class_from_mono_type (type->type);
2097 return klass->generic_class != NULL;
2101 ves_icall_Type_get_IsGenericType (MonoReflectionType *type)
2104 MONO_ARCH_SAVE_REGS;
2106 if (type->type->byref)
2109 klass = mono_class_from_mono_type (type->type);
2110 return klass->generic_class != NULL || klass->generic_container != NULL;
2114 ves_icall_Type_GetGenericParameterPosition (MonoReflectionType *type)
2116 MONO_ARCH_SAVE_REGS;
2118 if (is_generic_parameter (type->type))
2119 return type->type->data.generic_param->num;
2123 static GenericParameterAttributes
2124 ves_icall_Type_GetGenericParameterAttributes (MonoReflectionType *type)
2126 MONO_ARCH_SAVE_REGS;
2127 g_assert (is_generic_parameter (type->type));
2128 return type->type->data.generic_param->flags;
2132 ves_icall_Type_GetGenericParameterConstraints (MonoReflectionType *type)
2134 MonoGenericParam *param;
2140 MONO_ARCH_SAVE_REGS;
2142 domain = mono_object_domain (type);
2143 param = type->type->data.generic_param;
2144 for (count = 0, ptr = param->constraints; ptr && *ptr; ptr++, count++)
2147 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2148 for (i = 0; i < count; i++)
2149 mono_array_setref (res, i, mono_type_get_object (domain, ¶m->constraints [i]->byval_arg));
2156 ves_icall_MonoType_get_IsGenericParameter (MonoReflectionType *type)
2158 MONO_ARCH_SAVE_REGS;
2159 return is_generic_parameter (type->type);
2163 ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder *tb)
2165 MONO_ARCH_SAVE_REGS;
2166 return is_generic_parameter (tb->type.type);
2170 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
2171 MonoReflectionType *t)
2173 enumtype->type = t->type;
2176 static MonoReflectionType*
2177 ves_icall_MonoGenericClass_GetParentType (MonoReflectionGenericClass *type)
2179 MonoDynamicGenericClass *gclass;
2180 MonoReflectionType *parent = NULL;
2185 MONO_ARCH_SAVE_REGS;
2187 g_assert (type->type.type->data.generic_class->is_dynamic);
2188 gclass = (MonoDynamicGenericClass *) type->type.type->data.generic_class;
2190 domain = mono_object_domain (type);
2191 klass = mono_class_from_mono_type (type->generic_type->type);
2193 if (!klass->generic_class && !klass->generic_container)
2196 if (!strcmp (type->generic_type->object.vtable->klass->name, "TypeBuilder")) {
2197 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *) type->generic_type;
2198 parent = tb->parent;
2199 } else if (klass->wastypebuilder) {
2200 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *) type->generic_type;
2201 parent = tb->parent;
2203 MonoClass *pklass = klass->parent;
2205 parent = mono_type_get_object (domain, &pklass->byval_arg);
2208 if (!parent || (parent->type->type != MONO_TYPE_GENERICINST))
2211 inflated = mono_class_inflate_generic_type (
2212 parent->type, mono_generic_class_get_context ((MonoGenericClass *) gclass));
2214 return mono_type_get_object (domain, inflated);
2218 ves_icall_MonoGenericClass_GetInterfaces (MonoReflectionGenericClass *type)
2220 static MonoClass *System_Reflection_MonoGenericClass;
2221 MonoGenericClass *gclass;
2222 MonoReflectionTypeBuilder *tb = NULL;
2223 MonoClass *klass = NULL;
2228 MONO_ARCH_SAVE_REGS;
2230 if (!System_Reflection_MonoGenericClass) {
2231 System_Reflection_MonoGenericClass = mono_class_from_name (
2232 mono_defaults.corlib, "System.Reflection", "MonoGenericClass");
2233 g_assert (System_Reflection_MonoGenericClass);
2236 domain = mono_object_domain (type);
2238 gclass = type->type.type->data.generic_class;
2239 g_assert (gclass->is_dynamic);
2241 if (!strcmp (type->generic_type->object.vtable->klass->name, "TypeBuilder")) {
2242 tb = (MonoReflectionTypeBuilder *) type->generic_type;
2243 icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
2245 klass = gclass->container_class;
2246 mono_class_init (klass);
2247 icount = klass->interface_count;
2250 res = mono_array_new (domain, System_Reflection_MonoGenericClass, icount);
2252 for (i = 0; i < icount; i++) {
2253 MonoReflectionType *iface;
2257 iface = mono_array_get (tb->interfaces, MonoReflectionType *, i);
2260 it = &klass->interfaces [i]->byval_arg;
2262 it = mono_class_inflate_generic_type (it, mono_generic_class_get_context (gclass));
2264 iface = mono_type_get_object (domain, it);
2265 mono_array_setref (res, i, iface);
2271 static MonoReflectionMethod*
2272 ves_icall_MonoGenericClass_GetCorrespondingInflatedMethod (MonoReflectionGenericClass *type,
2273 MonoReflectionMethod* generic)
2275 MonoGenericClass *gclass;
2276 MonoDynamicGenericClass *dgclass;
2280 MONO_ARCH_SAVE_REGS;
2282 gclass = type->type.type->data.generic_class;
2283 g_assert (gclass->is_dynamic);
2285 dgclass = (MonoDynamicGenericClass *) gclass;
2287 domain = mono_object_domain (type);
2289 for (i = 0; i < dgclass->count_methods; i++)
2290 if (generic->method->token == dgclass->methods [i]->token)
2291 return mono_method_get_object (domain, dgclass->methods [i], NULL);
2296 static MonoReflectionMethod*
2297 ves_icall_MonoGenericClass_GetCorrespondingInflatedConstructor (MonoReflectionGenericClass *type,
2298 MonoReflectionMethod* generic)
2300 MonoGenericClass *gclass;
2301 MonoDynamicGenericClass *dgclass;
2305 MONO_ARCH_SAVE_REGS;
2307 gclass = type->type.type->data.generic_class;
2308 g_assert (gclass->is_dynamic);
2310 dgclass = (MonoDynamicGenericClass *) gclass;
2312 domain = mono_object_domain (type);
2314 for (i = 0; i < dgclass->count_ctors; i++)
2315 if (generic->method->token == dgclass->ctors [i]->token)
2316 return mono_method_get_object (domain, dgclass->ctors [i], NULL);
2322 static MonoReflectionField*
2323 ves_icall_MonoGenericClass_GetCorrespondingInflatedField (MonoReflectionGenericClass *type,
2324 MonoString* generic_name)
2326 MonoGenericClass *gclass;
2327 MonoDynamicGenericClass *dgclass;
2329 MonoClass *refclass;
2330 char *utf8_name = mono_string_to_utf8 (generic_name);
2333 MONO_ARCH_SAVE_REGS;
2335 gclass = type->type.type->data.generic_class;
2336 g_assert (gclass->is_dynamic);
2338 dgclass = (MonoDynamicGenericClass *) gclass;
2340 refclass = mono_class_from_mono_type (type->type.type);
2342 domain = mono_object_domain (type);
2344 for (i = 0; i < dgclass->count_fields; i++)
2345 if (strcmp (utf8_name, dgclass->fields [i].name) == 0) {
2347 return mono_field_get_object (domain, refclass, &dgclass->fields [i]);
2356 static MonoReflectionMethod*
2357 ves_icall_MonoType_GetCorrespondingInflatedMethod (MonoReflectionType *type,
2358 MonoReflectionMethod* generic)
2365 MONO_ARCH_SAVE_REGS;
2367 domain = ((MonoObject *)type)->vtable->domain;
2369 klass = mono_class_from_mono_type (type->type);
2372 while ((method = mono_class_get_methods (klass, &iter))) {
2373 if (method->token == generic->method->token)
2374 return mono_method_get_object (domain, method, klass);
2381 ves_icall_MonoGenericClass_GetMethods (MonoReflectionGenericClass *type,
2382 MonoReflectionType *reflected_type)
2384 MonoGenericClass *gclass;
2385 MonoDynamicGenericClass *dgclass;
2387 MonoClass *refclass;
2391 MONO_ARCH_SAVE_REGS;
2393 gclass = type->type.type->data.generic_class;
2394 g_assert (gclass->is_dynamic);
2395 dgclass = (MonoDynamicGenericClass *) gclass;
2397 refclass = mono_class_from_mono_type (reflected_type->type);
2399 domain = mono_object_domain (type);
2400 res = mono_array_new (domain, mono_defaults.method_info_class, dgclass->count_methods);
2402 for (i = 0; i < dgclass->count_methods; i++)
2403 mono_array_setref (res, i, mono_method_get_object (domain, dgclass->methods [i], refclass));
2409 ves_icall_MonoGenericClass_GetConstructors (MonoReflectionGenericClass *type,
2410 MonoReflectionType *reflected_type)
2412 static MonoClass *System_Reflection_ConstructorInfo;
2413 MonoGenericClass *gclass;
2414 MonoDynamicGenericClass *dgclass;
2416 MonoClass *refclass;
2420 MONO_ARCH_SAVE_REGS;
2422 if (!System_Reflection_ConstructorInfo)
2423 System_Reflection_ConstructorInfo = mono_class_from_name (
2424 mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
2426 gclass = type->type.type->data.generic_class;
2427 g_assert (gclass->is_dynamic);
2428 dgclass = (MonoDynamicGenericClass *) gclass;
2430 refclass = mono_class_from_mono_type (reflected_type->type);
2432 domain = mono_object_domain (type);
2433 res = mono_array_new (domain, System_Reflection_ConstructorInfo, dgclass->count_ctors);
2435 for (i = 0; i < dgclass->count_ctors; i++)
2436 mono_array_setref (res, i, mono_method_get_object (domain, dgclass->ctors [i], refclass));
2442 ves_icall_MonoGenericClass_GetFields (MonoReflectionGenericClass *type,
2443 MonoReflectionType *reflected_type)
2445 MonoGenericClass *gclass;
2446 MonoDynamicGenericClass *dgclass;
2448 MonoClass *refclass;
2452 MONO_ARCH_SAVE_REGS;
2454 gclass = type->type.type->data.generic_class;
2455 g_assert (gclass->is_dynamic);
2456 dgclass = (MonoDynamicGenericClass *) gclass;
2458 refclass = mono_class_from_mono_type (reflected_type->type);
2460 domain = mono_object_domain (type);
2461 res = mono_array_new (domain, mono_defaults.field_info_class, dgclass->count_fields);
2463 for (i = 0; i < dgclass->count_fields; i++)
2464 mono_array_setref (res, i, mono_field_get_object (domain, refclass, &dgclass->fields [i]));
2470 ves_icall_MonoGenericClass_GetProperties (MonoReflectionGenericClass *type,
2471 MonoReflectionType *reflected_type)
2473 static MonoClass *System_Reflection_PropertyInfo;
2474 MonoGenericClass *gclass;
2475 MonoDynamicGenericClass *dgclass;
2477 MonoClass *refclass;
2481 MONO_ARCH_SAVE_REGS;
2483 if (!System_Reflection_PropertyInfo)
2484 System_Reflection_PropertyInfo = mono_class_from_name (
2485 mono_defaults.corlib, "System.Reflection", "PropertyInfo");
2487 gclass = type->type.type->data.generic_class;
2488 g_assert (gclass->is_dynamic);
2489 dgclass = (MonoDynamicGenericClass *) gclass;
2491 refclass = mono_class_from_mono_type (reflected_type->type);
2493 domain = mono_object_domain (type);
2494 res = mono_array_new (domain, System_Reflection_PropertyInfo, dgclass->count_properties);
2496 for (i = 0; i < dgclass->count_properties; i++)
2497 mono_array_setref (res, i, mono_property_get_object (domain, refclass, &dgclass->properties [i]));
2503 ves_icall_MonoGenericClass_GetEvents (MonoReflectionGenericClass *type,
2504 MonoReflectionType *reflected_type)
2506 static MonoClass *System_Reflection_EventInfo;
2507 MonoGenericClass *gclass;
2508 MonoDynamicGenericClass *dgclass;
2510 MonoClass *refclass;
2514 MONO_ARCH_SAVE_REGS;
2516 if (!System_Reflection_EventInfo)
2517 System_Reflection_EventInfo = mono_class_from_name (
2518 mono_defaults.corlib, "System.Reflection", "EventInfo");
2520 gclass = type->type.type->data.generic_class;
2521 g_assert (gclass->is_dynamic);
2522 dgclass = (MonoDynamicGenericClass *) gclass;
2524 refclass = mono_class_from_mono_type (reflected_type->type);
2526 domain = mono_object_domain (type);
2527 res = mono_array_new (domain, System_Reflection_EventInfo, dgclass->count_events);
2529 for (i = 0; i < dgclass->count_events; i++)
2530 mono_array_setref (res, i, mono_event_get_object (domain, refclass, &dgclass->events [i]));
2535 static MonoReflectionMethod *
2536 ves_icall_MonoType_get_DeclaringMethod (MonoReflectionType *type)
2541 MONO_ARCH_SAVE_REGS;
2543 if (type->type->byref || type->type->type != MONO_TYPE_MVAR)
2546 method = type->type->data.generic_param->owner->owner.method;
2548 klass = mono_class_from_mono_type (type->type);
2549 return mono_method_get_object (mono_object_domain (type), method, klass);
2552 static MonoReflectionDllImportAttribute*
2553 ves_icall_MonoMethod_GetDllImportAttribute (MonoMethod *method)
2555 static MonoClass *DllImportAttributeClass = NULL;
2556 MonoDomain *domain = mono_domain_get ();
2557 MonoReflectionDllImportAttribute *attr;
2558 MonoImage *image = method->klass->image;
2559 MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method;
2560 MonoTableInfo *tables = image->tables;
2561 MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
2562 MonoTableInfo *mr = &tables [MONO_TABLE_MODULEREF];
2563 guint32 im_cols [MONO_IMPLMAP_SIZE];
2564 guint32 scope_token;
2565 const char *import = NULL;
2566 const char *scope = NULL;
2569 if (!method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)
2572 if (!DllImportAttributeClass) {
2573 DllImportAttributeClass =
2574 mono_class_from_name (mono_defaults.corlib,
2575 "System.Runtime.InteropServices", "DllImportAttribute");
2576 g_assert (DllImportAttributeClass);
2579 if (method->klass->image->dynamic) {
2580 MonoReflectionMethodAux *method_aux =
2581 g_hash_table_lookup (
2582 ((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
2584 import = method_aux->dllentry;
2585 scope = method_aux->dll;
2589 if (piinfo->implmap_idx) {
2590 mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
2592 piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
2593 import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
2594 scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
2595 scope = mono_metadata_string_heap (image, scope_token);
2598 flags = piinfo->piflags;
2600 attr = (MonoReflectionDllImportAttribute*)mono_object_new (domain, DllImportAttributeClass);
2602 MONO_OBJECT_SETREF (attr, dll, mono_string_new (domain, scope));
2603 MONO_OBJECT_SETREF (attr, entry_point, mono_string_new (domain, import));
2604 attr->call_conv = (flags & 0x700) >> 8;
2605 attr->charset = ((flags & 0x6) >> 1) + 1;
2606 if (attr->charset == 1)
2608 attr->exact_spelling = (flags & 0x1) != 0;
2609 attr->set_last_error = (flags & 0x40) != 0;
2610 attr->best_fit_mapping = (flags & 0x30) == 0x10;
2611 attr->throw_on_unmappable = (flags & 0x3000) == 0x1000;
2612 attr->preserve_sig = FALSE;
2617 static MonoReflectionMethod *
2618 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
2620 MonoMethodInflated *imethod;
2622 MONO_ARCH_SAVE_REGS;
2624 if (method->method->generic_container)
2627 if (!method->method->is_inflated)
2630 imethod = (MonoMethodInflated *) method->method;
2632 if (imethod->reflection_info)
2633 return imethod->reflection_info;
2635 return mono_method_get_object (
2636 mono_object_domain (method), imethod->declaring, NULL);
2640 ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethod *method)
2642 MONO_ARCH_SAVE_REGS;
2644 return mono_method_signature (method->method)->generic_param_count != 0;
2648 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method)
2650 MONO_ARCH_SAVE_REGS;
2652 return method->method->generic_container != NULL;
2656 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
2661 MONO_ARCH_SAVE_REGS;
2663 domain = mono_object_domain (method);
2665 if (method->method->is_inflated) {
2666 MonoGenericInst *inst = mono_method_get_context (method->method)->method_inst;
2669 count = inst->type_argc;
2670 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2672 for (i = 0; i < count; i++)
2673 mono_array_setref (res, i, mono_type_get_object (domain, inst->type_argv [i]));
2679 count = mono_method_signature (method->method)->generic_param_count;
2680 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2682 for (i = 0; i < count; i++) {
2683 MonoGenericParam *param = &method->method->generic_container->type_params [i];
2684 MonoClass *pklass = mono_class_from_generic_parameter (
2685 param, method->method->klass->image, TRUE);
2686 mono_array_setref (res, i,
2687 mono_type_get_object (domain, &pklass->byval_arg));
2694 ensure_reflection_security (void)
2696 MonoMethod *m = mono_method_get_last_managed ();
2700 g_print ("method %s.%s.%s in image %s\n",
2701 m->klass->name_space, m->klass->name, m->name, m->klass->image->name);
2704 /* We stop at the first method which is not in
2705 System.Reflection or which is not in a platform
2707 if (strcmp (m->klass->name_space, "System.Reflection") != 0 ||
2708 !mono_security_core_clr_is_platform_image (m->klass->image)) {
2709 /* If the method is transparent we throw an exception. */
2710 if (mono_security_core_clr_method_level (m, TRUE) == MONO_SECURITY_CORE_CLR_TRANSPARENT ) {
2711 MonoException *ex = mono_exception_from_name_msg (mono_defaults.corlib, "System", "MethodAccessException", "Reflection called from transparent code");
2713 mono_raise_exception (ex);
2718 mono_stack_walk_no_il (get_caller, &m);
2723 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoArray *params)
2726 * Invoke from reflection is supposed to always be a virtual call (the API
2727 * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
2728 * greater flexibility.
2730 MonoMethod *m = method->method;
2734 MONO_ARCH_SAVE_REGS;
2736 if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR &&
2737 mono_security_core_clr_method_level (m, TRUE) == MONO_SECURITY_CORE_CLR_CRITICAL)
2738 ensure_reflection_security ();
2740 if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
2742 if (!mono_object_isinst (this, m->klass))
2743 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
2744 m = mono_object_get_virtual_method (this, m);
2745 /* must pass the pointer to the value for valuetype methods */
2746 if (m->klass->valuetype)
2747 obj = mono_object_unbox (this);
2748 } else if (strcmp (m->name, ".ctor") && !m->wrapper_type)
2749 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
2752 pcount = params? mono_array_length (params): 0;
2753 if (pcount != mono_method_signature (m)->param_count)
2754 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
2756 if ((m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) && !strcmp (m->name, ".ctor") && !this)
2757 mono_raise_exception (mono_exception_from_name_msg (mono_defaults.corlib, "System", "MethodAccessException", "Cannot invoke constructor of an abstract class."));
2759 if (m->klass->image->assembly->ref_only)
2760 mono_raise_exception (mono_get_exception_invalid_operation ("It is illegal to invoke a method on a type loaded using the ReflectionOnly api."));
2762 if (m->klass->rank && !strcmp (m->name, ".ctor")) {
2765 guint32 *lower_bounds;
2766 pcount = mono_array_length (params);
2767 lengths = alloca (sizeof (guint32) * pcount);
2768 for (i = 0; i < pcount; ++i)
2769 lengths [i] = *(gint32*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
2771 if (m->klass->rank == pcount) {
2772 /* Only lengths provided. */
2773 lower_bounds = NULL;
2775 g_assert (pcount == (m->klass->rank * 2));
2776 /* lower bounds are first. */
2777 lower_bounds = lengths;
2778 lengths += m->klass->rank;
2781 return (MonoObject*)mono_array_new_full (mono_object_domain (params), m->klass, lengths, lower_bounds);
2783 return mono_runtime_invoke_array (m, obj, params, NULL);
2787 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this, MonoArray *params, MonoArray **outArgs)
2789 MonoDomain *domain = mono_object_domain (method);
2790 MonoMethod *m = method->method;
2791 MonoMethodSignature *sig = mono_method_signature (m);
2792 MonoArray *out_args;
2794 int i, j, outarg_count = 0;
2796 MONO_ARCH_SAVE_REGS;
2798 if (m->klass == mono_defaults.object_class) {
2800 if (!strcmp (m->name, "FieldGetter")) {
2801 MonoClass *k = this->vtable->klass;
2805 /* If this is a proxy, then it must be a CBO */
2806 if (k == mono_defaults.transparent_proxy_class) {
2807 MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
2808 this = tp->rp->unwrapped_server;
2810 k = this->vtable->klass;
2813 name = mono_array_get (params, MonoString *, 1);
2814 str = mono_string_to_utf8 (name);
2817 MonoClassField* field = mono_class_get_field_from_name (k, str);
2819 MonoClass *field_klass = mono_class_from_mono_type (field->type);
2820 if (field_klass->valuetype)
2821 result = mono_value_box (domain, field_klass, (char *)this + field->offset);
2823 result = *((gpointer *)((char *)this + field->offset));
2825 out_args = mono_array_new (domain, mono_defaults.object_class, 1);
2826 *outArgs = out_args;
2827 mono_array_setref (out_args, 0, result);
2835 g_assert_not_reached ();
2837 } else if (!strcmp (m->name, "FieldSetter")) {
2838 MonoClass *k = this->vtable->klass;
2844 /* If this is a proxy, then it must be a CBO */
2845 if (k == mono_defaults.transparent_proxy_class) {
2846 MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
2847 this = tp->rp->unwrapped_server;
2849 k = this->vtable->klass;
2852 name = mono_array_get (params, MonoString *, 1);
2853 str = mono_string_to_utf8 (name);
2856 MonoClassField* field = mono_class_get_field_from_name (k, str);
2858 MonoClass *field_klass = mono_class_from_mono_type (field->type);
2859 MonoObject *val = mono_array_get (params, gpointer, 2);
2861 if (field_klass->valuetype) {
2862 size = mono_type_size (field->type, &align);
2863 memcpy ((char *)this + field->offset,
2864 ((char *)val) + sizeof (MonoObject), size);
2866 *(MonoObject**)((char *)this + field->offset) = val;
2868 out_args = mono_array_new (domain, mono_defaults.object_class, 0);
2869 *outArgs = out_args;
2879 g_assert_not_reached ();
2884 for (i = 0; i < mono_array_length (params); i++) {
2885 if (sig->params [i]->byref)
2889 out_args = mono_array_new (domain, mono_defaults.object_class, outarg_count);
2891 /* handle constructors only for objects already allocated */
2892 if (!strcmp (method->method->name, ".ctor"))
2895 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
2896 g_assert (!method->method->klass->valuetype);
2897 result = mono_runtime_invoke_array (method->method, this, params, NULL);
2899 for (i = 0, j = 0; i < mono_array_length (params); i++) {
2900 if (sig->params [i]->byref) {
2902 arg = mono_array_get (params, gpointer, i);
2903 mono_array_setref (out_args, j, arg);
2908 *outArgs = out_args;
2914 read_enum_value (char *mem, int type)
2918 return *(guint8*)mem;
2920 return *(gint8*)mem;
2922 return *(guint16*)mem;
2924 return *(gint16*)mem;
2926 return *(guint32*)mem;
2928 return *(gint32*)mem;
2930 return *(guint64*)mem;
2932 return *(gint64*)mem;
2934 g_assert_not_reached ();
2940 write_enum_value (char *mem, int type, guint64 value)
2944 case MONO_TYPE_I1: {
2945 guint8 *p = (guint8*)mem;
2950 case MONO_TYPE_I2: {
2951 guint16 *p = (void*)mem;
2956 case MONO_TYPE_I4: {
2957 guint32 *p = (void*)mem;
2962 case MONO_TYPE_I8: {
2963 guint64 *p = (void*)mem;
2968 g_assert_not_reached ();
2974 ves_icall_System_Enum_ToObject (MonoReflectionType *type, MonoObject *obj)
2977 MonoClass *enumc, *objc;
2981 MONO_ARCH_SAVE_REGS;
2983 MONO_CHECK_ARG_NULL (type);
2984 MONO_CHECK_ARG_NULL (obj);
2986 domain = mono_object_domain (type);
2987 enumc = mono_class_from_mono_type (type->type);
2988 objc = obj->vtable->klass;
2990 if (!enumc->enumtype)
2991 mono_raise_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
2992 if (!((objc->enumtype) || (objc->byval_arg.type >= MONO_TYPE_I1 && objc->byval_arg.type <= MONO_TYPE_U8)))
2993 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."));
2995 res = mono_object_new (domain, enumc);
2996 val = read_enum_value ((char *)obj + sizeof (MonoObject), objc->enumtype? objc->enum_basetype->type: objc->byval_arg.type);
2997 write_enum_value ((char *)res + sizeof (MonoObject), enumc->enum_basetype->type, val);
3003 ves_icall_System_Enum_get_value (MonoObject *this)
3011 MONO_ARCH_SAVE_REGS;
3016 g_assert (this->vtable->klass->enumtype);
3018 enumc = mono_class_from_mono_type (this->vtable->klass->enum_basetype);
3019 res = mono_object_new (mono_object_domain (this), enumc);
3020 dst = (char *)res + sizeof (MonoObject);
3021 src = (char *)this + sizeof (MonoObject);
3022 size = mono_class_value_size (enumc, NULL);
3024 memcpy (dst, src, size);
3030 ves_icall_get_enum_info (MonoReflectionType *type, MonoEnumInfo *info)
3032 MonoDomain *domain = mono_object_domain (type);
3033 MonoClass *enumc = mono_class_from_mono_type (type->type);
3034 guint j = 0, nvalues, crow;
3036 MonoClassField *field;
3038 MONO_ARCH_SAVE_REGS;
3040 info->utype = mono_type_get_object (domain, enumc->enum_basetype);
3041 nvalues = mono_class_num_fields (enumc) ? mono_class_num_fields (enumc) - 1 : 0;
3042 info->names = mono_array_new (domain, mono_defaults.string_class, nvalues);
3043 info->values = mono_array_new (domain, enumc, nvalues);
3047 while ((field = mono_class_get_fields (enumc, &iter))) {
3051 if (strcmp ("value__", field->name) == 0)
3053 if (mono_field_is_deleted (field))
3055 mono_array_setref (info->names, j, mono_string_new (domain, field->name));
3058 crow = mono_metadata_get_constant_index (enumc->image, mono_class_get_field_token (field), crow + 1);
3059 field->def_type = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_TYPE);
3060 crow = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_VALUE);
3061 field->data = (gpointer)mono_metadata_blob_heap (enumc->image, crow);
3065 len = mono_metadata_decode_blob_size (p, &p);
3066 switch (enumc->enum_basetype->type) {
3069 mono_array_set (info->values, gchar, j, *p);
3071 case MONO_TYPE_CHAR:
3074 mono_array_set (info->values, gint16, j, read16 (p));
3078 mono_array_set (info->values, gint32, j, read32 (p));
3082 mono_array_set (info->values, gint64, j, read64 (p));
3085 g_error ("Implement type 0x%02x in get_enum_info", enumc->enum_basetype->type);
3092 BFLAGS_IgnoreCase = 1,
3093 BFLAGS_DeclaredOnly = 2,
3094 BFLAGS_Instance = 4,
3096 BFLAGS_Public = 0x10,
3097 BFLAGS_NonPublic = 0x20,
3098 BFLAGS_FlattenHierarchy = 0x40,
3099 BFLAGS_InvokeMethod = 0x100,
3100 BFLAGS_CreateInstance = 0x200,
3101 BFLAGS_GetField = 0x400,
3102 BFLAGS_SetField = 0x800,
3103 BFLAGS_GetProperty = 0x1000,
3104 BFLAGS_SetProperty = 0x2000,
3105 BFLAGS_ExactBinding = 0x10000,
3106 BFLAGS_SuppressChangeType = 0x20000,
3107 BFLAGS_OptionalParamBinding = 0x40000
3110 static MonoReflectionField *
3111 ves_icall_Type_GetField (MonoReflectionType *type, MonoString *name, guint32 bflags)
3114 MonoClass *startklass, *klass;
3116 MonoClassField *field;
3119 int (*compare_func) (const char *s1, const char *s2) = NULL;
3120 domain = ((MonoObject *)type)->vtable->domain;
3121 klass = startklass = mono_class_from_mono_type (type->type);
3123 MONO_ARCH_SAVE_REGS;
3126 mono_raise_exception (mono_get_exception_argument_null ("name"));
3127 if (type->type->byref)
3130 compare_func = (bflags & BFLAGS_IgnoreCase) ? g_strcasecmp : strcmp;
3133 if (klass->exception_type != MONO_EXCEPTION_NONE)
3134 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3137 while ((field = mono_class_get_fields (klass, &iter))) {
3140 if (field->type == NULL)
3142 if (mono_field_is_deleted (field))
3144 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3145 if (bflags & BFLAGS_Public)
3148 if (bflags & BFLAGS_NonPublic)
3154 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
3155 if (bflags & BFLAGS_Static)
3156 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3159 if (bflags & BFLAGS_Instance)
3166 utf8_name = mono_string_to_utf8 (name);
3168 if (compare_func (field->name, utf8_name)) {
3174 return mono_field_get_object (domain, klass, field);
3176 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3183 ves_icall_Type_GetFields_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3186 MonoClass *startklass, *klass, *refklass;
3191 MonoClassField *field;
3193 MONO_ARCH_SAVE_REGS;
3195 domain = ((MonoObject *)type)->vtable->domain;
3196 if (type->type->byref)
3197 return mono_array_new (domain, mono_defaults.field_info_class, 0);
3198 klass = startklass = mono_class_from_mono_type (type->type);
3199 refklass = mono_class_from_mono_type (reftype->type);
3203 res = mono_array_new (domain, mono_defaults.field_info_class, len);
3205 if (klass->exception_type != MONO_EXCEPTION_NONE)
3206 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3209 while ((field = mono_class_get_fields (klass, &iter))) {
3211 if (mono_field_is_deleted (field))
3213 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3214 if (bflags & BFLAGS_Public)
3217 if (bflags & BFLAGS_NonPublic) {
3218 /* Serialization currently depends on the old behavior.
3219 * if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE || startklass == klass)*/
3226 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
3227 if (bflags & BFLAGS_Static)
3228 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3231 if (bflags & BFLAGS_Instance)
3237 member = (MonoObject*)mono_field_get_object (domain, refklass, field);
3239 MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, len * 2);
3240 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3244 mono_array_setref (res, i, member);
3247 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3250 MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, i);
3251 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3254 * Better solution for the new GC.
3255 * res->max_length = i;
3262 ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
3265 MonoClass *startklass, *klass, *refklass;
3270 int i, len, match, nslots;
3271 guint32 method_slots_default [8];
3272 guint32 *method_slots;
3273 gchar *mname = NULL;
3274 int (*compare_func) (const char *s1, const char *s2) = NULL;
3276 MONO_ARCH_SAVE_REGS;
3278 domain = ((MonoObject *)type)->vtable->domain;
3279 if (type->type->byref)
3280 return mono_array_new (domain, mono_defaults.method_info_class, 0);
3281 klass = startklass = mono_class_from_mono_type (type->type);
3282 refklass = mono_class_from_mono_type (reftype->type);
3285 mname = mono_string_to_utf8 (name);
3286 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
3289 mono_class_setup_vtable (klass);
3291 if (is_generic_parameter (type->type))
3292 nslots = klass->parent->vtable_size;
3294 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : klass->vtable_size;
3295 if (nslots >= sizeof (method_slots_default) * 8) {
3296 method_slots = g_new0 (guint32, nslots / 32 + 1);
3298 method_slots = method_slots_default;
3299 memset (method_slots, 0, sizeof (method_slots_default));
3303 res = mono_array_new (domain, mono_defaults.method_info_class, len);
3305 mono_class_setup_vtable (klass);
3306 if (klass->exception_type != MONO_EXCEPTION_NONE)
3307 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3310 while ((method = mono_class_get_methods (klass, &iter))) {
3312 if (method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
3314 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3315 if (bflags & BFLAGS_Public)
3318 if (bflags & BFLAGS_NonPublic)
3324 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3325 if (bflags & BFLAGS_Static)
3326 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3329 if (bflags & BFLAGS_Instance)
3337 if (compare_func (mname, method->name))
3342 if (method->slot != -1) {
3343 g_assert (method->slot < nslots);
3344 if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
3346 method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
3349 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
3352 MonoArray *new_res = mono_array_new (domain, mono_defaults.method_info_class, len * 2);
3353 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3357 mono_array_setref (res, i, member);
3360 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3364 if (method_slots != method_slots_default)
3365 g_free (method_slots);
3367 MonoArray *new_res = mono_array_new (domain, mono_defaults.method_info_class, i);
3368 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3371 * Better solution for the new GC.
3372 * res->max_length = i;
3379 ves_icall_Type_GetConstructors_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3382 static MonoClass *System_Reflection_ConstructorInfo;
3383 MonoClass *startklass, *klass, *refklass;
3388 gpointer iter = NULL;
3390 MONO_ARCH_SAVE_REGS;
3392 domain = ((MonoObject *)type)->vtable->domain;
3393 if (type->type->byref)
3394 return mono_array_new (domain, mono_defaults.method_info_class, 0);
3395 klass = startklass = mono_class_from_mono_type (type->type);
3396 refklass = mono_class_from_mono_type (reftype->type);
3398 if (klass->exception_type != MONO_EXCEPTION_NONE)
3399 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3401 if (!System_Reflection_ConstructorInfo)
3402 System_Reflection_ConstructorInfo = mono_class_from_name (
3403 mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
3407 res = mono_array_new (domain, System_Reflection_ConstructorInfo, len);
3409 while ((method = mono_class_get_methods (klass, &iter))) {
3411 if (strcmp (method->name, ".ctor") && strcmp (method->name, ".cctor"))
3413 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3414 if (bflags & BFLAGS_Public)
3417 if (bflags & BFLAGS_NonPublic)
3423 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3424 if (bflags & BFLAGS_Static)
3425 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3428 if (bflags & BFLAGS_Instance)
3434 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
3437 MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, len * 2);
3438 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3442 mono_array_setref (res, i, member);
3446 MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, i);
3447 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3450 * Better solution for the new GC.
3451 * res->max_length = i;
3458 ves_icall_Type_GetPropertiesByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
3461 static MonoClass *System_Reflection_PropertyInfo;
3462 MonoClass *startklass, *klass;
3466 int i, match, nslots;
3469 guint32 method_slots_default [8];
3470 guint32 *method_slots;
3471 gchar *propname = NULL;
3472 int (*compare_func) (const char *s1, const char *s2) = NULL;
3475 MONO_ARCH_SAVE_REGS;
3477 if (!System_Reflection_PropertyInfo)
3478 System_Reflection_PropertyInfo = mono_class_from_name (
3479 mono_defaults.corlib, "System.Reflection", "PropertyInfo");
3481 domain = ((MonoObject *)type)->vtable->domain;
3482 if (type->type->byref)
3483 return mono_array_new (domain, System_Reflection_PropertyInfo, 0);
3484 klass = startklass = mono_class_from_mono_type (type->type);
3486 propname = mono_string_to_utf8 (name);
3487 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
3490 mono_class_setup_vtable (klass);
3492 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : klass->vtable_size;
3493 if (nslots >= sizeof (method_slots_default) * 8) {
3494 method_slots = g_new0 (guint32, nslots / 32 + 1);
3496 method_slots = method_slots_default;
3497 memset (method_slots, 0, sizeof (method_slots_default));
3501 res = mono_array_new (domain, System_Reflection_PropertyInfo, len);
3503 mono_class_setup_vtable (klass);
3504 if (klass->exception_type != MONO_EXCEPTION_NONE) {
3505 if (method_slots != method_slots_default)
3506 g_free (method_slots);
3509 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3513 while ((prop = mono_class_get_properties (klass, &iter))) {
3519 flags = method->flags;
3522 if ((prop->get && ((prop->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC)) ||
3523 (prop->set && ((prop->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC))) {
3524 if (bflags & BFLAGS_Public)
3527 if (bflags & BFLAGS_NonPublic)
3533 if (flags & METHOD_ATTRIBUTE_STATIC) {
3534 if (bflags & BFLAGS_Static)
3535 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3538 if (bflags & BFLAGS_Instance)
3547 if (compare_func (propname, prop->name))
3551 if (prop->get && prop->get->slot != -1) {
3552 if (method_slots [prop->get->slot >> 5] & (1 << (prop->get->slot & 0x1f)))
3554 method_slots [prop->get->slot >> 5] |= 1 << (prop->get->slot & 0x1f);
3556 if (prop->set && prop->set->slot != -1) {
3557 if (method_slots [prop->set->slot >> 5] & (1 << (prop->set->slot & 0x1f)))
3559 method_slots [prop->set->slot >> 5] |= 1 << (prop->set->slot & 0x1f);
3563 MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, len * 2);
3564 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3568 mono_array_setref (res, i, mono_property_get_object (domain, startklass, prop));
3571 if ((!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent)))
3575 if (method_slots != method_slots_default)
3576 g_free (method_slots);
3578 MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, i);
3579 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3582 * Better solution for the new GC.
3583 * res->max_length = i;
3589 static MonoReflectionEvent *
3590 ves_icall_MonoType_GetEvent (MonoReflectionType *type, MonoString *name, guint32 bflags)
3593 MonoClass *klass, *startklass;
3599 MONO_ARCH_SAVE_REGS;
3601 event_name = mono_string_to_utf8 (name);
3602 if (type->type->byref)
3604 klass = startklass = mono_class_from_mono_type (type->type);
3605 domain = mono_object_domain (type);
3608 if (klass->exception_type != MONO_EXCEPTION_NONE)
3609 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3612 while ((event = mono_class_get_events (klass, &iter))) {
3613 if (strcmp (event->name, event_name))
3616 method = event->add;
3618 method = event->remove;
3620 method = event->raise;
3622 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3623 if (!(bflags & BFLAGS_Public))
3626 if (!(bflags & BFLAGS_NonPublic))
3631 if (!(bflags & BFLAGS_NonPublic))
3634 g_free (event_name);
3635 return mono_event_get_object (domain, startklass, event);
3638 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3641 g_free (event_name);
3646 ves_icall_Type_GetEvents_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3649 static MonoClass *System_Reflection_EventInfo;
3650 MonoClass *startklass, *klass;
3657 MONO_ARCH_SAVE_REGS;
3659 if (!System_Reflection_EventInfo)
3660 System_Reflection_EventInfo = mono_class_from_name (
3661 mono_defaults.corlib, "System.Reflection", "EventInfo");
3663 domain = mono_object_domain (type);
3664 if (type->type->byref)
3665 return mono_array_new (domain, System_Reflection_EventInfo, 0);
3666 klass = startklass = mono_class_from_mono_type (type->type);
3670 res = mono_array_new (domain, System_Reflection_EventInfo, len);
3672 if (klass->exception_type != MONO_EXCEPTION_NONE)
3673 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3676 while ((event = mono_class_get_events (klass, &iter))) {
3678 method = event->add;
3680 method = event->remove;
3682 method = event->raise;
3684 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3685 if (bflags & BFLAGS_Public)
3688 if (bflags & BFLAGS_NonPublic)
3693 if (bflags & BFLAGS_NonPublic)
3699 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3700 if (bflags & BFLAGS_Static)
3701 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3704 if (bflags & BFLAGS_Instance)
3709 if (bflags & BFLAGS_Instance)
3715 MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, len * 2);
3716 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3720 mono_array_setref (res, i, mono_event_get_object (domain, startklass, event));
3723 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3726 MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, i);
3727 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3730 * Better solution for the new GC.
3731 * res->max_length = i;
3737 static MonoReflectionType *
3738 ves_icall_Type_GetNestedType (MonoReflectionType *type, MonoString *name, guint32 bflags)
3746 MONO_ARCH_SAVE_REGS;
3748 domain = ((MonoObject *)type)->vtable->domain;
3749 if (type->type->byref)
3751 klass = mono_class_from_mono_type (type->type);
3752 str = mono_string_to_utf8 (name);
3755 if (klass->exception_type != MONO_EXCEPTION_NONE)
3756 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3759 * If a nested type is generic, return its generic type definition.
3760 * Note that this means that the return value is essentially a
3761 * nested type of the generic type definition of @klass.
3763 * A note in MSDN claims that a generic type definition can have
3764 * nested types that aren't generic. In any case, the container of that
3765 * nested type would be the generic type definition.
3767 if (klass->generic_class)
3768 klass = klass->generic_class->container_class;
3770 for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
3772 nested = tmpn->data;
3773 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
3774 if (bflags & BFLAGS_Public)
3777 if (bflags & BFLAGS_NonPublic)
3782 if (strcmp (nested->name, str) == 0){
3784 return mono_type_get_object (domain, &nested->byval_arg);
3787 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3794 ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags)
3804 MONO_ARCH_SAVE_REGS;
3806 domain = ((MonoObject *)type)->vtable->domain;
3807 if (type->type->byref)
3808 return mono_array_new (domain, mono_defaults.monotype_class, 0);
3809 klass = mono_class_from_mono_type (type->type);
3810 if (klass->exception_type != MONO_EXCEPTION_NONE)
3811 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3814 * If a nested type is generic, return its generic type definition.
3815 * Note that this means that the return value is essentially the set
3816 * of nested types of the generic type definition of @klass.
3818 * A note in MSDN claims that a generic type definition can have
3819 * nested types that aren't generic. In any case, the container of that
3820 * nested type would be the generic type definition.
3822 if (klass->generic_class)
3823 klass = klass->generic_class->container_class;
3827 res = mono_array_new (domain, mono_defaults.monotype_class, len);
3828 for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
3830 nested = tmpn->data;
3831 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
3832 if (bflags & BFLAGS_Public)
3835 if (bflags & BFLAGS_NonPublic)
3840 member = (MonoObject*)mono_type_get_object (domain, &nested->byval_arg);
3842 MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, len * 2);
3843 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3847 mono_array_setref (res, i, member);
3851 MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, i);
3852 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3855 * Better solution for the new GC.
3856 * res->max_length = i;
3862 static MonoReflectionType*
3863 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *assembly, MonoReflectionModule *module, MonoString *name, MonoBoolean throwOnError, MonoBoolean ignoreCase)
3866 MonoType *type = NULL;
3867 MonoTypeNameParse info;
3868 gboolean type_resolve;
3870 MONO_ARCH_SAVE_REGS;
3872 /* On MS.NET, this does not fire a TypeResolve event */
3873 type_resolve = TRUE;
3874 str = mono_string_to_utf8 (name);
3875 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
3876 if (!mono_reflection_parse_type (str, &info)) {
3878 mono_reflection_free_type_info (&info);
3879 if (throwOnError) /* uhm: this is a parse error, though... */
3880 mono_raise_exception (mono_get_exception_type_load (name, NULL));
3881 /*g_print ("failed parse\n");*/
3885 if (module != NULL) {
3887 type = mono_reflection_get_type (module->image, &info, ignoreCase, &type_resolve);
3892 if (assembly->assembly->dynamic) {
3893 /* Enumerate all modules */
3894 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
3898 if (abuilder->modules) {
3899 for (i = 0; i < mono_array_length (abuilder->modules); ++i) {
3900 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
3901 type = mono_reflection_get_type (&mb->dynamic_image->image, &info, ignoreCase, &type_resolve);
3907 if (!type && abuilder->loaded_modules) {
3908 for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) {
3909 MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
3910 type = mono_reflection_get_type (mod->image, &info, ignoreCase, &type_resolve);
3917 type = mono_reflection_get_type (assembly->assembly->image, &info, ignoreCase, &type_resolve);
3919 mono_reflection_free_type_info (&info);
3921 MonoException *e = NULL;
3924 e = mono_get_exception_type_load (name, NULL);
3926 mono_loader_clear_error ();
3929 mono_raise_exception (e);
3934 if (type->type == MONO_TYPE_CLASS) {
3935 MonoClass *klass = mono_type_get_class (type);
3936 /* need to report exceptions ? */
3937 if (throwOnError && klass->exception_type) {
3938 /* report SecurityException (or others) that occured when loading the assembly */
3939 MonoException *exc = mono_class_get_exception_for_failure (klass);
3940 mono_loader_clear_error ();
3941 mono_raise_exception (exc);
3942 } else if (klass->exception_type == MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND) {
3947 /* g_print ("got it\n"); */
3948 return mono_type_get_object (mono_object_domain (assembly), type);
3952 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *assembly, MonoBoolean escaped)
3954 MonoDomain *domain = mono_object_domain (assembly);
3955 MonoAssembly *mass = assembly->assembly;
3956 MonoString *res = NULL;
3960 MONO_ARCH_SAVE_REGS;
3962 if (g_path_is_absolute (mass->image->name))
3963 absolute = g_strdup (mass->image->name);
3965 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
3969 for (i = strlen (absolute) - 1; i >= 0; i--)
3970 if (absolute [i] == '\\')
3975 uri = g_filename_to_uri (absolute, NULL, NULL);
3977 uri = g_strconcat ("file://", absolute, NULL);
3981 res = mono_string_new (domain, uri);
3989 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssembly *assembly)
3991 MonoAssembly *mass = assembly->assembly;
3993 MONO_ARCH_SAVE_REGS;
3995 return mass->in_gac;
3998 static MonoReflectionAssembly*
3999 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoString *mname, MonoObject *evidence)
4003 MonoImageOpenStatus status;
4005 MONO_ARCH_SAVE_REGS;
4007 name = mono_string_to_utf8 (mname);
4008 res = mono_assembly_load_with_partial_name (name, &status);
4014 return mono_assembly_get_object (mono_domain_get (), res);
4018 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssembly *assembly)
4020 MonoDomain *domain = mono_object_domain (assembly);
4023 MONO_ARCH_SAVE_REGS;
4025 res = mono_string_new (domain, mono_image_get_filename (assembly->assembly->image));
4031 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssembly *assembly)
4033 MONO_ARCH_SAVE_REGS;
4035 return assembly->assembly->ref_only;
4039 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssembly *assembly)
4041 MonoDomain *domain = mono_object_domain (assembly);
4043 MONO_ARCH_SAVE_REGS;
4045 return mono_string_new (domain, assembly->assembly->image->version);
4048 static MonoReflectionMethod*
4049 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssembly *assembly)
4051 guint32 token = mono_image_get_entry_point (assembly->assembly->image);
4053 MONO_ARCH_SAVE_REGS;
4057 return mono_method_get_object (mono_object_domain (assembly), mono_get_method (assembly->assembly->image, token, NULL), NULL);
4060 static MonoReflectionModule*
4061 ves_icall_System_Reflection_Assembly_get_ManifestModule (MonoReflectionAssembly *assembly)
4063 return mono_module_get_object (mono_object_domain (assembly), assembly->assembly->image);
4067 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssembly *assembly)
4069 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4070 MonoArray *result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, table->rows);
4074 MONO_ARCH_SAVE_REGS;
4076 for (i = 0; i < table->rows; ++i) {
4077 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_MANIFEST_NAME));
4078 mono_array_setref (result, i, mono_string_new (mono_object_domain (assembly), val));
4084 create_version (MonoDomain *domain, guint32 major, guint32 minor, guint32 build, guint32 revision)
4086 static MonoClass *System_Version = NULL;
4087 static MonoMethod *create_version = NULL;
4091 if (!System_Version) {
4092 System_Version = mono_class_from_name (mono_defaults.corlib, "System", "Version");
4093 g_assert (System_Version);
4096 if (!create_version) {
4097 MonoMethodDesc *desc = mono_method_desc_new (":.ctor(int,int,int,int)", FALSE);
4098 create_version = mono_method_desc_search_in_class (desc, System_Version);
4099 g_assert (create_version);
4100 mono_method_desc_free (desc);
4106 args [3] = &revision;
4107 result = mono_object_new (domain, System_Version);
4108 mono_runtime_invoke (create_version, result, args, NULL);
4114 ves_icall_System_Reflection_Assembly_GetReferencedAssemblies (MonoReflectionAssembly *assembly)
4116 static MonoClass *System_Reflection_AssemblyName;
4118 MonoDomain *domain = mono_object_domain (assembly);
4120 static MonoMethod *create_culture = NULL;
4121 MonoImage *image = assembly->assembly->image;
4124 MONO_ARCH_SAVE_REGS;
4126 if (!System_Reflection_AssemblyName)
4127 System_Reflection_AssemblyName = mono_class_from_name (
4128 mono_defaults.corlib, "System.Reflection", "AssemblyName");
4130 t = &assembly->assembly->image->tables [MONO_TABLE_ASSEMBLYREF];
4133 result = mono_array_new (domain, System_Reflection_AssemblyName, count);
4136 MonoMethodDesc *desc = mono_method_desc_new (
4137 "System.Globalization.CultureInfo:CreateSpecificCulture(string)", TRUE);
4138 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4139 g_assert (create_culture);
4140 mono_method_desc_free (desc);
4143 for (i = 0; i < count; i++) {
4144 MonoReflectionAssemblyName *aname;
4145 guint32 cols [MONO_ASSEMBLYREF_SIZE];
4147 mono_metadata_decode_row (t, i, cols, MONO_ASSEMBLYREF_SIZE);
4149 aname = (MonoReflectionAssemblyName *) mono_object_new (
4150 domain, System_Reflection_AssemblyName);
4152 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_NAME])));
4154 aname->major = cols [MONO_ASSEMBLYREF_MAJOR_VERSION];
4155 aname->minor = cols [MONO_ASSEMBLYREF_MINOR_VERSION];
4156 aname->build = cols [MONO_ASSEMBLYREF_BUILD_NUMBER];
4157 aname->revision = cols [MONO_ASSEMBLYREF_REV_NUMBER];
4158 aname->flags = cols [MONO_ASSEMBLYREF_FLAGS];
4159 aname->versioncompat = 1; /* SameMachine (default) */
4160 aname->hashalg = ASSEMBLY_HASH_SHA1; /* SHA1 (default) */
4161 MONO_OBJECT_SETREF (aname, version, create_version (domain, aname->major, aname->minor, aname->build, aname->revision));
4163 if (create_culture) {
4165 args [0] = mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_CULTURE]));
4166 MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
4169 if (cols [MONO_ASSEMBLYREF_PUBLIC_KEY]) {
4170 const gchar *pkey_ptr = mono_metadata_blob_heap (image, cols [MONO_ASSEMBLYREF_PUBLIC_KEY]);
4171 guint32 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
4173 if ((cols [MONO_ASSEMBLYREF_FLAGS] & ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG)) {
4174 /* public key token isn't copied - the class library will
4175 automatically generate it from the public key if required */
4176 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4177 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
4179 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4180 memcpy (mono_array_addr (aname->keyToken, guint8, 0), pkey_ptr, pkey_len);
4184 /* note: this function doesn't return the codebase on purpose (i.e. it can
4185 be used under partial trust as path information isn't present). */
4187 mono_array_setref (result, i, aname);
4198 foreach_namespace (const char* key, gconstpointer val, NameSpaceInfo *info)
4200 MonoString *name = mono_string_new (mono_object_domain (info->res), key);
4202 mono_array_setref (info->res, info->idx, name);
4207 ves_icall_System_Reflection_Assembly_GetNamespaces (MonoReflectionAssembly *assembly)
4209 MonoImage *img = assembly->assembly->image;
4213 MONO_ARCH_SAVE_REGS;
4215 if (!img->name_cache)
4216 mono_image_init_name_cache (img);
4218 res = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, g_hash_table_size (img->name_cache));
4221 g_hash_table_foreach (img->name_cache, (GHFunc)foreach_namespace, &info);
4226 /* move this in some file in mono/util/ */
4228 g_concat_dir_and_file (const char *dir, const char *file)
4230 g_return_val_if_fail (dir != NULL, NULL);
4231 g_return_val_if_fail (file != NULL, NULL);
4234 * If the directory name doesn't have a / on the end, we need
4235 * to add one so we get a proper path to the file
4237 if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
4238 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
4240 return g_strconcat (dir, file, NULL);
4244 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssembly *assembly, MonoString *name, gint32 *size, MonoReflectionModule **ref_module)
4246 char *n = mono_string_to_utf8 (name);
4247 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4249 guint32 cols [MONO_MANIFEST_SIZE];
4250 guint32 impl, file_idx;
4254 MONO_ARCH_SAVE_REGS;
4256 for (i = 0; i < table->rows; ++i) {
4257 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4258 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4259 if (strcmp (val, n) == 0)
4263 if (i == table->rows)
4266 impl = cols [MONO_MANIFEST_IMPLEMENTATION];
4269 * this code should only be called after obtaining the
4270 * ResourceInfo and handling the other cases.
4272 g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
4273 file_idx = impl >> MONO_IMPLEMENTATION_BITS;
4275 module = mono_image_load_file_for_image (assembly->assembly->image, file_idx);
4280 module = assembly->assembly->image;
4282 *ref_module = mono_module_get_object (mono_domain_get (), module);
4284 return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
4288 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoManifestResourceInfo *info)
4290 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4292 guint32 cols [MONO_MANIFEST_SIZE];
4293 guint32 file_cols [MONO_FILE_SIZE];
4297 MONO_ARCH_SAVE_REGS;
4299 n = mono_string_to_utf8 (name);
4300 for (i = 0; i < table->rows; ++i) {
4301 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4302 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4303 if (strcmp (val, n) == 0)
4307 if (i == table->rows)
4310 if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
4311 info->location = RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST;
4314 switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
4315 case MONO_IMPLEMENTATION_FILE:
4316 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4317 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4318 mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
4319 val = mono_metadata_string_heap (assembly->assembly->image, file_cols [MONO_FILE_NAME]);
4320 MONO_OBJECT_SETREF (info, filename, mono_string_new (mono_object_domain (assembly), val));
4321 if (file_cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA)
4324 info->location = RESOURCE_LOCATION_EMBEDDED;
4327 case MONO_IMPLEMENTATION_ASSEMBLYREF:
4328 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4329 mono_assembly_load_reference (assembly->assembly->image, i - 1);
4330 if (assembly->assembly->image->references [i - 1] == (gpointer)-1) {
4331 char *msg = g_strdup_printf ("Assembly %d referenced from assembly %s not found ", i - 1, assembly->assembly->image->name);
4332 MonoException *ex = mono_get_exception_file_not_found2 (msg, NULL);
4334 mono_raise_exception (ex);
4336 MONO_OBJECT_SETREF (info, assembly, mono_assembly_get_object (mono_domain_get (), assembly->assembly->image->references [i - 1]));
4338 /* Obtain info recursively */
4339 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (info->assembly, name, info);
4340 info->location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
4343 case MONO_IMPLEMENTATION_EXP_TYPE:
4344 g_assert_not_reached ();
4353 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoBoolean resource_modules)
4355 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4356 MonoArray *result = NULL;
4361 MONO_ARCH_SAVE_REGS;
4363 /* check hash if needed */
4365 n = mono_string_to_utf8 (name);
4366 for (i = 0; i < table->rows; ++i) {
4367 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4368 if (strcmp (val, n) == 0) {
4371 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4372 fn = mono_string_new (mono_object_domain (assembly), n);
4374 return (MonoObject*)fn;
4382 for (i = 0; i < table->rows; ++i) {
4383 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA))
4387 result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, count);
4390 for (i = 0; i < table->rows; ++i) {
4391 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4392 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4393 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4394 mono_array_setref (result, count, mono_string_new (mono_object_domain (assembly), n));
4399 return (MonoObject*)result;
4403 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly *assembly)
4405 MonoDomain *domain = mono_domain_get();
4408 int i, j, file_count = 0;
4409 MonoImage **modules;
4410 guint32 module_count, real_module_count;
4411 MonoTableInfo *table;
4413 g_assert (assembly->assembly->image != NULL);
4415 if (assembly->assembly->dynamic) {
4416 MonoReflectionAssemblyBuilder *assemblyb = (MonoReflectionAssemblyBuilder*)assembly;
4418 if (assemblyb->modules)
4419 module_count = mono_array_length (assemblyb->modules);
4422 real_module_count = module_count;
4424 modules = g_new0 (MonoImage*, module_count);
4425 if (assemblyb->modules) {
4426 for (i = 0; i < mono_array_length (assemblyb->modules); ++i) {
4428 mono_array_get (assemblyb->modules, MonoReflectionModuleBuilder*, i)->module.image;
4433 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4434 file_count = table->rows;
4436 modules = assembly->assembly->image->modules;
4437 module_count = assembly->assembly->image->module_count;
4439 real_module_count = 0;
4440 for (i = 0; i < module_count; ++i)
4442 real_module_count ++;
4445 klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "Module");
4446 res = mono_array_new (domain, klass, 1 + real_module_count + file_count);
4448 mono_array_setref (res, 0, mono_module_get_object (domain, assembly->assembly->image));
4450 for (i = 0; i < module_count; ++i)
4452 mono_array_setref (res, j, mono_module_get_object (domain, modules[i]));
4456 for (i = 0; i < file_count; ++i, ++j)
4457 mono_array_setref (res, j, mono_module_file_get_object (domain, assembly->assembly->image, i));
4459 if (assembly->assembly->dynamic)
4465 static MonoReflectionMethod*
4466 ves_icall_GetCurrentMethod (void)
4468 MonoMethod *m = mono_method_get_last_managed ();
4470 MONO_ARCH_SAVE_REGS;
4472 return mono_method_get_object (mono_domain_get (), m, NULL);
4475 static MonoReflectionMethod*
4476 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType (MonoMethod *method, MonoType *type)
4478 /* FIXME check that method belongs to klass or a parent */
4481 klass = mono_class_from_mono_type (type);
4483 klass = method->klass;
4484 return mono_method_get_object (mono_domain_get (), method, klass);
4487 static MonoReflectionMethod*
4488 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternal (MonoMethod *method)
4490 return mono_method_get_object (mono_domain_get (), method, NULL);
4493 static MonoReflectionMethodBody*
4494 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod *method)
4496 return mono_method_body_get_object (mono_domain_get (), method);
4499 static MonoReflectionAssembly*
4500 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (void)
4502 MonoMethod *m = mono_method_get_last_managed ();
4504 MONO_ARCH_SAVE_REGS;
4506 return mono_assembly_get_object (mono_domain_get (), m->klass->image->assembly);
4510 static MonoReflectionAssembly*
4511 ves_icall_System_Reflection_Assembly_GetEntryAssembly (void)
4513 MonoDomain* domain = mono_domain_get ();
4515 MONO_ARCH_SAVE_REGS;
4517 if (!domain->entry_assembly)
4520 return mono_assembly_get_object (domain, domain->entry_assembly);
4523 static MonoReflectionAssembly*
4524 ves_icall_System_Reflection_Assembly_GetCallingAssembly (void)
4526 MonoMethod *m = mono_method_get_last_managed ();
4527 MonoMethod *dest = m;
4529 MONO_ARCH_SAVE_REGS;
4531 mono_stack_walk_no_il (get_caller, &dest);
4534 return mono_assembly_get_object (mono_domain_get (), dest->klass->image->assembly);
4538 ves_icall_System_MonoType_getFullName (MonoReflectionType *object, gboolean full_name,
4539 gboolean assembly_qualified)
4541 MonoDomain *domain = mono_object_domain (object);
4542 MonoTypeNameFormat format;
4546 MONO_ARCH_SAVE_REGS;
4548 format = assembly_qualified ?
4549 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
4550 MONO_TYPE_NAME_FORMAT_FULL_NAME;
4552 format = MONO_TYPE_NAME_FORMAT_REFLECTION;
4554 name = mono_type_get_name_full (object->type, format);
4558 if (full_name && (object->type->type == MONO_TYPE_VAR || object->type->type == MONO_TYPE_MVAR)) {
4563 res = mono_string_new (domain, name);
4570 fill_reflection_assembly_name (MonoDomain *domain, MonoReflectionAssemblyName *aname, MonoAssemblyName *name, const char *absolute, gboolean by_default_version)
4572 static MonoMethod *create_culture = NULL;
4575 const char *pkey_ptr;
4578 MONO_ARCH_SAVE_REGS;
4580 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, name->name));
4581 aname->major = name->major;
4582 aname->minor = name->minor;
4583 aname->build = name->build;
4584 aname->revision = name->revision;
4585 aname->hashalg = name->hash_alg;
4586 if (by_default_version)
4587 MONO_OBJECT_SETREF (aname, version, create_version (domain, name->major, name->minor, name->build, name->revision));
4589 codebase = g_filename_to_uri (absolute, NULL, NULL);
4591 MONO_OBJECT_SETREF (aname, codebase, mono_string_new (domain, codebase));
4595 if (!create_culture) {
4596 MonoMethodDesc *desc = mono_method_desc_new ("System.Globalization.CultureInfo:CreateSpecificCulture(string)", TRUE);
4597 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4598 g_assert (create_culture);
4599 mono_method_desc_free (desc);
4602 if (name->culture) {
4603 args [0] = mono_string_new (domain, name->culture);
4604 MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
4607 if (name->public_key) {
4608 pkey_ptr = (char*)name->public_key;
4609 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
4611 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4612 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
4615 /* MonoAssemblyName keeps the public key token as an hexadecimal string */
4616 if (name->public_key_token [0]) {
4620 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, 8));
4621 p = mono_array_addr (aname->keyToken, char, 0);
4623 for (i = 0, j = 0; i < 8; i++) {
4624 *p = g_ascii_xdigit_value (name->public_key_token [j++]) << 4;
4625 *p |= g_ascii_xdigit_value (name->public_key_token [j++]);
4632 ves_icall_System_Reflection_Assembly_FillName (MonoReflectionAssembly *assembly, MonoReflectionAssemblyName *aname)
4635 MonoAssembly *mass = assembly->assembly;
4637 MONO_ARCH_SAVE_REGS;
4639 if (g_path_is_absolute (mass->image->name)) {
4640 fill_reflection_assembly_name (mono_object_domain (assembly),
4641 aname, &mass->aname, mass->image->name, TRUE);
4644 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4646 fill_reflection_assembly_name (mono_object_domain (assembly),
4647 aname, &mass->aname, absolute, TRUE);
4653 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoString *fname, MonoReflectionAssemblyName *aname)
4656 MonoImageOpenStatus status = MONO_IMAGE_OK;
4659 MonoAssemblyName name;
4661 MONO_ARCH_SAVE_REGS;
4663 filename = mono_string_to_utf8 (fname);
4665 image = mono_image_open (filename, &status);
4671 if (status == MONO_IMAGE_IMAGE_INVALID)
4672 exc = mono_get_exception_bad_image_format2 (NULL, fname);
4674 exc = mono_get_exception_file_not_found2 (NULL, fname);
4675 mono_raise_exception (exc);
4678 res = mono_assembly_fill_assembly_name (image, &name);
4680 mono_image_close (image);
4682 mono_raise_exception (mono_get_exception_argument ("assemblyFile", "The file does not contain a manifest"));
4685 fill_reflection_assembly_name (mono_domain_get (), aname, &name, filename, TRUE);
4688 mono_image_close (image);
4692 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssembly *assembly,
4693 char **minimum, guint32 *minLength, char **optional, guint32 *optLength, char **refused, guint32 *refLength)
4695 MonoBoolean result = FALSE;
4696 MonoDeclSecurityEntry entry;
4698 /* SecurityAction.RequestMinimum */
4699 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQMIN, &entry)) {
4700 *minimum = entry.blob;
4701 *minLength = entry.size;
4704 /* SecurityAction.RequestOptional */
4705 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQOPT, &entry)) {
4706 *optional = entry.blob;
4707 *optLength = entry.size;
4710 /* SecurityAction.RequestRefuse */
4711 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQREFUSE, &entry)) {
4712 *refused = entry.blob;
4713 *refLength = entry.size;
4721 mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoBoolean exportedOnly)
4725 MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
4727 guint32 attrs, visibility;
4729 /* we start the count from 1 because we skip the special type <Module> */
4732 for (i = 1; i < tdef->rows; ++i) {
4733 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
4734 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
4735 if (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)
4739 count = tdef->rows - 1;
4741 res = mono_array_new (domain, mono_defaults.monotype_class, count);
4743 for (i = 1; i < tdef->rows; ++i) {
4744 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
4745 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
4746 if (!exportedOnly || (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)) {
4747 klass = mono_class_get_throw (image, (i + 1) | MONO_TOKEN_TYPE_DEF);
4748 if (mono_loader_get_last_error ())
4749 mono_loader_clear_error ();
4750 mono_array_setref (res, count, mono_type_get_object (domain, &klass->byval_arg));
4759 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly, MonoBoolean exportedOnly)
4761 MonoArray *res = NULL;
4762 MonoImage *image = NULL;
4763 MonoTableInfo *table = NULL;
4768 MONO_ARCH_SAVE_REGS;
4770 domain = mono_object_domain (assembly);
4772 if (assembly->assembly->dynamic) {
4773 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
4774 if (abuilder->modules) {
4775 for (i = 0; i < mono_array_length(abuilder->modules); i++) {
4776 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
4777 MonoArray *append = mb->types;
4778 /* The types array might not be fully filled up */
4779 if (append && mb->num_types > 0) {
4782 len1 = res ? mono_array_length (res) : 0;
4783 len2 = mb->num_types;
4784 new = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4786 mono_array_memcpy_refs (new, 0, res, 0, len1);
4787 mono_array_memcpy_refs (new, len1, append, 0, len2);
4793 * Replace TypeBuilders with the created types to be compatible
4797 for (i = 0; i < mono_array_length (res); ++i) {
4798 MonoReflectionTypeBuilder *tb = mono_array_get (res, MonoReflectionTypeBuilder*, i);
4800 mono_array_setref (res, i, tb->created);
4805 if (abuilder->loaded_modules)
4806 for (i = 0; i < mono_array_length(abuilder->loaded_modules); i++) {
4807 MonoReflectionModule *rm = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
4808 MonoArray *append = mono_module_get_types (domain, rm->image, exportedOnly);
4809 if (append && mono_array_length (append) > 0) {
4812 len1 = res ? mono_array_length (res) : 0;
4813 len2 = mono_array_length (append);
4814 new = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4816 mono_array_memcpy_refs (new, 0, res, 0, len1);
4817 mono_array_memcpy_refs (new, len1, append, 0, len2);
4824 return mono_array_new (domain, mono_defaults.monotype_class, 0);
4826 image = assembly->assembly->image;
4827 table = &image->tables [MONO_TABLE_FILE];
4828 res = mono_module_get_types (domain, image, exportedOnly);
4830 /* Append data from all modules in the assembly */
4831 for (i = 0; i < table->rows; ++i) {
4832 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4833 MonoImage *loaded_image = mono_assembly_load_module (image->assembly, i + 1);
4835 MonoArray *res2 = mono_module_get_types (domain, loaded_image, exportedOnly);
4836 /* Append the new types to the end of the array */
4837 if (mono_array_length (res2) > 0) {
4841 len1 = mono_array_length (res);
4842 len2 = mono_array_length (res2);
4843 res3 = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4844 mono_array_memcpy_refs (res3, 0, res, 0, len1);
4845 mono_array_memcpy_refs (res3, len1, res2, 0, len2);
4852 /* the ReflectionTypeLoadException must have all the types (Types property),
4853 * NULL replacing types which throws an exception. The LoaderException must
4854 * contain all exceptions for NULL items.
4857 len = mono_array_length (res);
4859 for (i = 0; i < len; i++) {
4860 MonoReflectionType *t = mono_array_get (res, gpointer, i);
4861 MonoClass *klass = mono_type_get_class (t->type);
4862 if ((klass != NULL) && klass->exception_type) {
4863 /* keep the class in the list */
4864 list = g_list_append (list, klass);
4865 /* and replace Type with NULL */
4866 mono_array_setref (res, i, NULL);
4872 MonoException *exc = NULL;
4873 MonoArray *exl = NULL;
4874 int length = g_list_length (list);
4876 mono_loader_clear_error ();
4878 exl = mono_array_new (domain, mono_defaults.exception_class, length);
4879 for (i = 0, tmp = list; i < length; i++, tmp = tmp->next) {
4880 MonoException *exc = mono_class_get_exception_for_failure (tmp->data);
4881 mono_array_setref (exl, i, exc);
4886 exc = mono_get_exception_reflection_type_load (res, exl);
4887 mono_loader_clear_error ();
4888 mono_raise_exception (exc);
4895 ves_icall_System_Reflection_AssemblyName_ParseName (MonoReflectionAssemblyName *name, MonoString *assname)
4897 MonoAssemblyName aname;
4898 MonoDomain *domain = mono_object_domain (name);
4900 gboolean is_version_defined;
4902 val = mono_string_to_utf8 (assname);
4903 if (!mono_assembly_name_parse_full (val, &aname, TRUE, &is_version_defined))
4906 fill_reflection_assembly_name (domain, name, &aname, "", is_version_defined);
4908 mono_assembly_name_free (&aname);
4909 g_free ((guint8*) aname.public_key);
4915 static MonoReflectionType*
4916 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModule *module)
4918 MonoDomain *domain = mono_object_domain (module);
4921 MONO_ARCH_SAVE_REGS;
4923 g_assert (module->image);
4925 if (module->image->dynamic && ((MonoDynamicImage*)(module->image))->initial_image)
4926 /* These images do not have a global type */
4929 klass = mono_class_get (module->image, 1 | MONO_TOKEN_TYPE_DEF);
4930 return mono_type_get_object (domain, &klass->byval_arg);
4934 ves_icall_System_Reflection_Module_Close (MonoReflectionModule *module)
4936 /*if (module->image)
4937 mono_image_close (module->image);*/
4941 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModule *module)
4943 MonoDomain *domain = mono_object_domain (module);
4945 MONO_ARCH_SAVE_REGS;
4947 g_assert (module->image);
4948 return mono_string_new (domain, module->image->guid);
4952 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine)
4954 if (image->dynamic) {
4955 MonoDynamicImage *dyn = (MonoDynamicImage*)image;
4956 *pe_kind = dyn->pe_kind;
4957 *machine = dyn->machine;
4960 *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
4961 *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
4966 ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage *image)
4968 return (image->md_version_major << 16) | (image->md_version_minor);
4972 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModule *module)
4974 MONO_ARCH_SAVE_REGS;
4977 return mono_array_new (mono_object_domain (module), mono_defaults.monotype_class, 0);
4979 return mono_module_get_types (mono_object_domain (module), module->image, FALSE);
4983 mono_metadata_memberref_is_method (MonoImage *image, guint32 token)
4985 guint32 cols [MONO_MEMBERREF_SIZE];
4987 mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
4988 sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
4989 mono_metadata_decode_blob_size (sig, &sig);
4990 return (*sig != 0x6);
4994 init_generic_context_from_args (MonoGenericContext *context, MonoArray *type_args, MonoArray *method_args)
4997 context->class_inst = mono_metadata_get_generic_inst (mono_array_length (type_args),
4998 mono_array_addr (type_args, MonoType*, 0));
5000 context->class_inst = NULL;
5002 context->method_inst = mono_metadata_get_generic_inst (mono_array_length (method_args),
5003 mono_array_addr (method_args, MonoType*, 0));
5005 context->method_inst = NULL;
5009 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5012 int table = mono_metadata_token_table (token);
5013 int index = mono_metadata_token_index (token);
5014 MonoGenericContext context;
5016 *error = ResolveTokenError_Other;
5018 /* Validate token */
5019 if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) &&
5020 (table != MONO_TABLE_TYPESPEC)) {
5021 *error = ResolveTokenError_BadTable;
5025 if (image->dynamic) {
5026 if (type_args || method_args)
5027 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5028 return mono_lookup_dynamic_token (image, token, NULL);
5031 if ((index <= 0) || (index > image->tables [table].rows)) {
5032 *error = ResolveTokenError_OutOfRange;
5036 init_generic_context_from_args (&context, type_args, method_args);
5037 klass = mono_class_get_full (image, token, &context);
5040 return &klass->byval_arg;
5046 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5048 int table = mono_metadata_token_table (token);
5049 int index = mono_metadata_token_index (token);
5050 MonoGenericContext context;
5053 *error = ResolveTokenError_Other;
5055 /* Validate token */
5056 if ((table != MONO_TABLE_METHOD) && (table != MONO_TABLE_METHODSPEC) &&
5057 (table != MONO_TABLE_MEMBERREF)) {
5058 *error = ResolveTokenError_BadTable;
5062 if (image->dynamic) {
5063 if (type_args || method_args)
5064 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5065 /* FIXME: validate memberref token type */
5066 return mono_lookup_dynamic_token (image, token, NULL);
5069 if ((index <= 0) || (index > image->tables [table].rows)) {
5070 *error = ResolveTokenError_OutOfRange;
5073 if ((table == MONO_TABLE_MEMBERREF) && (!mono_metadata_memberref_is_method (image, token))) {
5074 *error = ResolveTokenError_BadTable;
5078 init_generic_context_from_args (&context, type_args, method_args);
5079 method = mono_get_method_full (image, token, NULL, &context);
5085 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
5087 int index = mono_metadata_token_index (token);
5089 *error = ResolveTokenError_Other;
5091 /* Validate token */
5092 if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
5093 *error = ResolveTokenError_BadTable;
5098 return mono_lookup_dynamic_token (image, token, NULL);
5100 if ((index <= 0) || (index >= image->heap_us.size)) {
5101 *error = ResolveTokenError_OutOfRange;
5105 /* FIXME: What to do if the index points into the middle of a string ? */
5107 return mono_ldstr (mono_domain_get (), image, index);
5110 static MonoClassField*
5111 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5114 int table = mono_metadata_token_table (token);
5115 int index = mono_metadata_token_index (token);
5116 MonoGenericContext context;
5117 MonoClassField *field;
5119 *error = ResolveTokenError_Other;
5121 /* Validate token */
5122 if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
5123 *error = ResolveTokenError_BadTable;
5127 if (image->dynamic) {
5128 if (type_args || method_args)
5129 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5130 /* FIXME: validate memberref token type */
5131 return mono_lookup_dynamic_token (image, token, NULL);
5134 if ((index <= 0) || (index > image->tables [table].rows)) {
5135 *error = ResolveTokenError_OutOfRange;
5138 if ((table == MONO_TABLE_MEMBERREF) && (mono_metadata_memberref_is_method (image, token))) {
5139 *error = ResolveTokenError_BadTable;
5143 init_generic_context_from_args (&context, type_args, method_args);
5144 field = mono_field_from_token (image, token, &klass, &context);
5151 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5153 int table = mono_metadata_token_table (token);
5155 *error = ResolveTokenError_Other;
5158 case MONO_TABLE_TYPEDEF:
5159 case MONO_TABLE_TYPEREF:
5160 case MONO_TABLE_TYPESPEC: {
5161 MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, type_args, method_args, error);
5163 return (MonoObject*)mono_type_get_object (mono_domain_get (), t);
5167 case MONO_TABLE_METHOD:
5168 case MONO_TABLE_METHODSPEC: {
5169 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5171 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
5175 case MONO_TABLE_FIELD: {
5176 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5178 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
5182 case MONO_TABLE_MEMBERREF:
5183 if (mono_metadata_memberref_is_method (image, token)) {
5184 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5186 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
5191 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5193 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
5200 *error = ResolveTokenError_BadTable;
5207 ves_icall_System_Reflection_Module_ResolveSignature (MonoImage *image, guint32 token, MonoResolveTokenError *error)
5209 int table = mono_metadata_token_table (token);
5210 int idx = mono_metadata_token_index (token);
5211 MonoTableInfo *tables = image->tables;
5216 *error = ResolveTokenError_OutOfRange;
5218 /* FIXME: Support other tables ? */
5219 if (table != MONO_TABLE_STANDALONESIG)
5225 if ((idx == 0) || (idx > tables [MONO_TABLE_STANDALONESIG].rows))
5228 sig = mono_metadata_decode_row_col (&tables [MONO_TABLE_STANDALONESIG], idx - 1, 0);
5230 ptr = mono_metadata_blob_heap (image, sig);
5231 len = mono_metadata_decode_blob_size (ptr, &ptr);
5233 res = mono_array_new (mono_domain_get (), mono_defaults.byte_class, len);
5234 memcpy (mono_array_addr (res, guint8, 0), ptr, len);
5238 static MonoReflectionType*
5239 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
5242 int isbyref = 0, rank;
5243 char *str = mono_string_to_utf8 (smodifiers);
5246 MONO_ARCH_SAVE_REGS;
5248 klass = mono_class_from_mono_type (tb->type.type);
5250 /* logic taken from mono_reflection_parse_type(): keep in sync */
5254 if (isbyref) { /* only one level allowed by the spec */
5261 return mono_type_get_object (mono_object_domain (tb), &klass->this_arg);
5264 klass = mono_ptr_class_get (&klass->byval_arg);
5265 mono_class_init (klass);
5276 else if (*p != '*') { /* '*' means unknown lower bound */
5287 klass = mono_array_class_get (klass, rank);
5288 mono_class_init (klass);
5295 return mono_type_get_object (mono_object_domain (tb), &klass->byval_arg);
5299 ves_icall_Type_IsArrayImpl (MonoReflectionType *t)
5304 MONO_ARCH_SAVE_REGS;
5307 res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
5312 static MonoReflectionType *
5313 ves_icall_Type_make_array_type (MonoReflectionType *type, int rank)
5315 MonoClass *klass, *aklass;
5317 MONO_ARCH_SAVE_REGS;
5319 klass = mono_class_from_mono_type (type->type);
5320 aklass = mono_array_class_get (klass, rank);
5322 return mono_type_get_object (mono_object_domain (type), &aklass->byval_arg);
5325 static MonoReflectionType *
5326 ves_icall_Type_make_byref_type (MonoReflectionType *type)
5330 MONO_ARCH_SAVE_REGS;
5332 klass = mono_class_from_mono_type (type->type);
5334 return mono_type_get_object (mono_object_domain (type), &klass->this_arg);
5337 static MonoReflectionType *
5338 ves_icall_Type_MakePointerType (MonoReflectionType *type)
5342 MONO_ARCH_SAVE_REGS;
5344 pklass = mono_ptr_class_get (type->type);
5346 return mono_type_get_object (mono_object_domain (type), &pklass->byval_arg);
5350 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
5351 MonoReflectionMethod *info)
5353 MonoClass *delegate_class = mono_class_from_mono_type (type->type);
5354 MonoObject *delegate;
5357 MONO_ARCH_SAVE_REGS;
5359 mono_assert (delegate_class->parent == mono_defaults.multicastdelegate_class);
5361 delegate = mono_object_new (mono_object_domain (type), delegate_class);
5363 func = mono_compile_method (info->method);
5365 mono_delegate_ctor (delegate, target, func);
5371 ves_icall_System_Delegate_SetMulticastInvoke (MonoDelegate *this)
5376 /* Find the Invoke method */
5378 while ((invoke = mono_class_get_methods (this->object.vtable->klass, &iter))) {
5379 if (!strcmp (invoke->name, "Invoke"))
5384 this->invoke_impl = mono_compile_method (mono_marshal_get_delegate_invoke (invoke));
5388 * Magic number to convert a time which is relative to
5389 * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
5391 #define EPOCH_ADJUST ((guint64)62135596800LL)
5394 * Magic number to convert FILETIME base Jan 1, 1601 to DateTime - base Jan, 1, 0001
5396 #define FILETIME_ADJUST ((guint64)504911232000000000LL)
5399 * This returns Now in UTC
5402 ves_icall_System_DateTime_GetNow (void)
5404 #ifdef PLATFORM_WIN32
5408 GetSystemTime (&st);
5409 SystemTimeToFileTime (&st, &ft);
5410 return (gint64) FILETIME_ADJUST + ((((gint64)ft.dwHighDateTime)<<32) | ft.dwLowDateTime);
5412 /* FIXME: put this in io-layer and call it GetLocalTime */
5416 MONO_ARCH_SAVE_REGS;
5418 if (gettimeofday (&tv, NULL) == 0) {
5419 res = (((gint64)tv.tv_sec + EPOCH_ADJUST)* 1000000 + tv.tv_usec)*10;
5422 /* fixme: raise exception */
5427 #ifdef PLATFORM_WIN32
5428 /* convert a SYSTEMTIME which is of the form "last thursday in october" to a real date */
5430 convert_to_absolute_date(SYSTEMTIME *date)
5432 #define IS_LEAP(y) ((y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0))
5433 static int days_in_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5434 static int leap_days_in_month[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5435 /* from the calendar FAQ */
5436 int a = (14 - date->wMonth) / 12;
5437 int y = date->wYear - a;
5438 int m = date->wMonth + 12 * a - 2;
5439 int d = (1 + y + y/4 - y/100 + y/400 + (31*m)/12) % 7;
5441 /* d is now the day of the week for the first of the month (0 == Sunday) */
5443 int day_of_week = date->wDayOfWeek;
5445 /* set day_in_month to the first day in the month which falls on day_of_week */
5446 int day_in_month = 1 + (day_of_week - d);
5447 if (day_in_month <= 0)
5450 /* wDay is 1 for first weekday in month, 2 for 2nd ... 5 means last - so work that out allowing for days in the month */
5451 date->wDay = day_in_month + (date->wDay - 1) * 7;
5452 if (date->wDay > (IS_LEAP(date->wYear) ? leap_days_in_month[date->wMonth - 1] : days_in_month[date->wMonth - 1]))
5457 #ifndef PLATFORM_WIN32
5459 * Return's the offset from GMT of a local time.
5461 * tm is a local time
5462 * t is the same local time as seconds.
5465 gmt_offset(struct tm *tm, time_t t)
5467 #if defined (HAVE_TM_GMTOFF)
5468 return tm->tm_gmtoff;
5473 g.tm_isdst = tm->tm_isdst;
5475 return (int)difftime(t, t2);
5480 * This is heavily based on zdump.c from glibc 2.2.
5482 * * data[0]: start of daylight saving time (in DateTime ticks).
5483 * * data[1]: end of daylight saving time (in DateTime ticks).
5484 * * data[2]: utcoffset (in TimeSpan ticks).
5485 * * data[3]: additional offset when daylight saving (in TimeSpan ticks).
5486 * * name[0]: name of this timezone when not daylight saving.
5487 * * name[1]: name of this timezone when daylight saving.
5489 * FIXME: This only works with "standard" Unix dates (years between 1900 and 2100) while
5490 * the class library allows years between 1 and 9999.
5492 * Returns true on success and zero on failure.
5495 ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year, MonoArray **data, MonoArray **names)
5497 #ifndef PLATFORM_WIN32
5498 MonoDomain *domain = mono_domain_get ();
5499 struct tm start, tt;
5503 int is_daylight = 0, day;
5506 MONO_ARCH_SAVE_REGS;
5508 MONO_CHECK_ARG_NULL (data);
5509 MONO_CHECK_ARG_NULL (names);
5511 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5512 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5515 * no info is better than crashing: we'll need our own tz data
5516 * to make this work properly, anyway. The range is probably
5517 * reduced to 1970 .. 2037 because that is what mktime is
5518 * guaranteed to support (we get into an infinite loop
5522 memset (&start, 0, sizeof (start));
5525 start.tm_year = year-1900;
5527 t = mktime (&start);
5529 if ((year < 1970) || (year > 2037) || (t == -1)) {
5531 tt = *localtime (&t);
5532 strftime (tzone, sizeof (tzone), "%Z", &tt);
5533 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5534 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5538 gmtoff = gmt_offset (&start, t);
5540 /* For each day of the year, calculate the tm_gmtoff. */
5541 for (day = 0; day < 365; day++) {
5544 tt = *localtime (&t);
5546 /* Daylight saving starts or ends here. */
5547 if (gmt_offset (&tt, t) != gmtoff) {
5551 /* Try to find the exact hour when daylight saving starts/ends. */
5555 tt1 = *localtime (&t1);
5556 } while (gmt_offset (&tt1, t1) != gmtoff);
5558 /* Try to find the exact minute when daylight saving starts/ends. */
5561 tt1 = *localtime (&t1);
5562 } while (gmt_offset (&tt1, t1) == gmtoff);
5564 strftime (tzone, sizeof (tzone), "%Z", &tt);
5566 /* Write data, if we're already in daylight saving, we're done. */
5568 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5569 mono_array_set ((*data), gint64, 1, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
5572 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5573 mono_array_set ((*data), gint64, 0, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
5577 /* This is only set once when we enter daylight saving. */
5578 mono_array_set ((*data), gint64, 2, (gint64)gmtoff * 10000000L);
5579 mono_array_set ((*data), gint64, 3, (gint64)(gmt_offset (&tt, t) - gmtoff) * 10000000L);
5581 gmtoff = gmt_offset (&tt, t);
5586 strftime (tzone, sizeof (tzone), "%Z", &tt);
5587 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5588 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5589 mono_array_set ((*data), gint64, 0, 0);
5590 mono_array_set ((*data), gint64, 1, 0);
5591 mono_array_set ((*data), gint64, 2, (gint64) gmtoff * 10000000L);
5592 mono_array_set ((*data), gint64, 3, 0);
5597 MonoDomain *domain = mono_domain_get ();
5598 TIME_ZONE_INFORMATION tz_info;
5603 tz_id = GetTimeZoneInformation (&tz_info);
5604 if (tz_id == TIME_ZONE_ID_INVALID)
5607 MONO_CHECK_ARG_NULL (data);
5608 MONO_CHECK_ARG_NULL (names);
5610 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5611 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5613 for (i = 0; i < 32; ++i)
5614 if (!tz_info.DaylightName [i])
5616 mono_array_setref ((*names), 1, mono_string_new_utf16 (domain, tz_info.DaylightName, i));
5617 for (i = 0; i < 32; ++i)
5618 if (!tz_info.StandardName [i])
5620 mono_array_setref ((*names), 0, mono_string_new_utf16 (domain, tz_info.StandardName, i));
5622 if ((year <= 1601) || (year > 30827)) {
5624 * According to MSDN, the MS time functions can't handle dates outside
5630 /* even if the timezone has no daylight savings it may have Bias (e.g. GMT+13 it seems) */
5631 if (tz_id != TIME_ZONE_ID_UNKNOWN) {
5632 tz_info.StandardDate.wYear = year;
5633 convert_to_absolute_date(&tz_info.StandardDate);
5634 err = SystemTimeToFileTime (&tz_info.StandardDate, &ft);
5636 mono_array_set ((*data), gint64, 1, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
5637 tz_info.DaylightDate.wYear = year;
5638 convert_to_absolute_date(&tz_info.DaylightDate);
5639 err = SystemTimeToFileTime (&tz_info.DaylightDate, &ft);
5641 mono_array_set ((*data), gint64, 0, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
5643 mono_array_set ((*data), gint64, 2, (tz_info.Bias + tz_info.StandardBias) * -600000000LL);
5644 mono_array_set ((*data), gint64, 3, (tz_info.DaylightBias - tz_info.StandardBias) * -600000000LL);
5651 ves_icall_System_Object_obj_address (MonoObject *this)
5653 MONO_ARCH_SAVE_REGS;
5660 static inline gint32
5661 mono_array_get_byte_length (MonoArray *array)
5667 klass = array->obj.vtable->klass;
5669 if (array->bounds == NULL)
5670 length = array->max_length;
5673 for (i = 0; i < klass->rank; ++ i)
5674 length *= array->bounds [i].length;
5677 switch (klass->element_class->byval_arg.type) {
5680 case MONO_TYPE_BOOLEAN:
5684 case MONO_TYPE_CHAR:
5692 return length * sizeof (gpointer);
5703 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array)
5705 MONO_ARCH_SAVE_REGS;
5707 return mono_array_get_byte_length (array);
5711 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx)
5713 MONO_ARCH_SAVE_REGS;
5715 return mono_array_get (array, gint8, idx);
5719 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value)
5721 MONO_ARCH_SAVE_REGS;
5723 mono_array_set (array, gint8, idx, value);
5727 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count)
5729 guint8 *src_buf, *dest_buf;
5731 MONO_ARCH_SAVE_REGS;
5733 /* watch out for integer overflow */
5734 if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count))
5737 src_buf = (guint8 *)src->vector + src_offset;
5738 dest_buf = (guint8 *)dest->vector + dest_offset;
5741 memcpy (dest_buf, src_buf, count);
5743 memmove (dest_buf, src_buf, count); /* Source and dest are the same array */
5749 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this, MonoString *class_name)
5751 MonoDomain *domain = mono_object_domain (this);
5753 MonoRealProxy *rp = ((MonoRealProxy *)this);
5754 MonoTransparentProxy *tp;
5758 MONO_ARCH_SAVE_REGS;
5760 res = mono_object_new (domain, mono_defaults.transparent_proxy_class);
5761 tp = (MonoTransparentProxy*) res;
5763 MONO_OBJECT_SETREF (tp, rp, rp);
5764 type = ((MonoReflectionType *)rp->class_to_proxy)->type;
5765 klass = mono_class_from_mono_type (type);
5767 tp->custom_type_info = (mono_object_isinst (this, mono_defaults.iremotingtypeinfo_class) != NULL);
5768 tp->remote_class = mono_remote_class (domain, class_name, klass);
5770 res->vtable = mono_remote_class_vtable (domain, tp->remote_class, rp);
5774 static MonoReflectionType *
5775 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
5777 return mono_type_get_object (mono_object_domain (tp), &tp->remote_class->proxy_class->byval_arg);
5780 /* System.Environment */
5783 ves_icall_System_Environment_get_MachineName (void)
5785 #if defined (PLATFORM_WIN32)
5790 len = MAX_COMPUTERNAME_LENGTH + 1;
5791 buf = g_new (gunichar2, len);
5794 if (GetComputerName (buf, (PDWORD) &len))
5795 result = mono_string_new_utf16 (mono_domain_get (), buf, len);
5803 if (gethostname (buf, sizeof (buf)) == 0)
5804 result = mono_string_new (mono_domain_get (), buf);
5813 ves_icall_System_Environment_get_Platform (void)
5815 MONO_ARCH_SAVE_REGS;
5817 #if defined (PLATFORM_WIN32)
5827 ves_icall_System_Environment_get_NewLine (void)
5829 MONO_ARCH_SAVE_REGS;
5831 #if defined (PLATFORM_WIN32)
5832 return mono_string_new (mono_domain_get (), "\r\n");
5834 return mono_string_new (mono_domain_get (), "\n");
5839 ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name)
5844 MONO_ARCH_SAVE_REGS;
5849 utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
5850 value = g_getenv (utf8_name);
5857 return mono_string_new (mono_domain_get (), value);
5861 * There is no standard way to get at environ.
5864 #ifndef __MINGW32_VERSION
5871 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
5879 MONO_ARCH_SAVE_REGS;
5882 for (e = environ; *e != 0; ++ e)
5885 domain = mono_domain_get ();
5886 names = mono_array_new (domain, mono_defaults.string_class, n);
5889 for (e = environ; *e != 0; ++ e) {
5890 parts = g_strsplit (*e, "=", 2);
5892 str = mono_string_new (domain, *parts);
5893 mono_array_setref (names, n, str);
5905 * If your platform lacks setenv/unsetenv, you must upgrade your glib.
5907 #if !GLIB_CHECK_VERSION(2,4,0)
5908 #define g_setenv(a,b,c) setenv(a,b,c)
5909 #define g_unsetenv(a) unsetenv(a)
5913 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
5915 #ifdef PLATFORM_WIN32
5916 gunichar2 *utf16_name, *utf16_value;
5918 gchar *utf8_name, *utf8_value;
5921 MONO_ARCH_SAVE_REGS;
5923 #ifdef PLATFORM_WIN32
5924 utf16_name = mono_string_to_utf16 (name);
5925 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
5926 SetEnvironmentVariable (utf16_name, NULL);
5927 g_free (utf16_name);
5931 utf16_value = mono_string_to_utf16 (value);
5933 SetEnvironmentVariable (utf16_name, utf16_value);
5935 g_free (utf16_name);
5936 g_free (utf16_value);
5938 utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
5940 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
5941 g_unsetenv (utf8_name);
5946 utf8_value = mono_string_to_utf8 (value);
5947 g_setenv (utf8_name, utf8_value, TRUE);
5950 g_free (utf8_value);
5955 * Returns: the number of milliseconds elapsed since the system started.
5958 ves_icall_System_Environment_get_TickCount (void)
5960 return GetTickCount ();
5965 ves_icall_System_Environment_Exit (int result)
5967 MONO_ARCH_SAVE_REGS;
5969 mono_runtime_set_shutting_down ();
5971 /* Suspend all managed threads since the runtime is going away */
5972 mono_thread_suspend_all_other_threads ();
5974 mono_runtime_quit ();
5976 /* we may need to do some cleanup here... */
5981 ves_icall_System_Environment_GetGacPath (void)
5983 return mono_string_new (mono_domain_get (), mono_assembly_getrootdir ());
5987 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
5989 #if defined (PLATFORM_WIN32)
5990 #ifndef CSIDL_FLAG_CREATE
5991 #define CSIDL_FLAG_CREATE 0x8000
5994 WCHAR path [MAX_PATH];
5995 /* Create directory if no existing */
5996 if (SUCCEEDED (SHGetFolderPathW (NULL, folder | CSIDL_FLAG_CREATE, NULL, 0, path))) {
6000 return mono_string_new_utf16 (mono_domain_get (), path, len);
6003 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
6005 return mono_string_new (mono_domain_get (), "");
6009 ves_icall_System_Environment_GetLogicalDrives (void)
6011 gunichar2 buf [128], *ptr, *dname;
6013 gint initial_size = 127, size = 128;
6016 MonoString *drivestr;
6017 MonoDomain *domain = mono_domain_get ();
6020 MONO_ARCH_SAVE_REGS;
6025 while (size > initial_size) {
6026 size = GetLogicalDriveStrings (initial_size, ptr);
6027 if (size > initial_size) {
6030 ptr = g_malloc0 ((size + 1) * sizeof (gunichar2));
6031 initial_size = size;
6045 result = mono_array_new (domain, mono_defaults.string_class, ndrives);
6050 while (*u16) { u16++; len ++; }
6051 drivestr = mono_string_new_utf16 (domain, dname, len);
6052 mono_array_setref (result, ndrives++, drivestr);
6063 ves_icall_System_Environment_InternalGetHome (void)
6065 MONO_ARCH_SAVE_REGS;
6067 return mono_string_new (mono_domain_get (), g_get_home_dir ());
6070 static const char *encodings [] = {
6072 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
6073 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
6074 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
6076 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
6077 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
6078 "x_unicode_2_0_utf_7",
6080 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
6081 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
6083 "utf_16", "UTF_16LE", "ucs_2", "unicode",
6086 "unicodefffe", "utf_16be",
6093 * Returns the internal codepage, if the value of "int_code_page" is
6094 * 1 at entry, and we can not compute a suitable code page number,
6095 * returns the code page as a string
6098 ves_icall_System_Text_Encoding_InternalCodePage (gint32 *int_code_page)
6103 char *codepage = NULL;
6105 int want_name = *int_code_page;
6108 *int_code_page = -1;
6109 MONO_ARCH_SAVE_REGS;
6111 g_get_charset (&cset);
6112 c = codepage = strdup (cset);
6113 for (c = codepage; *c; c++){
6114 if (isascii (*c) && isalpha (*c))
6119 /* g_print ("charset: %s\n", cset); */
6121 /* handle some common aliases */
6124 for (i = 0; p != 0; ){
6125 if ((gssize) p < 7){
6127 p = encodings [++i];
6130 if (strcmp (p, codepage) == 0){
6131 *int_code_page = code;
6134 p = encodings [++i];
6137 if (strstr (codepage, "utf_8") != NULL)
6138 *int_code_page |= 0x10000000;
6141 if (want_name && *int_code_page == -1)
6142 return mono_string_new (mono_domain_get (), cset);
6148 ves_icall_System_Environment_get_HasShutdownStarted (void)
6150 if (mono_runtime_is_shutting_down ())
6153 if (mono_domain_is_unloading (mono_domain_get ()))
6160 ves_icall_MonoMethodMessage_InitMessage (MonoMethodMessage *this,
6161 MonoReflectionMethod *method,
6162 MonoArray *out_args)
6164 MONO_ARCH_SAVE_REGS;
6166 mono_message_init (mono_object_domain (this), this, method, out_args);
6170 ves_icall_IsTransparentProxy (MonoObject *proxy)
6172 MONO_ARCH_SAVE_REGS;
6177 if (proxy->vtable->klass == mono_defaults.transparent_proxy_class)
6184 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6189 MONO_ARCH_SAVE_REGS;
6191 klass = mono_class_from_mono_type (type->type);
6192 vtable = mono_class_vtable (mono_domain_get (), klass);
6194 if (enable) vtable->remote = 1;
6195 else vtable->remote = 0;
6199 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type)
6204 MONO_ARCH_SAVE_REGS;
6206 domain = mono_object_domain (type);
6207 klass = mono_class_from_mono_type (type->type);
6209 if (klass->rank >= 1) {
6210 g_assert (klass->rank == 1);
6211 return (MonoObject *) mono_array_new (domain, klass->element_class, 0);
6213 /* Bypass remoting object creation check */
6214 return mono_object_new_alloc_specific (mono_class_vtable (domain, klass));
6219 ves_icall_System_IO_get_temp_path (void)
6221 MONO_ARCH_SAVE_REGS;
6223 return mono_string_new (mono_domain_get (), g_get_tmp_dir ());
6227 ves_icall_RuntimeMethod_GetFunctionPointer (MonoMethod *method)
6229 MONO_ARCH_SAVE_REGS;
6231 return mono_compile_method (method);
6235 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
6240 MONO_ARCH_SAVE_REGS;
6242 path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
6244 #if defined (PLATFORM_WIN32)
6245 /* Avoid mixing '/' and '\\' */
6248 for (i = strlen (path) - 1; i >= 0; i--)
6249 if (path [i] == '/')
6253 mcpath = mono_string_new (mono_domain_get (), path);
6260 ves_icall_System_Configuration_DefaultConfig_get_bundled_machine_config (void)
6262 const gchar *machine_config;
6264 MONO_ARCH_SAVE_REGS;
6266 machine_config = mono_get_machine_config ();
6268 if (!machine_config)
6271 return mono_string_new (mono_domain_get (), machine_config);
6275 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
6280 MONO_ARCH_SAVE_REGS;
6282 path = g_path_get_dirname (mono_get_config_dir ());
6284 #if defined (PLATFORM_WIN32)
6285 /* Avoid mixing '/' and '\\' */
6288 for (i = strlen (path) - 1; i >= 0; i--)
6289 if (path [i] == '/')
6293 ipath = mono_string_new (mono_domain_get (), path);
6300 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
6302 #if defined (PLATFORM_WIN32)
6303 OutputDebugString (mono_string_chars (message));
6305 g_warning ("WriteWindowsDebugString called and PLATFORM_WIN32 not defined!\n");
6309 /* Only used for value types */
6311 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
6316 MONO_ARCH_SAVE_REGS;
6318 domain = mono_object_domain (type);
6319 klass = mono_class_from_mono_type (type->type);
6321 if (mono_class_is_nullable (klass))
6322 /* No arguments -> null */
6325 return mono_object_new (domain, klass);
6328 static MonoReflectionMethod *
6329 ves_icall_MonoMethod_get_base_definition (MonoReflectionMethod *m)
6331 MonoClass *klass, *parent;
6332 MonoMethod *method = m->method;
6333 MonoMethod *result = NULL;
6335 MONO_ARCH_SAVE_REGS;
6337 if (method->klass == NULL)
6340 if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
6341 MONO_CLASS_IS_INTERFACE (method->klass) ||
6342 method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
6345 klass = method->klass;
6346 if (klass->generic_class)
6347 klass = klass->generic_class->container_class;
6349 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
6350 for (parent = klass->parent; parent != NULL; parent = parent->parent) {
6351 mono_class_setup_vtable (parent);
6352 if (parent->vtable_size <= method->slot)
6357 if (klass == method->klass)
6360 result = klass->vtable [method->slot];
6361 if (result == NULL) {
6362 /* It is an abstract method */
6363 gpointer iter = NULL;
6364 while ((result = mono_class_get_methods (klass, &iter)))
6365 if (result->slot == method->slot)
6372 return mono_method_get_object (mono_domain_get (), result, NULL);
6376 ves_icall_MonoMethod_get_name (MonoReflectionMethod *m)
6378 MonoMethod *method = m->method;
6380 MONO_OBJECT_SETREF (m, name, mono_string_new (mono_object_domain (m), method->name));
6385 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
6387 MONO_ARCH_SAVE_REGS;
6389 iter->sig = *(MonoMethodSignature**)argsp;
6391 g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
6392 g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
6395 /* FIXME: it's not documented what start is exactly... */
6399 guint32 i, arg_size;
6401 iter->args = argsp + sizeof (gpointer);
6402 #ifndef MONO_ARCH_REGPARMS
6403 for (i = 0; i < iter->sig->sentinelpos; ++i) {
6404 arg_size = mono_type_stack_size (iter->sig->params [i], &align);
6405 iter->args = (char*)iter->args + arg_size;
6409 iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
6411 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
6415 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
6417 guint32 i, arg_size;
6420 MONO_ARCH_SAVE_REGS;
6422 i = iter->sig->sentinelpos + iter->next_arg;
6424 g_assert (i < iter->sig->param_count);
6426 res.type = iter->sig->params [i];
6427 res.klass = mono_class_from_mono_type (res.type);
6428 /* FIXME: endianess issue... */
6429 res.value = iter->args;
6430 arg_size = mono_type_stack_size (res.type, &align);
6431 iter->args = (char*)iter->args + arg_size;
6434 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6440 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
6442 guint32 i, arg_size;
6445 MONO_ARCH_SAVE_REGS;
6447 i = iter->sig->sentinelpos + iter->next_arg;
6449 g_assert (i < iter->sig->param_count);
6451 while (i < iter->sig->param_count) {
6452 if (!mono_metadata_type_equal (type, iter->sig->params [i]))
6454 res.type = iter->sig->params [i];
6455 res.klass = mono_class_from_mono_type (res.type);
6456 /* FIXME: endianess issue... */
6457 res.value = iter->args;
6458 arg_size = mono_type_stack_size (res.type, &align);
6459 iter->args = (char*)iter->args + arg_size;
6461 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6464 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
6473 mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
6476 MONO_ARCH_SAVE_REGS;
6478 i = iter->sig->sentinelpos + iter->next_arg;
6480 g_assert (i < iter->sig->param_count);
6482 return iter->sig->params [i];
6486 mono_TypedReference_ToObject (MonoTypedRef tref)
6488 MONO_ARCH_SAVE_REGS;
6490 if (MONO_TYPE_IS_REFERENCE (tref.type)) {
6491 MonoObject** objp = tref.value;
6495 return mono_value_box (mono_domain_get (), tref.klass, tref.value);
6499 mono_TypedReference_ToObjectInternal (MonoType *type, gpointer value, MonoClass *klass)
6501 MONO_ARCH_SAVE_REGS;
6503 if (MONO_TYPE_IS_REFERENCE (type)) {
6504 MonoObject** objp = value;
6508 return mono_value_box (mono_domain_get (), klass, value);
6512 prelink_method (MonoMethod *method)
6514 const char *exc_class, *exc_arg;
6515 if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
6517 mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
6519 mono_raise_exception(
6520 mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg ) );
6522 /* create the wrapper, too? */
6526 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
6528 MONO_ARCH_SAVE_REGS;
6529 prelink_method (method->method);
6533 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
6535 MonoClass *klass = mono_class_from_mono_type (type->type);
6537 gpointer iter = NULL;
6538 MONO_ARCH_SAVE_REGS;
6540 while ((m = mono_class_get_methods (klass, &iter)))
6544 /* These parameters are "readonly" in corlib/System/Char.cs */
6546 ves_icall_System_Char_GetDataTablePointers (guint8 const **category_data,
6547 guint8 const **numeric_data,
6548 gdouble const **numeric_data_values,
6549 guint16 const **to_lower_data_low,
6550 guint16 const **to_lower_data_high,
6551 guint16 const **to_upper_data_low,
6552 guint16 const **to_upper_data_high)
6554 *category_data = CategoryData;
6555 *numeric_data = NumericData;
6556 *numeric_data_values = NumericDataValues;
6557 *to_lower_data_low = ToLowerDataLow;
6558 *to_lower_data_high = ToLowerDataHigh;
6559 *to_upper_data_low = ToUpperDataLow;
6560 *to_upper_data_high = ToUpperDataHigh;
6564 ves_icall_MonoDebugger_GetMethodToken (MonoReflectionMethod *method)
6566 return method->method->token;
6570 * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
6571 * and avoid useless allocations.
6574 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional)
6578 for (i = 0; i < type->num_mods; ++i) {
6579 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
6584 res = mono_array_new (mono_domain_get (), mono_defaults.systemtype_class, count);
6586 for (i = 0; i < type->num_mods; ++i) {
6587 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
6588 MonoClass *klass = mono_class_get (image, type->modifiers [i].token);
6589 mono_array_setref (res, count, mono_type_get_object (mono_domain_get (), &klass->byval_arg));
6597 param_info_get_type_modifiers (MonoReflectionParameter *param, MonoBoolean optional)
6599 MonoType *type = param->ClassImpl->type;
6600 MonoReflectionMethod *method = (MonoReflectionMethod*)param->MemberImpl;
6601 MonoImage *image = method->method->klass->image;
6602 int pos = param->PositionImpl;
6603 MonoMethodSignature *sig = mono_method_signature (method->method);
6607 type = sig->params [pos];
6609 return type_array_from_modifiers (image, type, optional);
6613 get_property_type (MonoProperty *prop)
6615 MonoMethodSignature *sig;
6617 sig = mono_method_signature (prop->get);
6619 } else if (prop->set) {
6620 sig = mono_method_signature (prop->set);
6621 return sig->params [sig->param_count - 1];
6627 property_info_get_type_modifiers (MonoReflectionProperty *property, MonoBoolean optional)
6629 MonoType *type = get_property_type (property->property);
6630 MonoImage *image = property->klass->image;
6634 return type_array_from_modifiers (image, type, optional);
6638 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
6640 MonoCustomAttrInfo *cinfo;
6643 cinfo = mono_reflection_get_custom_attrs_info (obj);
6646 found = mono_custom_attrs_has_attr (cinfo, mono_class_from_mono_type (attr_type->type));
6648 mono_custom_attrs_free (cinfo);
6653 custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
6655 MonoArray *res = mono_reflection_get_custom_attrs_by_type (obj, attr_type ? mono_class_from_mono_type (attr_type->type) : NULL);
6657 if (mono_loader_get_last_error ()) {
6658 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
6659 g_assert_not_reached ();
6666 GCHandle_CheckCurrentDomain (guint32 gchandle)
6668 return mono_gchandle_is_in_domain (gchandle, mono_domain_get ());
6672 ves_icall_Mono_Runtime_GetDisplayName (void)
6674 static const char display_name_str [] = "Mono " VERSION;
6675 MonoString *display_name = mono_string_new (mono_domain_get (), display_name_str);
6676 return display_name;
6681 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
6682 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
6683 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 62, 128, 128, 128, 63,
6684 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 0, 128, 128,
6685 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
6686 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 128, 128, 128, 128, 128,
6687 128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
6688 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
6692 base64_to_byte_array (gunichar2 *start, gint ilength, MonoBoolean allowWhitespaceOnly)
6697 gunichar2 last, prev_last;
6705 last = prev_last = 0;
6706 for (i = 0; i < ilength; i++) {
6708 if (c >= sizeof (dbase64)) {
6709 exc = mono_exception_from_name_msg (mono_get_corlib (),
6710 "System", "FormatException",
6711 "Invalid character found.");
6712 mono_raise_exception (exc);
6713 } else if (isspace (c)) {
6721 olength = ilength - ignored;
6723 if (allowWhitespaceOnly && olength == 0) {
6724 return mono_array_new (mono_domain_get (), mono_defaults.byte_class, 0);
6727 if ((olength & 3) != 0 || olength <= 0) {
6728 exc = mono_exception_from_name_msg (mono_get_corlib (), "System",
6729 "FormatException", "Invalid length.");
6730 mono_raise_exception (exc);
6733 olength = (olength * 3) / 4;
6737 if (prev_last == '=')
6740 result = mono_array_new (mono_domain_get (), mono_defaults.byte_class, olength);
6741 res_ptr = mono_array_addr (result, guchar, 0);
6742 for (i = 0; i < ilength; ) {
6745 for (k = 0; k < 4 && i < ilength;) {
6751 if (((b [k] = dbase64 [c]) & 0x80) != 0) {
6752 exc = mono_exception_from_name_msg (mono_get_corlib (),
6753 "System", "FormatException",
6754 "Invalid character found.");
6755 mono_raise_exception (exc);
6760 *res_ptr++ = (b [0] << 2) | (b [1] >> 4);
6762 *res_ptr++ = (b [1] << 4) | (b [2] >> 2);
6764 *res_ptr++ = (b [2] << 6) | b [3];
6766 while (i < ilength && isspace (start [i]))
6774 InternalFromBase64String (MonoString *str, MonoBoolean allowWhitespaceOnly)
6776 MONO_ARCH_SAVE_REGS;
6778 return base64_to_byte_array (mono_string_chars (str),
6779 mono_string_length (str), allowWhitespaceOnly);
6783 InternalFromBase64CharArray (MonoArray *input, gint offset, gint length)
6785 MONO_ARCH_SAVE_REGS;
6787 return base64_to_byte_array (mono_array_addr (input, gunichar2, offset),
6791 #define ICALL_TYPE(id,name,first)
6792 #define ICALL(id,name,func) Icall_ ## id,
6795 #include "metadata/icall-def.h"
6801 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
6802 #define ICALL(id,name,func)
6804 #include "metadata/icall-def.h"
6810 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
6811 #define ICALL(id,name,func)
6813 guint16 first_icall;
6816 static const IcallTypeDesc
6817 icall_type_descs [] = {
6818 #include "metadata/icall-def.h"
6822 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
6825 #define ICALL_TYPE(id,name,first)
6828 #ifdef HAVE_ARRAY_ELEM_INIT
6829 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
6830 #define MSGSTRFIELD1(line) str##line
6832 static const struct msgstrtn_t {
6833 #define ICALL(id,name,func)
6835 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
6836 #include "metadata/icall-def.h"
6838 } icall_type_names_str = {
6839 #define ICALL_TYPE(id,name,first) (name),
6840 #include "metadata/icall-def.h"
6843 static const guint16 icall_type_names_idx [] = {
6844 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
6845 #include "metadata/icall-def.h"
6848 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
6850 static const struct msgstr_t {
6852 #define ICALL_TYPE(id,name,first)
6853 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
6854 #include "metadata/icall-def.h"
6856 } icall_names_str = {
6857 #define ICALL(id,name,func) (name),
6858 #include "metadata/icall-def.h"
6861 static const guint16 icall_names_idx [] = {
6862 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
6863 #include "metadata/icall-def.h"
6866 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
6872 #define ICALL_TYPE(id,name,first) name,
6873 #define ICALL(id,name,func)
6874 static const char* const
6875 icall_type_names [] = {
6876 #include "metadata/icall-def.h"
6880 #define icall_type_name_get(id) (icall_type_names [(id)])
6884 #define ICALL_TYPE(id,name,first)
6885 #define ICALL(id,name,func) name,
6886 static const char* const
6888 #include "metadata/icall-def.h"
6891 #define icall_name_get(id) icall_names [(id)]
6893 #endif /* !HAVE_ARRAY_ELEM_INIT */
6897 #define ICALL_TYPE(id,name,first)
6898 #define ICALL(id,name,func) func,
6899 static const gconstpointer
6900 icall_functions [] = {
6901 #include "metadata/icall-def.h"
6905 static GHashTable *icall_hash = NULL;
6906 static GHashTable *jit_icall_hash_name = NULL;
6907 static GHashTable *jit_icall_hash_addr = NULL;
6910 mono_icall_init (void)
6914 /* check that tables are sorted: disable in release */
6917 const char *prev_class = NULL;
6918 const char *prev_method;
6920 for (i = 0; i < Icall_type_num; ++i) {
6921 const IcallTypeDesc *desc;
6924 if (prev_class && strcmp (prev_class, icall_type_name_get (i)) >= 0)
6925 g_print ("class %s should come before class %s\n", icall_type_name_get (i), prev_class);
6926 prev_class = icall_type_name_get (i);
6927 desc = &icall_type_descs [i];
6928 num_icalls = icall_desc_num_icalls (desc);
6929 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
6930 for (j = 0; j < num_icalls; ++j) {
6931 const char *methodn = icall_name_get (desc->first_icall + j);
6932 if (prev_method && strcmp (prev_method, methodn) >= 0)
6933 g_print ("method %s should come before method %s\n", methodn, prev_method);
6934 prev_method = methodn;
6939 icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
6943 mono_icall_cleanup (void)
6945 g_hash_table_destroy (icall_hash);
6946 g_hash_table_destroy (jit_icall_hash_name);
6947 g_hash_table_destroy (jit_icall_hash_addr);
6951 mono_add_internal_call (const char *name, gconstpointer method)
6953 mono_loader_lock ();
6955 g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
6957 mono_loader_unlock ();
6960 #ifdef HAVE_ARRAY_ELEM_INIT
6962 compare_method_imap (const void *key, const void *elem)
6964 const char* method_name = (const char*)&icall_names_str + (*(guint16*)elem);
6965 return strcmp (key, method_name);
6969 find_method_icall (const IcallTypeDesc *imap, const char *name)
6971 const guint16 *nameslot = bsearch (name, icall_names_idx + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names_idx [0]), compare_method_imap);
6974 return (gpointer)icall_functions [(nameslot - &icall_names_idx [0])];
6978 compare_class_imap (const void *key, const void *elem)
6980 const char* class_name = (const char*)&icall_type_names_str + (*(guint16*)elem);
6981 return strcmp (key, class_name);
6984 static const IcallTypeDesc*
6985 find_class_icalls (const char *name)
6987 const guint16 *nameslot = bsearch (name, icall_type_names_idx, Icall_type_num, sizeof (icall_type_names_idx [0]), compare_class_imap);
6990 return &icall_type_descs [nameslot - &icall_type_names_idx [0]];
6995 compare_method_imap (const void *key, const void *elem)
6997 const char** method_name = (const char**)elem;
6998 return strcmp (key, *method_name);
7002 find_method_icall (const IcallTypeDesc *imap, const char *name)
7004 const char **nameslot = bsearch (name, icall_names + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names [0]), compare_method_imap);
7007 return (gpointer)icall_functions [(nameslot - icall_names)];
7011 compare_class_imap (const void *key, const void *elem)
7013 const char** class_name = (const char**)elem;
7014 return strcmp (key, *class_name);
7017 static const IcallTypeDesc*
7018 find_class_icalls (const char *name)
7020 const char **nameslot = bsearch (name, icall_type_names, Icall_type_num, sizeof (icall_type_names [0]), compare_class_imap);
7023 return &icall_type_descs [nameslot - icall_type_names];
7029 * we should probably export this as an helper (handle nested types).
7030 * Returns the number of chars written in buf.
7033 concat_class_name (char *buf, int bufsize, MonoClass *klass)
7035 int nspacelen, cnamelen;
7036 nspacelen = strlen (klass->name_space);
7037 cnamelen = strlen (klass->name);
7038 if (nspacelen + cnamelen + 2 > bufsize)
7041 memcpy (buf, klass->name_space, nspacelen);
7042 buf [nspacelen ++] = '.';
7044 memcpy (buf + nspacelen, klass->name, cnamelen);
7045 buf [nspacelen + cnamelen] = 0;
7046 return nspacelen + cnamelen;
7050 mono_lookup_internal_call (MonoMethod *method)
7055 int typelen = 0, mlen, siglen;
7057 const IcallTypeDesc *imap;
7059 g_assert (method != NULL);
7061 if (method->is_inflated)
7062 method = ((MonoMethodInflated *) method)->declaring;
7064 if (method->klass->nested_in) {
7065 int pos = concat_class_name (mname, sizeof (mname)-2, method->klass->nested_in);
7069 mname [pos++] = '/';
7072 typelen = concat_class_name (mname+pos, sizeof (mname)-pos-1, method->klass);
7078 typelen = concat_class_name (mname, sizeof (mname), method->klass);
7083 imap = find_class_icalls (mname);
7085 mname [typelen] = ':';
7086 mname [typelen + 1] = ':';
7088 mlen = strlen (method->name);
7089 memcpy (mname + typelen + 2, method->name, mlen);
7090 sigstart = mname + typelen + 2 + mlen;
7093 tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
7094 siglen = strlen (tmpsig);
7095 if (typelen + mlen + siglen + 6 > sizeof (mname))
7098 memcpy (sigstart + 1, tmpsig, siglen);
7099 sigstart [siglen + 1] = ')';
7100 sigstart [siglen + 2] = 0;
7103 mono_loader_lock ();
7105 res = g_hash_table_lookup (icall_hash, mname);
7107 mono_loader_unlock ();
7110 /* try without signature */
7112 res = g_hash_table_lookup (icall_hash, mname);
7114 mono_loader_unlock ();
7118 /* it wasn't found in the static call tables */
7120 mono_loader_unlock ();
7123 res = find_method_icall (imap, sigstart - mlen);
7125 mono_loader_unlock ();
7128 /* try _with_ signature */
7130 res = find_method_icall (imap, sigstart - mlen);
7132 mono_loader_unlock ();
7136 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname);
7137 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
7138 g_print ("The out of sync library is: %s\n", method->klass->image->name);
7139 g_print ("\nWhen you update one from cvs you need to update, compile and install\nthe other too.\n");
7140 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");
7141 g_print ("If you see other errors or faults after this message they are probably related\n");
7142 g_print ("and you need to fix your mono install first.\n");
7144 mono_loader_unlock ();
7150 type_from_typename (char *typename)
7152 MonoClass *klass = NULL; /* assignment to shut GCC warning up */
7154 if (!strcmp (typename, "int"))
7155 klass = mono_defaults.int_class;
7156 else if (!strcmp (typename, "ptr"))
7157 klass = mono_defaults.int_class;
7158 else if (!strcmp (typename, "void"))
7159 klass = mono_defaults.void_class;
7160 else if (!strcmp (typename, "int32"))
7161 klass = mono_defaults.int32_class;
7162 else if (!strcmp (typename, "uint32"))
7163 klass = mono_defaults.uint32_class;
7164 else if (!strcmp (typename, "int8"))
7165 klass = mono_defaults.sbyte_class;
7166 else if (!strcmp (typename, "uint8"))
7167 klass = mono_defaults.byte_class;
7168 else if (!strcmp (typename, "int16"))
7169 klass = mono_defaults.int16_class;
7170 else if (!strcmp (typename, "uint16"))
7171 klass = mono_defaults.uint16_class;
7172 else if (!strcmp (typename, "long"))
7173 klass = mono_defaults.int64_class;
7174 else if (!strcmp (typename, "ulong"))
7175 klass = mono_defaults.uint64_class;
7176 else if (!strcmp (typename, "float"))
7177 klass = mono_defaults.single_class;
7178 else if (!strcmp (typename, "double"))
7179 klass = mono_defaults.double_class;
7180 else if (!strcmp (typename, "object"))
7181 klass = mono_defaults.object_class;
7182 else if (!strcmp (typename, "obj"))
7183 klass = mono_defaults.object_class;
7186 g_assert_not_reached ();
7188 return &klass->byval_arg;
7191 MonoMethodSignature*
7192 mono_create_icall_signature (const char *sigstr)
7197 MonoMethodSignature *res;
7199 mono_loader_lock ();
7200 res = g_hash_table_lookup (mono_defaults.corlib->helper_signatures, sigstr);
7202 mono_loader_unlock ();
7206 parts = g_strsplit (sigstr, " ", 256);
7215 res = mono_metadata_signature_alloc (mono_defaults.corlib, len - 1);
7218 #ifdef PLATFORM_WIN32
7220 * Under windows, the default pinvoke calling convention is STDCALL but
7223 res->call_convention = MONO_CALL_C;
7226 res->ret = type_from_typename (parts [0]);
7227 for (i = 1; i < len; ++i) {
7228 res->params [i - 1] = type_from_typename (parts [i]);
7233 g_hash_table_insert (mono_defaults.corlib->helper_signatures, (gpointer)sigstr, res);
7235 mono_loader_unlock ();
7241 mono_find_jit_icall_by_name (const char *name)
7243 MonoJitICallInfo *info;
7244 g_assert (jit_icall_hash_name);
7246 mono_loader_lock ();
7247 info = g_hash_table_lookup (jit_icall_hash_name, name);
7248 mono_loader_unlock ();
7253 mono_find_jit_icall_by_addr (gconstpointer addr)
7255 MonoJitICallInfo *info;
7256 g_assert (jit_icall_hash_addr);
7258 mono_loader_lock ();
7259 info = g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
7260 mono_loader_unlock ();
7266 mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
7268 mono_loader_lock ();
7269 g_hash_table_insert (jit_icall_hash_addr, (gpointer)wrapper, info);
7270 mono_loader_unlock ();
7274 mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
7276 MonoJitICallInfo *info;
7281 mono_loader_lock ();
7283 if (!jit_icall_hash_name) {
7284 jit_icall_hash_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
7285 jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
7288 if (g_hash_table_lookup (jit_icall_hash_name, name)) {
7289 g_warning ("jit icall already defined \"%s\"\n", name);
7290 g_assert_not_reached ();
7293 info = g_new0 (MonoJitICallInfo, 1);
7300 info->wrapper = func;
7302 info->wrapper = NULL;
7305 g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
7306 g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
7308 mono_loader_unlock ();