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/number-formatter.h>
61 #include <mono/metadata/security-manager.h>
62 #include <mono/metadata/security-core-clr.h>
63 #include <mono/io-layer/io-layer.h>
64 #include <mono/utils/strtod.h>
65 #include <mono/utils/monobitset.h>
67 #if defined (PLATFORM_WIN32)
73 static MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void);
76 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional);
78 static inline MonoBoolean
79 is_generic_parameter (MonoType *type)
81 return !type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR);
85 * We expect a pointer to a char, not a string
88 mono_double_ParseImpl (char *ptr, double *result)
97 *result = strtod (ptr, &endptr);
100 *result = mono_strtod (ptr, &endptr);
103 if (!*ptr || (endptr && *endptr))
110 mono_class_get_throw (MonoImage *image, guint32 type_token)
112 MonoClass *class = mono_class_get (image, type_token);
113 MonoLoaderError *error;
119 error = mono_loader_get_last_error ();
120 g_assert (error != NULL);
122 ex = mono_loader_error_prepare_exception (error);
123 mono_raise_exception (ex);
128 ves_icall_System_Array_GetValueImpl (MonoObject *this, guint32 pos)
137 ao = (MonoArray *)this;
138 ac = (MonoClass *)ao->obj.vtable->klass;
140 esize = mono_array_element_size (ac);
141 ea = (gpointer*)((char*)ao->vector + (pos * esize));
143 if (ac->element_class->valuetype)
144 return mono_value_box (this->vtable->domain, ac->element_class, ea);
150 ves_icall_System_Array_GetValue (MonoObject *this, MonoObject *idxs)
158 MONO_CHECK_ARG_NULL (idxs);
160 io = (MonoArray *)idxs;
161 ic = (MonoClass *)io->obj.vtable->klass;
163 ao = (MonoArray *)this;
164 ac = (MonoClass *)ao->obj.vtable->klass;
166 g_assert (ic->rank == 1);
167 if (io->bounds != NULL || io->max_length != ac->rank)
168 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
170 ind = (gint32 *)io->vector;
172 if (ao->bounds == NULL) {
173 if (*ind < 0 || *ind >= ao->max_length)
174 mono_raise_exception (mono_get_exception_index_out_of_range ());
176 return ves_icall_System_Array_GetValueImpl (this, *ind);
179 for (i = 0; i < ac->rank; i++)
180 if ((ind [i] < ao->bounds [i].lower_bound) ||
181 (ind [i] >= ao->bounds [i].length + ao->bounds [i].lower_bound))
182 mono_raise_exception (mono_get_exception_index_out_of_range ());
184 pos = ind [0] - ao->bounds [0].lower_bound;
185 for (i = 1; i < ac->rank; i++)
186 pos = pos*ao->bounds [i].length + ind [i] -
187 ao->bounds [i].lower_bound;
189 return ves_icall_System_Array_GetValueImpl (this, pos);
193 ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32 pos)
195 MonoClass *ac, *vc, *ec;
207 vc = value->vtable->klass;
211 ac = this->obj.vtable->klass;
212 ec = ac->element_class;
214 esize = mono_array_element_size (ac);
215 ea = (gpointer*)((char*)this->vector + (pos * esize));
216 va = (gpointer*)((char*)value + sizeof (MonoObject));
219 memset (ea, 0, esize);
223 #define NO_WIDENING_CONVERSION G_STMT_START{\
224 mono_raise_exception (mono_get_exception_argument ( \
225 "value", "not a widening conversion")); \
228 #define CHECK_WIDENING_CONVERSION(extra) G_STMT_START{\
229 if (esize < vsize + (extra)) \
230 mono_raise_exception (mono_get_exception_argument ( \
231 "value", "not a widening conversion")); \
234 #define INVALID_CAST G_STMT_START{\
235 mono_raise_exception (mono_get_exception_invalid_cast ()); \
238 /* Check element (destination) type. */
239 switch (ec->byval_arg.type) {
240 case MONO_TYPE_STRING:
241 switch (vc->byval_arg.type) {
242 case MONO_TYPE_STRING:
248 case MONO_TYPE_BOOLEAN:
249 switch (vc->byval_arg.type) {
250 case MONO_TYPE_BOOLEAN:
263 NO_WIDENING_CONVERSION;
270 if (!ec->valuetype) {
271 if (!mono_object_isinst (value, ec))
273 mono_gc_wbarrier_set_arrayref (this, ea, (MonoObject*)value);
277 if (mono_object_isinst (value, ec)) {
278 if (ec->has_references)
279 mono_value_copy (ea, (char*)value + sizeof (MonoObject), ec);
281 memcpy (ea, (char *)value + sizeof (MonoObject), esize);
288 vsize = mono_class_instance_size (vc) - sizeof (MonoObject);
290 et = ec->byval_arg.type;
291 if (et == MONO_TYPE_VALUETYPE && ec->byval_arg.data.klass->enumtype)
292 et = ec->byval_arg.data.klass->enum_basetype->type;
294 vt = vc->byval_arg.type;
295 if (vt == MONO_TYPE_VALUETYPE && vc->byval_arg.data.klass->enumtype)
296 vt = vc->byval_arg.data.klass->enum_basetype->type;
298 #define ASSIGN_UNSIGNED(etype) G_STMT_START{\
304 case MONO_TYPE_CHAR: \
305 CHECK_WIDENING_CONVERSION(0); \
306 *(etype *) ea = (etype) u64; \
308 /* You can't assign a signed value to an unsigned array. */ \
313 /* You can't assign a floating point number to an integer array. */ \
316 NO_WIDENING_CONVERSION; \
320 #define ASSIGN_SIGNED(etype) G_STMT_START{\
326 CHECK_WIDENING_CONVERSION(0); \
327 *(etype *) ea = (etype) i64; \
329 /* You can assign an unsigned value to a signed array if the array's */ \
330 /* element size is larger than the value size. */ \
335 case MONO_TYPE_CHAR: \
336 CHECK_WIDENING_CONVERSION(1); \
337 *(etype *) ea = (etype) u64; \
339 /* You can't assign a floating point number to an integer array. */ \
342 NO_WIDENING_CONVERSION; \
346 #define ASSIGN_REAL(etype) G_STMT_START{\
350 CHECK_WIDENING_CONVERSION(0); \
351 *(etype *) ea = (etype) r64; \
353 /* All integer values fit into a floating point array, so we don't */ \
354 /* need to CHECK_WIDENING_CONVERSION here. */ \
359 *(etype *) ea = (etype) i64; \
365 case MONO_TYPE_CHAR: \
366 *(etype *) ea = (etype) u64; \
373 u64 = *(guint8 *) va;
376 u64 = *(guint16 *) va;
379 u64 = *(guint32 *) va;
382 u64 = *(guint64 *) va;
388 i64 = *(gint16 *) va;
391 i64 = *(gint32 *) va;
394 i64 = *(gint64 *) va;
397 r64 = *(gfloat *) va;
400 r64 = *(gdouble *) va;
403 u64 = *(guint16 *) va;
405 case MONO_TYPE_BOOLEAN:
406 /* Boolean is only compatible with itself. */
419 NO_WIDENING_CONVERSION;
426 /* If we can't do a direct copy, let's try a widening conversion. */
429 ASSIGN_UNSIGNED (guint16);
431 ASSIGN_UNSIGNED (guint8);
433 ASSIGN_UNSIGNED (guint16);
435 ASSIGN_UNSIGNED (guint32);
437 ASSIGN_UNSIGNED (guint64);
439 ASSIGN_SIGNED (gint8);
441 ASSIGN_SIGNED (gint16);
443 ASSIGN_SIGNED (gint32);
445 ASSIGN_SIGNED (gint64);
447 ASSIGN_REAL (gfloat);
449 ASSIGN_REAL (gdouble);
453 /* Not reached, INVALID_CAST does not return. Just to avoid a compiler warning ... */
457 #undef NO_WIDENING_CONVERSION
458 #undef CHECK_WIDENING_CONVERSION
459 #undef ASSIGN_UNSIGNED
465 ves_icall_System_Array_SetValue (MonoArray *this, MonoObject *value,
473 MONO_CHECK_ARG_NULL (idxs);
475 ic = idxs->obj.vtable->klass;
476 ac = this->obj.vtable->klass;
478 g_assert (ic->rank == 1);
479 if (idxs->bounds != NULL || idxs->max_length != ac->rank)
480 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
482 ind = (gint32 *)idxs->vector;
484 if (this->bounds == NULL) {
485 if (*ind < 0 || *ind >= this->max_length)
486 mono_raise_exception (mono_get_exception_index_out_of_range ());
488 ves_icall_System_Array_SetValueImpl (this, value, *ind);
492 for (i = 0; i < ac->rank; i++)
493 if ((ind [i] < this->bounds [i].lower_bound) ||
494 (ind [i] >= this->bounds [i].length + this->bounds [i].lower_bound))
495 mono_raise_exception (mono_get_exception_index_out_of_range ());
497 pos = ind [0] - this->bounds [0].lower_bound;
498 for (i = 1; i < ac->rank; i++)
499 pos = pos * this->bounds [i].length + ind [i] -
500 this->bounds [i].lower_bound;
502 ves_icall_System_Array_SetValueImpl (this, value, pos);
506 ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
511 gboolean bounded = FALSE;
515 MONO_CHECK_ARG_NULL (type);
516 MONO_CHECK_ARG_NULL (lengths);
518 MONO_CHECK_ARG (lengths, mono_array_length (lengths) > 0);
520 MONO_CHECK_ARG (bounds, mono_array_length (lengths) == mono_array_length (bounds));
522 for (i = 0; i < mono_array_length (lengths); i++)
523 if (mono_array_get (lengths, gint32, i) < 0)
524 mono_raise_exception (mono_get_exception_argument_out_of_range (NULL));
526 if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint32, 0) != 0))
527 /* vectors are not the same as one dimensional arrays with no-zero bounds */
532 aklass = mono_bounded_array_class_get (mono_class_from_mono_type (type->type), mono_array_length (lengths), bounded);
534 sizes = alloca (aklass->rank * sizeof(guint32) * 2);
535 for (i = 0; i < aklass->rank; ++i) {
536 sizes [i] = mono_array_get (lengths, guint32, i);
538 sizes [i + aklass->rank] = mono_array_get (bounds, guint32, i);
540 sizes [i + aklass->rank] = 0;
543 array = mono_array_new_full (mono_object_domain (type), aklass, sizes, sizes + aklass->rank);
549 ves_icall_System_Array_GetRank (MonoObject *this)
553 return this->vtable->klass->rank;
557 ves_icall_System_Array_GetLength (MonoArray *this, gint32 dimension)
559 gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
563 if ((dimension < 0) || (dimension >= rank))
564 mono_raise_exception (mono_get_exception_index_out_of_range ());
566 if (this->bounds == NULL)
567 return this->max_length;
569 return this->bounds [dimension].length;
573 ves_icall_System_Array_GetLowerBound (MonoArray *this, gint32 dimension)
575 gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
579 if ((dimension < 0) || (dimension >= rank))
580 mono_raise_exception (mono_get_exception_index_out_of_range ());
582 if (this->bounds == NULL)
585 return this->bounds [dimension].lower_bound;
589 ves_icall_System_Array_ClearInternal (MonoArray *arr, int idx, int length)
591 int sz = mono_array_element_size (mono_object_class (arr));
592 memset (mono_array_addr_with_size (arr, sz, idx), 0, length * sz);
596 ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* dest, int dest_idx, int length)
601 MonoClass *src_class;
602 MonoClass *dest_class;
607 if (source->obj.vtable->klass->rank != dest->obj.vtable->klass->rank)
610 if (source->bounds || dest->bounds)
613 if ((dest_idx + length > mono_array_length (dest)) ||
614 (source_idx + length > mono_array_length (source)))
617 src_class = source->obj.vtable->klass->element_class;
618 dest_class = dest->obj.vtable->klass->element_class;
621 * Handle common cases.
624 /* Case1: object[] -> valuetype[] (ArrayList::ToArray) */
625 if (src_class == mono_defaults.object_class && dest_class->valuetype) {
626 int has_refs = dest_class->has_references;
627 for (i = source_idx; i < source_idx + length; ++i) {
628 MonoObject *elem = mono_array_get (source, MonoObject*, i);
629 if (elem && !mono_object_isinst (elem, dest_class))
633 element_size = mono_array_element_size (dest->obj.vtable->klass);
634 memset (mono_array_addr_with_size (dest, element_size, dest_idx), 0, element_size * length);
635 for (i = 0; i < length; ++i) {
636 MonoObject *elem = mono_array_get (source, MonoObject*, source_idx + i);
637 void *addr = mono_array_addr_with_size (dest, element_size, dest_idx + i);
641 mono_value_copy (addr, (char *)elem + sizeof (MonoObject), dest_class);
643 memcpy (addr, (char *)elem + sizeof (MonoObject), element_size);
648 /* Check if we're copying a char[] <==> (u)short[] */
649 if (src_class != dest_class) {
650 if (dest_class->valuetype || dest_class->enumtype || src_class->valuetype || src_class->enumtype)
653 if (mono_class_is_subclass_of (src_class, dest_class, FALSE))
655 /* Case2: object[] -> reftype[] (ArrayList::ToArray) */
656 else if (mono_class_is_subclass_of (dest_class, src_class, FALSE))
657 for (i = source_idx; i < source_idx + length; ++i) {
658 MonoObject *elem = mono_array_get (source, MonoObject*, i);
659 if (elem && !mono_object_isinst (elem, dest_class))
666 if (dest_class->valuetype) {
667 element_size = mono_array_element_size (source->obj.vtable->klass);
668 source_addr = mono_array_addr_with_size (source, element_size, source_idx);
669 if (dest_class->has_references) {
670 mono_value_copy_array (dest, dest_idx, source_addr, length);
672 dest_addr = mono_array_addr_with_size (dest, element_size, dest_idx);
673 memmove (dest_addr, source_addr, element_size * length);
676 mono_array_memcpy_refs (dest, dest_idx, source, source_idx, length);
683 ves_icall_System_Array_GetGenericValueImpl (MonoObject *this, guint32 pos, gpointer value)
692 ao = (MonoArray *)this;
693 ac = (MonoClass *)ao->obj.vtable->klass;
695 esize = mono_array_element_size (ac);
696 ea = (gpointer*)((char*)ao->vector + (pos * esize));
698 memcpy (value, ea, esize);
702 ves_icall_System_Array_SetGenericValueImpl (MonoObject *this, guint32 pos, gpointer value)
711 ao = (MonoArray *)this;
712 ac = (MonoClass *)ao->obj.vtable->klass;
714 esize = mono_array_element_size (ac);
715 ea = (gpointer*)((char*)ao->vector + (pos * esize));
717 memcpy (ea, value, esize);
721 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoArray *array, MonoClassField *field_handle)
723 MonoClass *klass = array->obj.vtable->klass;
724 guint32 size = mono_array_element_size (klass);
725 MonoType *type = mono_type_get_underlying_type (&klass->element_class->byval_arg);
728 if (MONO_TYPE_IS_REFERENCE (type) ||
729 (type->type == MONO_TYPE_VALUETYPE &&
730 (!mono_type_get_class (type) ||
731 mono_type_get_class (type)->has_references))) {
732 MonoException *exc = mono_get_exception_argument("array",
733 "Cannot initialize array containing references");
734 mono_raise_exception (exc);
737 if (!(field_handle->type->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA)) {
738 MonoException *exc = mono_get_exception_argument("field_handle",
739 "Field doesn't have an RVA");
740 mono_raise_exception (exc);
743 size *= array->max_length;
745 if (size > mono_type_size (field_handle->type, &align)) {
746 MonoException *exc = mono_get_exception_argument("field_handle",
747 "Field not large enough to fill array");
748 mono_raise_exception (exc);
751 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
753 guint ## n *data = (guint ## n *) mono_array_addr (array, char, 0); \
754 guint ## n *src = (guint ## n *) field_handle->data; \
755 guint ## n *end = (guint ## n *)((char*)src + size); \
757 for (; src < end; data++, src++) { \
758 *data = read ## n (src); \
762 /* printf ("Initialize array with elements of %s type\n", klass->element_class->name); */
764 switch (type->type) {
781 memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
785 memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
787 if (klass->element_class->byval_arg.type == MONO_TYPE_R8) {
790 double *data = (double*)mono_array_addr (array, double, 0);
792 for (i = 0; i < size; i++, data++) {
802 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData (void)
806 return offsetof (MonoString, chars);
810 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue (MonoObject *obj)
814 if ((obj == NULL) || (! (obj->vtable->klass->valuetype)))
817 return mono_object_clone (obj);
821 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (MonoType *handle)
827 MONO_CHECK_ARG_NULL (handle);
829 klass = mono_class_from_mono_type (handle);
830 MONO_CHECK_ARG (handle, klass);
832 /* This will call the type constructor */
833 mono_runtime_class_init (mono_class_vtable (mono_domain_get (), klass));
837 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunModuleConstructor (MonoImage *image)
841 mono_image_check_for_module_cctor (image);
842 if (image->has_module_cctor) {
843 MonoClass *module_klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | 1);
844 mono_runtime_class_init (mono_class_vtable (mono_domain_get (), module_klass));
849 ves_icall_System_Object_MemberwiseClone (MonoObject *this)
853 return mono_object_clone (this);
857 ves_icall_System_ValueType_InternalGetHashCode (MonoObject *this, MonoArray **fields)
860 MonoObject **values = NULL;
864 MonoClassField* field;
869 klass = mono_object_class (this);
871 if (mono_class_num_fields (klass) == 0)
872 return mono_object_hash (this);
875 * Compute the starting value of the hashcode for fields of primitive
876 * types, and return the remaining fields in an array to the managed side.
877 * This way, we can avoid costly reflection operations in managed code.
880 while ((field = mono_class_get_fields (klass, &iter))) {
881 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
883 if (mono_field_is_deleted (field))
885 /* FIXME: Add more types */
886 switch (field->type->type) {
888 result ^= *(gint32*)((guint8*)this + field->offset);
890 case MONO_TYPE_STRING: {
892 s = *(MonoString**)((guint8*)this + field->offset);
894 result ^= mono_string_hash (s);
899 values = g_newa (MonoObject*, mono_class_num_fields (klass));
900 o = mono_field_get_value_object (mono_object_domain (this), field, this);
901 values [count++] = o;
907 *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
908 for (i = 0; i < count; ++i)
909 mono_array_setref (*fields, i, values [i]);
917 ves_icall_System_ValueType_Equals (MonoObject *this, MonoObject *that, MonoArray **fields)
920 MonoObject **values = NULL;
922 MonoClassField* field;
928 MONO_CHECK_ARG_NULL (that);
930 if (this->vtable != that->vtable)
933 klass = mono_object_class (this);
936 * Do the comparison for fields of primitive type and return a result if
937 * possible. Otherwise, return the remaining fields in an array to the
938 * managed side. This way, we can avoid costly reflection operations in
943 while ((field = mono_class_get_fields (klass, &iter))) {
944 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
946 if (mono_field_is_deleted (field))
948 /* FIXME: Add more types */
949 switch (field->type->type) {
951 if (*(gint32*)((guint8*)this + field->offset) != *(gint32*)((guint8*)that + field->offset))
954 case MONO_TYPE_STRING: {
956 guint32 s1len, s2len;
957 s1 = *(MonoString**)((guint8*)this + field->offset);
958 s2 = *(MonoString**)((guint8*)that + field->offset);
961 if ((s1 == NULL) || (s2 == NULL))
963 s1len = mono_string_length (s1);
964 s2len = mono_string_length (s2);
968 if (memcmp (mono_string_chars (s1), mono_string_chars (s2), s1len * sizeof (gunichar2)) != 0)
974 values = g_newa (MonoObject*, mono_class_num_fields (klass) * 2);
975 o = mono_field_get_value_object (mono_object_domain (this), field, this);
976 values [count++] = o;
977 o = mono_field_get_value_object (mono_object_domain (this), field, that);
978 values [count++] = o;
984 *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
985 for (i = 0; i < count; ++i)
986 mono_array_setref (*fields, i, values [i]);
993 static MonoReflectionType *
994 ves_icall_System_Object_GetType (MonoObject *obj)
998 if (obj->vtable->klass != mono_defaults.transparent_proxy_class)
999 return mono_type_get_object (mono_object_domain (obj), &obj->vtable->klass->byval_arg);
1001 return mono_type_get_object (mono_object_domain (obj), &((MonoTransparentProxy*)obj)->remote_class->proxy_class->byval_arg);
1005 mono_type_type_from_obj (MonoReflectionType *mtype, MonoObject *obj)
1007 MONO_ARCH_SAVE_REGS;
1009 mtype->type = &obj->vtable->klass->byval_arg;
1010 g_assert (mtype->type->type);
1014 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj)
1016 MONO_ARCH_SAVE_REGS;
1018 MONO_CHECK_ARG_NULL (obj);
1020 return mono_image_create_token (mb->dynamic_image, obj, TRUE);
1024 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder *mb,
1025 MonoReflectionMethod *method,
1026 MonoArray *opt_param_types)
1028 MONO_ARCH_SAVE_REGS;
1030 MONO_CHECK_ARG_NULL (method);
1032 return mono_image_create_method_token (
1033 mb->dynamic_image, (MonoObject *) method, opt_param_types);
1037 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder *mb, HANDLE file)
1039 MONO_ARCH_SAVE_REGS;
1041 mono_image_create_pefile (mb, file);
1045 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
1047 MONO_ARCH_SAVE_REGS;
1049 mono_image_build_metadata (mb);
1053 get_caller (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1055 MonoMethod **dest = data;
1057 /* skip unmanaged frames */
1072 static MonoReflectionType *
1073 type_from_name (const char *str, MonoBoolean ignoreCase)
1075 MonoType *type = NULL;
1076 MonoAssembly *assembly = NULL;
1077 MonoTypeNameParse info;
1078 char *temp_str = g_strdup (str);
1079 gboolean type_resolve = FALSE;
1081 MONO_ARCH_SAVE_REGS;
1083 /* mono_reflection_parse_type() mangles the string */
1084 if (!mono_reflection_parse_type (temp_str, &info)) {
1085 mono_reflection_free_type_info (&info);
1090 if (info.assembly.name) {
1091 assembly = mono_assembly_load (&info.assembly, NULL, NULL);
1093 MonoMethod *m = mono_method_get_last_managed ();
1094 MonoMethod *dest = m;
1096 mono_stack_walk_no_il (get_caller, &dest);
1101 * FIXME: mono_method_get_last_managed() sometimes returns NULL, thus
1102 * causing ves_icall_System_Reflection_Assembly_GetCallingAssembly()
1103 * to crash. This only seems to happen in some strange remoting
1104 * scenarios and I was unable to figure out what's happening there.
1105 * Dec 10, 2005 - Martin.
1109 assembly = dest->klass->image->assembly;
1111 g_warning (G_STRLOC);
1116 type = mono_reflection_get_type (assembly->image, &info, ignoreCase, &type_resolve);
1118 if (!info.assembly.name && !type) /* try mscorlib */
1119 type = mono_reflection_get_type (NULL, &info, ignoreCase, &type_resolve);
1121 mono_reflection_free_type_info (&info);
1127 return mono_type_get_object (mono_domain_get (), type);
1131 MonoReflectionType *
1132 mono_type_get (const char *str)
1134 char *copy = g_strdup (str);
1135 MonoReflectionType *type = type_from_name (copy, FALSE);
1142 static MonoReflectionType*
1143 ves_icall_type_from_name (MonoString *name,
1144 MonoBoolean throwOnError,
1145 MonoBoolean ignoreCase)
1147 char *str = mono_string_to_utf8 (name);
1148 MonoReflectionType *type;
1150 type = type_from_name (str, ignoreCase);
1153 MonoException *e = NULL;
1156 e = mono_get_exception_type_load (name, NULL);
1158 mono_loader_clear_error ();
1160 mono_raise_exception (e);
1167 static MonoReflectionType*
1168 ves_icall_type_from_handle (MonoType *handle)
1170 MonoDomain *domain = mono_domain_get ();
1171 MonoClass *klass = mono_class_from_mono_type (handle);
1173 MONO_ARCH_SAVE_REGS;
1175 mono_class_init (klass);
1176 return mono_type_get_object (domain, handle);
1180 ves_icall_System_Type_EqualsInternal (MonoReflectionType *type, MonoReflectionType *c)
1182 MONO_ARCH_SAVE_REGS;
1184 if (c && type->type && c->type)
1185 return mono_metadata_type_equal (type->type, c->type);
1190 /* System.TypeCode */
1209 TYPECODE_STRING = 18
1213 ves_icall_type_GetTypeCodeInternal (MonoReflectionType *type)
1215 int t = type->type->type;
1217 MONO_ARCH_SAVE_REGS;
1219 if (type->type->byref)
1220 return TYPECODE_OBJECT;
1224 case MONO_TYPE_VOID:
1225 return TYPECODE_OBJECT;
1226 case MONO_TYPE_BOOLEAN:
1227 return TYPECODE_BOOLEAN;
1229 return TYPECODE_BYTE;
1231 return TYPECODE_SBYTE;
1233 return TYPECODE_UINT16;
1235 return TYPECODE_INT16;
1236 case MONO_TYPE_CHAR:
1237 return TYPECODE_CHAR;
1241 return TYPECODE_OBJECT;
1243 return TYPECODE_UINT32;
1245 return TYPECODE_INT32;
1247 return TYPECODE_UINT64;
1249 return TYPECODE_INT64;
1251 return TYPECODE_SINGLE;
1253 return TYPECODE_DOUBLE;
1254 case MONO_TYPE_VALUETYPE:
1255 if (type->type->data.klass->enumtype) {
1256 t = type->type->data.klass->enum_basetype->type;
1259 MonoClass *k = type->type->data.klass;
1260 if (strcmp (k->name_space, "System") == 0) {
1261 if (strcmp (k->name, "Decimal") == 0)
1262 return TYPECODE_DECIMAL;
1263 else if (strcmp (k->name, "DateTime") == 0)
1264 return TYPECODE_DATETIME;
1267 return TYPECODE_OBJECT;
1268 case MONO_TYPE_STRING:
1269 return TYPECODE_STRING;
1270 case MONO_TYPE_SZARRAY:
1271 case MONO_TYPE_ARRAY:
1272 case MONO_TYPE_OBJECT:
1274 case MONO_TYPE_MVAR:
1275 case MONO_TYPE_TYPEDBYREF:
1276 return TYPECODE_OBJECT;
1277 case MONO_TYPE_CLASS:
1279 MonoClass *k = type->type->data.klass;
1280 if (strcmp (k->name_space, "System") == 0) {
1281 if (strcmp (k->name, "DBNull") == 0)
1282 return TYPECODE_DBNULL;
1285 return TYPECODE_OBJECT;
1286 case MONO_TYPE_GENERICINST:
1287 return TYPECODE_OBJECT;
1289 g_error ("type 0x%02x not handled in GetTypeCode()", t);
1295 ves_icall_type_is_subtype_of (MonoReflectionType *type, MonoReflectionType *c, MonoBoolean check_interfaces)
1301 MONO_ARCH_SAVE_REGS;
1303 g_assert (type != NULL);
1305 domain = ((MonoObject *)type)->vtable->domain;
1307 if (!c) /* FIXME: dont know what do do here */
1310 klass = mono_class_from_mono_type (type->type);
1311 klassc = mono_class_from_mono_type (c->type);
1313 if (type->type->byref)
1314 return klassc == mono_defaults.object_class;
1316 return mono_class_is_subclass_of (klass, klassc, check_interfaces);
1320 ves_icall_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType *c)
1326 MONO_ARCH_SAVE_REGS;
1328 g_assert (type != NULL);
1330 domain = ((MonoObject *)type)->vtable->domain;
1332 klass = mono_class_from_mono_type (type->type);
1333 klassc = mono_class_from_mono_type (c->type);
1335 if (type->type->byref && !c->type->byref)
1338 return mono_class_is_assignable_from (klass, klassc);
1342 ves_icall_type_IsInstanceOfType (MonoReflectionType *type, MonoObject *obj)
1344 MonoClass *klass = mono_class_from_mono_type (type->type);
1345 return mono_object_isinst (obj, klass) != NULL;
1349 ves_icall_get_attributes (MonoReflectionType *type)
1351 MonoClass *klass = mono_class_from_mono_type (type->type);
1353 MONO_ARCH_SAVE_REGS;
1355 return klass->flags;
1358 static MonoReflectionMarshal*
1359 ves_icall_System_Reflection_FieldInfo_GetUnmanagedMarshal (MonoReflectionField *field)
1361 MonoClass *klass = field->field->parent;
1362 MonoMarshalType *info;
1365 if (klass->generic_container ||
1366 (klass->generic_class && klass->generic_class->context.class_inst->is_open))
1369 info = mono_marshal_load_type_info (klass);
1371 for (i = 0; i < info->num_fields; ++i) {
1372 if (info->fields [i].field == field->field) {
1373 if (!info->fields [i].mspec)
1376 return mono_reflection_marshal_from_marshal_spec (field->object.vtable->domain, klass, info->fields [i].mspec);
1383 static MonoReflectionField*
1384 ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoClass *klass)
1389 klass = handle->parent;
1391 /* FIXME: check that handle is a field of klass or of a parent: return null
1392 * and throw the exception in managed code.
1394 return mono_field_get_object (mono_domain_get (), klass, handle);
1397 static MonoReflectionField*
1398 ves_icall_System_Reflection_FieldInfo_internal_from_handle (MonoClassField *handle)
1400 MONO_ARCH_SAVE_REGS;
1404 return mono_field_get_object (mono_domain_get (), handle->parent, handle);
1408 ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionField *field, MonoBoolean optional)
1410 MonoType *type = field->field->type;
1412 return type_array_from_modifiers (field->field->parent->image, type, optional);
1416 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
1418 MonoDomain *domain = mono_domain_get ();
1419 MonoMethodSignature* sig;
1420 MONO_ARCH_SAVE_REGS;
1422 sig = mono_method_signature (method);
1424 g_assert (mono_loader_get_last_error ());
1425 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
1428 info->parent = mono_type_get_object (domain, &method->klass->byval_arg);
1429 info->ret = mono_type_get_object (domain, sig->ret);
1430 info->attrs = method->flags;
1431 info->implattrs = method->iflags;
1432 if (sig->call_convention == MONO_CALL_DEFAULT)
1435 if (sig->call_convention == MONO_CALL_VARARG)
1440 info->callconv |= (sig->hasthis << 5) | (sig->explicit_this << 6);
1444 ves_icall_get_parameter_info (MonoMethod *method)
1446 MonoDomain *domain = mono_domain_get ();
1448 return mono_param_get_objects (domain, method);
1451 static MonoReflectionMarshal*
1452 ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod *method)
1454 MonoDomain *domain = mono_domain_get ();
1455 MonoReflectionMarshal* res = NULL;
1456 MonoMarshalSpec **mspecs;
1459 mspecs = g_new (MonoMarshalSpec*, mono_method_signature (method)->param_count + 1);
1460 mono_method_get_marshal_info (method, mspecs);
1463 res = mono_reflection_marshal_from_marshal_spec (domain, method->klass, mspecs [0]);
1465 for (i = mono_method_signature (method)->param_count; i >= 0; i--)
1467 mono_metadata_free_marshal_spec (mspecs [i]);
1474 ves_icall_MonoField_GetFieldOffset (MonoReflectionField *field)
1476 return field->field->offset - sizeof (MonoObject);
1479 static MonoReflectionType*
1480 ves_icall_MonoField_GetParentType (MonoReflectionField *field, MonoBoolean declaring)
1483 MONO_ARCH_SAVE_REGS;
1485 parent = declaring? field->field->parent: field->klass;
1487 return mono_type_get_object (mono_object_domain (field), &parent->byval_arg);
1491 ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj)
1494 MonoClassField *cf = field->field;
1498 MonoDomain *domain = mono_object_domain (field);
1500 gboolean is_static = FALSE;
1501 gboolean is_ref = FALSE;
1503 MONO_ARCH_SAVE_REGS;
1505 if (field->klass->image->assembly->ref_only)
1506 mono_raise_exception (mono_get_exception_invalid_operation (
1507 "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
1509 mono_class_init (field->klass);
1511 if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC)
1514 if (obj && !is_static) {
1515 /* Check that the field belongs to the object */
1516 gboolean found = FALSE;
1519 for (k = obj->vtable->klass; k; k = k->parent) {
1520 if (k == cf->parent) {
1527 char *msg = g_strdup_printf ("Field '%s' defined on type '%s' is not a field on the target object which is of type '%s'.", cf->name, cf->parent->name, obj->vtable->klass->name);
1528 MonoException *ex = mono_get_exception_argument (NULL, msg);
1530 mono_raise_exception (ex);
1534 t = mono_type_get_underlying_type (cf->type);
1536 case MONO_TYPE_STRING:
1537 case MONO_TYPE_OBJECT:
1538 case MONO_TYPE_CLASS:
1539 case MONO_TYPE_ARRAY:
1540 case MONO_TYPE_SZARRAY:
1545 case MONO_TYPE_BOOLEAN:
1548 case MONO_TYPE_CHAR:
1557 case MONO_TYPE_VALUETYPE:
1560 case MONO_TYPE_GENERICINST:
1561 if (mono_type_generic_inst_is_valuetype (t)) {
1568 g_error ("type 0x%x not handled in "
1569 "ves_icall_Monofield_GetValue", t->type);
1575 vtable = mono_class_vtable (domain, cf->parent);
1576 if (!vtable->initialized && !(cf->type->attrs & FIELD_ATTRIBUTE_LITERAL))
1577 mono_runtime_class_init (vtable);
1582 mono_field_static_get_value (vtable, cf, &o);
1584 mono_field_get_value (obj, cf, &o);
1589 if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) {
1590 MonoClass *nklass = mono_class_from_mono_type (cf->type);
1593 /* Convert the Nullable structure into a boxed vtype */
1595 buf = (guint8*)vtable->data + cf->offset;
1597 buf = (guint8*)obj + cf->offset;
1599 return mono_nullable_box (buf, nklass);
1602 /* boxed value type */
1603 klass = mono_class_from_mono_type (cf->type);
1604 o = mono_object_new (domain, klass);
1605 v = ((gchar *) o) + sizeof (MonoObject);
1607 mono_field_static_get_value (vtable, cf, v);
1609 mono_field_get_value (obj, cf, v);
1616 ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value)
1618 MonoClassField *cf = field->field;
1621 MONO_ARCH_SAVE_REGS;
1623 if (field->klass->image->assembly->ref_only)
1624 mono_raise_exception (mono_get_exception_invalid_operation (
1625 "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
1627 v = (gchar *) value;
1628 if (!cf->type->byref) {
1629 switch (cf->type->type) {
1632 case MONO_TYPE_BOOLEAN:
1635 case MONO_TYPE_CHAR:
1644 case MONO_TYPE_VALUETYPE:
1646 v += sizeof (MonoObject);
1648 case MONO_TYPE_STRING:
1649 case MONO_TYPE_OBJECT:
1650 case MONO_TYPE_CLASS:
1651 case MONO_TYPE_ARRAY:
1652 case MONO_TYPE_SZARRAY:
1655 case MONO_TYPE_GENERICINST: {
1656 MonoGenericClass *gclass = cf->type->data.generic_class;
1657 g_assert (!gclass->context.class_inst->is_open);
1659 if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) {
1660 MonoClass *nklass = mono_class_from_mono_type (cf->type);
1661 MonoObject *nullable;
1664 * Convert the boxed vtype into a Nullable structure.
1665 * This is complicated by the fact that Nullables have
1666 * a variable structure.
1668 nullable = mono_object_new (mono_domain_get (), nklass);
1670 mono_nullable_init (mono_object_unbox (nullable), value, nklass);
1672 v = mono_object_unbox (nullable);
1675 if (gclass->container_class->valuetype && (v != NULL))
1676 v += sizeof (MonoObject);
1680 g_error ("type 0x%x not handled in "
1681 "ves_icall_FieldInfo_SetValueInternal", cf->type->type);
1686 if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) {
1687 MonoVTable *vtable = mono_class_vtable (mono_object_domain (field), cf->parent);
1688 if (!vtable->initialized)
1689 mono_runtime_class_init (vtable);
1690 mono_field_static_set_value (vtable, cf, v);
1692 mono_field_set_value (obj, cf, v);
1697 ves_icall_MonoField_GetRawConstantValue (MonoReflectionField *this)
1699 MonoObject *o = NULL;
1700 MonoClassField *field = this->field;
1702 MonoDomain *domain = mono_object_domain (this);
1704 MonoTypeEnum def_type;
1705 const char *def_value;
1707 MONO_ARCH_SAVE_REGS;
1709 mono_class_init (field->parent);
1711 if (!(field->type->attrs & FIELD_ATTRIBUTE_HAS_DEFAULT))
1712 mono_raise_exception (mono_get_exception_invalid_operation (NULL));
1714 if (field->parent->image->dynamic) {
1716 g_assert_not_reached ();
1719 def_value = mono_class_get_field_default_value (field, &def_type);
1724 case MONO_TYPE_BOOLEAN:
1727 case MONO_TYPE_CHAR:
1735 case MONO_TYPE_R8: {
1738 /* boxed value type */
1739 t = g_new0 (MonoType, 1);
1741 klass = mono_class_from_mono_type (t);
1743 o = mono_object_new (domain, klass);
1744 v = ((gchar *) o) + sizeof (MonoObject);
1745 mono_get_constant_value_from_blob (domain, def_type, def_value, v);
1748 case MONO_TYPE_STRING:
1749 case MONO_TYPE_CLASS:
1750 mono_get_constant_value_from_blob (domain, def_type, def_value, &o);
1753 g_assert_not_reached ();
1759 static MonoReflectionType*
1760 ves_icall_MonoGenericMethod_get_ReflectedType (MonoReflectionGenericMethod *rmethod)
1762 MonoMethod *method = rmethod->method.method;
1764 return mono_type_get_object (mono_object_domain (rmethod), &method->klass->byval_arg);
1767 /* From MonoProperty.cs */
1769 PInfo_Attributes = 1,
1770 PInfo_GetMethod = 1 << 1,
1771 PInfo_SetMethod = 1 << 2,
1772 PInfo_ReflectedType = 1 << 3,
1773 PInfo_DeclaringType = 1 << 4,
1778 ves_icall_get_property_info (MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
1780 MonoDomain *domain = mono_object_domain (property);
1782 MONO_ARCH_SAVE_REGS;
1784 if ((req_info & PInfo_ReflectedType) != 0)
1785 MONO_STRUCT_SETREF (info, parent, mono_type_get_object (domain, &property->klass->byval_arg));
1786 else if ((req_info & PInfo_DeclaringType) != 0)
1787 MONO_STRUCT_SETREF (info, parent, mono_type_get_object (domain, &property->property->parent->byval_arg));
1789 if ((req_info & PInfo_Name) != 0)
1790 MONO_STRUCT_SETREF (info, name, mono_string_new (domain, property->property->name));
1792 if ((req_info & PInfo_Attributes) != 0)
1793 info->attrs = property->property->attrs;
1795 if ((req_info & PInfo_GetMethod) != 0)
1796 MONO_STRUCT_SETREF (info, get, property->property->get ?
1797 mono_method_get_object (domain, property->property->get, property->klass): NULL);
1799 if ((req_info & PInfo_SetMethod) != 0)
1800 MONO_STRUCT_SETREF (info, set, property->property->set ?
1801 mono_method_get_object (domain, property->property->set, property->klass): NULL);
1803 * There may be other methods defined for properties, though, it seems they are not exposed
1804 * in the reflection API
1809 ves_icall_get_event_info (MonoReflectionEvent *event, MonoEventInfo *info)
1811 MonoDomain *domain = mono_object_domain (event);
1813 MONO_ARCH_SAVE_REGS;
1815 info->reflected_type = mono_type_get_object (domain, &event->klass->byval_arg);
1816 info->declaring_type = mono_type_get_object (domain, &event->event->parent->byval_arg);
1818 info->name = mono_string_new (domain, event->event->name);
1819 info->attrs = event->event->attrs;
1820 info->add_method = event->event->add ? mono_method_get_object (domain, event->event->add, NULL): NULL;
1821 info->remove_method = event->event->remove ? mono_method_get_object (domain, event->event->remove, NULL): NULL;
1822 info->raise_method = event->event->raise ? mono_method_get_object (domain, event->event->raise, NULL): NULL;
1824 if (event->event->other) {
1826 while (event->event->other [n])
1828 info->other_methods = mono_array_new (domain, mono_defaults.method_info_class, n);
1830 for (i = 0; i < n; i++)
1831 mono_array_setref (info->other_methods, i, mono_method_get_object (domain, event->event->other [i], NULL));
1836 ves_icall_Type_GetInterfaces (MonoReflectionType* type)
1838 MonoDomain *domain = mono_object_domain (type);
1840 GPtrArray *ifaces = NULL;
1842 MonoClass *class = mono_class_from_mono_type (type->type);
1845 MonoGenericContext *context = NULL;
1847 MONO_ARCH_SAVE_REGS;
1849 if (class->generic_class && class->generic_class->context.class_inst->is_open) {
1850 context = mono_class_get_context (class);
1851 class = class->generic_class->container_class;
1854 mono_class_setup_vtable (class);
1856 slots = mono_bitset_new (class->max_interface_id + 1, 0);
1858 for (parent = class; parent; parent = parent->parent) {
1859 GPtrArray *tmp_ifaces = mono_class_get_implemented_interfaces (parent);
1861 for (i = 0; i < tmp_ifaces->len; ++i) {
1862 MonoClass *ic = g_ptr_array_index (tmp_ifaces, i);
1864 if (mono_bitset_test (slots, ic->interface_id))
1867 mono_bitset_set (slots, ic->interface_id);
1869 ifaces = g_ptr_array_new ();
1870 g_ptr_array_add (ifaces, ic);
1872 g_ptr_array_free (tmp_ifaces, TRUE);
1875 mono_bitset_free (slots);
1878 return mono_array_new (domain, mono_defaults.monotype_class, 0);
1880 intf = mono_array_new (domain, mono_defaults.monotype_class, ifaces->len);
1881 for (i = 0; i < ifaces->len; ++i) {
1882 MonoClass *ic = g_ptr_array_index (ifaces, i);
1883 MonoType *ret = &ic->byval_arg;
1884 if (context && ic->generic_class && ic->generic_class->context.class_inst->is_open)
1885 ret = mono_class_inflate_generic_type (ret, context);
1887 mono_array_setref (intf, i, mono_type_get_object (domain, ret));
1889 g_ptr_array_free (ifaces, TRUE);
1895 ves_icall_Type_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType *iface, MonoArray **targets, MonoArray **methods)
1897 MonoClass *class = mono_class_from_mono_type (type->type);
1898 MonoClass *iclass = mono_class_from_mono_type (iface->type);
1899 MonoReflectionMethod *member;
1902 int i = 0, len, ioffset;
1905 MONO_ARCH_SAVE_REGS;
1907 mono_class_setup_vtable (class);
1909 /* type doesn't implement iface: the exception is thrown in managed code */
1910 if (! MONO_CLASS_IMPLEMENTS_INTERFACE (class, iclass->interface_id))
1913 len = mono_class_num_methods (iclass);
1914 ioffset = mono_class_interface_offset (class, iclass);
1915 domain = mono_object_domain (type);
1916 *targets = mono_array_new (domain, mono_defaults.method_info_class, len);
1917 *methods = mono_array_new (domain, mono_defaults.method_info_class, len);
1920 while ((method = mono_class_get_methods (iclass, &iter))) {
1921 member = mono_method_get_object (domain, method, iclass);
1922 mono_array_setref (*methods, i, member);
1923 member = mono_method_get_object (domain, class->vtable [i + ioffset], class);
1924 mono_array_setref (*targets, i, member);
1931 ves_icall_Type_GetPacking (MonoReflectionType *type, guint32 *packing, guint32 *size)
1933 MonoClass *klass = mono_class_from_mono_type (type->type);
1935 g_assert (!klass->image->dynamic);
1937 mono_metadata_packing_from_typedef (klass->image, klass->type_token, packing, size);
1940 static MonoReflectionType*
1941 ves_icall_MonoType_GetElementType (MonoReflectionType *type)
1943 MonoClass *class = mono_class_from_mono_type (type->type);
1945 MONO_ARCH_SAVE_REGS;
1947 // GetElementType should only return a type for:
1948 // Array Pointer PassedByRef
1949 if (type->type->byref)
1950 return mono_type_get_object (mono_object_domain (type), &class->byval_arg);
1951 else if (class->element_class && MONO_CLASS_IS_ARRAY (class))
1952 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
1953 else if (class->element_class && type->type->type == MONO_TYPE_PTR)
1954 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
1959 static MonoReflectionType*
1960 ves_icall_get_type_parent (MonoReflectionType *type)
1962 MonoClass *class = mono_class_from_mono_type (type->type);
1964 MONO_ARCH_SAVE_REGS;
1966 return class->parent ? mono_type_get_object (mono_object_domain (type), &class->parent->byval_arg): NULL;
1970 ves_icall_type_ispointer (MonoReflectionType *type)
1972 MONO_ARCH_SAVE_REGS;
1974 return type->type->type == MONO_TYPE_PTR;
1978 ves_icall_type_isprimitive (MonoReflectionType *type)
1980 MONO_ARCH_SAVE_REGS;
1982 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)));
1986 ves_icall_type_isbyref (MonoReflectionType *type)
1988 MONO_ARCH_SAVE_REGS;
1990 return type->type->byref;
1994 ves_icall_type_iscomobject (MonoReflectionType *type)
1996 MonoClass *klass = mono_class_from_mono_type (type->type);
1997 MONO_ARCH_SAVE_REGS;
1999 return (klass && klass->is_com_object);
2002 static MonoReflectionModule*
2003 ves_icall_MonoType_get_Module (MonoReflectionType *type)
2005 MonoClass *class = mono_class_from_mono_type (type->type);
2007 MONO_ARCH_SAVE_REGS;
2009 return mono_module_get_object (mono_object_domain (type), class->image);
2012 static MonoReflectionAssembly*
2013 ves_icall_MonoType_get_Assembly (MonoReflectionType *type)
2015 MonoDomain *domain = mono_domain_get ();
2016 MonoClass *class = mono_class_from_mono_type (type->type);
2018 MONO_ARCH_SAVE_REGS;
2020 return mono_assembly_get_object (domain, class->image->assembly);
2023 static MonoReflectionType*
2024 ves_icall_MonoType_get_DeclaringType (MonoReflectionType *type)
2026 MonoDomain *domain = mono_domain_get ();
2029 MONO_ARCH_SAVE_REGS;
2031 if (type->type->byref)
2033 if (type->type->type == MONO_TYPE_VAR)
2034 class = type->type->data.generic_param->owner->owner.klass;
2035 else if (type->type->type == MONO_TYPE_MVAR)
2036 class = type->type->data.generic_param->owner->owner.method->klass;
2038 class = mono_class_from_mono_type (type->type)->nested_in;
2040 return class ? mono_type_get_object (domain, &class->byval_arg) : NULL;
2043 static MonoReflectionType*
2044 ves_icall_MonoType_get_UnderlyingSystemType (MonoReflectionType *type)
2046 MonoDomain *domain = mono_domain_get ();
2047 MonoClass *class = mono_class_from_mono_type (type->type);
2049 MONO_ARCH_SAVE_REGS;
2051 if (class->enumtype && class->enum_basetype) /* types that are modified typebuilders may not have enum_basetype set */
2052 return mono_type_get_object (domain, class->enum_basetype);
2053 else if (class->element_class)
2054 return mono_type_get_object (domain, &class->element_class->byval_arg);
2060 ves_icall_MonoType_get_Name (MonoReflectionType *type)
2062 MonoDomain *domain = mono_domain_get ();
2063 MonoClass *class = mono_class_from_mono_type (type->type);
2065 MONO_ARCH_SAVE_REGS;
2067 if (type->type->byref) {
2068 char *n = g_strdup_printf ("%s&", class->name);
2069 MonoString *res = mono_string_new (domain, n);
2075 return mono_string_new (domain, class->name);
2080 ves_icall_MonoType_get_Namespace (MonoReflectionType *type)
2082 MonoDomain *domain = mono_domain_get ();
2083 MonoClass *class = mono_class_from_mono_type (type->type);
2085 MONO_ARCH_SAVE_REGS;
2087 while (class->nested_in)
2088 class = class->nested_in;
2090 if (class->name_space [0] == '\0')
2093 return mono_string_new (domain, class->name_space);
2097 ves_icall_MonoType_GetArrayRank (MonoReflectionType *type)
2099 MonoClass *class = mono_class_from_mono_type (type->type);
2101 MONO_ARCH_SAVE_REGS;
2107 ves_icall_MonoType_GetGenericArguments (MonoReflectionType *type)
2110 MonoClass *klass, *pklass;
2112 MONO_ARCH_SAVE_REGS;
2114 klass = mono_class_from_mono_type (type->type);
2116 if (klass->generic_container) {
2117 MonoGenericContainer *container = klass->generic_container;
2118 res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, container->type_argc);
2119 for (i = 0; i < container->type_argc; ++i) {
2120 pklass = mono_class_from_generic_parameter (&container->type_params [i], klass->image, FALSE);
2121 mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), &pklass->byval_arg));
2123 } else if (klass->generic_class) {
2124 MonoGenericInst *inst = klass->generic_class->context.class_inst;
2125 res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, inst->type_argc);
2126 for (i = 0; i < inst->type_argc; ++i)
2127 mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), inst->type_argv [i]));
2129 res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, 0);
2135 ves_icall_Type_get_IsGenericTypeDefinition (MonoReflectionType *type)
2138 MONO_ARCH_SAVE_REGS;
2140 if (type->type->byref)
2143 klass = mono_class_from_mono_type (type->type);
2145 return klass->generic_container != NULL;
2148 static MonoReflectionType*
2149 ves_icall_Type_GetGenericTypeDefinition_impl (MonoReflectionType *type)
2152 MONO_ARCH_SAVE_REGS;
2154 if (type->type->byref)
2157 klass = mono_class_from_mono_type (type->type);
2158 if (klass->generic_container) {
2159 return type; /* check this one */
2161 if (klass->generic_class) {
2162 MonoClass *generic_class = klass->generic_class->container_class;
2164 if (generic_class->wastypebuilder && generic_class->reflection_info)
2165 return generic_class->reflection_info;
2167 return mono_type_get_object (mono_object_domain (type), &generic_class->byval_arg);
2172 static MonoReflectionType*
2173 ves_icall_Type_MakeGenericType (MonoReflectionType *type, MonoArray *type_array)
2175 MonoType *geninst, **types;
2178 MONO_ARCH_SAVE_REGS;
2180 count = mono_array_length (type_array);
2181 types = g_new0 (MonoType *, count);
2183 for (i = 0; i < count; i++) {
2184 MonoReflectionType *t = mono_array_get (type_array, gpointer, i);
2185 types [i] = t->type;
2188 geninst = mono_reflection_bind_generic_parameters (type, count, types);
2193 return mono_type_get_object (mono_object_domain (type), geninst);
2197 ves_icall_Type_get_IsGenericInstance (MonoReflectionType *type)
2200 MONO_ARCH_SAVE_REGS;
2202 if (type->type->byref)
2205 klass = mono_class_from_mono_type (type->type);
2206 return klass->generic_class != NULL;
2210 ves_icall_Type_get_IsGenericType (MonoReflectionType *type)
2213 MONO_ARCH_SAVE_REGS;
2215 if (type->type->byref)
2218 klass = mono_class_from_mono_type (type->type);
2219 return klass->generic_class != NULL || klass->generic_container != NULL;
2223 ves_icall_Type_GetGenericParameterPosition (MonoReflectionType *type)
2225 MONO_ARCH_SAVE_REGS;
2227 if (is_generic_parameter (type->type))
2228 return type->type->data.generic_param->num;
2232 static GenericParameterAttributes
2233 ves_icall_Type_GetGenericParameterAttributes (MonoReflectionType *type)
2235 MONO_ARCH_SAVE_REGS;
2236 g_assert (is_generic_parameter (type->type));
2237 return type->type->data.generic_param->flags;
2241 ves_icall_Type_GetGenericParameterConstraints (MonoReflectionType *type)
2243 MonoGenericParam *param;
2249 MONO_ARCH_SAVE_REGS;
2251 domain = mono_object_domain (type);
2252 param = type->type->data.generic_param;
2253 for (count = 0, ptr = param->constraints; ptr && *ptr; ptr++, count++)
2256 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2257 for (i = 0; i < count; i++)
2258 mono_array_setref (res, i, mono_type_get_object (domain, ¶m->constraints [i]->byval_arg));
2265 ves_icall_MonoType_get_IsGenericParameter (MonoReflectionType *type)
2267 MONO_ARCH_SAVE_REGS;
2268 return is_generic_parameter (type->type);
2272 ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder *tb)
2274 MONO_ARCH_SAVE_REGS;
2275 return is_generic_parameter (tb->type.type);
2279 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
2280 MonoReflectionType *t)
2282 enumtype->type = t->type;
2285 static MonoReflectionType*
2286 ves_icall_MonoGenericClass_GetParentType (MonoReflectionGenericClass *type)
2288 MonoDynamicGenericClass *gclass;
2289 MonoReflectionType *parent = NULL;
2294 MONO_ARCH_SAVE_REGS;
2296 g_assert (type->type.type->data.generic_class->is_dynamic);
2297 gclass = (MonoDynamicGenericClass *) type->type.type->data.generic_class;
2299 domain = mono_object_domain (type);
2300 klass = mono_class_from_mono_type (type->generic_type->type);
2302 if (!klass->generic_class && !klass->generic_container)
2305 if (!strcmp (type->generic_type->object.vtable->klass->name, "TypeBuilder")) {
2306 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *) type->generic_type;
2307 parent = tb->parent;
2308 } else if (klass->wastypebuilder) {
2309 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *) type->generic_type;
2310 parent = tb->parent;
2312 MonoClass *pklass = klass->parent;
2314 parent = mono_type_get_object (domain, &pklass->byval_arg);
2317 if (!parent || (parent->type->type != MONO_TYPE_GENERICINST))
2320 inflated = mono_class_inflate_generic_type (
2321 parent->type, mono_generic_class_get_context ((MonoGenericClass *) gclass));
2323 return mono_type_get_object (domain, inflated);
2327 ves_icall_MonoGenericClass_GetInterfaces (MonoReflectionGenericClass *type)
2329 static MonoClass *System_Reflection_MonoGenericClass;
2330 MonoGenericClass *gclass;
2331 MonoReflectionTypeBuilder *tb = NULL;
2332 MonoClass *klass = NULL;
2337 MONO_ARCH_SAVE_REGS;
2339 if (!System_Reflection_MonoGenericClass) {
2340 System_Reflection_MonoGenericClass = mono_class_from_name (
2341 mono_defaults.corlib, "System.Reflection", "MonoGenericClass");
2342 g_assert (System_Reflection_MonoGenericClass);
2345 domain = mono_object_domain (type);
2347 gclass = type->type.type->data.generic_class;
2348 g_assert (gclass->is_dynamic);
2350 if (!strcmp (type->generic_type->object.vtable->klass->name, "TypeBuilder")) {
2351 tb = (MonoReflectionTypeBuilder *) type->generic_type;
2352 icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
2354 klass = gclass->container_class;
2355 mono_class_init (klass);
2356 icount = klass->interface_count;
2359 res = mono_array_new (domain, System_Reflection_MonoGenericClass, icount);
2361 for (i = 0; i < icount; i++) {
2362 MonoReflectionType *iface;
2366 iface = mono_array_get (tb->interfaces, MonoReflectionType *, i);
2369 it = &klass->interfaces [i]->byval_arg;
2371 it = mono_class_inflate_generic_type (it, mono_generic_class_get_context (gclass));
2373 iface = mono_type_get_object (domain, it);
2374 mono_array_setref (res, i, iface);
2380 static MonoReflectionMethod*
2381 ves_icall_MonoGenericClass_GetCorrespondingInflatedMethod (MonoReflectionGenericClass *type,
2382 MonoReflectionMethod* generic)
2384 MonoGenericClass *gclass;
2385 MonoDynamicGenericClass *dgclass;
2389 MONO_ARCH_SAVE_REGS;
2391 gclass = type->type.type->data.generic_class;
2392 g_assert (gclass->is_dynamic);
2394 dgclass = (MonoDynamicGenericClass *) gclass;
2396 domain = mono_object_domain (type);
2398 for (i = 0; i < dgclass->count_methods; i++)
2399 if (generic->method->token == dgclass->methods [i]->token)
2400 return mono_method_get_object (domain, dgclass->methods [i], NULL);
2405 static MonoReflectionMethod*
2406 ves_icall_MonoGenericClass_GetCorrespondingInflatedConstructor (MonoReflectionGenericClass *type,
2407 MonoReflectionMethod* generic)
2409 MonoGenericClass *gclass;
2410 MonoDynamicGenericClass *dgclass;
2414 MONO_ARCH_SAVE_REGS;
2416 gclass = type->type.type->data.generic_class;
2417 g_assert (gclass->is_dynamic);
2419 dgclass = (MonoDynamicGenericClass *) gclass;
2421 domain = mono_object_domain (type);
2423 for (i = 0; i < dgclass->count_ctors; i++)
2424 if (generic->method->token == dgclass->ctors [i]->token)
2425 return mono_method_get_object (domain, dgclass->ctors [i], NULL);
2431 static MonoReflectionField*
2432 ves_icall_MonoGenericClass_GetCorrespondingInflatedField (MonoReflectionGenericClass *type,
2433 MonoString* generic_name)
2435 MonoGenericClass *gclass;
2436 MonoDynamicGenericClass *dgclass;
2438 MonoClass *refclass;
2439 char *utf8_name = mono_string_to_utf8 (generic_name);
2442 MONO_ARCH_SAVE_REGS;
2444 gclass = type->type.type->data.generic_class;
2445 g_assert (gclass->is_dynamic);
2447 dgclass = (MonoDynamicGenericClass *) gclass;
2449 refclass = mono_class_from_mono_type (type->type.type);
2451 domain = mono_object_domain (type);
2453 for (i = 0; i < dgclass->count_fields; i++)
2454 if (strcmp (utf8_name, dgclass->fields [i].name) == 0) {
2456 return mono_field_get_object (domain, refclass, &dgclass->fields [i]);
2465 static MonoReflectionMethod*
2466 ves_icall_MonoType_GetCorrespondingInflatedMethod (MonoReflectionType *type,
2467 MonoReflectionMethod* generic)
2474 MONO_ARCH_SAVE_REGS;
2476 domain = ((MonoObject *)type)->vtable->domain;
2478 klass = mono_class_from_mono_type (type->type);
2481 while ((method = mono_class_get_methods (klass, &iter))) {
2482 if (method->token == generic->method->token)
2483 return mono_method_get_object (domain, method, klass);
2490 ves_icall_MonoGenericClass_GetMethods (MonoReflectionGenericClass *type,
2491 MonoReflectionType *reflected_type)
2493 MonoGenericClass *gclass;
2494 MonoDynamicGenericClass *dgclass;
2496 MonoClass *refclass;
2500 MONO_ARCH_SAVE_REGS;
2502 gclass = type->type.type->data.generic_class;
2503 g_assert (gclass->is_dynamic);
2504 dgclass = (MonoDynamicGenericClass *) gclass;
2506 refclass = mono_class_from_mono_type (reflected_type->type);
2508 domain = mono_object_domain (type);
2509 res = mono_array_new (domain, mono_defaults.method_info_class, dgclass->count_methods);
2511 for (i = 0; i < dgclass->count_methods; i++)
2512 mono_array_setref (res, i, mono_method_get_object (domain, dgclass->methods [i], refclass));
2518 ves_icall_MonoGenericClass_GetConstructors (MonoReflectionGenericClass *type,
2519 MonoReflectionType *reflected_type)
2521 static MonoClass *System_Reflection_ConstructorInfo;
2522 MonoGenericClass *gclass;
2523 MonoDynamicGenericClass *dgclass;
2525 MonoClass *refclass;
2529 MONO_ARCH_SAVE_REGS;
2531 if (!System_Reflection_ConstructorInfo)
2532 System_Reflection_ConstructorInfo = mono_class_from_name (
2533 mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
2535 gclass = type->type.type->data.generic_class;
2536 g_assert (gclass->is_dynamic);
2537 dgclass = (MonoDynamicGenericClass *) gclass;
2539 refclass = mono_class_from_mono_type (reflected_type->type);
2541 domain = mono_object_domain (type);
2542 res = mono_array_new (domain, System_Reflection_ConstructorInfo, dgclass->count_ctors);
2544 for (i = 0; i < dgclass->count_ctors; i++)
2545 mono_array_setref (res, i, mono_method_get_object (domain, dgclass->ctors [i], refclass));
2551 ves_icall_MonoGenericClass_GetFields (MonoReflectionGenericClass *type,
2552 MonoReflectionType *reflected_type)
2554 MonoGenericClass *gclass;
2555 MonoDynamicGenericClass *dgclass;
2557 MonoClass *refclass;
2561 MONO_ARCH_SAVE_REGS;
2563 gclass = type->type.type->data.generic_class;
2564 g_assert (gclass->is_dynamic);
2565 dgclass = (MonoDynamicGenericClass *) gclass;
2567 refclass = mono_class_from_mono_type (reflected_type->type);
2569 domain = mono_object_domain (type);
2570 res = mono_array_new (domain, mono_defaults.field_info_class, dgclass->count_fields);
2572 for (i = 0; i < dgclass->count_fields; i++)
2573 mono_array_setref (res, i, mono_field_get_object (domain, refclass, &dgclass->fields [i]));
2579 ves_icall_MonoGenericClass_GetProperties (MonoReflectionGenericClass *type,
2580 MonoReflectionType *reflected_type)
2582 static MonoClass *System_Reflection_PropertyInfo;
2583 MonoGenericClass *gclass;
2584 MonoDynamicGenericClass *dgclass;
2586 MonoClass *refclass;
2590 MONO_ARCH_SAVE_REGS;
2592 if (!System_Reflection_PropertyInfo)
2593 System_Reflection_PropertyInfo = mono_class_from_name (
2594 mono_defaults.corlib, "System.Reflection", "PropertyInfo");
2596 gclass = type->type.type->data.generic_class;
2597 g_assert (gclass->is_dynamic);
2598 dgclass = (MonoDynamicGenericClass *) gclass;
2600 refclass = mono_class_from_mono_type (reflected_type->type);
2602 domain = mono_object_domain (type);
2603 res = mono_array_new (domain, System_Reflection_PropertyInfo, dgclass->count_properties);
2605 for (i = 0; i < dgclass->count_properties; i++)
2606 mono_array_setref (res, i, mono_property_get_object (domain, refclass, &dgclass->properties [i]));
2612 ves_icall_MonoGenericClass_GetEvents (MonoReflectionGenericClass *type,
2613 MonoReflectionType *reflected_type)
2615 static MonoClass *System_Reflection_EventInfo;
2616 MonoGenericClass *gclass;
2617 MonoDynamicGenericClass *dgclass;
2619 MonoClass *refclass;
2623 MONO_ARCH_SAVE_REGS;
2625 if (!System_Reflection_EventInfo)
2626 System_Reflection_EventInfo = mono_class_from_name (
2627 mono_defaults.corlib, "System.Reflection", "EventInfo");
2629 gclass = type->type.type->data.generic_class;
2630 g_assert (gclass->is_dynamic);
2631 dgclass = (MonoDynamicGenericClass *) gclass;
2633 refclass = mono_class_from_mono_type (reflected_type->type);
2635 domain = mono_object_domain (type);
2636 res = mono_array_new (domain, System_Reflection_EventInfo, dgclass->count_events);
2638 for (i = 0; i < dgclass->count_events; i++)
2639 mono_array_setref (res, i, mono_event_get_object (domain, refclass, &dgclass->events [i]));
2644 static MonoReflectionMethod *
2645 ves_icall_MonoType_get_DeclaringMethod (MonoReflectionType *type)
2650 MONO_ARCH_SAVE_REGS;
2652 if (type->type->byref || type->type->type != MONO_TYPE_MVAR)
2655 method = type->type->data.generic_param->owner->owner.method;
2657 klass = mono_class_from_mono_type (type->type);
2658 return mono_method_get_object (mono_object_domain (type), method, klass);
2661 static MonoReflectionDllImportAttribute*
2662 ves_icall_MonoMethod_GetDllImportAttribute (MonoMethod *method)
2664 static MonoClass *DllImportAttributeClass = NULL;
2665 MonoDomain *domain = mono_domain_get ();
2666 MonoReflectionDllImportAttribute *attr;
2667 MonoImage *image = method->klass->image;
2668 MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method;
2669 MonoTableInfo *tables = image->tables;
2670 MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
2671 MonoTableInfo *mr = &tables [MONO_TABLE_MODULEREF];
2672 guint32 im_cols [MONO_IMPLMAP_SIZE];
2673 guint32 scope_token;
2674 const char *import = NULL;
2675 const char *scope = NULL;
2678 if (!method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)
2681 if (!DllImportAttributeClass) {
2682 DllImportAttributeClass =
2683 mono_class_from_name (mono_defaults.corlib,
2684 "System.Runtime.InteropServices", "DllImportAttribute");
2685 g_assert (DllImportAttributeClass);
2688 if (method->klass->image->dynamic) {
2689 MonoReflectionMethodAux *method_aux =
2690 g_hash_table_lookup (
2691 ((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
2693 import = method_aux->dllentry;
2694 scope = method_aux->dll;
2698 if (piinfo->implmap_idx) {
2699 mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
2701 piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
2702 import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
2703 scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
2704 scope = mono_metadata_string_heap (image, scope_token);
2707 flags = piinfo->piflags;
2709 attr = (MonoReflectionDllImportAttribute*)mono_object_new (domain, DllImportAttributeClass);
2711 MONO_OBJECT_SETREF (attr, dll, mono_string_new (domain, scope));
2712 MONO_OBJECT_SETREF (attr, entry_point, mono_string_new (domain, import));
2713 attr->call_conv = (flags & 0x700) >> 8;
2714 attr->charset = ((flags & 0x6) >> 1) + 1;
2715 if (attr->charset == 1)
2717 attr->exact_spelling = (flags & 0x1) != 0;
2718 attr->set_last_error = (flags & 0x40) != 0;
2719 attr->best_fit_mapping = (flags & 0x30) == 0x10;
2720 attr->throw_on_unmappable = (flags & 0x3000) == 0x1000;
2721 attr->preserve_sig = FALSE;
2726 static MonoReflectionMethod *
2727 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
2729 MonoMethodInflated *imethod;
2731 MONO_ARCH_SAVE_REGS;
2733 if (method->method->generic_container)
2736 if (!method->method->is_inflated)
2739 imethod = (MonoMethodInflated *) method->method;
2741 if (imethod->reflection_info)
2742 return imethod->reflection_info;
2744 return mono_method_get_object (
2745 mono_object_domain (method), imethod->declaring, NULL);
2749 ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethod *method)
2751 MONO_ARCH_SAVE_REGS;
2753 return mono_method_signature (method->method)->generic_param_count != 0;
2757 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method)
2759 MONO_ARCH_SAVE_REGS;
2761 return method->method->generic_container != NULL;
2765 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
2770 MONO_ARCH_SAVE_REGS;
2772 domain = mono_object_domain (method);
2774 if (method->method->is_inflated) {
2775 MonoGenericInst *inst = mono_method_get_context (method->method)->method_inst;
2778 count = inst->type_argc;
2779 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2781 for (i = 0; i < count; i++)
2782 mono_array_setref (res, i, mono_type_get_object (domain, inst->type_argv [i]));
2788 count = mono_method_signature (method->method)->generic_param_count;
2789 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2791 for (i = 0; i < count; i++) {
2792 MonoGenericParam *param = &method->method->generic_container->type_params [i];
2793 MonoClass *pklass = mono_class_from_generic_parameter (
2794 param, method->method->klass->image, TRUE);
2795 mono_array_setref (res, i,
2796 mono_type_get_object (domain, &pklass->byval_arg));
2803 ensure_reflection_security (void)
2805 MonoMethod *m = mono_method_get_last_managed ();
2809 g_print ("method %s.%s.%s in image %s\n",
2810 m->klass->name_space, m->klass->name, m->name, m->klass->image->name);
2813 /* We stop at the first method which is not in
2814 System.Reflection or which is not in a platform
2816 if (strcmp (m->klass->name_space, "System.Reflection") != 0 ||
2817 !mono_security_core_clr_is_platform_image (m->klass->image)) {
2818 /* If the method is transparent we throw an exception. */
2819 if (mono_security_core_clr_method_level (m, TRUE) == MONO_SECURITY_CORE_CLR_TRANSPARENT ) {
2820 MonoException *ex = mono_exception_from_name_msg (mono_defaults.corlib, "System", "MethodAccessException", "Reflection called from transparent code");
2822 mono_raise_exception (ex);
2827 mono_stack_walk_no_il (get_caller, &m);
2832 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoArray *params)
2835 * Invoke from reflection is supposed to always be a virtual call (the API
2836 * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
2837 * greater flexibility.
2839 MonoMethod *m = method->method;
2843 MONO_ARCH_SAVE_REGS;
2845 if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR &&
2846 mono_security_core_clr_method_level (m, TRUE) == MONO_SECURITY_CORE_CLR_CRITICAL)
2847 ensure_reflection_security ();
2849 if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
2851 if (!mono_object_isinst (this, m->klass))
2852 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
2853 m = mono_object_get_virtual_method (this, m);
2854 /* must pass the pointer to the value for valuetype methods */
2855 if (m->klass->valuetype)
2856 obj = mono_object_unbox (this);
2857 } else if (strcmp (m->name, ".ctor") && !m->wrapper_type)
2858 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
2861 pcount = params? mono_array_length (params): 0;
2862 if (pcount != mono_method_signature (m)->param_count)
2863 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
2865 if ((m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) && !strcmp (m->name, ".ctor") && !this)
2866 mono_raise_exception (mono_exception_from_name_msg (mono_defaults.corlib, "System", "MethodAccessException", "Cannot invoke constructor of an abstract class."));
2868 if (m->klass->image->assembly->ref_only)
2869 mono_raise_exception (mono_get_exception_invalid_operation ("It is illegal to invoke a method on a type loaded using the ReflectionOnly api."));
2871 if (m->klass->rank && !strcmp (m->name, ".ctor")) {
2874 guint32 *lower_bounds;
2875 pcount = mono_array_length (params);
2876 lengths = alloca (sizeof (guint32) * pcount);
2877 for (i = 0; i < pcount; ++i)
2878 lengths [i] = *(gint32*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
2880 if (m->klass->rank == pcount) {
2881 /* Only lengths provided. */
2882 lower_bounds = NULL;
2884 g_assert (pcount == (m->klass->rank * 2));
2885 /* lower bounds are first. */
2886 lower_bounds = lengths;
2887 lengths += m->klass->rank;
2890 return (MonoObject*)mono_array_new_full (mono_object_domain (params), m->klass, lengths, lower_bounds);
2892 return mono_runtime_invoke_array (m, obj, params, NULL);
2896 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this, MonoArray *params, MonoArray **outArgs)
2898 MonoDomain *domain = mono_object_domain (method);
2899 MonoMethod *m = method->method;
2900 MonoMethodSignature *sig = mono_method_signature (m);
2901 MonoArray *out_args;
2903 int i, j, outarg_count = 0;
2905 MONO_ARCH_SAVE_REGS;
2907 if (m->klass == mono_defaults.object_class) {
2909 if (!strcmp (m->name, "FieldGetter")) {
2910 MonoClass *k = this->vtable->klass;
2914 /* If this is a proxy, then it must be a CBO */
2915 if (k == mono_defaults.transparent_proxy_class) {
2916 MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
2917 this = tp->rp->unwrapped_server;
2919 k = this->vtable->klass;
2922 name = mono_array_get (params, MonoString *, 1);
2923 str = mono_string_to_utf8 (name);
2926 MonoClassField* field = mono_class_get_field_from_name (k, str);
2928 MonoClass *field_klass = mono_class_from_mono_type (field->type);
2929 if (field_klass->valuetype)
2930 result = mono_value_box (domain, field_klass, (char *)this + field->offset);
2932 result = *((gpointer *)((char *)this + field->offset));
2934 out_args = mono_array_new (domain, mono_defaults.object_class, 1);
2935 *outArgs = out_args;
2936 mono_array_setref (out_args, 0, result);
2944 g_assert_not_reached ();
2946 } else if (!strcmp (m->name, "FieldSetter")) {
2947 MonoClass *k = this->vtable->klass;
2953 /* If this is a proxy, then it must be a CBO */
2954 if (k == mono_defaults.transparent_proxy_class) {
2955 MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
2956 this = tp->rp->unwrapped_server;
2958 k = this->vtable->klass;
2961 name = mono_array_get (params, MonoString *, 1);
2962 str = mono_string_to_utf8 (name);
2965 MonoClassField* field = mono_class_get_field_from_name (k, str);
2967 MonoClass *field_klass = mono_class_from_mono_type (field->type);
2968 MonoObject *val = mono_array_get (params, gpointer, 2);
2970 if (field_klass->valuetype) {
2971 size = mono_type_size (field->type, &align);
2972 memcpy ((char *)this + field->offset,
2973 ((char *)val) + sizeof (MonoObject), size);
2975 *(MonoObject**)((char *)this + field->offset) = val;
2977 out_args = mono_array_new (domain, mono_defaults.object_class, 0);
2978 *outArgs = out_args;
2988 g_assert_not_reached ();
2993 for (i = 0; i < mono_array_length (params); i++) {
2994 if (sig->params [i]->byref)
2998 out_args = mono_array_new (domain, mono_defaults.object_class, outarg_count);
3000 /* handle constructors only for objects already allocated */
3001 if (!strcmp (method->method->name, ".ctor"))
3004 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
3005 g_assert (!method->method->klass->valuetype);
3006 result = mono_runtime_invoke_array (method->method, this, params, NULL);
3008 for (i = 0, j = 0; i < mono_array_length (params); i++) {
3009 if (sig->params [i]->byref) {
3011 arg = mono_array_get (params, gpointer, i);
3012 mono_array_setref (out_args, j, arg);
3017 *outArgs = out_args;
3023 read_enum_value (char *mem, int type)
3027 return *(guint8*)mem;
3029 return *(gint8*)mem;
3031 return *(guint16*)mem;
3033 return *(gint16*)mem;
3035 return *(guint32*)mem;
3037 return *(gint32*)mem;
3039 return *(guint64*)mem;
3041 return *(gint64*)mem;
3043 g_assert_not_reached ();
3049 write_enum_value (char *mem, int type, guint64 value)
3053 case MONO_TYPE_I1: {
3054 guint8 *p = (guint8*)mem;
3059 case MONO_TYPE_I2: {
3060 guint16 *p = (void*)mem;
3065 case MONO_TYPE_I4: {
3066 guint32 *p = (void*)mem;
3071 case MONO_TYPE_I8: {
3072 guint64 *p = (void*)mem;
3077 g_assert_not_reached ();
3083 ves_icall_System_Enum_ToObject (MonoReflectionType *enumType, MonoObject *value)
3086 MonoClass *enumc, *objc;
3090 MONO_ARCH_SAVE_REGS;
3092 MONO_CHECK_ARG_NULL (enumType);
3093 MONO_CHECK_ARG_NULL (value);
3095 domain = mono_object_domain (enumType);
3096 enumc = mono_class_from_mono_type (enumType->type);
3097 objc = value->vtable->klass;
3099 if (!enumc->enumtype)
3100 mono_raise_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
3101 if (!((objc->enumtype) || (objc->byval_arg.type >= MONO_TYPE_I1 && objc->byval_arg.type <= MONO_TYPE_U8)))
3102 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."));
3104 res = mono_object_new (domain, enumc);
3105 val = read_enum_value ((char *)value + sizeof (MonoObject), objc->enumtype? objc->enum_basetype->type: objc->byval_arg.type);
3106 write_enum_value ((char *)res + sizeof (MonoObject), enumc->enum_basetype->type, val);
3112 ves_icall_System_Enum_get_value (MonoObject *this)
3120 MONO_ARCH_SAVE_REGS;
3125 g_assert (this->vtable->klass->enumtype);
3127 enumc = mono_class_from_mono_type (this->vtable->klass->enum_basetype);
3128 res = mono_object_new (mono_object_domain (this), enumc);
3129 dst = (char *)res + sizeof (MonoObject);
3130 src = (char *)this + sizeof (MonoObject);
3131 size = mono_class_value_size (enumc, NULL);
3133 memcpy (dst, src, size);
3139 ves_icall_get_enum_info (MonoReflectionType *type, MonoEnumInfo *info)
3141 MonoDomain *domain = mono_object_domain (type);
3142 MonoClass *enumc = mono_class_from_mono_type (type->type);
3143 guint j = 0, nvalues, crow;
3145 MonoClassField *field;
3147 MONO_ARCH_SAVE_REGS;
3149 info->utype = mono_type_get_object (domain, enumc->enum_basetype);
3150 nvalues = mono_class_num_fields (enumc) ? mono_class_num_fields (enumc) - 1 : 0;
3151 info->names = mono_array_new (domain, mono_defaults.string_class, nvalues);
3152 info->values = mono_array_new (domain, enumc, nvalues);
3156 while ((field = mono_class_get_fields (enumc, &iter))) {
3160 if (strcmp ("value__", field->name) == 0)
3162 if (mono_field_is_deleted (field))
3164 mono_array_setref (info->names, j, mono_string_new (domain, field->name));
3167 crow = mono_metadata_get_constant_index (enumc->image, mono_class_get_field_token (field), crow + 1);
3168 field->def_type = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_TYPE);
3169 crow = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_VALUE);
3170 field->data = (gpointer)mono_metadata_blob_heap (enumc->image, crow);
3174 len = mono_metadata_decode_blob_size (p, &p);
3175 switch (enumc->enum_basetype->type) {
3178 mono_array_set (info->values, gchar, j, *p);
3180 case MONO_TYPE_CHAR:
3183 mono_array_set (info->values, gint16, j, read16 (p));
3187 mono_array_set (info->values, gint32, j, read32 (p));
3191 mono_array_set (info->values, gint64, j, read64 (p));
3194 g_error ("Implement type 0x%02x in get_enum_info", enumc->enum_basetype->type);
3201 BFLAGS_IgnoreCase = 1,
3202 BFLAGS_DeclaredOnly = 2,
3203 BFLAGS_Instance = 4,
3205 BFLAGS_Public = 0x10,
3206 BFLAGS_NonPublic = 0x20,
3207 BFLAGS_FlattenHierarchy = 0x40,
3208 BFLAGS_InvokeMethod = 0x100,
3209 BFLAGS_CreateInstance = 0x200,
3210 BFLAGS_GetField = 0x400,
3211 BFLAGS_SetField = 0x800,
3212 BFLAGS_GetProperty = 0x1000,
3213 BFLAGS_SetProperty = 0x2000,
3214 BFLAGS_ExactBinding = 0x10000,
3215 BFLAGS_SuppressChangeType = 0x20000,
3216 BFLAGS_OptionalParamBinding = 0x40000
3219 static MonoReflectionField *
3220 ves_icall_Type_GetField (MonoReflectionType *type, MonoString *name, guint32 bflags)
3223 MonoClass *startklass, *klass;
3225 MonoClassField *field;
3228 int (*compare_func) (const char *s1, const char *s2) = NULL;
3229 domain = ((MonoObject *)type)->vtable->domain;
3230 klass = startklass = mono_class_from_mono_type (type->type);
3232 MONO_ARCH_SAVE_REGS;
3235 mono_raise_exception (mono_get_exception_argument_null ("name"));
3236 if (type->type->byref)
3239 compare_func = (bflags & BFLAGS_IgnoreCase) ? g_strcasecmp : strcmp;
3242 if (klass->exception_type != MONO_EXCEPTION_NONE)
3243 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3246 while ((field = mono_class_get_fields (klass, &iter))) {
3249 if (field->type == NULL)
3251 if (mono_field_is_deleted (field))
3253 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3254 if (bflags & BFLAGS_Public)
3256 } else if ((klass == startklass) || (field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
3257 if (bflags & BFLAGS_NonPublic) {
3264 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
3265 if (bflags & BFLAGS_Static)
3266 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3269 if (bflags & BFLAGS_Instance)
3276 utf8_name = mono_string_to_utf8 (name);
3278 if (compare_func (field->name, utf8_name)) {
3284 return mono_field_get_object (domain, klass, field);
3286 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3293 ves_icall_Type_GetFields_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3296 MonoClass *startklass, *klass, *refklass;
3301 MonoClassField *field;
3303 MONO_ARCH_SAVE_REGS;
3305 domain = ((MonoObject *)type)->vtable->domain;
3306 if (type->type->byref)
3307 return mono_array_new (domain, mono_defaults.field_info_class, 0);
3308 klass = startklass = mono_class_from_mono_type (type->type);
3309 refklass = mono_class_from_mono_type (reftype->type);
3313 res = mono_array_new (domain, mono_defaults.field_info_class, len);
3315 if (klass->exception_type != MONO_EXCEPTION_NONE)
3316 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3319 while ((field = mono_class_get_fields (klass, &iter))) {
3321 if (mono_field_is_deleted (field))
3323 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3324 if (bflags & BFLAGS_Public)
3326 } else if ((klass == startklass) || (field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
3327 if (bflags & BFLAGS_NonPublic) {
3334 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
3335 if (bflags & BFLAGS_Static)
3336 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3339 if (bflags & BFLAGS_Instance)
3345 member = (MonoObject*)mono_field_get_object (domain, refklass, field);
3347 MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, len * 2);
3348 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3352 mono_array_setref (res, i, member);
3355 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3358 MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, i);
3359 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3362 * Better solution for the new GC.
3363 * res->max_length = i;
3370 method_nonpublic (MonoMethod* method, gboolean start_klass)
3372 switch (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) {
3373 case METHOD_ATTRIBUTE_ASSEM:
3374 return (start_klass || mono_defaults.generic_ilist_class);
3375 case METHOD_ATTRIBUTE_PRIVATE:
3377 case METHOD_ATTRIBUTE_PUBLIC:
3385 ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
3388 MonoClass *startklass, *klass, *refklass;
3393 int i, len, match, nslots;
3394 guint32 method_slots_default [8];
3395 guint32 *method_slots;
3396 gchar *mname = NULL;
3397 int (*compare_func) (const char *s1, const char *s2) = NULL;
3399 MONO_ARCH_SAVE_REGS;
3401 domain = ((MonoObject *)type)->vtable->domain;
3402 if (type->type->byref)
3403 return mono_array_new (domain, mono_defaults.method_info_class, 0);
3404 klass = startklass = mono_class_from_mono_type (type->type);
3405 refklass = mono_class_from_mono_type (reftype->type);
3408 mname = mono_string_to_utf8 (name);
3409 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
3412 mono_class_setup_vtable (klass);
3414 if (is_generic_parameter (type->type))
3415 nslots = klass->parent->vtable_size;
3417 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : klass->vtable_size;
3418 if (nslots >= sizeof (method_slots_default) * 8) {
3419 method_slots = g_new0 (guint32, nslots / 32 + 1);
3421 method_slots = method_slots_default;
3422 memset (method_slots, 0, sizeof (method_slots_default));
3426 res = mono_array_new (domain, mono_defaults.method_info_class, len);
3428 mono_class_setup_vtable (klass);
3429 if (klass->exception_type != MONO_EXCEPTION_NONE)
3430 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3433 while ((method = mono_class_get_methods (klass, &iter))) {
3435 if (method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
3437 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3438 if (bflags & BFLAGS_Public)
3440 } else if ((bflags & BFLAGS_NonPublic) && method_nonpublic (method, (klass == startklass))) {
3446 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3447 if (bflags & BFLAGS_Static)
3448 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3451 if (bflags & BFLAGS_Instance)
3459 if (compare_func (mname, method->name))
3464 if (method->slot != -1) {
3465 g_assert (method->slot < nslots);
3466 if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
3468 method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
3471 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
3474 MonoArray *new_res = mono_array_new (domain, mono_defaults.method_info_class, len * 2);
3475 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3479 mono_array_setref (res, i, member);
3482 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3486 if (method_slots != method_slots_default)
3487 g_free (method_slots);
3489 MonoArray *new_res = mono_array_new (domain, mono_defaults.method_info_class, i);
3490 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3493 * Better solution for the new GC.
3494 * res->max_length = i;
3501 ves_icall_Type_GetConstructors_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3504 static MonoClass *System_Reflection_ConstructorInfo;
3505 MonoClass *startklass, *klass, *refklass;
3510 gpointer iter = NULL;
3512 MONO_ARCH_SAVE_REGS;
3514 domain = ((MonoObject *)type)->vtable->domain;
3515 if (type->type->byref)
3516 return mono_array_new (domain, mono_defaults.method_info_class, 0);
3517 klass = startklass = mono_class_from_mono_type (type->type);
3518 refklass = mono_class_from_mono_type (reftype->type);
3520 if (klass->exception_type != MONO_EXCEPTION_NONE)
3521 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3523 if (!System_Reflection_ConstructorInfo)
3524 System_Reflection_ConstructorInfo = mono_class_from_name (
3525 mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
3529 res = mono_array_new (domain, System_Reflection_ConstructorInfo, len);
3531 while ((method = mono_class_get_methods (klass, &iter))) {
3533 if (strcmp (method->name, ".ctor") && strcmp (method->name, ".cctor"))
3535 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3536 if (bflags & BFLAGS_Public)
3539 if (bflags & BFLAGS_NonPublic)
3545 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3546 if (bflags & BFLAGS_Static)
3547 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3550 if (bflags & BFLAGS_Instance)
3556 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
3559 MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, len * 2);
3560 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3564 mono_array_setref (res, i, member);
3568 MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, i);
3569 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3572 * Better solution for the new GC.
3573 * res->max_length = i;
3580 property_hash (gconstpointer data)
3582 MonoProperty *prop = (MonoProperty*)data;
3584 return g_str_hash (prop->name);
3588 property_equal (MonoProperty *prop1, MonoProperty *prop2)
3590 // Properties are hide-by-name-and-signature
3591 if (!g_str_equal (prop1->name, prop2->name))
3594 if (prop1->get && prop2->get && !mono_metadata_signature_equal (mono_method_signature (prop1->get), mono_method_signature (prop2->get)))
3596 if (prop1->set && prop2->set && !mono_metadata_signature_equal (mono_method_signature (prop1->set), mono_method_signature (prop2->set)))
3602 property_accessor_nonpublic (MonoMethod* accessor, gboolean start_klass)
3607 return method_nonpublic (accessor, start_klass);
3611 ves_icall_Type_GetPropertiesByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
3614 static MonoClass *System_Reflection_PropertyInfo;
3615 MonoClass *startklass, *klass;
3622 gchar *propname = NULL;
3623 int (*compare_func) (const char *s1, const char *s2) = NULL;
3625 GHashTable *properties;
3627 MONO_ARCH_SAVE_REGS;
3629 if (!System_Reflection_PropertyInfo)
3630 System_Reflection_PropertyInfo = mono_class_from_name (
3631 mono_defaults.corlib, "System.Reflection", "PropertyInfo");
3633 domain = ((MonoObject *)type)->vtable->domain;
3634 if (type->type->byref)
3635 return mono_array_new (domain, System_Reflection_PropertyInfo, 0);
3636 klass = startklass = mono_class_from_mono_type (type->type);
3638 propname = mono_string_to_utf8 (name);
3639 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
3642 mono_class_setup_vtable (klass);
3644 properties = g_hash_table_new (property_hash, (GEqualFunc)property_equal);
3647 res = mono_array_new (domain, System_Reflection_PropertyInfo, len);
3649 mono_class_setup_vtable (klass);
3650 if (klass->exception_type != MONO_EXCEPTION_NONE) {
3651 g_hash_table_destroy (properties);
3654 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3658 while ((prop = mono_class_get_properties (klass, &iter))) {
3664 flags = method->flags;
3667 if ((prop->get && ((prop->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC)) ||
3668 (prop->set && ((prop->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC))) {
3669 if (bflags & BFLAGS_Public)
3671 } else if (bflags & BFLAGS_NonPublic) {
3672 if (property_accessor_nonpublic(prop->get, startklass == klass) ||
3673 property_accessor_nonpublic(prop->set, startklass == klass)) {
3680 if (flags & METHOD_ATTRIBUTE_STATIC) {
3681 if (bflags & BFLAGS_Static)
3682 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3685 if (bflags & BFLAGS_Instance)
3694 if (compare_func (propname, prop->name))
3698 if (g_hash_table_lookup (properties, prop))
3702 MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, len * 2);
3703 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3707 mono_array_setref (res, i, mono_property_get_object (domain, startklass, prop));
3710 g_hash_table_insert (properties, prop, prop);
3712 if ((!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent)))
3715 g_hash_table_destroy (properties);
3718 MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, i);
3719 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3722 * Better solution for the new GC.
3723 * res->max_length = i;
3729 static MonoReflectionEvent *
3730 ves_icall_MonoType_GetEvent (MonoReflectionType *type, MonoString *name, guint32 bflags)
3733 MonoClass *klass, *startklass;
3739 MONO_ARCH_SAVE_REGS;
3741 event_name = mono_string_to_utf8 (name);
3742 if (type->type->byref)
3744 klass = startklass = mono_class_from_mono_type (type->type);
3745 domain = mono_object_domain (type);
3748 if (klass->exception_type != MONO_EXCEPTION_NONE)
3749 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3752 while ((event = mono_class_get_events (klass, &iter))) {
3753 if (strcmp (event->name, event_name))
3756 method = event->add;
3758 method = event->remove;
3760 method = event->raise;
3762 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3763 if (!(bflags & BFLAGS_Public))
3766 if (!(bflags & BFLAGS_NonPublic))
3768 if ((klass != startklass) && (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PRIVATE)
3773 if (!(bflags & BFLAGS_NonPublic))
3776 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3777 if (!(bflags & BFLAGS_Static))
3779 if (!(bflags & BFLAGS_FlattenHierarchy) && (klass != startklass))
3782 if (!(bflags & BFLAGS_Instance))
3786 g_free (event_name);
3787 return mono_event_get_object (domain, startklass, event);
3790 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3793 g_free (event_name);
3798 ves_icall_Type_GetEvents_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3801 static MonoClass *System_Reflection_EventInfo;
3802 MonoClass *startklass, *klass;
3809 MONO_ARCH_SAVE_REGS;
3811 if (!System_Reflection_EventInfo)
3812 System_Reflection_EventInfo = mono_class_from_name (
3813 mono_defaults.corlib, "System.Reflection", "EventInfo");
3815 domain = mono_object_domain (type);
3816 if (type->type->byref)
3817 return mono_array_new (domain, System_Reflection_EventInfo, 0);
3818 klass = startklass = mono_class_from_mono_type (type->type);
3822 res = mono_array_new (domain, System_Reflection_EventInfo, len);
3824 if (klass->exception_type != MONO_EXCEPTION_NONE)
3825 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3828 while ((event = mono_class_get_events (klass, &iter))) {
3830 method = event->add;
3832 method = event->remove;
3834 method = event->raise;
3836 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3837 if (bflags & BFLAGS_Public)
3839 } else if ((klass == startklass) || (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) {
3840 if (bflags & BFLAGS_NonPublic)
3845 if (bflags & BFLAGS_NonPublic)
3851 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3852 if (bflags & BFLAGS_Static)
3853 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3856 if (bflags & BFLAGS_Instance)
3861 if (bflags & BFLAGS_Instance)
3867 MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, len * 2);
3868 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3872 mono_array_setref (res, i, mono_event_get_object (domain, startklass, event));
3875 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3878 MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, i);
3879 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3882 * Better solution for the new GC.
3883 * res->max_length = i;
3889 static MonoReflectionType *
3890 ves_icall_Type_GetNestedType (MonoReflectionType *type, MonoString *name, guint32 bflags)
3898 MONO_ARCH_SAVE_REGS;
3900 domain = ((MonoObject *)type)->vtable->domain;
3901 if (type->type->byref)
3903 klass = mono_class_from_mono_type (type->type);
3904 str = mono_string_to_utf8 (name);
3907 if (klass->exception_type != MONO_EXCEPTION_NONE)
3908 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3911 * If a nested type is generic, return its generic type definition.
3912 * Note that this means that the return value is essentially a
3913 * nested type of the generic type definition of @klass.
3915 * A note in MSDN claims that a generic type definition can have
3916 * nested types that aren't generic. In any case, the container of that
3917 * nested type would be the generic type definition.
3919 if (klass->generic_class)
3920 klass = klass->generic_class->container_class;
3922 for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
3924 nested = tmpn->data;
3925 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
3926 if (bflags & BFLAGS_Public)
3929 if (bflags & BFLAGS_NonPublic)
3934 if (strcmp (nested->name, str) == 0){
3936 return mono_type_get_object (domain, &nested->byval_arg);
3939 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3946 ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags)
3956 MONO_ARCH_SAVE_REGS;
3958 domain = ((MonoObject *)type)->vtable->domain;
3959 if (type->type->byref)
3960 return mono_array_new (domain, mono_defaults.monotype_class, 0);
3961 klass = mono_class_from_mono_type (type->type);
3962 if (klass->exception_type != MONO_EXCEPTION_NONE)
3963 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3966 * If a nested type is generic, return its generic type definition.
3967 * Note that this means that the return value is essentially the set
3968 * of nested types of the generic type definition of @klass.
3970 * A note in MSDN claims that a generic type definition can have
3971 * nested types that aren't generic. In any case, the container of that
3972 * nested type would be the generic type definition.
3974 if (klass->generic_class)
3975 klass = klass->generic_class->container_class;
3979 res = mono_array_new (domain, mono_defaults.monotype_class, len);
3980 for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
3982 nested = tmpn->data;
3983 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
3984 if (bflags & BFLAGS_Public)
3987 if (bflags & BFLAGS_NonPublic)
3992 member = (MonoObject*)mono_type_get_object (domain, &nested->byval_arg);
3994 MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, len * 2);
3995 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3999 mono_array_setref (res, i, member);
4003 MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, i);
4004 mono_array_memcpy_refs (new_res, 0, res, 0, i);
4007 * Better solution for the new GC.
4008 * res->max_length = i;
4014 static MonoReflectionType*
4015 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *assembly, MonoReflectionModule *module, MonoString *name, MonoBoolean throwOnError, MonoBoolean ignoreCase)
4018 MonoType *type = NULL;
4019 MonoTypeNameParse info;
4020 gboolean type_resolve;
4022 MONO_ARCH_SAVE_REGS;
4024 /* On MS.NET, this does not fire a TypeResolve event */
4025 type_resolve = TRUE;
4026 str = mono_string_to_utf8 (name);
4027 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
4028 if (!mono_reflection_parse_type (str, &info)) {
4030 mono_reflection_free_type_info (&info);
4031 if (throwOnError) /* uhm: this is a parse error, though... */
4032 mono_raise_exception (mono_get_exception_type_load (name, NULL));
4033 /*g_print ("failed parse\n");*/
4037 if (info.assembly.name) {
4039 /* 1.0 and 2.0 throw different exceptions */
4040 if (mono_defaults.generic_ilist_class)
4041 mono_raise_exception (mono_get_exception_argument (NULL, "Type names passed to Assembly.GetType() must not specify an assembly."));
4043 mono_raise_exception (mono_get_exception_type_load (name, NULL));
4048 if (module != NULL) {
4050 type = mono_reflection_get_type (module->image, &info, ignoreCase, &type_resolve);
4055 if (assembly->assembly->dynamic) {
4056 /* Enumerate all modules */
4057 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
4061 if (abuilder->modules) {
4062 for (i = 0; i < mono_array_length (abuilder->modules); ++i) {
4063 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
4064 type = mono_reflection_get_type (&mb->dynamic_image->image, &info, ignoreCase, &type_resolve);
4070 if (!type && abuilder->loaded_modules) {
4071 for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) {
4072 MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
4073 type = mono_reflection_get_type (mod->image, &info, ignoreCase, &type_resolve);
4080 type = mono_reflection_get_type (assembly->assembly->image, &info, ignoreCase, &type_resolve);
4082 mono_reflection_free_type_info (&info);
4084 MonoException *e = NULL;
4087 e = mono_get_exception_type_load (name, NULL);
4089 mono_loader_clear_error ();
4092 mono_raise_exception (e);
4097 if (type->type == MONO_TYPE_CLASS) {
4098 MonoClass *klass = mono_type_get_class (type);
4099 /* need to report exceptions ? */
4100 if (throwOnError && klass->exception_type) {
4101 /* report SecurityException (or others) that occured when loading the assembly */
4102 MonoException *exc = mono_class_get_exception_for_failure (klass);
4103 mono_loader_clear_error ();
4104 mono_raise_exception (exc);
4105 } else if (klass->exception_type == MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND) {
4110 /* g_print ("got it\n"); */
4111 return mono_type_get_object (mono_object_domain (assembly), type);
4115 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *assembly, MonoBoolean escaped)
4117 MonoDomain *domain = mono_object_domain (assembly);
4118 MonoAssembly *mass = assembly->assembly;
4119 MonoString *res = NULL;
4123 MONO_ARCH_SAVE_REGS;
4125 if (g_path_is_absolute (mass->image->name))
4126 absolute = g_strdup (mass->image->name);
4128 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4132 for (i = strlen (absolute) - 1; i >= 0; i--)
4133 if (absolute [i] == '\\')
4138 uri = g_filename_to_uri (absolute, NULL, NULL);
4140 uri = g_strconcat ("file://", absolute, NULL);
4144 res = mono_string_new (domain, uri);
4152 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssembly *assembly)
4154 MonoAssembly *mass = assembly->assembly;
4156 MONO_ARCH_SAVE_REGS;
4158 return mass->in_gac;
4161 static MonoReflectionAssembly*
4162 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoString *mname, MonoObject *evidence)
4166 MonoImageOpenStatus status;
4168 MONO_ARCH_SAVE_REGS;
4170 name = mono_string_to_utf8 (mname);
4171 res = mono_assembly_load_with_partial_name (name, &status);
4177 return mono_assembly_get_object (mono_domain_get (), res);
4181 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssembly *assembly)
4183 MonoDomain *domain = mono_object_domain (assembly);
4186 MONO_ARCH_SAVE_REGS;
4188 res = mono_string_new (domain, mono_image_get_filename (assembly->assembly->image));
4194 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssembly *assembly)
4196 MONO_ARCH_SAVE_REGS;
4198 return assembly->assembly->ref_only;
4202 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssembly *assembly)
4204 MonoDomain *domain = mono_object_domain (assembly);
4206 MONO_ARCH_SAVE_REGS;
4208 return mono_string_new (domain, assembly->assembly->image->version);
4211 static MonoReflectionMethod*
4212 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssembly *assembly)
4214 guint32 token = mono_image_get_entry_point (assembly->assembly->image);
4216 MONO_ARCH_SAVE_REGS;
4220 return mono_method_get_object (mono_object_domain (assembly), mono_get_method (assembly->assembly->image, token, NULL), NULL);
4223 static MonoReflectionModule*
4224 ves_icall_System_Reflection_Assembly_GetManifestModuleInternal (MonoReflectionAssembly *assembly)
4226 return mono_module_get_object (mono_object_domain (assembly), assembly->assembly->image);
4230 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssembly *assembly)
4232 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4233 MonoArray *result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, table->rows);
4237 MONO_ARCH_SAVE_REGS;
4239 for (i = 0; i < table->rows; ++i) {
4240 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_MANIFEST_NAME));
4241 mono_array_setref (result, i, mono_string_new (mono_object_domain (assembly), val));
4247 create_version (MonoDomain *domain, guint32 major, guint32 minor, guint32 build, guint32 revision)
4249 static MonoClass *System_Version = NULL;
4250 static MonoMethod *create_version = NULL;
4254 if (!System_Version) {
4255 System_Version = mono_class_from_name (mono_defaults.corlib, "System", "Version");
4256 g_assert (System_Version);
4259 if (!create_version) {
4260 MonoMethodDesc *desc = mono_method_desc_new (":.ctor(int,int,int,int)", FALSE);
4261 create_version = mono_method_desc_search_in_class (desc, System_Version);
4262 g_assert (create_version);
4263 mono_method_desc_free (desc);
4269 args [3] = &revision;
4270 result = mono_object_new (domain, System_Version);
4271 mono_runtime_invoke (create_version, result, args, NULL);
4277 ves_icall_System_Reflection_Assembly_GetReferencedAssemblies (MonoReflectionAssembly *assembly)
4279 static MonoClass *System_Reflection_AssemblyName;
4281 MonoDomain *domain = mono_object_domain (assembly);
4283 static MonoMethod *create_culture = NULL;
4284 MonoImage *image = assembly->assembly->image;
4287 MONO_ARCH_SAVE_REGS;
4289 if (!System_Reflection_AssemblyName)
4290 System_Reflection_AssemblyName = mono_class_from_name (
4291 mono_defaults.corlib, "System.Reflection", "AssemblyName");
4293 t = &assembly->assembly->image->tables [MONO_TABLE_ASSEMBLYREF];
4296 result = mono_array_new (domain, System_Reflection_AssemblyName, count);
4299 MonoMethodDesc *desc = mono_method_desc_new (
4300 "System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE);
4301 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4302 g_assert (create_culture);
4303 mono_method_desc_free (desc);
4306 for (i = 0; i < count; i++) {
4307 MonoReflectionAssemblyName *aname;
4308 guint32 cols [MONO_ASSEMBLYREF_SIZE];
4310 mono_metadata_decode_row (t, i, cols, MONO_ASSEMBLYREF_SIZE);
4312 aname = (MonoReflectionAssemblyName *) mono_object_new (
4313 domain, System_Reflection_AssemblyName);
4315 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_NAME])));
4317 aname->major = cols [MONO_ASSEMBLYREF_MAJOR_VERSION];
4318 aname->minor = cols [MONO_ASSEMBLYREF_MINOR_VERSION];
4319 aname->build = cols [MONO_ASSEMBLYREF_BUILD_NUMBER];
4320 aname->revision = cols [MONO_ASSEMBLYREF_REV_NUMBER];
4321 aname->flags = cols [MONO_ASSEMBLYREF_FLAGS];
4322 aname->versioncompat = 1; /* SameMachine (default) */
4323 aname->hashalg = ASSEMBLY_HASH_SHA1; /* SHA1 (default) */
4324 MONO_OBJECT_SETREF (aname, version, create_version (domain, aname->major, aname->minor, aname->build, aname->revision));
4326 if (create_culture) {
4328 gboolean assembly_ref = TRUE;
4329 args [0] = mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_CULTURE]));
4330 args [1] = &assembly_ref;
4331 MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
4334 if (cols [MONO_ASSEMBLYREF_PUBLIC_KEY]) {
4335 const gchar *pkey_ptr = mono_metadata_blob_heap (image, cols [MONO_ASSEMBLYREF_PUBLIC_KEY]);
4336 guint32 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
4338 if ((cols [MONO_ASSEMBLYREF_FLAGS] & ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG)) {
4339 /* public key token isn't copied - the class library will
4340 automatically generate it from the public key if required */
4341 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4342 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
4344 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4345 memcpy (mono_array_addr (aname->keyToken, guint8, 0), pkey_ptr, pkey_len);
4348 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, 0));
4351 /* note: this function doesn't return the codebase on purpose (i.e. it can
4352 be used under partial trust as path information isn't present). */
4354 mono_array_setref (result, i, aname);
4365 foreach_namespace (const char* key, gconstpointer val, NameSpaceInfo *info)
4367 MonoString *name = mono_string_new (mono_object_domain (info->res), key);
4369 mono_array_setref (info->res, info->idx, name);
4374 ves_icall_System_Reflection_Assembly_GetNamespaces (MonoReflectionAssembly *assembly)
4376 MonoImage *img = assembly->assembly->image;
4380 MONO_ARCH_SAVE_REGS;
4382 if (!img->name_cache)
4383 mono_image_init_name_cache (img);
4385 res = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, g_hash_table_size (img->name_cache));
4388 g_hash_table_foreach (img->name_cache, (GHFunc)foreach_namespace, &info);
4393 /* move this in some file in mono/util/ */
4395 g_concat_dir_and_file (const char *dir, const char *file)
4397 g_return_val_if_fail (dir != NULL, NULL);
4398 g_return_val_if_fail (file != NULL, NULL);
4401 * If the directory name doesn't have a / on the end, we need
4402 * to add one so we get a proper path to the file
4404 if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
4405 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
4407 return g_strconcat (dir, file, NULL);
4411 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssembly *assembly, MonoString *name, gint32 *size, MonoReflectionModule **ref_module)
4413 char *n = mono_string_to_utf8 (name);
4414 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4416 guint32 cols [MONO_MANIFEST_SIZE];
4417 guint32 impl, file_idx;
4421 MONO_ARCH_SAVE_REGS;
4423 for (i = 0; i < table->rows; ++i) {
4424 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4425 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4426 if (strcmp (val, n) == 0)
4430 if (i == table->rows)
4433 impl = cols [MONO_MANIFEST_IMPLEMENTATION];
4436 * this code should only be called after obtaining the
4437 * ResourceInfo and handling the other cases.
4439 g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
4440 file_idx = impl >> MONO_IMPLEMENTATION_BITS;
4442 module = mono_image_load_file_for_image (assembly->assembly->image, file_idx);
4447 module = assembly->assembly->image;
4449 *ref_module = mono_module_get_object (mono_domain_get (), module);
4451 return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
4455 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoManifestResourceInfo *info)
4457 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4459 guint32 cols [MONO_MANIFEST_SIZE];
4460 guint32 file_cols [MONO_FILE_SIZE];
4464 MONO_ARCH_SAVE_REGS;
4466 n = mono_string_to_utf8 (name);
4467 for (i = 0; i < table->rows; ++i) {
4468 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4469 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4470 if (strcmp (val, n) == 0)
4474 if (i == table->rows)
4477 if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
4478 info->location = RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST;
4481 switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
4482 case MONO_IMPLEMENTATION_FILE:
4483 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4484 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4485 mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
4486 val = mono_metadata_string_heap (assembly->assembly->image, file_cols [MONO_FILE_NAME]);
4487 MONO_OBJECT_SETREF (info, filename, mono_string_new (mono_object_domain (assembly), val));
4488 if (file_cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA)
4491 info->location = RESOURCE_LOCATION_EMBEDDED;
4494 case MONO_IMPLEMENTATION_ASSEMBLYREF:
4495 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4496 mono_assembly_load_reference (assembly->assembly->image, i - 1);
4497 if (assembly->assembly->image->references [i - 1] == (gpointer)-1) {
4498 char *msg = g_strdup_printf ("Assembly %d referenced from assembly %s not found ", i - 1, assembly->assembly->image->name);
4499 MonoException *ex = mono_get_exception_file_not_found2 (msg, NULL);
4501 mono_raise_exception (ex);
4503 MONO_OBJECT_SETREF (info, assembly, mono_assembly_get_object (mono_domain_get (), assembly->assembly->image->references [i - 1]));
4505 /* Obtain info recursively */
4506 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (info->assembly, name, info);
4507 info->location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
4510 case MONO_IMPLEMENTATION_EXP_TYPE:
4511 g_assert_not_reached ();
4520 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoBoolean resource_modules)
4522 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4523 MonoArray *result = NULL;
4528 MONO_ARCH_SAVE_REGS;
4530 /* check hash if needed */
4532 n = mono_string_to_utf8 (name);
4533 for (i = 0; i < table->rows; ++i) {
4534 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4535 if (strcmp (val, n) == 0) {
4538 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4539 fn = mono_string_new (mono_object_domain (assembly), n);
4541 return (MonoObject*)fn;
4549 for (i = 0; i < table->rows; ++i) {
4550 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA))
4554 result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, count);
4557 for (i = 0; i < table->rows; ++i) {
4558 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4559 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4560 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4561 mono_array_setref (result, count, mono_string_new (mono_object_domain (assembly), n));
4566 return (MonoObject*)result;
4570 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly *assembly)
4572 MonoDomain *domain = mono_domain_get();
4575 int i, j, file_count = 0;
4576 MonoImage **modules;
4577 guint32 module_count, real_module_count;
4578 MonoTableInfo *table;
4580 g_assert (assembly->assembly->image != NULL);
4582 if (assembly->assembly->dynamic) {
4583 MonoReflectionAssemblyBuilder *assemblyb = (MonoReflectionAssemblyBuilder*)assembly;
4585 if (assemblyb->modules)
4586 module_count = mono_array_length (assemblyb->modules);
4589 real_module_count = module_count;
4591 modules = g_new0 (MonoImage*, module_count);
4592 if (assemblyb->modules) {
4593 for (i = 0; i < mono_array_length (assemblyb->modules); ++i) {
4595 mono_array_get (assemblyb->modules, MonoReflectionModuleBuilder*, i)->module.image;
4600 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4601 file_count = table->rows;
4603 modules = assembly->assembly->image->modules;
4604 module_count = assembly->assembly->image->module_count;
4606 real_module_count = 0;
4607 for (i = 0; i < module_count; ++i)
4609 real_module_count ++;
4612 klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "Module");
4613 res = mono_array_new (domain, klass, 1 + real_module_count + file_count);
4615 mono_array_setref (res, 0, mono_module_get_object (domain, assembly->assembly->image));
4617 for (i = 0; i < module_count; ++i)
4619 mono_array_setref (res, j, mono_module_get_object (domain, modules[i]));
4623 for (i = 0; i < file_count; ++i, ++j)
4624 mono_array_setref (res, j, mono_module_file_get_object (domain, assembly->assembly->image, i));
4626 if (assembly->assembly->dynamic)
4632 static MonoReflectionMethod*
4633 ves_icall_GetCurrentMethod (void)
4635 MonoMethod *m = mono_method_get_last_managed ();
4637 MONO_ARCH_SAVE_REGS;
4639 return mono_method_get_object (mono_domain_get (), m, NULL);
4642 static MonoReflectionMethod*
4643 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType (MonoMethod *method, MonoType *type)
4645 /* FIXME check that method belongs to klass or a parent */
4648 klass = mono_class_from_mono_type (type);
4650 klass = method->klass;
4651 return mono_method_get_object (mono_domain_get (), method, klass);
4654 static MonoReflectionMethod*
4655 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternal (MonoMethod *method)
4657 return mono_method_get_object (mono_domain_get (), method, NULL);
4660 static MonoReflectionMethodBody*
4661 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod *method)
4663 return mono_method_body_get_object (mono_domain_get (), method);
4666 static MonoReflectionAssembly*
4667 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (void)
4669 MonoMethod *m = mono_method_get_last_managed ();
4671 MONO_ARCH_SAVE_REGS;
4673 return mono_assembly_get_object (mono_domain_get (), m->klass->image->assembly);
4677 static MonoReflectionAssembly*
4678 ves_icall_System_Reflection_Assembly_GetEntryAssembly (void)
4680 MonoDomain* domain = mono_domain_get ();
4682 MONO_ARCH_SAVE_REGS;
4684 if (!domain->entry_assembly)
4687 return mono_assembly_get_object (domain, domain->entry_assembly);
4690 static MonoReflectionAssembly*
4691 ves_icall_System_Reflection_Assembly_GetCallingAssembly (void)
4693 MonoMethod *m = mono_method_get_last_managed ();
4694 MonoMethod *dest = m;
4696 MONO_ARCH_SAVE_REGS;
4698 mono_stack_walk_no_il (get_caller, &dest);
4701 return mono_assembly_get_object (mono_domain_get (), dest->klass->image->assembly);
4705 ves_icall_System_MonoType_getFullName (MonoReflectionType *object, gboolean full_name,
4706 gboolean assembly_qualified)
4708 MonoDomain *domain = mono_object_domain (object);
4709 MonoTypeNameFormat format;
4713 MONO_ARCH_SAVE_REGS;
4715 format = assembly_qualified ?
4716 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
4717 MONO_TYPE_NAME_FORMAT_FULL_NAME;
4719 format = MONO_TYPE_NAME_FORMAT_REFLECTION;
4721 name = mono_type_get_name_full (object->type, format);
4725 if (full_name && (object->type->type == MONO_TYPE_VAR || object->type->type == MONO_TYPE_MVAR)) {
4730 res = mono_string_new (domain, name);
4737 fill_reflection_assembly_name (MonoDomain *domain, MonoReflectionAssemblyName *aname, MonoAssemblyName *name, const char *absolute, gboolean by_default_version, gboolean default_publickey, gboolean default_token)
4739 static MonoMethod *create_culture = NULL;
4742 const char *pkey_ptr;
4744 gboolean assembly_ref = FALSE;
4746 MONO_ARCH_SAVE_REGS;
4748 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, name->name));
4749 aname->major = name->major;
4750 aname->minor = name->minor;
4751 aname->build = name->build;
4752 aname->flags = name->flags;
4753 aname->revision = name->revision;
4754 aname->hashalg = name->hash_alg;
4755 aname->versioncompat = 1; /* SameMachine (default) */
4757 if (by_default_version)
4758 MONO_OBJECT_SETREF (aname, version, create_version (domain, name->major, name->minor, name->build, name->revision));
4760 codebase = g_filename_to_uri (absolute, NULL, NULL);
4762 MONO_OBJECT_SETREF (aname, codebase, mono_string_new (domain, codebase));
4766 if (!create_culture) {
4767 MonoMethodDesc *desc = mono_method_desc_new ("System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE);
4768 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4769 g_assert (create_culture);
4770 mono_method_desc_free (desc);
4773 if (name->culture) {
4774 args [0] = mono_string_new (domain, name->culture);
4775 args [1] = &assembly_ref;
4776 MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
4779 if (name->public_key) {
4780 pkey_ptr = (char*)name->public_key;
4781 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
4783 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4784 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
4785 aname->flags |= ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG;
4786 } else if (default_publickey) {
4787 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, 0));
4788 aname->flags |= ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG;
4791 /* MonoAssemblyName keeps the public key token as an hexadecimal string */
4792 if (name->public_key_token [0]) {
4796 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, 8));
4797 p = mono_array_addr (aname->keyToken, char, 0);
4799 for (i = 0, j = 0; i < 8; i++) {
4800 *p = g_ascii_xdigit_value (name->public_key_token [j++]) << 4;
4801 *p |= g_ascii_xdigit_value (name->public_key_token [j++]);
4804 } else if (default_token) {
4805 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, 0));
4810 ves_icall_System_Reflection_Assembly_FillName (MonoReflectionAssembly *assembly, MonoReflectionAssemblyName *aname)
4813 MonoAssembly *mass = assembly->assembly;
4815 MONO_ARCH_SAVE_REGS;
4817 if (g_path_is_absolute (mass->image->name)) {
4818 fill_reflection_assembly_name (mono_object_domain (assembly),
4819 aname, &mass->aname, mass->image->name, TRUE,
4820 TRUE, mono_get_runtime_info ()->framework_version [0] >= '2');
4823 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4825 fill_reflection_assembly_name (mono_object_domain (assembly),
4826 aname, &mass->aname, absolute, TRUE, TRUE,
4827 mono_get_runtime_info ()->framework_version [0] >= '2');
4833 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoString *fname, MonoReflectionAssemblyName *aname)
4836 MonoImageOpenStatus status = MONO_IMAGE_OK;
4839 MonoAssemblyName name;
4841 MONO_ARCH_SAVE_REGS;
4843 filename = mono_string_to_utf8 (fname);
4845 image = mono_image_open (filename, &status);
4851 if (status == MONO_IMAGE_IMAGE_INVALID)
4852 exc = mono_get_exception_bad_image_format2 (NULL, fname);
4854 exc = mono_get_exception_file_not_found2 (NULL, fname);
4855 mono_raise_exception (exc);
4858 res = mono_assembly_fill_assembly_name (image, &name);
4860 mono_image_close (image);
4862 mono_raise_exception (mono_get_exception_argument ("assemblyFile", "The file does not contain a manifest"));
4865 fill_reflection_assembly_name (mono_domain_get (), aname, &name, filename,
4866 TRUE, mono_get_runtime_info ()->framework_version [0] == '1',
4867 mono_get_runtime_info ()->framework_version [0] >= '2');
4870 mono_image_close (image);
4874 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssembly *assembly,
4875 char **minimum, guint32 *minLength, char **optional, guint32 *optLength, char **refused, guint32 *refLength)
4877 MonoBoolean result = FALSE;
4878 MonoDeclSecurityEntry entry;
4880 /* SecurityAction.RequestMinimum */
4881 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQMIN, &entry)) {
4882 *minimum = entry.blob;
4883 *minLength = entry.size;
4886 /* SecurityAction.RequestOptional */
4887 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQOPT, &entry)) {
4888 *optional = entry.blob;
4889 *optLength = entry.size;
4892 /* SecurityAction.RequestRefuse */
4893 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQREFUSE, &entry)) {
4894 *refused = entry.blob;
4895 *refLength = entry.size;
4903 mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoBoolean exportedOnly)
4907 MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
4909 guint32 attrs, visibility;
4911 /* we start the count from 1 because we skip the special type <Module> */
4914 for (i = 1; i < tdef->rows; ++i) {
4915 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
4916 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
4917 if (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)
4921 count = tdef->rows - 1;
4923 res = mono_array_new (domain, mono_defaults.monotype_class, count);
4925 for (i = 1; i < tdef->rows; ++i) {
4926 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
4927 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
4928 if (!exportedOnly || (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)) {
4929 klass = mono_class_get_throw (image, (i + 1) | MONO_TOKEN_TYPE_DEF);
4930 if (mono_loader_get_last_error ())
4931 mono_loader_clear_error ();
4932 mono_array_setref (res, count, mono_type_get_object (domain, &klass->byval_arg));
4941 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly, MonoBoolean exportedOnly)
4943 MonoArray *res = NULL;
4944 MonoImage *image = NULL;
4945 MonoTableInfo *table = NULL;
4950 MONO_ARCH_SAVE_REGS;
4952 domain = mono_object_domain (assembly);
4954 if (assembly->assembly->dynamic) {
4955 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
4956 if (abuilder->modules) {
4957 for (i = 0; i < mono_array_length(abuilder->modules); i++) {
4958 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
4959 MonoArray *append = mb->types;
4960 /* The types array might not be fully filled up */
4961 if (append && mb->num_types > 0) {
4964 len1 = res ? mono_array_length (res) : 0;
4965 len2 = mb->num_types;
4966 new = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4968 mono_array_memcpy_refs (new, 0, res, 0, len1);
4969 mono_array_memcpy_refs (new, len1, append, 0, len2);
4975 * Replace TypeBuilders with the created types to be compatible
4979 for (i = 0; i < mono_array_length (res); ++i) {
4980 MonoReflectionTypeBuilder *tb = mono_array_get (res, MonoReflectionTypeBuilder*, i);
4982 mono_array_setref (res, i, tb->created);
4987 if (abuilder->loaded_modules)
4988 for (i = 0; i < mono_array_length(abuilder->loaded_modules); i++) {
4989 MonoReflectionModule *rm = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
4990 MonoArray *append = mono_module_get_types (domain, rm->image, exportedOnly);
4991 if (append && mono_array_length (append) > 0) {
4994 len1 = res ? mono_array_length (res) : 0;
4995 len2 = mono_array_length (append);
4996 new = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4998 mono_array_memcpy_refs (new, 0, res, 0, len1);
4999 mono_array_memcpy_refs (new, len1, append, 0, len2);
5006 return mono_array_new (domain, mono_defaults.monotype_class, 0);
5008 image = assembly->assembly->image;
5009 table = &image->tables [MONO_TABLE_FILE];
5010 res = mono_module_get_types (domain, image, exportedOnly);
5012 /* Append data from all modules in the assembly */
5013 for (i = 0; i < table->rows; ++i) {
5014 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
5015 MonoImage *loaded_image = mono_assembly_load_module (image->assembly, i + 1);
5017 MonoArray *res2 = mono_module_get_types (domain, loaded_image, exportedOnly);
5018 /* Append the new types to the end of the array */
5019 if (mono_array_length (res2) > 0) {
5023 len1 = mono_array_length (res);
5024 len2 = mono_array_length (res2);
5025 res3 = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
5026 mono_array_memcpy_refs (res3, 0, res, 0, len1);
5027 mono_array_memcpy_refs (res3, len1, res2, 0, len2);
5034 /* the ReflectionTypeLoadException must have all the types (Types property),
5035 * NULL replacing types which throws an exception. The LoaderException must
5036 * contain all exceptions for NULL items.
5039 len = mono_array_length (res);
5041 for (i = 0; i < len; i++) {
5042 MonoReflectionType *t = mono_array_get (res, gpointer, i);
5043 MonoClass *klass = mono_type_get_class (t->type);
5044 if ((klass != NULL) && klass->exception_type) {
5045 /* keep the class in the list */
5046 list = g_list_append (list, klass);
5047 /* and replace Type with NULL */
5048 mono_array_setref (res, i, NULL);
5054 MonoException *exc = NULL;
5055 MonoArray *exl = NULL;
5056 int length = g_list_length (list);
5058 mono_loader_clear_error ();
5060 exl = mono_array_new (domain, mono_defaults.exception_class, length);
5061 for (i = 0, tmp = list; i < length; i++, tmp = tmp->next) {
5062 MonoException *exc = mono_class_get_exception_for_failure (tmp->data);
5063 mono_array_setref (exl, i, exc);
5068 exc = mono_get_exception_reflection_type_load (res, exl);
5069 mono_loader_clear_error ();
5070 mono_raise_exception (exc);
5077 ves_icall_System_Reflection_AssemblyName_ParseName (MonoReflectionAssemblyName *name, MonoString *assname)
5079 MonoAssemblyName aname;
5080 MonoDomain *domain = mono_object_domain (name);
5082 gboolean is_version_defined;
5083 gboolean is_token_defined;
5085 val = mono_string_to_utf8 (assname);
5086 if (!mono_assembly_name_parse_full (val, &aname, TRUE, &is_version_defined, &is_token_defined))
5089 fill_reflection_assembly_name (domain, name, &aname, "", is_version_defined,
5090 FALSE, is_token_defined);
5092 mono_assembly_name_free (&aname);
5093 g_free ((guint8*) aname.public_key);
5099 static MonoReflectionType*
5100 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModule *module)
5102 MonoDomain *domain = mono_object_domain (module);
5105 MONO_ARCH_SAVE_REGS;
5107 g_assert (module->image);
5109 if (module->image->dynamic && ((MonoDynamicImage*)(module->image))->initial_image)
5110 /* These images do not have a global type */
5113 klass = mono_class_get (module->image, 1 | MONO_TOKEN_TYPE_DEF);
5114 return mono_type_get_object (domain, &klass->byval_arg);
5118 ves_icall_System_Reflection_Module_Close (MonoReflectionModule *module)
5120 /*if (module->image)
5121 mono_image_close (module->image);*/
5125 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModule *module)
5127 MonoDomain *domain = mono_object_domain (module);
5129 MONO_ARCH_SAVE_REGS;
5131 g_assert (module->image);
5132 return mono_string_new (domain, module->image->guid);
5136 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine)
5138 if (image->dynamic) {
5139 MonoDynamicImage *dyn = (MonoDynamicImage*)image;
5140 *pe_kind = dyn->pe_kind;
5141 *machine = dyn->machine;
5144 *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
5145 *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
5150 ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage *image)
5152 return (image->md_version_major << 16) | (image->md_version_minor);
5156 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModule *module)
5158 MONO_ARCH_SAVE_REGS;
5161 return mono_array_new (mono_object_domain (module), mono_defaults.monotype_class, 0);
5163 return mono_module_get_types (mono_object_domain (module), module->image, FALSE);
5167 mono_metadata_memberref_is_method (MonoImage *image, guint32 token)
5169 guint32 cols [MONO_MEMBERREF_SIZE];
5171 mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
5172 sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
5173 mono_metadata_decode_blob_size (sig, &sig);
5174 return (*sig != 0x6);
5178 init_generic_context_from_args (MonoGenericContext *context, MonoArray *type_args, MonoArray *method_args)
5181 context->class_inst = mono_metadata_get_generic_inst (mono_array_length (type_args),
5182 mono_array_addr (type_args, MonoType*, 0));
5184 context->class_inst = NULL;
5186 context->method_inst = mono_metadata_get_generic_inst (mono_array_length (method_args),
5187 mono_array_addr (method_args, MonoType*, 0));
5189 context->method_inst = NULL;
5193 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5196 int table = mono_metadata_token_table (token);
5197 int index = mono_metadata_token_index (token);
5198 MonoGenericContext context;
5200 *error = ResolveTokenError_Other;
5202 /* Validate token */
5203 if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) &&
5204 (table != MONO_TABLE_TYPESPEC)) {
5205 *error = ResolveTokenError_BadTable;
5209 if (image->dynamic) {
5210 if (type_args || method_args)
5211 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5212 return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5215 if ((index <= 0) || (index > image->tables [table].rows)) {
5216 *error = ResolveTokenError_OutOfRange;
5220 init_generic_context_from_args (&context, type_args, method_args);
5221 klass = mono_class_get_full (image, token, &context);
5224 return &klass->byval_arg;
5230 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5232 int table = mono_metadata_token_table (token);
5233 int index = mono_metadata_token_index (token);
5234 MonoGenericContext context;
5237 *error = ResolveTokenError_Other;
5239 /* Validate token */
5240 if ((table != MONO_TABLE_METHOD) && (table != MONO_TABLE_METHODSPEC) &&
5241 (table != MONO_TABLE_MEMBERREF)) {
5242 *error = ResolveTokenError_BadTable;
5246 if (image->dynamic) {
5247 if (type_args || method_args)
5248 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5249 /* FIXME: validate memberref token type */
5250 return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5253 if ((index <= 0) || (index > image->tables [table].rows)) {
5254 *error = ResolveTokenError_OutOfRange;
5257 if ((table == MONO_TABLE_MEMBERREF) && (!mono_metadata_memberref_is_method (image, token))) {
5258 *error = ResolveTokenError_BadTable;
5262 init_generic_context_from_args (&context, type_args, method_args);
5263 method = mono_get_method_full (image, token, NULL, &context);
5269 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
5271 int index = mono_metadata_token_index (token);
5273 *error = ResolveTokenError_Other;
5275 /* Validate token */
5276 if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
5277 *error = ResolveTokenError_BadTable;
5282 return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5284 if ((index <= 0) || (index >= image->heap_us.size)) {
5285 *error = ResolveTokenError_OutOfRange;
5289 /* FIXME: What to do if the index points into the middle of a string ? */
5291 return mono_ldstr (mono_domain_get (), image, index);
5294 static MonoClassField*
5295 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5298 int table = mono_metadata_token_table (token);
5299 int index = mono_metadata_token_index (token);
5300 MonoGenericContext context;
5301 MonoClassField *field;
5303 *error = ResolveTokenError_Other;
5305 /* Validate token */
5306 if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
5307 *error = ResolveTokenError_BadTable;
5311 if (image->dynamic) {
5312 if (type_args || method_args)
5313 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5314 /* FIXME: validate memberref token type */
5315 return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5318 if ((index <= 0) || (index > image->tables [table].rows)) {
5319 *error = ResolveTokenError_OutOfRange;
5322 if ((table == MONO_TABLE_MEMBERREF) && (mono_metadata_memberref_is_method (image, token))) {
5323 *error = ResolveTokenError_BadTable;
5327 init_generic_context_from_args (&context, type_args, method_args);
5328 field = mono_field_from_token (image, token, &klass, &context);
5335 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5337 int table = mono_metadata_token_table (token);
5339 *error = ResolveTokenError_Other;
5342 case MONO_TABLE_TYPEDEF:
5343 case MONO_TABLE_TYPEREF:
5344 case MONO_TABLE_TYPESPEC: {
5345 MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, type_args, method_args, error);
5347 return (MonoObject*)mono_type_get_object (mono_domain_get (), t);
5351 case MONO_TABLE_METHOD:
5352 case MONO_TABLE_METHODSPEC: {
5353 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5355 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
5359 case MONO_TABLE_FIELD: {
5360 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5362 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
5366 case MONO_TABLE_MEMBERREF:
5367 if (mono_metadata_memberref_is_method (image, token)) {
5368 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5370 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
5375 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5377 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
5384 *error = ResolveTokenError_BadTable;
5391 ves_icall_System_Reflection_Module_ResolveSignature (MonoImage *image, guint32 token, MonoResolveTokenError *error)
5393 int table = mono_metadata_token_table (token);
5394 int idx = mono_metadata_token_index (token);
5395 MonoTableInfo *tables = image->tables;
5400 *error = ResolveTokenError_OutOfRange;
5402 /* FIXME: Support other tables ? */
5403 if (table != MONO_TABLE_STANDALONESIG)
5409 if ((idx == 0) || (idx > tables [MONO_TABLE_STANDALONESIG].rows))
5412 sig = mono_metadata_decode_row_col (&tables [MONO_TABLE_STANDALONESIG], idx - 1, 0);
5414 ptr = mono_metadata_blob_heap (image, sig);
5415 len = mono_metadata_decode_blob_size (ptr, &ptr);
5417 res = mono_array_new (mono_domain_get (), mono_defaults.byte_class, len);
5418 memcpy (mono_array_addr (res, guint8, 0), ptr, len);
5422 static MonoReflectionType*
5423 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
5426 int isbyref = 0, rank;
5427 char *str = mono_string_to_utf8 (smodifiers);
5430 MONO_ARCH_SAVE_REGS;
5432 klass = mono_class_from_mono_type (tb->type.type);
5434 /* logic taken from mono_reflection_parse_type(): keep in sync */
5438 if (isbyref) { /* only one level allowed by the spec */
5445 return mono_type_get_object (mono_object_domain (tb), &klass->this_arg);
5448 klass = mono_ptr_class_get (&klass->byval_arg);
5449 mono_class_init (klass);
5460 else if (*p != '*') { /* '*' means unknown lower bound */
5471 klass = mono_array_class_get (klass, rank);
5472 mono_class_init (klass);
5479 return mono_type_get_object (mono_object_domain (tb), &klass->byval_arg);
5483 ves_icall_Type_IsArrayImpl (MonoReflectionType *t)
5488 MONO_ARCH_SAVE_REGS;
5491 res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
5496 static MonoReflectionType *
5497 ves_icall_Type_make_array_type (MonoReflectionType *type, int rank)
5499 MonoClass *klass, *aklass;
5501 MONO_ARCH_SAVE_REGS;
5503 klass = mono_class_from_mono_type (type->type);
5504 aklass = mono_array_class_get (klass, rank);
5506 return mono_type_get_object (mono_object_domain (type), &aklass->byval_arg);
5509 static MonoReflectionType *
5510 ves_icall_Type_make_byref_type (MonoReflectionType *type)
5514 MONO_ARCH_SAVE_REGS;
5516 klass = mono_class_from_mono_type (type->type);
5518 return mono_type_get_object (mono_object_domain (type), &klass->this_arg);
5521 static MonoReflectionType *
5522 ves_icall_Type_MakePointerType (MonoReflectionType *type)
5526 MONO_ARCH_SAVE_REGS;
5528 pklass = mono_ptr_class_get (type->type);
5530 return mono_type_get_object (mono_object_domain (type), &pklass->byval_arg);
5534 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
5535 MonoReflectionMethod *info)
5537 MonoClass *delegate_class = mono_class_from_mono_type (type->type);
5538 MonoObject *delegate;
5541 MONO_ARCH_SAVE_REGS;
5543 mono_assert (delegate_class->parent == mono_defaults.multicastdelegate_class);
5545 delegate = mono_object_new (mono_object_domain (type), delegate_class);
5547 if (info->method->dynamic)
5548 /* Creating a trampoline would leak memory */
5549 func = mono_compile_method (info->method);
5551 func = mono_create_ftnptr (mono_domain_get (), mono_runtime_create_jump_trampoline (mono_domain_get (), info->method, TRUE));
5553 mono_delegate_ctor (delegate, target, func);
5559 ves_icall_System_Delegate_SetMulticastInvoke (MonoDelegate *this)
5561 /* Reset the invoke impl to the default one */
5562 this->invoke_impl = mono_runtime_create_delegate_trampoline (this->object.vtable->klass);
5566 * Magic number to convert a time which is relative to
5567 * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
5569 #define EPOCH_ADJUST ((guint64)62135596800LL)
5572 * Magic number to convert FILETIME base Jan 1, 1601 to DateTime - base Jan, 1, 0001
5574 #define FILETIME_ADJUST ((guint64)504911232000000000LL)
5577 * This returns Now in UTC
5580 ves_icall_System_DateTime_GetNow (void)
5582 #ifdef PLATFORM_WIN32
5586 GetSystemTime (&st);
5587 SystemTimeToFileTime (&st, &ft);
5588 return (gint64) FILETIME_ADJUST + ((((gint64)ft.dwHighDateTime)<<32) | ft.dwLowDateTime);
5590 /* FIXME: put this in io-layer and call it GetLocalTime */
5594 MONO_ARCH_SAVE_REGS;
5596 if (gettimeofday (&tv, NULL) == 0) {
5597 res = (((gint64)tv.tv_sec + EPOCH_ADJUST)* 1000000 + tv.tv_usec)*10;
5600 /* fixme: raise exception */
5605 #ifdef PLATFORM_WIN32
5606 /* convert a SYSTEMTIME which is of the form "last thursday in october" to a real date */
5608 convert_to_absolute_date(SYSTEMTIME *date)
5610 #define IS_LEAP(y) ((y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0))
5611 static int days_in_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5612 static int leap_days_in_month[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5613 /* from the calendar FAQ */
5614 int a = (14 - date->wMonth) / 12;
5615 int y = date->wYear - a;
5616 int m = date->wMonth + 12 * a - 2;
5617 int d = (1 + y + y/4 - y/100 + y/400 + (31*m)/12) % 7;
5619 /* d is now the day of the week for the first of the month (0 == Sunday) */
5621 int day_of_week = date->wDayOfWeek;
5623 /* set day_in_month to the first day in the month which falls on day_of_week */
5624 int day_in_month = 1 + (day_of_week - d);
5625 if (day_in_month <= 0)
5628 /* wDay is 1 for first weekday in month, 2 for 2nd ... 5 means last - so work that out allowing for days in the month */
5629 date->wDay = day_in_month + (date->wDay - 1) * 7;
5630 if (date->wDay > (IS_LEAP(date->wYear) ? leap_days_in_month[date->wMonth - 1] : days_in_month[date->wMonth - 1]))
5635 #ifndef PLATFORM_WIN32
5637 * Return's the offset from GMT of a local time.
5639 * tm is a local time
5640 * t is the same local time as seconds.
5643 gmt_offset(struct tm *tm, time_t t)
5645 #if defined (HAVE_TM_GMTOFF)
5646 return tm->tm_gmtoff;
5651 g.tm_isdst = tm->tm_isdst;
5653 return (int)difftime(t, t2);
5658 * This is heavily based on zdump.c from glibc 2.2.
5660 * * data[0]: start of daylight saving time (in DateTime ticks).
5661 * * data[1]: end of daylight saving time (in DateTime ticks).
5662 * * data[2]: utcoffset (in TimeSpan ticks).
5663 * * data[3]: additional offset when daylight saving (in TimeSpan ticks).
5664 * * name[0]: name of this timezone when not daylight saving.
5665 * * name[1]: name of this timezone when daylight saving.
5667 * FIXME: This only works with "standard" Unix dates (years between 1900 and 2100) while
5668 * the class library allows years between 1 and 9999.
5670 * Returns true on success and zero on failure.
5673 ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year, MonoArray **data, MonoArray **names)
5675 #ifndef PLATFORM_WIN32
5676 MonoDomain *domain = mono_domain_get ();
5677 struct tm start, tt;
5681 int is_daylight = 0, day;
5684 MONO_ARCH_SAVE_REGS;
5686 MONO_CHECK_ARG_NULL (data);
5687 MONO_CHECK_ARG_NULL (names);
5689 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5690 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5693 * no info is better than crashing: we'll need our own tz data
5694 * to make this work properly, anyway. The range is probably
5695 * reduced to 1970 .. 2037 because that is what mktime is
5696 * guaranteed to support (we get into an infinite loop
5700 memset (&start, 0, sizeof (start));
5703 start.tm_year = year-1900;
5705 t = mktime (&start);
5707 if ((year < 1970) || (year > 2037) || (t == -1)) {
5709 tt = *localtime (&t);
5710 strftime (tzone, sizeof (tzone), "%Z", &tt);
5711 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5712 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5716 gmtoff = gmt_offset (&start, t);
5718 /* For each day of the year, calculate the tm_gmtoff. */
5719 for (day = 0; day < 365; day++) {
5722 tt = *localtime (&t);
5724 /* Daylight saving starts or ends here. */
5725 if (gmt_offset (&tt, t) != gmtoff) {
5729 /* Try to find the exact hour when daylight saving starts/ends. */
5733 tt1 = *localtime (&t1);
5734 } while (gmt_offset (&tt1, t1) != gmtoff);
5736 /* Try to find the exact minute when daylight saving starts/ends. */
5739 tt1 = *localtime (&t1);
5740 } while (gmt_offset (&tt1, t1) == gmtoff);
5742 strftime (tzone, sizeof (tzone), "%Z", &tt);
5744 /* Write data, if we're already in daylight saving, we're done. */
5746 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5747 mono_array_set ((*data), gint64, 1, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
5750 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5751 mono_array_set ((*data), gint64, 0, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
5755 /* This is only set once when we enter daylight saving. */
5756 mono_array_set ((*data), gint64, 2, (gint64)gmtoff * 10000000L);
5757 mono_array_set ((*data), gint64, 3, (gint64)(gmt_offset (&tt, t) - gmtoff) * 10000000L);
5759 gmtoff = gmt_offset (&tt, t);
5764 strftime (tzone, sizeof (tzone), "%Z", &tt);
5765 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5766 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5767 mono_array_set ((*data), gint64, 0, 0);
5768 mono_array_set ((*data), gint64, 1, 0);
5769 mono_array_set ((*data), gint64, 2, (gint64) gmtoff * 10000000L);
5770 mono_array_set ((*data), gint64, 3, 0);
5775 MonoDomain *domain = mono_domain_get ();
5776 TIME_ZONE_INFORMATION tz_info;
5781 tz_id = GetTimeZoneInformation (&tz_info);
5782 if (tz_id == TIME_ZONE_ID_INVALID)
5785 MONO_CHECK_ARG_NULL (data);
5786 MONO_CHECK_ARG_NULL (names);
5788 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5789 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5791 for (i = 0; i < 32; ++i)
5792 if (!tz_info.DaylightName [i])
5794 mono_array_setref ((*names), 1, mono_string_new_utf16 (domain, tz_info.DaylightName, i));
5795 for (i = 0; i < 32; ++i)
5796 if (!tz_info.StandardName [i])
5798 mono_array_setref ((*names), 0, mono_string_new_utf16 (domain, tz_info.StandardName, i));
5800 if ((year <= 1601) || (year > 30827)) {
5802 * According to MSDN, the MS time functions can't handle dates outside
5808 /* even if the timezone has no daylight savings it may have Bias (e.g. GMT+13 it seems) */
5809 if (tz_id != TIME_ZONE_ID_UNKNOWN) {
5810 tz_info.StandardDate.wYear = year;
5811 convert_to_absolute_date(&tz_info.StandardDate);
5812 err = SystemTimeToFileTime (&tz_info.StandardDate, &ft);
5817 mono_array_set ((*data), gint64, 1, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
5818 tz_info.DaylightDate.wYear = year;
5819 convert_to_absolute_date(&tz_info.DaylightDate);
5820 err = SystemTimeToFileTime (&tz_info.DaylightDate, &ft);
5825 mono_array_set ((*data), gint64, 0, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
5827 mono_array_set ((*data), gint64, 2, (tz_info.Bias + tz_info.StandardBias) * -600000000LL);
5828 mono_array_set ((*data), gint64, 3, (tz_info.DaylightBias - tz_info.StandardBias) * -600000000LL);
5835 ves_icall_System_Object_obj_address (MonoObject *this)
5837 MONO_ARCH_SAVE_REGS;
5844 static inline gint32
5845 mono_array_get_byte_length (MonoArray *array)
5851 klass = array->obj.vtable->klass;
5853 if (array->bounds == NULL)
5854 length = array->max_length;
5857 for (i = 0; i < klass->rank; ++ i)
5858 length *= array->bounds [i].length;
5861 switch (klass->element_class->byval_arg.type) {
5864 case MONO_TYPE_BOOLEAN:
5868 case MONO_TYPE_CHAR:
5876 return length * sizeof (gpointer);
5887 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array)
5889 MONO_ARCH_SAVE_REGS;
5891 return mono_array_get_byte_length (array);
5895 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx)
5897 MONO_ARCH_SAVE_REGS;
5899 return mono_array_get (array, gint8, idx);
5903 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value)
5905 MONO_ARCH_SAVE_REGS;
5907 mono_array_set (array, gint8, idx, value);
5911 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count)
5913 guint8 *src_buf, *dest_buf;
5915 MONO_ARCH_SAVE_REGS;
5917 /* watch out for integer overflow */
5918 if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count))
5921 src_buf = (guint8 *)src->vector + src_offset;
5922 dest_buf = (guint8 *)dest->vector + dest_offset;
5925 memcpy (dest_buf, src_buf, count);
5927 memmove (dest_buf, src_buf, count); /* Source and dest are the same array */
5933 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this, MonoString *class_name)
5935 MonoDomain *domain = mono_object_domain (this);
5937 MonoRealProxy *rp = ((MonoRealProxy *)this);
5938 MonoTransparentProxy *tp;
5942 MONO_ARCH_SAVE_REGS;
5944 res = mono_object_new (domain, mono_defaults.transparent_proxy_class);
5945 tp = (MonoTransparentProxy*) res;
5947 MONO_OBJECT_SETREF (tp, rp, rp);
5948 type = ((MonoReflectionType *)rp->class_to_proxy)->type;
5949 klass = mono_class_from_mono_type (type);
5951 tp->custom_type_info = (mono_object_isinst (this, mono_defaults.iremotingtypeinfo_class) != NULL);
5952 tp->remote_class = mono_remote_class (domain, class_name, klass);
5954 res->vtable = mono_remote_class_vtable (domain, tp->remote_class, rp);
5958 static MonoReflectionType *
5959 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
5961 return mono_type_get_object (mono_object_domain (tp), &tp->remote_class->proxy_class->byval_arg);
5964 /* System.Environment */
5967 ves_icall_System_Environment_get_MachineName (void)
5969 #if defined (PLATFORM_WIN32)
5974 len = MAX_COMPUTERNAME_LENGTH + 1;
5975 buf = g_new (gunichar2, len);
5978 if (GetComputerName (buf, (PDWORD) &len))
5979 result = mono_string_new_utf16 (mono_domain_get (), buf, len);
5987 if (gethostname (buf, sizeof (buf)) == 0)
5988 result = mono_string_new (mono_domain_get (), buf);
5997 ves_icall_System_Environment_get_Platform (void)
5999 MONO_ARCH_SAVE_REGS;
6001 #if defined (PLATFORM_WIN32)
6011 ves_icall_System_Environment_get_NewLine (void)
6013 MONO_ARCH_SAVE_REGS;
6015 #if defined (PLATFORM_WIN32)
6016 return mono_string_new (mono_domain_get (), "\r\n");
6018 return mono_string_new (mono_domain_get (), "\n");
6023 ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name)
6028 MONO_ARCH_SAVE_REGS;
6033 utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
6034 value = g_getenv (utf8_name);
6041 return mono_string_new (mono_domain_get (), value);
6045 * There is no standard way to get at environ.
6048 #ifndef __MINGW32_VERSION
6055 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
6057 #ifdef PLATFORM_WIN32
6066 env_strings = GetEnvironmentStrings();
6069 env_string = env_strings;
6070 while (*env_string != '\0') {
6071 /* weird case that MS seems to skip */
6072 if (*env_string != '=')
6074 while (*env_string != '\0')
6080 domain = mono_domain_get ();
6081 names = mono_array_new (domain, mono_defaults.string_class, n);
6085 env_string = env_strings;
6086 while (*env_string != '\0') {
6087 /* weird case that MS seems to skip */
6088 if (*env_string != '=') {
6089 equal_str = wcschr(env_string, '=');
6090 g_assert(equal_str);
6091 str = mono_string_new_utf16 (domain, env_string, equal_str-env_string);
6092 mono_array_setref (names, n, str);
6095 while (*env_string != '\0')
6100 FreeEnvironmentStrings (env_strings);
6112 MONO_ARCH_SAVE_REGS;
6115 for (e = environ; *e != 0; ++ e)
6118 domain = mono_domain_get ();
6119 names = mono_array_new (domain, mono_defaults.string_class, n);
6122 for (e = environ; *e != 0; ++ e) {
6123 parts = g_strsplit (*e, "=", 2);
6125 str = mono_string_new (domain, *parts);
6126 mono_array_setref (names, n, str);
6139 * If your platform lacks setenv/unsetenv, you must upgrade your glib.
6141 #if !GLIB_CHECK_VERSION(2,4,0)
6142 #define g_setenv(a,b,c) setenv(a,b,c)
6143 #define g_unsetenv(a) unsetenv(a)
6147 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
6149 #ifdef PLATFORM_WIN32
6150 gunichar2 *utf16_name, *utf16_value;
6152 gchar *utf8_name, *utf8_value;
6155 MONO_ARCH_SAVE_REGS;
6157 #ifdef PLATFORM_WIN32
6158 utf16_name = mono_string_to_utf16 (name);
6159 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
6160 SetEnvironmentVariable (utf16_name, NULL);
6161 g_free (utf16_name);
6165 utf16_value = mono_string_to_utf16 (value);
6167 SetEnvironmentVariable (utf16_name, utf16_value);
6169 g_free (utf16_name);
6170 g_free (utf16_value);
6172 utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
6174 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
6175 g_unsetenv (utf8_name);
6180 utf8_value = mono_string_to_utf8 (value);
6181 g_setenv (utf8_name, utf8_value, TRUE);
6184 g_free (utf8_value);
6189 * Returns: the number of milliseconds elapsed since the system started.
6192 ves_icall_System_Environment_get_TickCount (void)
6194 return GetTickCount ();
6199 ves_icall_System_Environment_Exit (int result)
6201 MONO_ARCH_SAVE_REGS;
6203 if (!mono_threads_set_shutting_down (TRUE))
6206 mono_runtime_set_shutting_down ();
6208 /* Suspend all managed threads since the runtime is going away */
6209 mono_thread_suspend_all_other_threads ();
6211 mono_runtime_quit ();
6213 /* we may need to do some cleanup here... */
6218 ves_icall_System_Environment_GetGacPath (void)
6220 return mono_string_new (mono_domain_get (), mono_assembly_getrootdir ());
6224 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
6226 #if defined (PLATFORM_WIN32)
6227 #ifndef CSIDL_FLAG_CREATE
6228 #define CSIDL_FLAG_CREATE 0x8000
6231 WCHAR path [MAX_PATH];
6232 /* Create directory if no existing */
6233 if (SUCCEEDED (SHGetFolderPathW (NULL, folder | CSIDL_FLAG_CREATE, NULL, 0, path))) {
6237 return mono_string_new_utf16 (mono_domain_get (), path, len);
6240 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
6242 return mono_string_new (mono_domain_get (), "");
6246 ves_icall_System_Environment_GetLogicalDrives (void)
6248 gunichar2 buf [128], *ptr, *dname;
6250 gint initial_size = 127, size = 128;
6253 MonoString *drivestr;
6254 MonoDomain *domain = mono_domain_get ();
6257 MONO_ARCH_SAVE_REGS;
6262 while (size > initial_size) {
6263 size = GetLogicalDriveStrings (initial_size, ptr);
6264 if (size > initial_size) {
6267 ptr = g_malloc0 ((size + 1) * sizeof (gunichar2));
6268 initial_size = size;
6282 result = mono_array_new (domain, mono_defaults.string_class, ndrives);
6287 while (*u16) { u16++; len ++; }
6288 drivestr = mono_string_new_utf16 (domain, dname, len);
6289 mono_array_setref (result, ndrives++, drivestr);
6300 ves_icall_System_Environment_InternalGetHome (void)
6302 MONO_ARCH_SAVE_REGS;
6304 return mono_string_new (mono_domain_get (), g_get_home_dir ());
6307 static const char *encodings [] = {
6309 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
6310 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
6311 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
6313 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
6314 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
6315 "x_unicode_2_0_utf_7",
6317 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
6318 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
6320 "utf_16", "UTF_16LE", "ucs_2", "unicode",
6323 "unicodefffe", "utf_16be",
6330 * Returns the internal codepage, if the value of "int_code_page" is
6331 * 1 at entry, and we can not compute a suitable code page number,
6332 * returns the code page as a string
6335 ves_icall_System_Text_Encoding_InternalCodePage (gint32 *int_code_page)
6340 char *codepage = NULL;
6342 int want_name = *int_code_page;
6345 *int_code_page = -1;
6346 MONO_ARCH_SAVE_REGS;
6348 g_get_charset (&cset);
6349 c = codepage = strdup (cset);
6350 for (c = codepage; *c; c++){
6351 if (isascii (*c) && isalpha (*c))
6356 /* g_print ("charset: %s\n", cset); */
6358 /* handle some common aliases */
6361 for (i = 0; p != 0; ){
6362 if ((gssize) p < 7){
6364 p = encodings [++i];
6367 if (strcmp (p, codepage) == 0){
6368 *int_code_page = code;
6371 p = encodings [++i];
6374 if (strstr (codepage, "utf_8") != NULL)
6375 *int_code_page |= 0x10000000;
6378 if (want_name && *int_code_page == -1)
6379 return mono_string_new (mono_domain_get (), cset);
6385 ves_icall_System_Environment_get_HasShutdownStarted (void)
6387 if (mono_runtime_is_shutting_down ())
6390 if (mono_domain_is_unloading (mono_domain_get ()))
6397 ves_icall_MonoMethodMessage_InitMessage (MonoMethodMessage *this,
6398 MonoReflectionMethod *method,
6399 MonoArray *out_args)
6401 MONO_ARCH_SAVE_REGS;
6403 mono_message_init (mono_object_domain (this), this, method, out_args);
6407 ves_icall_IsTransparentProxy (MonoObject *proxy)
6409 MONO_ARCH_SAVE_REGS;
6414 if (proxy->vtable->klass == mono_defaults.transparent_proxy_class)
6420 static MonoReflectionMethod *
6421 ves_icall_Remoting_RemotingServices_GetVirtualMethod (
6422 MonoReflectionType *rtype, MonoReflectionMethod *rmethod)
6426 MonoMethod **vtable;
6427 MonoMethod *res = NULL;
6429 MONO_CHECK_ARG_NULL (rtype);
6430 MONO_CHECK_ARG_NULL (rmethod);
6432 method = rmethod->method;
6433 klass = mono_class_from_mono_type (rtype->type);
6435 if (MONO_CLASS_IS_INTERFACE (klass))
6438 if (method->flags & METHOD_ATTRIBUTE_STATIC)
6441 if ((method->flags & METHOD_ATTRIBUTE_FINAL) || !(method->flags & METHOD_ATTRIBUTE_VIRTUAL)) {
6442 if (klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE))
6448 mono_class_setup_vtable (klass);
6449 vtable = klass->vtable;
6451 if (method->klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
6452 int offs = mono_class_interface_offset (klass, method->klass);
6454 res = vtable [offs + method->slot];
6456 if (!(klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE)))
6459 if (method->slot != -1)
6460 res = vtable [method->slot];
6466 return mono_method_get_object (mono_domain_get (), res, NULL);
6470 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6475 MONO_ARCH_SAVE_REGS;
6477 klass = mono_class_from_mono_type (type->type);
6478 vtable = mono_class_vtable (mono_domain_get (), klass);
6480 if (enable) vtable->remote = 1;
6481 else vtable->remote = 0;
6485 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type)
6490 MONO_ARCH_SAVE_REGS;
6492 domain = mono_object_domain (type);
6493 klass = mono_class_from_mono_type (type->type);
6495 if (klass->rank >= 1) {
6496 g_assert (klass->rank == 1);
6497 return (MonoObject *) mono_array_new (domain, klass->element_class, 0);
6499 /* Bypass remoting object creation check */
6500 return mono_object_new_alloc_specific (mono_class_vtable (domain, klass));
6505 ves_icall_System_IO_get_temp_path (void)
6507 MONO_ARCH_SAVE_REGS;
6509 return mono_string_new (mono_domain_get (), g_get_tmp_dir ());
6513 ves_icall_RuntimeMethod_GetFunctionPointer (MonoMethod *method)
6515 MONO_ARCH_SAVE_REGS;
6517 return mono_compile_method (method);
6521 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
6526 MONO_ARCH_SAVE_REGS;
6528 path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
6530 #if defined (PLATFORM_WIN32)
6531 /* Avoid mixing '/' and '\\' */
6534 for (i = strlen (path) - 1; i >= 0; i--)
6535 if (path [i] == '/')
6539 mcpath = mono_string_new (mono_domain_get (), path);
6546 get_bundled_machine_config (void)
6548 const gchar *machine_config;
6550 MONO_ARCH_SAVE_REGS;
6552 machine_config = mono_get_machine_config ();
6554 if (!machine_config)
6557 return mono_string_new (mono_domain_get (), machine_config);
6561 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
6566 MONO_ARCH_SAVE_REGS;
6568 path = g_path_get_dirname (mono_get_config_dir ());
6570 #if defined (PLATFORM_WIN32)
6571 /* Avoid mixing '/' and '\\' */
6574 for (i = strlen (path) - 1; i >= 0; i--)
6575 if (path [i] == '/')
6579 ipath = mono_string_new (mono_domain_get (), path);
6586 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
6588 #if defined (PLATFORM_WIN32)
6589 OutputDebugString (mono_string_chars (message));
6591 g_warning ("WriteWindowsDebugString called and PLATFORM_WIN32 not defined!\n");
6595 /* Only used for value types */
6597 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
6602 MONO_ARCH_SAVE_REGS;
6604 domain = mono_object_domain (type);
6605 klass = mono_class_from_mono_type (type->type);
6607 if (mono_class_is_nullable (klass))
6608 /* No arguments -> null */
6611 return mono_object_new (domain, klass);
6614 static MonoReflectionMethod *
6615 ves_icall_MonoMethod_get_base_definition (MonoReflectionMethod *m)
6617 MonoClass *klass, *parent;
6618 MonoMethod *method = m->method;
6619 MonoMethod *result = NULL;
6621 MONO_ARCH_SAVE_REGS;
6623 if (method->klass == NULL)
6626 if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
6627 MONO_CLASS_IS_INTERFACE (method->klass) ||
6628 method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
6631 klass = method->klass;
6632 if (klass->generic_class)
6633 klass = klass->generic_class->container_class;
6635 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
6636 for (parent = klass->parent; parent != NULL; parent = parent->parent) {
6637 mono_class_setup_vtable (parent);
6638 if (parent->vtable_size <= method->slot)
6643 if (klass == method->klass)
6646 result = klass->vtable [method->slot];
6647 if (result == NULL) {
6648 /* It is an abstract method */
6649 gpointer iter = NULL;
6650 while ((result = mono_class_get_methods (klass, &iter)))
6651 if (result->slot == method->slot)
6658 return mono_method_get_object (mono_domain_get (), result, NULL);
6662 ves_icall_MonoMethod_get_name (MonoReflectionMethod *m)
6664 MonoMethod *method = m->method;
6666 MONO_OBJECT_SETREF (m, name, mono_string_new (mono_object_domain (m), method->name));
6671 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
6673 MONO_ARCH_SAVE_REGS;
6675 iter->sig = *(MonoMethodSignature**)argsp;
6677 g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
6678 g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
6681 /* FIXME: it's not documented what start is exactly... */
6685 guint32 i, arg_size;
6687 iter->args = argsp + sizeof (gpointer);
6688 #ifndef MONO_ARCH_REGPARMS
6689 for (i = 0; i < iter->sig->sentinelpos; ++i) {
6690 arg_size = mono_type_stack_size (iter->sig->params [i], &align);
6691 iter->args = (char*)iter->args + arg_size;
6695 iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
6697 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
6701 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
6703 guint32 i, arg_size;
6706 MONO_ARCH_SAVE_REGS;
6708 i = iter->sig->sentinelpos + iter->next_arg;
6710 g_assert (i < iter->sig->param_count);
6712 res.type = iter->sig->params [i];
6713 res.klass = mono_class_from_mono_type (res.type);
6714 /* FIXME: endianess issue... */
6715 res.value = iter->args;
6716 arg_size = mono_type_stack_size (res.type, &align);
6717 iter->args = (char*)iter->args + arg_size;
6720 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6726 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
6728 guint32 i, arg_size;
6731 MONO_ARCH_SAVE_REGS;
6733 i = iter->sig->sentinelpos + iter->next_arg;
6735 g_assert (i < iter->sig->param_count);
6737 while (i < iter->sig->param_count) {
6738 if (!mono_metadata_type_equal (type, iter->sig->params [i]))
6740 res.type = iter->sig->params [i];
6741 res.klass = mono_class_from_mono_type (res.type);
6742 /* FIXME: endianess issue... */
6743 res.value = iter->args;
6744 arg_size = mono_type_stack_size (res.type, &align);
6745 iter->args = (char*)iter->args + arg_size;
6747 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6750 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
6759 mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
6762 MONO_ARCH_SAVE_REGS;
6764 i = iter->sig->sentinelpos + iter->next_arg;
6766 g_assert (i < iter->sig->param_count);
6768 return iter->sig->params [i];
6772 mono_TypedReference_ToObject (MonoTypedRef tref)
6774 MONO_ARCH_SAVE_REGS;
6776 if (MONO_TYPE_IS_REFERENCE (tref.type)) {
6777 MonoObject** objp = tref.value;
6781 return mono_value_box (mono_domain_get (), tref.klass, tref.value);
6785 mono_TypedReference_ToObjectInternal (MonoType *type, gpointer value, MonoClass *klass)
6787 MONO_ARCH_SAVE_REGS;
6789 if (MONO_TYPE_IS_REFERENCE (type)) {
6790 MonoObject** objp = value;
6794 return mono_value_box (mono_domain_get (), klass, value);
6798 prelink_method (MonoMethod *method)
6800 const char *exc_class, *exc_arg;
6801 if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
6803 mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
6805 mono_raise_exception(
6806 mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg ) );
6808 /* create the wrapper, too? */
6812 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
6814 MONO_ARCH_SAVE_REGS;
6815 prelink_method (method->method);
6819 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
6821 MonoClass *klass = mono_class_from_mono_type (type->type);
6823 gpointer iter = NULL;
6824 MONO_ARCH_SAVE_REGS;
6826 while ((m = mono_class_get_methods (klass, &iter)))
6830 /* These parameters are "readonly" in corlib/System/NumberFormatter.cs */
6832 ves_icall_System_NumberFormatter_GetFormatterTables (guint64 const **mantissas,
6833 gint32 const **exponents,
6834 gunichar2 const **digitLowerTable,
6835 gunichar2 const **digitUpperTable,
6836 gint64 const **tenPowersList,
6837 gint32 const **decHexDigits)
6839 *mantissas = Formatter_MantissaBitsTable;
6840 *exponents = Formatter_TensExponentTable;
6841 *digitLowerTable = Formatter_DigitLowerTable;
6842 *digitUpperTable = Formatter_DigitUpperTable;
6843 *tenPowersList = Formatter_TenPowersList;
6844 *decHexDigits = Formatter_DecHexDigits;
6847 /* These parameters are "readonly" in corlib/System/Char.cs */
6849 ves_icall_System_Char_GetDataTablePointers (guint8 const **category_data,
6850 guint8 const **numeric_data,
6851 gdouble const **numeric_data_values,
6852 guint16 const **to_lower_data_low,
6853 guint16 const **to_lower_data_high,
6854 guint16 const **to_upper_data_low,
6855 guint16 const **to_upper_data_high)
6857 *category_data = CategoryData;
6858 *numeric_data = NumericData;
6859 *numeric_data_values = NumericDataValues;
6860 *to_lower_data_low = ToLowerDataLow;
6861 *to_lower_data_high = ToLowerDataHigh;
6862 *to_upper_data_low = ToUpperDataLow;
6863 *to_upper_data_high = ToUpperDataHigh;
6867 ves_icall_MonoDebugger_GetMethodToken (MonoReflectionMethod *method)
6869 return method->method->token;
6873 * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
6874 * and avoid useless allocations.
6877 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional)
6881 for (i = 0; i < type->num_mods; ++i) {
6882 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
6887 res = mono_array_new (mono_domain_get (), mono_defaults.systemtype_class, count);
6889 for (i = 0; i < type->num_mods; ++i) {
6890 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
6891 MonoClass *klass = mono_class_get (image, type->modifiers [i].token);
6892 mono_array_setref (res, count, mono_type_get_object (mono_domain_get (), &klass->byval_arg));
6900 param_info_get_type_modifiers (MonoReflectionParameter *param, MonoBoolean optional)
6902 MonoType *type = param->ClassImpl->type;
6903 MonoReflectionMethod *method = (MonoReflectionMethod*)param->MemberImpl;
6904 MonoImage *image = method->method->klass->image;
6905 int pos = param->PositionImpl;
6906 MonoMethodSignature *sig = mono_method_signature (method->method);
6910 type = sig->params [pos];
6912 return type_array_from_modifiers (image, type, optional);
6916 get_property_type (MonoProperty *prop)
6918 MonoMethodSignature *sig;
6920 sig = mono_method_signature (prop->get);
6922 } else if (prop->set) {
6923 sig = mono_method_signature (prop->set);
6924 return sig->params [sig->param_count - 1];
6930 property_info_get_type_modifiers (MonoReflectionProperty *property, MonoBoolean optional)
6932 MonoType *type = get_property_type (property->property);
6933 MonoImage *image = property->klass->image;
6937 return type_array_from_modifiers (image, type, optional);
6941 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
6943 MonoCustomAttrInfo *cinfo;
6946 cinfo = mono_reflection_get_custom_attrs_info (obj);
6949 found = mono_custom_attrs_has_attr (cinfo, mono_class_from_mono_type (attr_type->type));
6951 mono_custom_attrs_free (cinfo);
6956 custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
6958 MonoArray *res = mono_reflection_get_custom_attrs_by_type (obj, attr_type ? mono_class_from_mono_type (attr_type->type) : NULL);
6960 if (mono_loader_get_last_error ()) {
6961 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
6962 g_assert_not_reached ();
6969 GCHandle_CheckCurrentDomain (guint32 gchandle)
6971 return mono_gchandle_is_in_domain (gchandle, mono_domain_get ());
6975 ves_icall_Mono_Runtime_GetDisplayName (void)
6977 static const char display_name_str [] = "Mono " VERSION;
6978 MonoString *display_name = mono_string_new (mono_domain_get (), display_name_str);
6979 return display_name;
6984 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
6985 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
6986 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 62, 128, 128, 128, 63,
6987 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 0, 128, 128,
6988 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
6989 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 128, 128, 128, 128, 128,
6990 128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
6991 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
6995 base64_to_byte_array (gunichar2 *start, gint ilength, MonoBoolean allowWhitespaceOnly)
7000 gunichar2 last, prev_last;
7008 last = prev_last = 0;
7009 for (i = 0; i < ilength; i++) {
7011 if (c >= sizeof (dbase64)) {
7012 exc = mono_exception_from_name_msg (mono_get_corlib (),
7013 "System", "FormatException",
7014 "Invalid character found.");
7015 mono_raise_exception (exc);
7016 } else if (isspace (c)) {
7024 olength = ilength - ignored;
7026 if (allowWhitespaceOnly && olength == 0) {
7027 return mono_array_new (mono_domain_get (), mono_defaults.byte_class, 0);
7030 if ((olength & 3) != 0 || olength <= 0) {
7031 exc = mono_exception_from_name_msg (mono_get_corlib (), "System",
7032 "FormatException", "Invalid length.");
7033 mono_raise_exception (exc);
7036 olength = (olength * 3) / 4;
7040 if (prev_last == '=')
7043 result = mono_array_new (mono_domain_get (), mono_defaults.byte_class, olength);
7044 res_ptr = mono_array_addr (result, guchar, 0);
7045 for (i = 0; i < ilength; ) {
7048 for (k = 0; k < 4 && i < ilength;) {
7054 if (((b [k] = dbase64 [c]) & 0x80) != 0) {
7055 exc = mono_exception_from_name_msg (mono_get_corlib (),
7056 "System", "FormatException",
7057 "Invalid character found.");
7058 mono_raise_exception (exc);
7063 *res_ptr++ = (b [0] << 2) | (b [1] >> 4);
7065 *res_ptr++ = (b [1] << 4) | (b [2] >> 2);
7067 *res_ptr++ = (b [2] << 6) | b [3];
7069 while (i < ilength && isspace (start [i]))
7077 InternalFromBase64String (MonoString *str, MonoBoolean allowWhitespaceOnly)
7079 MONO_ARCH_SAVE_REGS;
7081 return base64_to_byte_array (mono_string_chars (str),
7082 mono_string_length (str), allowWhitespaceOnly);
7086 InternalFromBase64CharArray (MonoArray *input, gint offset, gint length)
7088 MONO_ARCH_SAVE_REGS;
7090 return base64_to_byte_array (mono_array_addr (input, gunichar2, offset),
7094 #define ICALL_TYPE(id,name,first)
7095 #define ICALL(id,name,func) Icall_ ## id,
7098 #include "metadata/icall-def.h"
7104 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
7105 #define ICALL(id,name,func)
7107 #include "metadata/icall-def.h"
7113 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
7114 #define ICALL(id,name,func)
7116 guint16 first_icall;
7119 static const IcallTypeDesc
7120 icall_type_descs [] = {
7121 #include "metadata/icall-def.h"
7125 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
7128 #define ICALL_TYPE(id,name,first)
7131 #ifdef HAVE_ARRAY_ELEM_INIT
7132 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
7133 #define MSGSTRFIELD1(line) str##line
7135 static const struct msgstrtn_t {
7136 #define ICALL(id,name,func)
7138 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7139 #include "metadata/icall-def.h"
7141 } icall_type_names_str = {
7142 #define ICALL_TYPE(id,name,first) (name),
7143 #include "metadata/icall-def.h"
7146 static const guint16 icall_type_names_idx [] = {
7147 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
7148 #include "metadata/icall-def.h"
7151 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
7153 static const struct msgstr_t {
7155 #define ICALL_TYPE(id,name,first)
7156 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7157 #include "metadata/icall-def.h"
7159 } icall_names_str = {
7160 #define ICALL(id,name,func) (name),
7161 #include "metadata/icall-def.h"
7164 static const guint16 icall_names_idx [] = {
7165 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
7166 #include "metadata/icall-def.h"
7169 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
7175 #define ICALL_TYPE(id,name,first) name,
7176 #define ICALL(id,name,func)
7177 static const char* const
7178 icall_type_names [] = {
7179 #include "metadata/icall-def.h"
7183 #define icall_type_name_get(id) (icall_type_names [(id)])
7187 #define ICALL_TYPE(id,name,first)
7188 #define ICALL(id,name,func) name,
7189 static const char* const
7191 #include "metadata/icall-def.h"
7194 #define icall_name_get(id) icall_names [(id)]
7196 #endif /* !HAVE_ARRAY_ELEM_INIT */
7200 #define ICALL_TYPE(id,name,first)
7201 #define ICALL(id,name,func) func,
7202 static const gconstpointer
7203 icall_functions [] = {
7204 #include "metadata/icall-def.h"
7208 static GHashTable *icall_hash = NULL;
7209 static GHashTable *jit_icall_hash_name = NULL;
7210 static GHashTable *jit_icall_hash_addr = NULL;
7213 mono_icall_init (void)
7217 /* check that tables are sorted: disable in release */
7220 const char *prev_class = NULL;
7221 const char *prev_method;
7223 for (i = 0; i < Icall_type_num; ++i) {
7224 const IcallTypeDesc *desc;
7227 if (prev_class && strcmp (prev_class, icall_type_name_get (i)) >= 0)
7228 g_print ("class %s should come before class %s\n", icall_type_name_get (i), prev_class);
7229 prev_class = icall_type_name_get (i);
7230 desc = &icall_type_descs [i];
7231 num_icalls = icall_desc_num_icalls (desc);
7232 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
7233 for (j = 0; j < num_icalls; ++j) {
7234 const char *methodn = icall_name_get (desc->first_icall + j);
7235 if (prev_method && strcmp (prev_method, methodn) >= 0)
7236 g_print ("method %s should come before method %s\n", methodn, prev_method);
7237 prev_method = methodn;
7242 icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
7246 mono_icall_cleanup (void)
7248 g_hash_table_destroy (icall_hash);
7249 g_hash_table_destroy (jit_icall_hash_name);
7250 g_hash_table_destroy (jit_icall_hash_addr);
7254 mono_add_internal_call (const char *name, gconstpointer method)
7256 mono_loader_lock ();
7258 g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
7260 mono_loader_unlock ();
7263 #ifdef HAVE_ARRAY_ELEM_INIT
7265 compare_method_imap (const void *key, const void *elem)
7267 const char* method_name = (const char*)&icall_names_str + (*(guint16*)elem);
7268 return strcmp (key, method_name);
7272 find_method_icall (const IcallTypeDesc *imap, const char *name)
7274 const guint16 *nameslot = bsearch (name, icall_names_idx + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names_idx [0]), compare_method_imap);
7277 return (gpointer)icall_functions [(nameslot - &icall_names_idx [0])];
7281 compare_class_imap (const void *key, const void *elem)
7283 const char* class_name = (const char*)&icall_type_names_str + (*(guint16*)elem);
7284 return strcmp (key, class_name);
7287 static const IcallTypeDesc*
7288 find_class_icalls (const char *name)
7290 const guint16 *nameslot = bsearch (name, icall_type_names_idx, Icall_type_num, sizeof (icall_type_names_idx [0]), compare_class_imap);
7293 return &icall_type_descs [nameslot - &icall_type_names_idx [0]];
7298 compare_method_imap (const void *key, const void *elem)
7300 const char** method_name = (const char**)elem;
7301 return strcmp (key, *method_name);
7305 find_method_icall (const IcallTypeDesc *imap, const char *name)
7307 const char **nameslot = bsearch (name, icall_names + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names [0]), compare_method_imap);
7310 return (gpointer)icall_functions [(nameslot - icall_names)];
7314 compare_class_imap (const void *key, const void *elem)
7316 const char** class_name = (const char**)elem;
7317 return strcmp (key, *class_name);
7320 static const IcallTypeDesc*
7321 find_class_icalls (const char *name)
7323 const char **nameslot = bsearch (name, icall_type_names, Icall_type_num, sizeof (icall_type_names [0]), compare_class_imap);
7326 return &icall_type_descs [nameslot - icall_type_names];
7332 * we should probably export this as an helper (handle nested types).
7333 * Returns the number of chars written in buf.
7336 concat_class_name (char *buf, int bufsize, MonoClass *klass)
7338 int nspacelen, cnamelen;
7339 nspacelen = strlen (klass->name_space);
7340 cnamelen = strlen (klass->name);
7341 if (nspacelen + cnamelen + 2 > bufsize)
7344 memcpy (buf, klass->name_space, nspacelen);
7345 buf [nspacelen ++] = '.';
7347 memcpy (buf + nspacelen, klass->name, cnamelen);
7348 buf [nspacelen + cnamelen] = 0;
7349 return nspacelen + cnamelen;
7353 mono_lookup_internal_call (MonoMethod *method)
7358 int typelen = 0, mlen, siglen;
7360 const IcallTypeDesc *imap;
7362 g_assert (method != NULL);
7364 if (method->is_inflated)
7365 method = ((MonoMethodInflated *) method)->declaring;
7367 if (method->klass->nested_in) {
7368 int pos = concat_class_name (mname, sizeof (mname)-2, method->klass->nested_in);
7372 mname [pos++] = '/';
7375 typelen = concat_class_name (mname+pos, sizeof (mname)-pos-1, method->klass);
7381 typelen = concat_class_name (mname, sizeof (mname), method->klass);
7386 imap = find_class_icalls (mname);
7388 mname [typelen] = ':';
7389 mname [typelen + 1] = ':';
7391 mlen = strlen (method->name);
7392 memcpy (mname + typelen + 2, method->name, mlen);
7393 sigstart = mname + typelen + 2 + mlen;
7396 tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
7397 siglen = strlen (tmpsig);
7398 if (typelen + mlen + siglen + 6 > sizeof (mname))
7401 memcpy (sigstart + 1, tmpsig, siglen);
7402 sigstart [siglen + 1] = ')';
7403 sigstart [siglen + 2] = 0;
7406 mono_loader_lock ();
7408 res = g_hash_table_lookup (icall_hash, mname);
7410 mono_loader_unlock ();
7413 /* try without signature */
7415 res = g_hash_table_lookup (icall_hash, mname);
7417 mono_loader_unlock ();
7421 /* it wasn't found in the static call tables */
7423 mono_loader_unlock ();
7426 res = find_method_icall (imap, sigstart - mlen);
7428 mono_loader_unlock ();
7431 /* try _with_ signature */
7433 res = find_method_icall (imap, sigstart - mlen);
7435 mono_loader_unlock ();
7439 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname);
7440 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
7441 g_print ("The out of sync library is: %s\n", method->klass->image->name);
7442 g_print ("\nWhen you update one from cvs you need to update, compile and install\nthe other too.\n");
7443 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");
7444 g_print ("If you see other errors or faults after this message they are probably related\n");
7445 g_print ("and you need to fix your mono install first.\n");
7447 mono_loader_unlock ();
7453 type_from_typename (char *typename)
7455 MonoClass *klass = NULL; /* assignment to shut GCC warning up */
7457 if (!strcmp (typename, "int"))
7458 klass = mono_defaults.int_class;
7459 else if (!strcmp (typename, "ptr"))
7460 klass = mono_defaults.int_class;
7461 else if (!strcmp (typename, "void"))
7462 klass = mono_defaults.void_class;
7463 else if (!strcmp (typename, "int32"))
7464 klass = mono_defaults.int32_class;
7465 else if (!strcmp (typename, "uint32"))
7466 klass = mono_defaults.uint32_class;
7467 else if (!strcmp (typename, "int8"))
7468 klass = mono_defaults.sbyte_class;
7469 else if (!strcmp (typename, "uint8"))
7470 klass = mono_defaults.byte_class;
7471 else if (!strcmp (typename, "int16"))
7472 klass = mono_defaults.int16_class;
7473 else if (!strcmp (typename, "uint16"))
7474 klass = mono_defaults.uint16_class;
7475 else if (!strcmp (typename, "long"))
7476 klass = mono_defaults.int64_class;
7477 else if (!strcmp (typename, "ulong"))
7478 klass = mono_defaults.uint64_class;
7479 else if (!strcmp (typename, "float"))
7480 klass = mono_defaults.single_class;
7481 else if (!strcmp (typename, "double"))
7482 klass = mono_defaults.double_class;
7483 else if (!strcmp (typename, "object"))
7484 klass = mono_defaults.object_class;
7485 else if (!strcmp (typename, "obj"))
7486 klass = mono_defaults.object_class;
7489 g_assert_not_reached ();
7491 return &klass->byval_arg;
7494 MonoMethodSignature*
7495 mono_create_icall_signature (const char *sigstr)
7500 MonoMethodSignature *res;
7502 mono_loader_lock ();
7503 res = g_hash_table_lookup (mono_defaults.corlib->helper_signatures, sigstr);
7505 mono_loader_unlock ();
7509 parts = g_strsplit (sigstr, " ", 256);
7518 res = mono_metadata_signature_alloc (mono_defaults.corlib, len - 1);
7521 #ifdef PLATFORM_WIN32
7523 * Under windows, the default pinvoke calling convention is STDCALL but
7526 res->call_convention = MONO_CALL_C;
7529 res->ret = type_from_typename (parts [0]);
7530 for (i = 1; i < len; ++i) {
7531 res->params [i - 1] = type_from_typename (parts [i]);
7536 g_hash_table_insert (mono_defaults.corlib->helper_signatures, (gpointer)sigstr, res);
7538 mono_loader_unlock ();
7544 mono_find_jit_icall_by_name (const char *name)
7546 MonoJitICallInfo *info;
7547 g_assert (jit_icall_hash_name);
7549 mono_loader_lock ();
7550 info = g_hash_table_lookup (jit_icall_hash_name, name);
7551 mono_loader_unlock ();
7556 mono_find_jit_icall_by_addr (gconstpointer addr)
7558 MonoJitICallInfo *info;
7559 g_assert (jit_icall_hash_addr);
7561 mono_loader_lock ();
7562 info = g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
7563 mono_loader_unlock ();
7569 mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
7571 mono_loader_lock ();
7572 g_hash_table_insert (jit_icall_hash_addr, (gpointer)wrapper, info);
7573 mono_loader_unlock ();
7577 mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
7579 MonoJitICallInfo *info;
7584 mono_loader_lock ();
7586 if (!jit_icall_hash_name) {
7587 jit_icall_hash_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
7588 jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
7591 if (g_hash_table_lookup (jit_icall_hash_name, name)) {
7592 g_warning ("jit icall already defined \"%s\"\n", name);
7593 g_assert_not_reached ();
7596 info = g_new0 (MonoJitICallInfo, 1);
7603 info->wrapper = func;
7605 info->wrapper = NULL;
7608 g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
7609 g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
7611 mono_loader_unlock ();