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/utils/mono-membar.h"
28 #include <mono/metadata/object.h>
29 #include <mono/metadata/threads.h>
30 #include <mono/metadata/threads-types.h>
31 #include <mono/metadata/threadpool.h>
32 #include <mono/metadata/monitor.h>
33 #include <mono/metadata/reflection.h>
34 #include <mono/metadata/assembly.h>
35 #include <mono/metadata/tabledefs.h>
36 #include <mono/metadata/exception.h>
37 #include <mono/metadata/file-io.h>
38 #include <mono/metadata/console-io.h>
39 #include <mono/metadata/socket-io.h>
40 #include <mono/metadata/mono-endian.h>
41 #include <mono/metadata/tokentype.h>
42 #include <mono/metadata/domain-internals.h>
43 #include <mono/metadata/metadata-internals.h>
44 #include <mono/metadata/class-internals.h>
45 #include <mono/metadata/marshal.h>
46 #include <mono/metadata/gc-internal.h>
47 #include <mono/metadata/mono-gc.h>
48 #include <mono/metadata/rand.h>
49 #include <mono/metadata/sysmath.h>
50 #include <mono/metadata/string-icalls.h>
51 #include <mono/metadata/debug-helpers.h>
52 #include <mono/metadata/process.h>
53 #include <mono/metadata/environment.h>
54 #include <mono/metadata/profiler-private.h>
55 #include <mono/metadata/locales.h>
56 #include <mono/metadata/filewatcher.h>
57 #include <mono/metadata/char-conversions.h>
58 #include <mono/metadata/security.h>
59 #include <mono/metadata/mono-config.h>
60 #include <mono/metadata/cil-coff.h>
61 #include <mono/metadata/number-formatter.h>
62 #include <mono/metadata/security-manager.h>
63 #include <mono/metadata/security-core-clr.h>
64 #include <mono/metadata/mono-perfcounters.h>
65 #include <mono/metadata/mono-debug.h>
66 #include <mono/io-layer/io-layer.h>
67 #include <mono/utils/strtod.h>
68 #include <mono/utils/monobitset.h>
69 #include <mono/utils/mono-time.h>
70 #include <mono/utils/mono-proclib.h>
72 #if defined (PLATFORM_WIN32)
78 static MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void);
81 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional);
83 static inline MonoBoolean
84 is_generic_parameter (MonoType *type)
86 return !type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR);
90 * We expect a pointer to a char, not a string
93 mono_double_ParseImpl (char *ptr, double *result)
102 *result = strtod (ptr, &endptr);
105 *result = mono_strtod (ptr, &endptr);
108 if (!*ptr || (endptr && *endptr))
115 ves_icall_System_Array_GetValueImpl (MonoObject *this, guint32 pos)
124 ao = (MonoArray *)this;
125 ac = (MonoClass *)ao->obj.vtable->klass;
127 esize = mono_array_element_size (ac);
128 ea = (gpointer*)((char*)ao->vector + (pos * esize));
130 if (ac->element_class->valuetype)
131 return mono_value_box (this->vtable->domain, ac->element_class, ea);
137 ves_icall_System_Array_GetValue (MonoObject *this, MonoObject *idxs)
145 MONO_CHECK_ARG_NULL (idxs);
147 io = (MonoArray *)idxs;
148 ic = (MonoClass *)io->obj.vtable->klass;
150 ao = (MonoArray *)this;
151 ac = (MonoClass *)ao->obj.vtable->klass;
153 g_assert (ic->rank == 1);
154 if (io->bounds != NULL || io->max_length != ac->rank)
155 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
157 ind = (gint32 *)io->vector;
159 if (ao->bounds == NULL) {
160 if (*ind < 0 || *ind >= ao->max_length)
161 mono_raise_exception (mono_get_exception_index_out_of_range ());
163 return ves_icall_System_Array_GetValueImpl (this, *ind);
166 for (i = 0; i < ac->rank; i++)
167 if ((ind [i] < ao->bounds [i].lower_bound) ||
168 (ind [i] >= ao->bounds [i].length + ao->bounds [i].lower_bound))
169 mono_raise_exception (mono_get_exception_index_out_of_range ());
171 pos = ind [0] - ao->bounds [0].lower_bound;
172 for (i = 1; i < ac->rank; i++)
173 pos = pos*ao->bounds [i].length + ind [i] -
174 ao->bounds [i].lower_bound;
176 return ves_icall_System_Array_GetValueImpl (this, pos);
180 ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32 pos)
182 MonoClass *ac, *vc, *ec;
194 vc = value->vtable->klass;
198 ac = this->obj.vtable->klass;
199 ec = ac->element_class;
201 esize = mono_array_element_size (ac);
202 ea = (gpointer*)((char*)this->vector + (pos * esize));
203 va = (gpointer*)((char*)value + sizeof (MonoObject));
206 memset (ea, 0, esize);
210 #define NO_WIDENING_CONVERSION G_STMT_START{\
211 mono_raise_exception (mono_get_exception_argument ( \
212 "value", "not a widening conversion")); \
215 #define CHECK_WIDENING_CONVERSION(extra) G_STMT_START{\
216 if (esize < vsize + (extra)) \
217 mono_raise_exception (mono_get_exception_argument ( \
218 "value", "not a widening conversion")); \
221 #define INVALID_CAST G_STMT_START{\
222 mono_raise_exception (mono_get_exception_invalid_cast ()); \
225 /* Check element (destination) type. */
226 switch (ec->byval_arg.type) {
227 case MONO_TYPE_STRING:
228 switch (vc->byval_arg.type) {
229 case MONO_TYPE_STRING:
235 case MONO_TYPE_BOOLEAN:
236 switch (vc->byval_arg.type) {
237 case MONO_TYPE_BOOLEAN:
250 NO_WIDENING_CONVERSION;
257 if (!ec->valuetype) {
258 if (!mono_object_isinst (value, ec))
260 mono_gc_wbarrier_set_arrayref (this, ea, (MonoObject*)value);
264 if (mono_object_isinst (value, ec)) {
265 if (ec->has_references)
266 mono_value_copy (ea, (char*)value + sizeof (MonoObject), ec);
268 memcpy (ea, (char *)value + sizeof (MonoObject), esize);
275 vsize = mono_class_instance_size (vc) - sizeof (MonoObject);
277 et = ec->byval_arg.type;
278 if (et == MONO_TYPE_VALUETYPE && ec->byval_arg.data.klass->enumtype)
279 et = ec->byval_arg.data.klass->enum_basetype->type;
281 vt = vc->byval_arg.type;
282 if (vt == MONO_TYPE_VALUETYPE && vc->byval_arg.data.klass->enumtype)
283 vt = vc->byval_arg.data.klass->enum_basetype->type;
285 #define ASSIGN_UNSIGNED(etype) G_STMT_START{\
291 case MONO_TYPE_CHAR: \
292 CHECK_WIDENING_CONVERSION(0); \
293 *(etype *) ea = (etype) u64; \
295 /* You can't assign a signed value to an unsigned array. */ \
300 /* You can't assign a floating point number to an integer array. */ \
303 NO_WIDENING_CONVERSION; \
307 #define ASSIGN_SIGNED(etype) G_STMT_START{\
313 CHECK_WIDENING_CONVERSION(0); \
314 *(etype *) ea = (etype) i64; \
316 /* You can assign an unsigned value to a signed array if the array's */ \
317 /* element size is larger than the value size. */ \
322 case MONO_TYPE_CHAR: \
323 CHECK_WIDENING_CONVERSION(1); \
324 *(etype *) ea = (etype) u64; \
326 /* You can't assign a floating point number to an integer array. */ \
329 NO_WIDENING_CONVERSION; \
333 #define ASSIGN_REAL(etype) G_STMT_START{\
337 CHECK_WIDENING_CONVERSION(0); \
338 *(etype *) ea = (etype) r64; \
340 /* All integer values fit into a floating point array, so we don't */ \
341 /* need to CHECK_WIDENING_CONVERSION here. */ \
346 *(etype *) ea = (etype) i64; \
352 case MONO_TYPE_CHAR: \
353 *(etype *) ea = (etype) u64; \
360 u64 = *(guint8 *) va;
363 u64 = *(guint16 *) va;
366 u64 = *(guint32 *) va;
369 u64 = *(guint64 *) va;
375 i64 = *(gint16 *) va;
378 i64 = *(gint32 *) va;
381 i64 = *(gint64 *) va;
384 r64 = *(gfloat *) va;
387 r64 = *(gdouble *) va;
390 u64 = *(guint16 *) va;
392 case MONO_TYPE_BOOLEAN:
393 /* Boolean is only compatible with itself. */
406 NO_WIDENING_CONVERSION;
413 /* If we can't do a direct copy, let's try a widening conversion. */
416 ASSIGN_UNSIGNED (guint16);
418 ASSIGN_UNSIGNED (guint8);
420 ASSIGN_UNSIGNED (guint16);
422 ASSIGN_UNSIGNED (guint32);
424 ASSIGN_UNSIGNED (guint64);
426 ASSIGN_SIGNED (gint8);
428 ASSIGN_SIGNED (gint16);
430 ASSIGN_SIGNED (gint32);
432 ASSIGN_SIGNED (gint64);
434 ASSIGN_REAL (gfloat);
436 ASSIGN_REAL (gdouble);
440 /* Not reached, INVALID_CAST does not return. Just to avoid a compiler warning ... */
444 #undef NO_WIDENING_CONVERSION
445 #undef CHECK_WIDENING_CONVERSION
446 #undef ASSIGN_UNSIGNED
452 ves_icall_System_Array_SetValue (MonoArray *this, MonoObject *value,
460 MONO_CHECK_ARG_NULL (idxs);
462 ic = idxs->obj.vtable->klass;
463 ac = this->obj.vtable->klass;
465 g_assert (ic->rank == 1);
466 if (idxs->bounds != NULL || idxs->max_length != ac->rank)
467 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
469 ind = (gint32 *)idxs->vector;
471 if (this->bounds == NULL) {
472 if (*ind < 0 || *ind >= this->max_length)
473 mono_raise_exception (mono_get_exception_index_out_of_range ());
475 ves_icall_System_Array_SetValueImpl (this, value, *ind);
479 for (i = 0; i < ac->rank; i++)
480 if ((ind [i] < this->bounds [i].lower_bound) ||
481 (ind [i] >= this->bounds [i].length + this->bounds [i].lower_bound))
482 mono_raise_exception (mono_get_exception_index_out_of_range ());
484 pos = ind [0] - this->bounds [0].lower_bound;
485 for (i = 1; i < ac->rank; i++)
486 pos = pos * this->bounds [i].length + ind [i] -
487 this->bounds [i].lower_bound;
489 ves_icall_System_Array_SetValueImpl (this, value, pos);
493 ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
497 mono_array_size_t *sizes, i;
498 gboolean bounded = FALSE;
502 MONO_CHECK_ARG_NULL (type);
503 MONO_CHECK_ARG_NULL (lengths);
505 MONO_CHECK_ARG (lengths, mono_array_length (lengths) > 0);
507 MONO_CHECK_ARG (bounds, mono_array_length (lengths) == mono_array_length (bounds));
509 for (i = 0; i < mono_array_length (lengths); i++)
510 if (mono_array_get (lengths, gint32, i) < 0)
511 mono_raise_exception (mono_get_exception_argument_out_of_range (NULL));
513 if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint32, 0) != 0))
514 /* vectors are not the same as one dimensional arrays with no-zero bounds */
519 aklass = mono_bounded_array_class_get (mono_class_from_mono_type (type->type), mono_array_length (lengths), bounded);
521 sizes = alloca (aklass->rank * sizeof(mono_array_size_t) * 2);
522 for (i = 0; i < aklass->rank; ++i) {
523 sizes [i] = mono_array_get (lengths, guint32, i);
525 sizes [i + aklass->rank] = mono_array_get (bounds, guint32, i);
527 sizes [i + aklass->rank] = 0;
530 array = mono_array_new_full (mono_object_domain (type), aklass, sizes, sizes + aklass->rank);
536 ves_icall_System_Array_CreateInstanceImpl64 (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
540 mono_array_size_t *sizes, i;
541 gboolean bounded = FALSE;
545 MONO_CHECK_ARG_NULL (type);
546 MONO_CHECK_ARG_NULL (lengths);
548 MONO_CHECK_ARG (lengths, mono_array_length (lengths) > 0);
550 MONO_CHECK_ARG (bounds, mono_array_length (lengths) == mono_array_length (bounds));
552 for (i = 0; i < mono_array_length (lengths); i++)
553 if ((mono_array_get (lengths, gint64, i) < 0) ||
554 (mono_array_get (lengths, gint64, i) > MONO_ARRAY_MAX_INDEX))
555 mono_raise_exception (mono_get_exception_argument_out_of_range (NULL));
557 if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint64, 0) != 0))
558 /* vectors are not the same as one dimensional arrays with no-zero bounds */
563 aklass = mono_bounded_array_class_get (mono_class_from_mono_type (type->type), mono_array_length (lengths), bounded);
565 sizes = alloca (aklass->rank * sizeof(mono_array_size_t) * 2);
566 for (i = 0; i < aklass->rank; ++i) {
567 sizes [i] = mono_array_get (lengths, guint64, i);
569 sizes [i + aklass->rank] = (mono_array_size_t) mono_array_get (bounds, guint64, i);
571 sizes [i + aklass->rank] = 0;
574 array = mono_array_new_full (mono_object_domain (type), aklass, sizes, sizes + aklass->rank);
580 ves_icall_System_Array_GetRank (MonoObject *this)
584 return this->vtable->klass->rank;
588 ves_icall_System_Array_GetLength (MonoArray *this, gint32 dimension)
590 gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
591 mono_array_size_t length;
595 if ((dimension < 0) || (dimension >= rank))
596 mono_raise_exception (mono_get_exception_index_out_of_range ());
598 if (this->bounds == NULL)
599 length = this->max_length;
601 length = this->bounds [dimension].length;
603 #ifdef MONO_BIG_ARRAYS
604 if (length > G_MAXINT32)
605 mono_raise_exception (mono_get_exception_overflow ());
611 ves_icall_System_Array_GetLongLength (MonoArray *this, gint32 dimension)
613 gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
617 if ((dimension < 0) || (dimension >= rank))
618 mono_raise_exception (mono_get_exception_index_out_of_range ());
620 if (this->bounds == NULL)
621 return this->max_length;
623 return this->bounds [dimension].length;
627 ves_icall_System_Array_GetLowerBound (MonoArray *this, gint32 dimension)
629 gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
633 if ((dimension < 0) || (dimension >= rank))
634 mono_raise_exception (mono_get_exception_index_out_of_range ());
636 if (this->bounds == NULL)
639 return this->bounds [dimension].lower_bound;
643 ves_icall_System_Array_ClearInternal (MonoArray *arr, int idx, int length)
645 int sz = mono_array_element_size (mono_object_class (arr));
646 memset (mono_array_addr_with_size (arr, sz, idx), 0, length * sz);
650 ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* dest, int dest_idx, int length)
655 MonoClass *src_class;
656 MonoClass *dest_class;
661 if (source->obj.vtable->klass->rank != dest->obj.vtable->klass->rank)
664 if (source->bounds || dest->bounds)
667 if ((dest_idx + length > mono_array_length (dest)) ||
668 (source_idx + length > mono_array_length (source)))
671 src_class = source->obj.vtable->klass->element_class;
672 dest_class = dest->obj.vtable->klass->element_class;
675 * Handle common cases.
678 /* Case1: object[] -> valuetype[] (ArrayList::ToArray) */
679 if (src_class == mono_defaults.object_class && dest_class->valuetype) {
680 int has_refs = dest_class->has_references;
681 for (i = source_idx; i < source_idx + length; ++i) {
682 MonoObject *elem = mono_array_get (source, MonoObject*, i);
683 if (elem && !mono_object_isinst (elem, dest_class))
687 element_size = mono_array_element_size (dest->obj.vtable->klass);
688 memset (mono_array_addr_with_size (dest, element_size, dest_idx), 0, element_size * length);
689 for (i = 0; i < length; ++i) {
690 MonoObject *elem = mono_array_get (source, MonoObject*, source_idx + i);
691 void *addr = mono_array_addr_with_size (dest, element_size, dest_idx + i);
695 mono_value_copy (addr, (char *)elem + sizeof (MonoObject), dest_class);
697 memcpy (addr, (char *)elem + sizeof (MonoObject), element_size);
702 /* Check if we're copying a char[] <==> (u)short[] */
703 if (src_class != dest_class) {
704 if (dest_class->valuetype || dest_class->enumtype || src_class->valuetype || src_class->enumtype)
707 if (mono_class_is_subclass_of (src_class, dest_class, FALSE))
709 /* Case2: object[] -> reftype[] (ArrayList::ToArray) */
710 else if (mono_class_is_subclass_of (dest_class, src_class, FALSE))
711 for (i = source_idx; i < source_idx + length; ++i) {
712 MonoObject *elem = mono_array_get (source, MonoObject*, i);
713 if (elem && !mono_object_isinst (elem, dest_class))
720 if (dest_class->valuetype) {
721 element_size = mono_array_element_size (source->obj.vtable->klass);
722 source_addr = mono_array_addr_with_size (source, element_size, source_idx);
723 if (dest_class->has_references) {
724 mono_value_copy_array (dest, dest_idx, source_addr, length);
726 dest_addr = mono_array_addr_with_size (dest, element_size, dest_idx);
727 memmove (dest_addr, source_addr, element_size * length);
730 mono_array_memcpy_refs (dest, dest_idx, source, source_idx, length);
737 ves_icall_System_Array_GetGenericValueImpl (MonoObject *this, guint32 pos, gpointer value)
746 ao = (MonoArray *)this;
747 ac = (MonoClass *)ao->obj.vtable->klass;
749 esize = mono_array_element_size (ac);
750 ea = (gpointer*)((char*)ao->vector + (pos * esize));
752 memcpy (value, ea, esize);
756 ves_icall_System_Array_SetGenericValueImpl (MonoObject *this, guint32 pos, gpointer value)
765 ao = (MonoArray *)this;
766 ac = (MonoClass *)ao->obj.vtable->klass;
768 esize = mono_array_element_size (ac);
769 ea = (gpointer*)((char*)ao->vector + (pos * esize));
771 memcpy (ea, value, esize);
775 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoArray *array, MonoClassField *field_handle)
777 MonoClass *klass = array->obj.vtable->klass;
778 guint32 size = mono_array_element_size (klass);
779 MonoType *type = mono_type_get_underlying_type (&klass->element_class->byval_arg);
781 const char *field_data;
783 if (MONO_TYPE_IS_REFERENCE (type) ||
784 (type->type == MONO_TYPE_VALUETYPE &&
785 (!mono_type_get_class (type) ||
786 mono_type_get_class (type)->has_references))) {
787 MonoException *exc = mono_get_exception_argument("array",
788 "Cannot initialize array containing references");
789 mono_raise_exception (exc);
792 if (!(field_handle->type->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA)) {
793 MonoException *exc = mono_get_exception_argument("field_handle",
794 "Field doesn't have an RVA");
795 mono_raise_exception (exc);
798 size *= array->max_length;
799 field_data = mono_field_get_data (field_handle);
801 if (size > mono_type_size (field_handle->type, &align)) {
802 MonoException *exc = mono_get_exception_argument("field_handle",
803 "Field not large enough to fill array");
804 mono_raise_exception (exc);
807 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
809 guint ## n *data = (guint ## n *) mono_array_addr (array, char, 0); \
810 guint ## n *src = (guint ## n *) field_data; \
811 guint ## n *end = (guint ## n *)((char*)src + size); \
813 for (; src < end; data++, src++) { \
814 *data = read ## n (src); \
818 /* printf ("Initialize array with elements of %s type\n", klass->element_class->name); */
820 switch (type->type) {
837 memcpy (mono_array_addr (array, char, 0), field_data, size);
841 memcpy (mono_array_addr (array, char, 0), field_data, size);
843 if (klass->element_class->byval_arg.type == MONO_TYPE_R8) {
846 double *data = (double*)mono_array_addr (array, double, 0);
848 for (i = 0; i < size; i++, data++) {
858 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData (void)
862 return offsetof (MonoString, chars);
866 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue (MonoObject *obj)
870 if ((obj == NULL) || (! (obj->vtable->klass->valuetype)))
873 return mono_object_clone (obj);
877 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (MonoType *handle)
883 MONO_CHECK_ARG_NULL (handle);
885 klass = mono_class_from_mono_type (handle);
886 MONO_CHECK_ARG (handle, klass);
888 /* This will call the type constructor */
889 mono_runtime_class_init (mono_class_vtable (mono_domain_get (), klass));
893 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunModuleConstructor (MonoImage *image)
897 mono_image_check_for_module_cctor (image);
898 if (image->has_module_cctor) {
899 MonoClass *module_klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | 1);
900 mono_runtime_class_init (mono_class_vtable (mono_domain_get (), module_klass));
905 ves_icall_System_Object_MemberwiseClone (MonoObject *this)
909 return mono_object_clone (this);
913 ves_icall_System_ValueType_InternalGetHashCode (MonoObject *this, MonoArray **fields)
916 MonoObject **values = NULL;
920 MonoClassField* field;
925 klass = mono_object_class (this);
927 if (mono_class_num_fields (klass) == 0)
928 return mono_object_hash (this);
931 * Compute the starting value of the hashcode for fields of primitive
932 * types, and return the remaining fields in an array to the managed side.
933 * This way, we can avoid costly reflection operations in managed code.
936 while ((field = mono_class_get_fields (klass, &iter))) {
937 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
939 if (mono_field_is_deleted (field))
941 /* FIXME: Add more types */
942 switch (field->type->type) {
944 result ^= *(gint32*)((guint8*)this + field->offset);
946 case MONO_TYPE_STRING: {
948 s = *(MonoString**)((guint8*)this + field->offset);
950 result ^= mono_string_hash (s);
955 values = g_newa (MonoObject*, mono_class_num_fields (klass));
956 o = mono_field_get_value_object (mono_object_domain (this), field, this);
957 values [count++] = o;
963 *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
964 for (i = 0; i < count; ++i)
965 mono_array_setref (*fields, i, values [i]);
973 ves_icall_System_ValueType_Equals (MonoObject *this, MonoObject *that, MonoArray **fields)
976 MonoObject **values = NULL;
978 MonoClassField* field;
984 MONO_CHECK_ARG_NULL (that);
986 if (this->vtable != that->vtable)
989 klass = mono_object_class (this);
991 if (klass->enumtype && klass->enum_basetype && klass->enum_basetype->type == MONO_TYPE_I4)
992 return (*(gint32*)((guint8*)this + sizeof (MonoObject)) == *(gint32*)((guint8*)that + sizeof (MonoObject)));
995 * Do the comparison for fields of primitive type and return a result if
996 * possible. Otherwise, return the remaining fields in an array to the
997 * managed side. This way, we can avoid costly reflection operations in
1002 while ((field = mono_class_get_fields (klass, &iter))) {
1003 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
1005 if (mono_field_is_deleted (field))
1007 /* FIXME: Add more types */
1008 switch (field->type->type) {
1011 case MONO_TYPE_BOOLEAN:
1012 if (*((guint8*)this + field->offset) != *((guint8*)that + field->offset))
1017 case MONO_TYPE_CHAR:
1018 if (*(gint16*)((guint8*)this + field->offset) != *(gint16*)((guint8*)that + field->offset))
1023 if (*(gint32*)((guint8*)this + field->offset) != *(gint32*)((guint8*)that + field->offset))
1028 if (*(gint64*)((guint8*)this + field->offset) != *(gint64*)((guint8*)that + field->offset))
1032 if (*(float*)((guint8*)this + field->offset) != *(float*)((guint8*)that + field->offset))
1036 if (*(double*)((guint8*)this + field->offset) != *(double*)((guint8*)that + field->offset))
1041 case MONO_TYPE_STRING: {
1042 MonoString *s1, *s2;
1043 guint32 s1len, s2len;
1044 s1 = *(MonoString**)((guint8*)this + field->offset);
1045 s2 = *(MonoString**)((guint8*)that + field->offset);
1048 if ((s1 == NULL) || (s2 == NULL))
1050 s1len = mono_string_length (s1);
1051 s2len = mono_string_length (s2);
1055 if (memcmp (mono_string_chars (s1), mono_string_chars (s2), s1len * sizeof (gunichar2)) != 0)
1061 values = g_newa (MonoObject*, mono_class_num_fields (klass) * 2);
1062 o = mono_field_get_value_object (mono_object_domain (this), field, this);
1063 values [count++] = o;
1064 o = mono_field_get_value_object (mono_object_domain (this), field, that);
1065 values [count++] = o;
1068 if (klass->enumtype)
1069 /* enums only have one non-static field */
1075 *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
1076 for (i = 0; i < count; ++i)
1077 mono_array_setref (*fields, i, values [i]);
1084 static MonoReflectionType *
1085 ves_icall_System_Object_GetType (MonoObject *obj)
1087 MONO_ARCH_SAVE_REGS;
1089 if (obj->vtable->klass != mono_defaults.transparent_proxy_class)
1090 return mono_type_get_object (mono_object_domain (obj), &obj->vtable->klass->byval_arg);
1092 return mono_type_get_object (mono_object_domain (obj), &((MonoTransparentProxy*)obj)->remote_class->proxy_class->byval_arg);
1096 mono_type_type_from_obj (MonoReflectionType *mtype, MonoObject *obj)
1098 MONO_ARCH_SAVE_REGS;
1100 mtype->type = &obj->vtable->klass->byval_arg;
1101 g_assert (mtype->type->type);
1105 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj)
1107 MONO_ARCH_SAVE_REGS;
1109 MONO_CHECK_ARG_NULL (obj);
1111 return mono_image_create_token (mb->dynamic_image, obj, TRUE, TRUE);
1115 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder *mb,
1116 MonoReflectionMethod *method,
1117 MonoArray *opt_param_types)
1119 MONO_ARCH_SAVE_REGS;
1121 MONO_CHECK_ARG_NULL (method);
1123 return mono_image_create_method_token (
1124 mb->dynamic_image, (MonoObject *) method, opt_param_types);
1128 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder *mb, HANDLE file)
1130 MONO_ARCH_SAVE_REGS;
1132 mono_image_create_pefile (mb, file);
1136 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
1138 MONO_ARCH_SAVE_REGS;
1140 mono_image_build_metadata (mb);
1144 ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, guint32 token)
1146 MONO_ARCH_SAVE_REGS;
1148 mono_image_register_token (mb->dynamic_image, token, obj);
1152 get_caller (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1154 MonoMethod **dest = data;
1156 /* skip unmanaged frames */
1171 static MonoReflectionType *
1172 type_from_name (const char *str, MonoBoolean ignoreCase)
1174 MonoType *type = NULL;
1175 MonoAssembly *assembly = NULL;
1176 MonoTypeNameParse info;
1177 char *temp_str = g_strdup (str);
1178 gboolean type_resolve = FALSE;
1180 MONO_ARCH_SAVE_REGS;
1182 /* mono_reflection_parse_type() mangles the string */
1183 if (!mono_reflection_parse_type (temp_str, &info)) {
1184 mono_reflection_free_type_info (&info);
1189 if (info.assembly.name) {
1190 assembly = mono_assembly_load (&info.assembly, NULL, NULL);
1192 MonoMethod *m = mono_method_get_last_managed ();
1193 MonoMethod *dest = m;
1195 mono_stack_walk_no_il (get_caller, &dest);
1200 * FIXME: mono_method_get_last_managed() sometimes returns NULL, thus
1201 * causing ves_icall_System_Reflection_Assembly_GetCallingAssembly()
1202 * to crash. This only seems to happen in some strange remoting
1203 * scenarios and I was unable to figure out what's happening there.
1204 * Dec 10, 2005 - Martin.
1208 assembly = dest->klass->image->assembly;
1210 g_warning (G_STRLOC);
1215 type = mono_reflection_get_type (assembly->image, &info, ignoreCase, &type_resolve);
1217 if (!info.assembly.name && !type) /* try mscorlib */
1218 type = mono_reflection_get_type (NULL, &info, ignoreCase, &type_resolve);
1220 mono_reflection_free_type_info (&info);
1226 return mono_type_get_object (mono_domain_get (), type);
1230 MonoReflectionType *
1231 mono_type_get (const char *str)
1233 char *copy = g_strdup (str);
1234 MonoReflectionType *type = type_from_name (copy, FALSE);
1241 static MonoReflectionType*
1242 ves_icall_type_from_name (MonoString *name,
1243 MonoBoolean throwOnError,
1244 MonoBoolean ignoreCase)
1246 char *str = mono_string_to_utf8 (name);
1247 MonoReflectionType *type;
1249 type = type_from_name (str, ignoreCase);
1252 MonoException *e = NULL;
1255 e = mono_get_exception_type_load (name, NULL);
1257 mono_loader_clear_error ();
1259 mono_raise_exception (e);
1266 static MonoReflectionType*
1267 ves_icall_type_from_handle (MonoType *handle)
1269 MonoDomain *domain = mono_domain_get ();
1270 MonoClass *klass = mono_class_from_mono_type (handle);
1272 MONO_ARCH_SAVE_REGS;
1274 mono_class_init (klass);
1275 return mono_type_get_object (domain, handle);
1279 ves_icall_System_Type_EqualsInternal (MonoReflectionType *type, MonoReflectionType *c)
1281 MONO_ARCH_SAVE_REGS;
1283 if (c && type->type && c->type)
1284 return mono_metadata_type_equal (type->type, c->type);
1289 /* System.TypeCode */
1308 TYPECODE_STRING = 18
1312 ves_icall_type_GetTypeCodeInternal (MonoReflectionType *type)
1314 int t = type->type->type;
1316 MONO_ARCH_SAVE_REGS;
1318 if (type->type->byref)
1319 return TYPECODE_OBJECT;
1323 case MONO_TYPE_VOID:
1324 return TYPECODE_OBJECT;
1325 case MONO_TYPE_BOOLEAN:
1326 return TYPECODE_BOOLEAN;
1328 return TYPECODE_BYTE;
1330 return TYPECODE_SBYTE;
1332 return TYPECODE_UINT16;
1334 return TYPECODE_INT16;
1335 case MONO_TYPE_CHAR:
1336 return TYPECODE_CHAR;
1340 return TYPECODE_OBJECT;
1342 return TYPECODE_UINT32;
1344 return TYPECODE_INT32;
1346 return TYPECODE_UINT64;
1348 return TYPECODE_INT64;
1350 return TYPECODE_SINGLE;
1352 return TYPECODE_DOUBLE;
1353 case MONO_TYPE_VALUETYPE:
1354 if (type->type->data.klass->enumtype) {
1355 t = type->type->data.klass->enum_basetype->type;
1358 MonoClass *k = type->type->data.klass;
1359 if (strcmp (k->name_space, "System") == 0) {
1360 if (strcmp (k->name, "Decimal") == 0)
1361 return TYPECODE_DECIMAL;
1362 else if (strcmp (k->name, "DateTime") == 0)
1363 return TYPECODE_DATETIME;
1366 return TYPECODE_OBJECT;
1367 case MONO_TYPE_STRING:
1368 return TYPECODE_STRING;
1369 case MONO_TYPE_SZARRAY:
1370 case MONO_TYPE_ARRAY:
1371 case MONO_TYPE_OBJECT:
1373 case MONO_TYPE_MVAR:
1374 case MONO_TYPE_TYPEDBYREF:
1375 return TYPECODE_OBJECT;
1376 case MONO_TYPE_CLASS:
1378 MonoClass *k = type->type->data.klass;
1379 if (strcmp (k->name_space, "System") == 0) {
1380 if (strcmp (k->name, "DBNull") == 0)
1381 return TYPECODE_DBNULL;
1384 return TYPECODE_OBJECT;
1385 case MONO_TYPE_GENERICINST:
1386 return TYPECODE_OBJECT;
1388 g_error ("type 0x%02x not handled in GetTypeCode()", t);
1394 ves_icall_type_is_subtype_of (MonoReflectionType *type, MonoReflectionType *c, MonoBoolean check_interfaces)
1400 MONO_ARCH_SAVE_REGS;
1402 g_assert (type != NULL);
1404 domain = ((MonoObject *)type)->vtable->domain;
1406 if (!c) /* FIXME: dont know what do do here */
1409 klass = mono_class_from_mono_type (type->type);
1410 klassc = mono_class_from_mono_type (c->type);
1412 if (type->type->byref)
1413 return klassc == mono_defaults.object_class;
1415 return mono_class_is_subclass_of (klass, klassc, check_interfaces);
1419 ves_icall_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType *c)
1425 MONO_ARCH_SAVE_REGS;
1427 g_assert (type != NULL);
1429 domain = ((MonoObject *)type)->vtable->domain;
1431 klass = mono_class_from_mono_type (type->type);
1432 klassc = mono_class_from_mono_type (c->type);
1434 if (type->type->byref && !c->type->byref)
1437 return mono_class_is_assignable_from (klass, klassc);
1441 ves_icall_type_IsInstanceOfType (MonoReflectionType *type, MonoObject *obj)
1443 MonoClass *klass = mono_class_from_mono_type (type->type);
1444 return mono_object_isinst (obj, klass) != NULL;
1448 ves_icall_get_attributes (MonoReflectionType *type)
1450 MonoClass *klass = mono_class_from_mono_type (type->type);
1452 MONO_ARCH_SAVE_REGS;
1454 return klass->flags;
1457 static MonoReflectionMarshal*
1458 ves_icall_System_Reflection_FieldInfo_GetUnmanagedMarshal (MonoReflectionField *field)
1460 MonoClass *klass = field->field->parent;
1461 MonoMarshalType *info;
1464 if (klass->generic_container ||
1465 (klass->generic_class && klass->generic_class->context.class_inst->is_open))
1468 info = mono_marshal_load_type_info (klass);
1470 for (i = 0; i < info->num_fields; ++i) {
1471 if (info->fields [i].field == field->field) {
1472 if (!info->fields [i].mspec)
1475 return mono_reflection_marshal_from_marshal_spec (field->object.vtable->domain, klass, info->fields [i].mspec);
1482 static MonoReflectionField*
1483 ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoClass *klass)
1488 klass = handle->parent;
1490 /* FIXME: check that handle is a field of klass or of a parent: return null
1491 * and throw the exception in managed code.
1493 return mono_field_get_object (mono_domain_get (), klass, handle);
1496 static MonoReflectionField*
1497 ves_icall_System_Reflection_FieldInfo_internal_from_handle (MonoClassField *handle)
1499 MONO_ARCH_SAVE_REGS;
1503 return mono_field_get_object (mono_domain_get (), handle->parent, handle);
1507 ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionField *field, MonoBoolean optional)
1509 MonoType *type = field->field->type;
1511 return type_array_from_modifiers (field->field->parent->image, type, optional);
1515 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
1517 MonoDomain *domain = mono_domain_get ();
1518 MonoMethodSignature* sig;
1519 MONO_ARCH_SAVE_REGS;
1521 sig = mono_method_signature (method);
1523 g_assert (mono_loader_get_last_error ());
1524 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
1527 info->parent = mono_type_get_object (domain, &method->klass->byval_arg);
1528 info->ret = mono_type_get_object (domain, sig->ret);
1529 info->attrs = method->flags;
1530 info->implattrs = method->iflags;
1531 if (sig->call_convention == MONO_CALL_DEFAULT)
1532 info->callconv = sig->sentinelpos >= 0 ? 2 : 1;
1534 if (sig->call_convention == MONO_CALL_VARARG || sig->sentinelpos >= 0)
1539 info->callconv |= (sig->hasthis << 5) | (sig->explicit_this << 6);
1543 ves_icall_get_parameter_info (MonoMethod *method)
1545 MonoDomain *domain = mono_domain_get ();
1547 return mono_param_get_objects (domain, method);
1550 static MonoReflectionMarshal*
1551 ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod *method)
1553 MonoDomain *domain = mono_domain_get ();
1554 MonoReflectionMarshal* res = NULL;
1555 MonoMarshalSpec **mspecs;
1558 mspecs = g_new (MonoMarshalSpec*, mono_method_signature (method)->param_count + 1);
1559 mono_method_get_marshal_info (method, mspecs);
1562 res = mono_reflection_marshal_from_marshal_spec (domain, method->klass, mspecs [0]);
1564 for (i = mono_method_signature (method)->param_count; i >= 0; i--)
1566 mono_metadata_free_marshal_spec (mspecs [i]);
1573 ves_icall_MonoField_GetFieldOffset (MonoReflectionField *field)
1575 return field->field->offset - sizeof (MonoObject);
1578 static MonoReflectionType*
1579 ves_icall_MonoField_GetParentType (MonoReflectionField *field, MonoBoolean declaring)
1582 MONO_ARCH_SAVE_REGS;
1584 parent = declaring? field->field->parent: field->klass;
1586 return mono_type_get_object (mono_object_domain (field), &parent->byval_arg);
1590 ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj)
1593 MonoClassField *cf = field->field;
1597 MonoDomain *domain = mono_object_domain (field);
1599 gboolean is_static = FALSE;
1600 gboolean is_ref = FALSE;
1602 MONO_ARCH_SAVE_REGS;
1604 if (field->klass->image->assembly->ref_only)
1605 mono_raise_exception (mono_get_exception_invalid_operation (
1606 "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
1608 mono_class_init (field->klass);
1610 if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC)
1613 if (obj && !is_static) {
1614 /* Check that the field belongs to the object */
1615 gboolean found = FALSE;
1618 for (k = obj->vtable->klass; k; k = k->parent) {
1619 if (k == cf->parent) {
1626 char *msg = g_strdup_printf ("Field '%s' defined on type '%s' is not a field on the target object which is of type '%s'.", mono_field_get_name (cf), cf->parent->name, obj->vtable->klass->name);
1627 MonoException *ex = mono_get_exception_argument (NULL, msg);
1629 mono_raise_exception (ex);
1633 t = mono_type_get_underlying_type (cf->type);
1635 case MONO_TYPE_STRING:
1636 case MONO_TYPE_OBJECT:
1637 case MONO_TYPE_CLASS:
1638 case MONO_TYPE_ARRAY:
1639 case MONO_TYPE_SZARRAY:
1644 case MONO_TYPE_BOOLEAN:
1647 case MONO_TYPE_CHAR:
1656 case MONO_TYPE_VALUETYPE:
1659 case MONO_TYPE_GENERICINST:
1660 if (mono_type_generic_inst_is_valuetype (t)) {
1667 g_error ("type 0x%x not handled in "
1668 "ves_icall_Monofield_GetValue", t->type);
1674 vtable = mono_class_vtable (domain, cf->parent);
1675 if (!vtable->initialized && !(cf->type->attrs & FIELD_ATTRIBUTE_LITERAL))
1676 mono_runtime_class_init (vtable);
1681 mono_field_static_get_value (vtable, cf, &o);
1683 mono_field_get_value (obj, cf, &o);
1688 if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) {
1689 MonoClass *nklass = mono_class_from_mono_type (cf->type);
1692 /* Convert the Nullable structure into a boxed vtype */
1694 buf = (guint8*)vtable->data + cf->offset;
1696 buf = (guint8*)obj + cf->offset;
1698 return mono_nullable_box (buf, nklass);
1701 /* boxed value type */
1702 klass = mono_class_from_mono_type (cf->type);
1703 o = mono_object_new (domain, klass);
1704 v = ((gchar *) o) + sizeof (MonoObject);
1706 mono_field_static_get_value (vtable, cf, v);
1708 mono_field_get_value (obj, cf, v);
1715 ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value)
1717 MonoClassField *cf = field->field;
1720 MONO_ARCH_SAVE_REGS;
1722 if (field->klass->image->assembly->ref_only)
1723 mono_raise_exception (mono_get_exception_invalid_operation (
1724 "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
1726 v = (gchar *) value;
1727 if (!cf->type->byref) {
1728 switch (cf->type->type) {
1731 case MONO_TYPE_BOOLEAN:
1734 case MONO_TYPE_CHAR:
1743 case MONO_TYPE_VALUETYPE:
1745 v += sizeof (MonoObject);
1747 case MONO_TYPE_STRING:
1748 case MONO_TYPE_OBJECT:
1749 case MONO_TYPE_CLASS:
1750 case MONO_TYPE_ARRAY:
1751 case MONO_TYPE_SZARRAY:
1754 case MONO_TYPE_GENERICINST: {
1755 MonoGenericClass *gclass = cf->type->data.generic_class;
1756 g_assert (!gclass->context.class_inst->is_open);
1758 if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) {
1759 MonoClass *nklass = mono_class_from_mono_type (cf->type);
1760 MonoObject *nullable;
1763 * Convert the boxed vtype into a Nullable structure.
1764 * This is complicated by the fact that Nullables have
1765 * a variable structure.
1767 nullable = mono_object_new (mono_domain_get (), nklass);
1769 mono_nullable_init (mono_object_unbox (nullable), value, nklass);
1771 v = mono_object_unbox (nullable);
1774 if (gclass->container_class->valuetype && (v != NULL))
1775 v += sizeof (MonoObject);
1779 g_error ("type 0x%x not handled in "
1780 "ves_icall_FieldInfo_SetValueInternal", cf->type->type);
1785 if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) {
1786 MonoVTable *vtable = mono_class_vtable (mono_object_domain (field), cf->parent);
1787 if (!vtable->initialized)
1788 mono_runtime_class_init (vtable);
1789 mono_field_static_set_value (vtable, cf, v);
1791 mono_field_set_value (obj, cf, v);
1796 ves_icall_MonoField_GetRawConstantValue (MonoReflectionField *this)
1798 MonoObject *o = NULL;
1799 MonoClassField *field = this->field;
1801 MonoDomain *domain = mono_object_domain (this);
1803 MonoTypeEnum def_type;
1804 const char *def_value;
1806 MONO_ARCH_SAVE_REGS;
1808 mono_class_init (field->parent);
1810 if (!(field->type->attrs & FIELD_ATTRIBUTE_HAS_DEFAULT))
1811 mono_raise_exception (mono_get_exception_invalid_operation (NULL));
1813 if (field->parent->image->dynamic) {
1815 g_assert_not_reached ();
1818 def_value = mono_class_get_field_default_value (field, &def_type);
1823 case MONO_TYPE_BOOLEAN:
1826 case MONO_TYPE_CHAR:
1834 case MONO_TYPE_R8: {
1837 /* boxed value type */
1838 t = g_new0 (MonoType, 1);
1840 klass = mono_class_from_mono_type (t);
1842 o = mono_object_new (domain, klass);
1843 v = ((gchar *) o) + sizeof (MonoObject);
1844 mono_get_constant_value_from_blob (domain, def_type, def_value, v);
1847 case MONO_TYPE_STRING:
1848 case MONO_TYPE_CLASS:
1849 mono_get_constant_value_from_blob (domain, def_type, def_value, &o);
1852 g_assert_not_reached ();
1858 static MonoReflectionType*
1859 ves_icall_MonoGenericMethod_get_ReflectedType (MonoReflectionGenericMethod *rmethod)
1861 MonoMethod *method = rmethod->method.method;
1863 return mono_type_get_object (mono_object_domain (rmethod), &method->klass->byval_arg);
1866 /* From MonoProperty.cs */
1868 PInfo_Attributes = 1,
1869 PInfo_GetMethod = 1 << 1,
1870 PInfo_SetMethod = 1 << 2,
1871 PInfo_ReflectedType = 1 << 3,
1872 PInfo_DeclaringType = 1 << 4,
1877 ves_icall_get_property_info (MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
1879 MonoDomain *domain = mono_object_domain (property);
1881 MONO_ARCH_SAVE_REGS;
1883 if ((req_info & PInfo_ReflectedType) != 0)
1884 MONO_STRUCT_SETREF (info, parent, mono_type_get_object (domain, &property->klass->byval_arg));
1885 else if ((req_info & PInfo_DeclaringType) != 0)
1886 MONO_STRUCT_SETREF (info, parent, mono_type_get_object (domain, &property->property->parent->byval_arg));
1888 if ((req_info & PInfo_Name) != 0)
1889 MONO_STRUCT_SETREF (info, name, mono_string_new (domain, property->property->name));
1891 if ((req_info & PInfo_Attributes) != 0)
1892 info->attrs = property->property->attrs;
1894 if ((req_info & PInfo_GetMethod) != 0)
1895 MONO_STRUCT_SETREF (info, get, property->property->get ?
1896 mono_method_get_object (domain, property->property->get, property->klass): NULL);
1898 if ((req_info & PInfo_SetMethod) != 0)
1899 MONO_STRUCT_SETREF (info, set, property->property->set ?
1900 mono_method_get_object (domain, property->property->set, property->klass): NULL);
1902 * There may be other methods defined for properties, though, it seems they are not exposed
1903 * in the reflection API
1908 ves_icall_get_event_info (MonoReflectionEvent *event, MonoEventInfo *info)
1910 MonoDomain *domain = mono_object_domain (event);
1912 MONO_ARCH_SAVE_REGS;
1914 info->reflected_type = mono_type_get_object (domain, &event->klass->byval_arg);
1915 info->declaring_type = mono_type_get_object (domain, &event->event->parent->byval_arg);
1917 info->name = mono_string_new (domain, event->event->name);
1918 info->attrs = event->event->attrs;
1919 info->add_method = event->event->add ? mono_method_get_object (domain, event->event->add, NULL): NULL;
1920 info->remove_method = event->event->remove ? mono_method_get_object (domain, event->event->remove, NULL): NULL;
1921 info->raise_method = event->event->raise ? mono_method_get_object (domain, event->event->raise, NULL): NULL;
1923 if (event->event->other) {
1925 while (event->event->other [n])
1927 info->other_methods = mono_array_new (domain, mono_defaults.method_info_class, n);
1929 for (i = 0; i < n; i++)
1930 mono_array_setref (info->other_methods, i, mono_method_get_object (domain, event->event->other [i], NULL));
1935 ves_icall_Type_GetInterfaces (MonoReflectionType* type)
1937 MonoDomain *domain = mono_object_domain (type);
1939 GPtrArray *ifaces = NULL;
1941 MonoClass *class = mono_class_from_mono_type (type->type);
1944 MonoGenericContext *context = NULL;
1946 MONO_ARCH_SAVE_REGS;
1948 if (class->generic_class && class->generic_class->context.class_inst->is_open) {
1949 context = mono_class_get_context (class);
1950 class = class->generic_class->container_class;
1953 mono_class_setup_vtable (class);
1955 slots = mono_bitset_new (class->max_interface_id + 1, 0);
1957 for (parent = class; parent; parent = parent->parent) {
1958 GPtrArray *tmp_ifaces = mono_class_get_implemented_interfaces (parent);
1960 for (i = 0; i < tmp_ifaces->len; ++i) {
1961 MonoClass *ic = g_ptr_array_index (tmp_ifaces, i);
1963 if (mono_bitset_test (slots, ic->interface_id))
1966 mono_bitset_set (slots, ic->interface_id);
1968 ifaces = g_ptr_array_new ();
1969 g_ptr_array_add (ifaces, ic);
1971 g_ptr_array_free (tmp_ifaces, TRUE);
1974 mono_bitset_free (slots);
1977 return mono_array_new (domain, mono_defaults.monotype_class, 0);
1979 intf = mono_array_new (domain, mono_defaults.monotype_class, ifaces->len);
1980 for (i = 0; i < ifaces->len; ++i) {
1981 MonoClass *ic = g_ptr_array_index (ifaces, i);
1982 MonoType *ret = &ic->byval_arg, *inflated = NULL;
1983 if (context && ic->generic_class && ic->generic_class->context.class_inst->is_open)
1984 inflated = ret = mono_class_inflate_generic_type (ret, context);
1986 mono_array_setref (intf, i, mono_type_get_object (domain, ret));
1988 mono_metadata_free_type (inflated);
1990 g_ptr_array_free (ifaces, TRUE);
1996 ves_icall_Type_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType *iface, MonoArray **targets, MonoArray **methods)
1998 MonoClass *class = mono_class_from_mono_type (type->type);
1999 MonoClass *iclass = mono_class_from_mono_type (iface->type);
2000 MonoReflectionMethod *member;
2003 int i = 0, len, ioffset;
2006 MONO_ARCH_SAVE_REGS;
2008 mono_class_setup_vtable (class);
2010 /* type doesn't implement iface: the exception is thrown in managed code */
2011 if (! MONO_CLASS_IMPLEMENTS_INTERFACE (class, iclass->interface_id))
2014 len = mono_class_num_methods (iclass);
2015 ioffset = mono_class_interface_offset (class, iclass);
2016 domain = mono_object_domain (type);
2017 *targets = mono_array_new (domain, mono_defaults.method_info_class, len);
2018 *methods = mono_array_new (domain, mono_defaults.method_info_class, len);
2021 while ((method = mono_class_get_methods (iclass, &iter))) {
2022 member = mono_method_get_object (domain, method, iclass);
2023 mono_array_setref (*methods, i, member);
2024 member = mono_method_get_object (domain, class->vtable [i + ioffset], class);
2025 mono_array_setref (*targets, i, member);
2032 ves_icall_Type_GetPacking (MonoReflectionType *type, guint32 *packing, guint32 *size)
2034 MonoClass *klass = mono_class_from_mono_type (type->type);
2036 if (klass->image->dynamic) {
2037 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)type;
2038 *packing = tb->packing_size;
2039 *size = tb->class_size;
2041 mono_metadata_packing_from_typedef (klass->image, klass->type_token, packing, size);
2045 static MonoReflectionType*
2046 ves_icall_MonoType_GetElementType (MonoReflectionType *type)
2048 MonoClass *class = mono_class_from_mono_type (type->type);
2050 MONO_ARCH_SAVE_REGS;
2052 // GetElementType should only return a type for:
2053 // Array Pointer PassedByRef
2054 if (type->type->byref)
2055 return mono_type_get_object (mono_object_domain (type), &class->byval_arg);
2056 else if (class->element_class && MONO_CLASS_IS_ARRAY (class))
2057 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
2058 else if (class->element_class && type->type->type == MONO_TYPE_PTR)
2059 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
2064 static MonoReflectionType*
2065 ves_icall_get_type_parent (MonoReflectionType *type)
2067 MonoClass *class = mono_class_from_mono_type (type->type);
2069 MONO_ARCH_SAVE_REGS;
2071 return class->parent ? mono_type_get_object (mono_object_domain (type), &class->parent->byval_arg): NULL;
2075 ves_icall_type_ispointer (MonoReflectionType *type)
2077 MONO_ARCH_SAVE_REGS;
2079 return type->type->type == MONO_TYPE_PTR;
2083 ves_icall_type_isprimitive (MonoReflectionType *type)
2085 MONO_ARCH_SAVE_REGS;
2087 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)));
2091 ves_icall_type_isbyref (MonoReflectionType *type)
2093 MONO_ARCH_SAVE_REGS;
2095 return type->type->byref;
2099 ves_icall_type_iscomobject (MonoReflectionType *type)
2101 MonoClass *klass = mono_class_from_mono_type (type->type);
2102 MONO_ARCH_SAVE_REGS;
2104 return (klass && klass->is_com_object);
2107 static MonoReflectionModule*
2108 ves_icall_MonoType_get_Module (MonoReflectionType *type)
2110 MonoClass *class = mono_class_from_mono_type (type->type);
2112 MONO_ARCH_SAVE_REGS;
2114 return mono_module_get_object (mono_object_domain (type), class->image);
2117 static MonoReflectionAssembly*
2118 ves_icall_MonoType_get_Assembly (MonoReflectionType *type)
2120 MonoDomain *domain = mono_domain_get ();
2121 MonoClass *class = mono_class_from_mono_type (type->type);
2123 MONO_ARCH_SAVE_REGS;
2125 return mono_assembly_get_object (domain, class->image->assembly);
2128 static MonoReflectionType*
2129 ves_icall_MonoType_get_DeclaringType (MonoReflectionType *type)
2131 MonoDomain *domain = mono_domain_get ();
2134 MONO_ARCH_SAVE_REGS;
2136 if (type->type->byref)
2138 if (type->type->type == MONO_TYPE_VAR)
2139 class = type->type->data.generic_param->owner->owner.klass;
2140 else if (type->type->type == MONO_TYPE_MVAR)
2141 class = type->type->data.generic_param->owner->owner.method->klass;
2143 class = mono_class_from_mono_type (type->type)->nested_in;
2145 return class ? mono_type_get_object (domain, &class->byval_arg) : NULL;
2148 static MonoReflectionType*
2149 ves_icall_MonoType_get_UnderlyingSystemType (MonoReflectionType *type)
2151 MonoDomain *domain = mono_domain_get ();
2152 MonoClass *class = mono_class_from_mono_type (type->type);
2154 MONO_ARCH_SAVE_REGS;
2156 if (class->enumtype && class->enum_basetype) /* types that are modified typebuilders may not have enum_basetype set */
2157 return mono_type_get_object (domain, class->enum_basetype);
2158 else if (class->element_class)
2159 return mono_type_get_object (domain, &class->element_class->byval_arg);
2165 ves_icall_MonoType_get_Name (MonoReflectionType *type)
2167 MonoDomain *domain = mono_domain_get ();
2168 MonoClass *class = mono_class_from_mono_type (type->type);
2170 MONO_ARCH_SAVE_REGS;
2172 if (type->type->byref) {
2173 char *n = g_strdup_printf ("%s&", class->name);
2174 MonoString *res = mono_string_new (domain, n);
2180 return mono_string_new (domain, class->name);
2185 ves_icall_MonoType_get_Namespace (MonoReflectionType *type)
2187 MonoDomain *domain = mono_domain_get ();
2188 MonoClass *class = mono_class_from_mono_type (type->type);
2190 MONO_ARCH_SAVE_REGS;
2192 while (class->nested_in)
2193 class = class->nested_in;
2195 if (class->name_space [0] == '\0')
2198 return mono_string_new (domain, class->name_space);
2202 ves_icall_MonoType_GetArrayRank (MonoReflectionType *type)
2204 MonoClass *class = mono_class_from_mono_type (type->type);
2206 MONO_ARCH_SAVE_REGS;
2212 ves_icall_MonoType_GetGenericArguments (MonoReflectionType *type)
2215 MonoClass *klass, *pklass;
2217 MONO_ARCH_SAVE_REGS;
2219 klass = mono_class_from_mono_type (type->type);
2221 if (klass->generic_container) {
2222 MonoGenericContainer *container = klass->generic_container;
2223 res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, container->type_argc);
2224 for (i = 0; i < container->type_argc; ++i) {
2225 pklass = mono_class_from_generic_parameter (&container->type_params [i], klass->image, FALSE);
2226 mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), &pklass->byval_arg));
2228 } else if (klass->generic_class) {
2229 MonoGenericInst *inst = klass->generic_class->context.class_inst;
2230 res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, inst->type_argc);
2231 for (i = 0; i < inst->type_argc; ++i)
2232 mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), inst->type_argv [i]));
2234 res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, 0);
2240 ves_icall_Type_get_IsGenericTypeDefinition (MonoReflectionType *type)
2243 MONO_ARCH_SAVE_REGS;
2245 if (type->type->byref)
2248 klass = mono_class_from_mono_type (type->type);
2250 return klass->generic_container != NULL;
2253 static MonoReflectionType*
2254 ves_icall_Type_GetGenericTypeDefinition_impl (MonoReflectionType *type)
2257 MONO_ARCH_SAVE_REGS;
2259 if (type->type->byref)
2262 klass = mono_class_from_mono_type (type->type);
2263 if (klass->generic_container) {
2264 return type; /* check this one */
2266 if (klass->generic_class) {
2267 MonoClass *generic_class = klass->generic_class->container_class;
2269 if (generic_class->wastypebuilder && generic_class->reflection_info)
2270 return generic_class->reflection_info;
2272 return mono_type_get_object (mono_object_domain (type), &generic_class->byval_arg);
2277 static MonoReflectionType*
2278 ves_icall_Type_MakeGenericType (MonoReflectionType *type, MonoArray *type_array)
2280 MonoType *geninst, **types;
2283 MONO_ARCH_SAVE_REGS;
2285 count = mono_array_length (type_array);
2286 types = g_new0 (MonoType *, count);
2288 for (i = 0; i < count; i++) {
2289 MonoReflectionType *t = mono_array_get (type_array, gpointer, i);
2290 types [i] = t->type;
2293 geninst = mono_reflection_bind_generic_parameters (type, count, types);
2298 return mono_type_get_object (mono_object_domain (type), geninst);
2302 ves_icall_Type_get_IsGenericInstance (MonoReflectionType *type)
2305 MONO_ARCH_SAVE_REGS;
2307 if (type->type->byref)
2310 klass = mono_class_from_mono_type (type->type);
2311 return klass->generic_class != NULL;
2315 ves_icall_Type_get_IsGenericType (MonoReflectionType *type)
2318 MONO_ARCH_SAVE_REGS;
2320 if (type->type->byref)
2323 klass = mono_class_from_mono_type (type->type);
2324 return klass->generic_class != NULL || klass->generic_container != NULL;
2328 ves_icall_Type_GetGenericParameterPosition (MonoReflectionType *type)
2330 MONO_ARCH_SAVE_REGS;
2332 if (is_generic_parameter (type->type))
2333 return type->type->data.generic_param->num;
2337 static GenericParameterAttributes
2338 ves_icall_Type_GetGenericParameterAttributes (MonoReflectionType *type)
2340 MONO_ARCH_SAVE_REGS;
2341 g_assert (is_generic_parameter (type->type));
2342 return type->type->data.generic_param->flags;
2346 ves_icall_Type_GetGenericParameterConstraints (MonoReflectionType *type)
2348 MonoGenericParam *param;
2354 MONO_ARCH_SAVE_REGS;
2356 domain = mono_object_domain (type);
2357 param = type->type->data.generic_param;
2358 for (count = 0, ptr = param->constraints; ptr && *ptr; ptr++, count++)
2361 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2362 for (i = 0; i < count; i++)
2363 mono_array_setref (res, i, mono_type_get_object (domain, ¶m->constraints [i]->byval_arg));
2370 ves_icall_MonoType_get_IsGenericParameter (MonoReflectionType *type)
2372 MONO_ARCH_SAVE_REGS;
2373 return is_generic_parameter (type->type);
2377 ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder *tb)
2379 MONO_ARCH_SAVE_REGS;
2380 return is_generic_parameter (tb->type.type);
2384 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
2385 MonoReflectionType *t)
2387 enumtype->type = t->type;
2390 static MonoReflectionType*
2391 ves_icall_MonoGenericClass_GetParentType (MonoReflectionGenericClass *type)
2393 MonoDynamicGenericClass *gclass;
2394 MonoReflectionType *parent = NULL, *res;
2400 MONO_ARCH_SAVE_REGS;
2402 g_assert (type->type.type->data.generic_class->is_dynamic);
2403 gclass = (MonoDynamicGenericClass *) type->type.type->data.generic_class;
2405 domain = mono_object_domain (type);
2406 klass = mono_class_from_mono_type (type->generic_type->type.type);
2408 if (!klass->generic_class && !klass->generic_container)
2411 parent = type->generic_type->parent;
2413 if (!parent || (parent->type->type != MONO_TYPE_GENERICINST))
2416 inflated = mono_class_inflate_generic_type (
2417 parent->type, mono_generic_class_get_context ((MonoGenericClass *) gclass));
2419 res = mono_type_get_object (domain, inflated);
2420 mono_metadata_free_type (inflated);
2425 ves_icall_MonoGenericClass_GetInterfaces (MonoReflectionGenericClass *type)
2427 static MonoClass *System_Reflection_MonoGenericClass;
2428 MonoGenericClass *gclass;
2429 MonoReflectionTypeBuilder *tb = NULL;
2430 MonoClass *klass = NULL;
2435 MONO_ARCH_SAVE_REGS;
2437 if (!System_Reflection_MonoGenericClass) {
2438 System_Reflection_MonoGenericClass = mono_class_from_name (
2439 mono_defaults.corlib, "System.Reflection", "MonoGenericClass");
2440 g_assert (System_Reflection_MonoGenericClass);
2443 domain = mono_object_domain (type);
2445 gclass = type->type.type->data.generic_class;
2446 g_assert (gclass->is_dynamic);
2448 tb = type->generic_type;
2449 icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
2451 res = mono_array_new (domain, System_Reflection_MonoGenericClass, icount);
2453 for (i = 0; i < icount; i++) {
2454 MonoReflectionType *iface;
2458 iface = mono_array_get (tb->interfaces, MonoReflectionType *, i);
2461 it = &klass->interfaces [i]->byval_arg;
2463 it = mono_class_inflate_generic_type (it, mono_generic_class_get_context (gclass));
2465 iface = mono_type_get_object (domain, it);
2466 mono_array_setref (res, i, iface);
2467 mono_metadata_free_type (it);
2473 static MonoReflectionMethod*
2474 ves_icall_MonoGenericClass_GetCorrespondingInflatedMethod (MonoReflectionGenericClass *type,
2475 MonoReflectionMethod* generic)
2477 MonoGenericClass *gclass;
2478 MonoDynamicGenericClass *dgclass;
2482 MONO_ARCH_SAVE_REGS;
2484 gclass = type->type.type->data.generic_class;
2485 g_assert (gclass->is_dynamic);
2487 dgclass = (MonoDynamicGenericClass *) gclass;
2489 domain = mono_object_domain (type);
2491 for (i = 0; i < dgclass->count_methods; i++)
2492 if (generic->method->token == dgclass->methods [i]->token)
2493 return mono_method_get_object (domain, dgclass->methods [i], NULL);
2498 static MonoReflectionMethod*
2499 ves_icall_MonoGenericClass_GetCorrespondingInflatedConstructor (MonoReflectionGenericClass *type,
2500 MonoReflectionMethod* generic)
2502 MonoGenericClass *gclass;
2503 MonoDynamicGenericClass *dgclass;
2507 MONO_ARCH_SAVE_REGS;
2509 gclass = type->type.type->data.generic_class;
2510 g_assert (gclass->is_dynamic);
2512 dgclass = (MonoDynamicGenericClass *) gclass;
2514 domain = mono_object_domain (type);
2516 for (i = 0; i < dgclass->count_ctors; i++)
2517 if (generic->method->token == dgclass->ctors [i]->token)
2518 return mono_method_get_object (domain, dgclass->ctors [i], NULL);
2524 static MonoReflectionField*
2525 ves_icall_MonoGenericClass_GetCorrespondingInflatedField (MonoReflectionGenericClass *type,
2526 MonoString* generic_name)
2528 MonoGenericClass *gclass;
2529 MonoDynamicGenericClass *dgclass;
2531 MonoClass *refclass;
2532 char *utf8_name = mono_string_to_utf8 (generic_name);
2535 MONO_ARCH_SAVE_REGS;
2537 gclass = type->type.type->data.generic_class;
2538 g_assert (gclass->is_dynamic);
2540 dgclass = (MonoDynamicGenericClass *) gclass;
2542 refclass = mono_class_from_mono_type (type->type.type);
2544 domain = mono_object_domain (type);
2546 for (i = 0; i < dgclass->count_fields; i++)
2547 if (strcmp (utf8_name, mono_field_get_name (&dgclass->fields [i])) == 0) {
2549 return mono_field_get_object (domain, refclass, &dgclass->fields [i]);
2558 static MonoReflectionMethod*
2559 ves_icall_MonoType_GetCorrespondingInflatedMethod (MonoReflectionType *type,
2560 MonoReflectionMethod* generic)
2567 MONO_ARCH_SAVE_REGS;
2569 domain = ((MonoObject *)type)->vtable->domain;
2571 klass = mono_class_from_mono_type (type->type);
2574 while ((method = mono_class_get_methods (klass, &iter))) {
2575 if (method->token == generic->method->token)
2576 return mono_method_get_object (domain, method, klass);
2583 ves_icall_MonoGenericClass_GetMethods (MonoReflectionGenericClass *type,
2584 MonoReflectionType *reflected_type)
2586 MonoGenericClass *gclass;
2587 MonoDynamicGenericClass *dgclass;
2589 MonoClass *refclass;
2593 MONO_ARCH_SAVE_REGS;
2595 gclass = type->type.type->data.generic_class;
2596 g_assert (gclass->is_dynamic);
2597 dgclass = (MonoDynamicGenericClass *) gclass;
2599 refclass = mono_class_from_mono_type (reflected_type->type);
2601 domain = mono_object_domain (type);
2602 res = mono_array_new (domain, mono_defaults.method_info_class, dgclass->count_methods);
2604 for (i = 0; i < dgclass->count_methods; i++)
2605 mono_array_setref (res, i, mono_method_get_object (domain, dgclass->methods [i], refclass));
2611 ves_icall_MonoGenericClass_GetConstructors (MonoReflectionGenericClass *type,
2612 MonoReflectionType *reflected_type)
2614 static MonoClass *System_Reflection_ConstructorInfo;
2615 MonoGenericClass *gclass;
2616 MonoDynamicGenericClass *dgclass;
2618 MonoClass *refclass;
2622 MONO_ARCH_SAVE_REGS;
2624 if (!System_Reflection_ConstructorInfo)
2625 System_Reflection_ConstructorInfo = mono_class_from_name (
2626 mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
2628 gclass = type->type.type->data.generic_class;
2629 g_assert (gclass->is_dynamic);
2630 dgclass = (MonoDynamicGenericClass *) gclass;
2632 refclass = mono_class_from_mono_type (reflected_type->type);
2634 domain = mono_object_domain (type);
2635 res = mono_array_new (domain, System_Reflection_ConstructorInfo, dgclass->count_ctors);
2637 for (i = 0; i < dgclass->count_ctors; i++)
2638 mono_array_setref (res, i, mono_method_get_object (domain, dgclass->ctors [i], refclass));
2644 ves_icall_MonoGenericClass_GetFields (MonoReflectionGenericClass *type,
2645 MonoReflectionType *reflected_type)
2647 MonoGenericClass *gclass;
2648 MonoDynamicGenericClass *dgclass;
2650 MonoClass *refclass;
2654 MONO_ARCH_SAVE_REGS;
2656 gclass = type->type.type->data.generic_class;
2657 g_assert (gclass->is_dynamic);
2658 dgclass = (MonoDynamicGenericClass *) gclass;
2660 refclass = mono_class_from_mono_type (reflected_type->type);
2662 domain = mono_object_domain (type);
2663 res = mono_array_new (domain, mono_defaults.field_info_class, dgclass->count_fields);
2665 for (i = 0; i < dgclass->count_fields; i++)
2666 mono_array_setref (res, i, mono_field_get_object (domain, refclass, &dgclass->fields [i]));
2672 ves_icall_MonoGenericClass_GetProperties (MonoReflectionGenericClass *type,
2673 MonoReflectionType *reflected_type)
2675 static MonoClass *System_Reflection_PropertyInfo;
2676 MonoGenericClass *gclass;
2677 MonoDynamicGenericClass *dgclass;
2679 MonoClass *refclass;
2683 MONO_ARCH_SAVE_REGS;
2685 if (!System_Reflection_PropertyInfo)
2686 System_Reflection_PropertyInfo = mono_class_from_name (
2687 mono_defaults.corlib, "System.Reflection", "PropertyInfo");
2689 gclass = type->type.type->data.generic_class;
2690 g_assert (gclass->is_dynamic);
2691 dgclass = (MonoDynamicGenericClass *) gclass;
2693 refclass = mono_class_from_mono_type (reflected_type->type);
2695 domain = mono_object_domain (type);
2696 res = mono_array_new (domain, System_Reflection_PropertyInfo, dgclass->count_properties);
2698 for (i = 0; i < dgclass->count_properties; i++)
2699 mono_array_setref (res, i, mono_property_get_object (domain, refclass, &dgclass->properties [i]));
2705 ves_icall_MonoGenericClass_GetEvents (MonoReflectionGenericClass *type,
2706 MonoReflectionType *reflected_type)
2708 static MonoClass *System_Reflection_EventInfo;
2709 MonoGenericClass *gclass;
2710 MonoDynamicGenericClass *dgclass;
2712 MonoClass *refclass;
2716 MONO_ARCH_SAVE_REGS;
2718 if (!System_Reflection_EventInfo)
2719 System_Reflection_EventInfo = mono_class_from_name (
2720 mono_defaults.corlib, "System.Reflection", "EventInfo");
2722 gclass = type->type.type->data.generic_class;
2723 g_assert (gclass->is_dynamic);
2724 dgclass = (MonoDynamicGenericClass *) gclass;
2726 refclass = mono_class_from_mono_type (reflected_type->type);
2728 domain = mono_object_domain (type);
2729 res = mono_array_new (domain, System_Reflection_EventInfo, dgclass->count_events);
2731 for (i = 0; i < dgclass->count_events; i++)
2732 mono_array_setref (res, i, mono_event_get_object (domain, refclass, &dgclass->events [i]));
2737 static MonoReflectionType*
2738 ves_icall_MonoGenericClass_InflateType (MonoReflectionGenericClass *type,
2739 MonoReflectionType *target)
2743 MonoReflectionType *res;
2745 MONO_ARCH_SAVE_REGS;
2747 gklass = mono_class_from_mono_type (type->type.type);
2748 res_type = mono_class_inflate_generic_type (target->type, mono_class_get_context (gklass));
2749 res = mono_type_get_object (mono_object_domain (type), res_type);
2750 mono_metadata_free_type (res_type);
2754 static MonoReflectionMethod *
2755 ves_icall_MonoType_get_DeclaringMethod (MonoReflectionType *type)
2760 MONO_ARCH_SAVE_REGS;
2762 if (type->type->byref || type->type->type != MONO_TYPE_MVAR)
2765 method = type->type->data.generic_param->owner->owner.method;
2767 klass = mono_class_from_mono_type (type->type);
2768 return mono_method_get_object (mono_object_domain (type), method, klass);
2771 static MonoReflectionDllImportAttribute*
2772 ves_icall_MonoMethod_GetDllImportAttribute (MonoMethod *method)
2774 static MonoClass *DllImportAttributeClass = NULL;
2775 MonoDomain *domain = mono_domain_get ();
2776 MonoReflectionDllImportAttribute *attr;
2777 MonoImage *image = method->klass->image;
2778 MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method;
2779 MonoTableInfo *tables = image->tables;
2780 MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
2781 MonoTableInfo *mr = &tables [MONO_TABLE_MODULEREF];
2782 guint32 im_cols [MONO_IMPLMAP_SIZE];
2783 guint32 scope_token;
2784 const char *import = NULL;
2785 const char *scope = NULL;
2788 if (!method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)
2791 if (!DllImportAttributeClass) {
2792 DllImportAttributeClass =
2793 mono_class_from_name (mono_defaults.corlib,
2794 "System.Runtime.InteropServices", "DllImportAttribute");
2795 g_assert (DllImportAttributeClass);
2798 if (method->klass->image->dynamic) {
2799 MonoReflectionMethodAux *method_aux =
2800 g_hash_table_lookup (
2801 ((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
2803 import = method_aux->dllentry;
2804 scope = method_aux->dll;
2808 if (piinfo->implmap_idx) {
2809 mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
2811 piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
2812 import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
2813 scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
2814 scope = mono_metadata_string_heap (image, scope_token);
2817 flags = piinfo->piflags;
2819 attr = (MonoReflectionDllImportAttribute*)mono_object_new (domain, DllImportAttributeClass);
2821 MONO_OBJECT_SETREF (attr, dll, mono_string_new (domain, scope));
2822 MONO_OBJECT_SETREF (attr, entry_point, mono_string_new (domain, import));
2823 attr->call_conv = (flags & 0x700) >> 8;
2824 attr->charset = ((flags & 0x6) >> 1) + 1;
2825 if (attr->charset == 1)
2827 attr->exact_spelling = (flags & 0x1) != 0;
2828 attr->set_last_error = (flags & 0x40) != 0;
2829 attr->best_fit_mapping = (flags & 0x30) == 0x10;
2830 attr->throw_on_unmappable = (flags & 0x3000) == 0x1000;
2831 attr->preserve_sig = FALSE;
2836 static MonoReflectionMethod *
2837 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
2839 MonoMethodInflated *imethod;
2842 MONO_ARCH_SAVE_REGS;
2844 if (method->method->is_generic)
2847 if (!method->method->is_inflated)
2850 imethod = (MonoMethodInflated *) method->method;
2852 result = imethod->declaring;
2853 /* Not a generic method. */
2854 if (!result->is_generic)
2857 if (method->method->klass->image->dynamic) {
2858 MonoDynamicImage *image = (MonoDynamicImage*)method->method->klass->image;
2859 MonoReflectionMethod *res;
2862 * FIXME: Why is this stuff needed at all ? Why can't the code below work for
2863 * the dynamic case as well ?
2865 mono_loader_lock ();
2866 res = mono_g_hash_table_lookup (image->generic_def_objects, imethod);
2867 mono_loader_unlock ();
2873 if (imethod->context.class_inst) {
2874 MonoClass *klass = ((MonoMethod *) imethod)->klass;
2875 result = mono_class_inflate_generic_method_full (result, klass, mono_class_get_context (klass));
2878 return mono_method_get_object (mono_object_domain (method), result, NULL);
2882 ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethod *method)
2884 MONO_ARCH_SAVE_REGS;
2886 return mono_method_signature (method->method)->generic_param_count != 0;
2890 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method)
2892 MONO_ARCH_SAVE_REGS;
2894 return method->method->is_generic;
2898 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
2903 MONO_ARCH_SAVE_REGS;
2905 domain = mono_object_domain (method);
2907 if (method->method->is_inflated) {
2908 MonoGenericInst *inst = mono_method_get_context (method->method)->method_inst;
2911 count = inst->type_argc;
2912 res = mono_array_new (domain, mono_defaults.systemtype_class, count);
2914 for (i = 0; i < count; i++)
2915 mono_array_setref (res, i, mono_type_get_object (domain, inst->type_argv [i]));
2921 count = mono_method_signature (method->method)->generic_param_count;
2922 res = mono_array_new (domain, mono_defaults.systemtype_class, count);
2924 for (i = 0; i < count; i++) {
2925 MonoGenericContainer *container = mono_method_get_generic_container (method->method);
2926 MonoGenericParam *param = &container->type_params [i];
2927 MonoClass *pklass = mono_class_from_generic_parameter (
2928 param, method->method->klass->image, TRUE);
2929 mono_array_setref (res, i,
2930 mono_type_get_object (domain, &pklass->byval_arg));
2937 ensure_reflection_security (void)
2939 MonoMethod *m = mono_method_get_last_managed ();
2943 g_print ("method %s.%s.%s in image %s\n",
2944 m->klass->name_space, m->klass->name, m->name, m->klass->image->name);
2947 /* We stop at the first method which is not in
2948 System.Reflection or which is not in a platform
2950 if (strcmp (m->klass->name_space, "System.Reflection") != 0 ||
2951 !mono_security_core_clr_is_platform_image (m->klass->image)) {
2952 /* If the method is transparent we throw an exception. */
2953 if (mono_security_core_clr_method_level (m, TRUE) == MONO_SECURITY_CORE_CLR_TRANSPARENT ) {
2954 MonoException *ex = mono_exception_from_name_msg (mono_defaults.corlib, "System", "MethodAccessException", "Reflection called from transparent code");
2956 mono_raise_exception (ex);
2961 mono_stack_walk_no_il (get_caller, &m);
2966 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoArray *params, MonoException **exc)
2969 * Invoke from reflection is supposed to always be a virtual call (the API
2970 * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
2971 * greater flexibility.
2973 MonoMethod *m = method->method;
2977 MONO_ARCH_SAVE_REGS;
2981 if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR &&
2982 mono_security_core_clr_method_level (m, TRUE) == MONO_SECURITY_CORE_CLR_CRITICAL)
2983 ensure_reflection_security ();
2985 if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
2987 if (!mono_object_isinst (this, m->klass)) {
2988 *exc = mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Object does not match target type.");
2991 m = mono_object_get_virtual_method (this, m);
2992 /* must pass the pointer to the value for valuetype methods */
2993 if (m->klass->valuetype)
2994 obj = mono_object_unbox (this);
2995 } else if (strcmp (m->name, ".ctor") && !m->wrapper_type) {
2996 *exc = mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Non-static method requires a target.");
3001 pcount = params? mono_array_length (params): 0;
3002 if (pcount != mono_method_signature (m)->param_count) {
3003 *exc = mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException");
3007 if ((m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) && !strcmp (m->name, ".ctor") && !this) {
3008 *exc = mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Cannot invoke constructor of an abstract class.");
3012 if (m->klass->image->assembly->ref_only) {
3013 *exc = mono_get_exception_invalid_operation ("It is illegal to invoke a method on a type loaded using the ReflectionOnly api.");
3017 if (m->klass->rank && !strcmp (m->name, ".ctor")) {
3019 mono_array_size_t *lengths;
3020 mono_array_size_t *lower_bounds;
3021 pcount = mono_array_length (params);
3022 lengths = alloca (sizeof (mono_array_size_t) * pcount);
3023 for (i = 0; i < pcount; ++i)
3024 lengths [i] = *(mono_array_size_t*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
3026 if (m->klass->rank == pcount) {
3027 /* Only lengths provided. */
3028 lower_bounds = NULL;
3030 g_assert (pcount == (m->klass->rank * 2));
3031 /* lower bounds are first. */
3032 lower_bounds = lengths;
3033 lengths += m->klass->rank;
3036 return (MonoObject*)mono_array_new_full (mono_object_domain (params), m->klass, lengths, lower_bounds);
3038 return mono_runtime_invoke_array (m, obj, params, NULL);
3042 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this, MonoArray *params, MonoArray **outArgs)
3044 MonoDomain *domain = mono_object_domain (method);
3045 MonoMethod *m = method->method;
3046 MonoMethodSignature *sig = mono_method_signature (m);
3047 MonoArray *out_args;
3049 int i, j, outarg_count = 0;
3051 MONO_ARCH_SAVE_REGS;
3053 if (m->klass == mono_defaults.object_class) {
3055 if (!strcmp (m->name, "FieldGetter")) {
3056 MonoClass *k = this->vtable->klass;
3060 /* If this is a proxy, then it must be a CBO */
3061 if (k == mono_defaults.transparent_proxy_class) {
3062 MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
3063 this = tp->rp->unwrapped_server;
3065 k = this->vtable->klass;
3068 name = mono_array_get (params, MonoString *, 1);
3069 str = mono_string_to_utf8 (name);
3072 MonoClassField* field = mono_class_get_field_from_name (k, str);
3074 MonoClass *field_klass = mono_class_from_mono_type (field->type);
3075 if (field_klass->valuetype)
3076 result = mono_value_box (domain, field_klass, (char *)this + field->offset);
3078 result = *((gpointer *)((char *)this + field->offset));
3080 out_args = mono_array_new (domain, mono_defaults.object_class, 1);
3081 *outArgs = out_args;
3082 mono_array_setref (out_args, 0, result);
3090 g_assert_not_reached ();
3092 } else if (!strcmp (m->name, "FieldSetter")) {
3093 MonoClass *k = this->vtable->klass;
3099 /* If this is a proxy, then it must be a CBO */
3100 if (k == mono_defaults.transparent_proxy_class) {
3101 MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
3102 this = tp->rp->unwrapped_server;
3104 k = this->vtable->klass;
3107 name = mono_array_get (params, MonoString *, 1);
3108 str = mono_string_to_utf8 (name);
3111 MonoClassField* field = mono_class_get_field_from_name (k, str);
3113 MonoClass *field_klass = mono_class_from_mono_type (field->type);
3114 MonoObject *val = mono_array_get (params, gpointer, 2);
3116 if (field_klass->valuetype) {
3117 size = mono_type_size (field->type, &align);
3118 memcpy ((char *)this + field->offset,
3119 ((char *)val) + sizeof (MonoObject), size);
3121 *(MonoObject**)((char *)this + field->offset) = val;
3123 out_args = mono_array_new (domain, mono_defaults.object_class, 0);
3124 *outArgs = out_args;
3134 g_assert_not_reached ();
3139 for (i = 0; i < mono_array_length (params); i++) {
3140 if (sig->params [i]->byref)
3144 out_args = mono_array_new (domain, mono_defaults.object_class, outarg_count);
3146 /* handle constructors only for objects already allocated */
3147 if (!strcmp (method->method->name, ".ctor"))
3150 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
3151 g_assert (!method->method->klass->valuetype);
3152 result = mono_runtime_invoke_array (method->method, this, params, NULL);
3154 for (i = 0, j = 0; i < mono_array_length (params); i++) {
3155 if (sig->params [i]->byref) {
3157 arg = mono_array_get (params, gpointer, i);
3158 mono_array_setref (out_args, j, arg);
3163 *outArgs = out_args;
3169 read_enum_value (char *mem, int type)
3173 return *(guint8*)mem;
3175 return *(gint8*)mem;
3177 return *(guint16*)mem;
3179 return *(gint16*)mem;
3181 return *(guint32*)mem;
3183 return *(gint32*)mem;
3185 return *(guint64*)mem;
3187 return *(gint64*)mem;
3189 g_assert_not_reached ();
3195 write_enum_value (char *mem, int type, guint64 value)
3199 case MONO_TYPE_I1: {
3200 guint8 *p = (guint8*)mem;
3205 case MONO_TYPE_I2: {
3206 guint16 *p = (void*)mem;
3211 case MONO_TYPE_I4: {
3212 guint32 *p = (void*)mem;
3217 case MONO_TYPE_I8: {
3218 guint64 *p = (void*)mem;
3223 g_assert_not_reached ();
3229 ves_icall_System_Enum_ToObject (MonoReflectionType *enumType, MonoObject *value)
3232 MonoClass *enumc, *objc;
3236 MONO_ARCH_SAVE_REGS;
3238 MONO_CHECK_ARG_NULL (enumType);
3239 MONO_CHECK_ARG_NULL (value);
3241 domain = mono_object_domain (enumType);
3242 enumc = mono_class_from_mono_type (enumType->type);
3243 objc = value->vtable->klass;
3245 if (!enumc->enumtype)
3246 mono_raise_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
3247 if (!((objc->enumtype) || (objc->byval_arg.type >= MONO_TYPE_I1 && objc->byval_arg.type <= MONO_TYPE_U8)))
3248 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."));
3250 res = mono_object_new (domain, enumc);
3251 val = read_enum_value ((char *)value + sizeof (MonoObject), objc->enumtype? objc->enum_basetype->type: objc->byval_arg.type);
3252 write_enum_value ((char *)res + sizeof (MonoObject), enumc->enum_basetype->type, val);
3258 ves_icall_System_Enum_get_value (MonoObject *this)
3266 MONO_ARCH_SAVE_REGS;
3271 g_assert (this->vtable->klass->enumtype);
3273 enumc = mono_class_from_mono_type (this->vtable->klass->enum_basetype);
3274 res = mono_object_new (mono_object_domain (this), enumc);
3275 dst = (char *)res + sizeof (MonoObject);
3276 src = (char *)this + sizeof (MonoObject);
3277 size = mono_class_value_size (enumc, NULL);
3279 memcpy (dst, src, size);
3284 static MonoReflectionType *
3285 ves_icall_System_Enum_get_underlying_type (MonoReflectionType *type)
3287 MONO_ARCH_SAVE_REGS;
3289 return mono_type_get_object (mono_object_domain (type), mono_class_from_mono_type (type->type)->enum_basetype);
3293 ves_icall_System_Enum_get_hashcode (MonoObject *this)
3295 gpointer data = (char *)this + sizeof (MonoObject);
3296 MonoType *basetype = this->vtable->klass->enum_basetype;
3297 g_assert (basetype);
3299 switch (basetype->type) {
3301 return *((gint8*)data);
3303 return *((guint8*)data);
3304 case MONO_TYPE_CHAR:
3306 return *((guint16*)data);
3309 return *((gint16*)data);
3311 return *((guint32*)data);
3313 return *((gint32*)data);
3315 case MONO_TYPE_I8: {
3316 gint64 value = *((gint64*)data);
3317 return (gint)(value & 0xffffffff) ^ (int)(value >> 32);
3320 g_error ("Implement type 0x%02x in get_hashcode", basetype->type);
3326 ves_icall_get_enum_info (MonoReflectionType *type, MonoEnumInfo *info)
3328 MonoDomain *domain = mono_object_domain (type);
3329 MonoClass *enumc = mono_class_from_mono_type (type->type);
3330 guint j = 0, nvalues, crow;
3332 MonoClassField *field;
3334 MONO_ARCH_SAVE_REGS;
3336 info->utype = mono_type_get_object (domain, enumc->enum_basetype);
3337 nvalues = mono_class_num_fields (enumc) ? mono_class_num_fields (enumc) - 1 : 0;
3338 info->names = mono_array_new (domain, mono_defaults.string_class, nvalues);
3339 info->values = mono_array_new (domain, enumc, nvalues);
3343 while ((field = mono_class_get_fields (enumc, &iter))) {
3346 MonoTypeEnum def_type;
3348 if (strcmp ("value__", mono_field_get_name (field)) == 0)
3350 if (mono_field_is_deleted (field))
3352 mono_array_setref (info->names, j, mono_string_new (domain, mono_field_get_name (field)));
3354 p = mono_class_get_field_default_value (field, &def_type);
3355 len = mono_metadata_decode_blob_size (p, &p);
3356 switch (enumc->enum_basetype->type) {
3359 mono_array_set (info->values, gchar, j, *p);
3361 case MONO_TYPE_CHAR:
3364 mono_array_set (info->values, gint16, j, read16 (p));
3368 mono_array_set (info->values, gint32, j, read32 (p));
3372 mono_array_set (info->values, gint64, j, read64 (p));
3375 g_error ("Implement type 0x%02x in get_enum_info", enumc->enum_basetype->type);
3382 BFLAGS_IgnoreCase = 1,
3383 BFLAGS_DeclaredOnly = 2,
3384 BFLAGS_Instance = 4,
3386 BFLAGS_Public = 0x10,
3387 BFLAGS_NonPublic = 0x20,
3388 BFLAGS_FlattenHierarchy = 0x40,
3389 BFLAGS_InvokeMethod = 0x100,
3390 BFLAGS_CreateInstance = 0x200,
3391 BFLAGS_GetField = 0x400,
3392 BFLAGS_SetField = 0x800,
3393 BFLAGS_GetProperty = 0x1000,
3394 BFLAGS_SetProperty = 0x2000,
3395 BFLAGS_ExactBinding = 0x10000,
3396 BFLAGS_SuppressChangeType = 0x20000,
3397 BFLAGS_OptionalParamBinding = 0x40000
3400 static MonoReflectionField *
3401 ves_icall_Type_GetField (MonoReflectionType *type, MonoString *name, guint32 bflags)
3404 MonoClass *startklass, *klass;
3406 MonoClassField *field;
3409 int (*compare_func) (const char *s1, const char *s2) = NULL;
3410 domain = ((MonoObject *)type)->vtable->domain;
3411 klass = startklass = mono_class_from_mono_type (type->type);
3413 MONO_ARCH_SAVE_REGS;
3416 mono_raise_exception (mono_get_exception_argument_null ("name"));
3417 if (type->type->byref)
3420 compare_func = (bflags & BFLAGS_IgnoreCase) ? g_strcasecmp : strcmp;
3423 if (klass->exception_type != MONO_EXCEPTION_NONE)
3424 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3427 while ((field = mono_class_get_fields (klass, &iter))) {
3430 if (field->type == NULL)
3432 if (mono_field_is_deleted (field))
3434 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3435 if (bflags & BFLAGS_Public)
3437 } else if ((klass == startklass) || (field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
3438 if (bflags & BFLAGS_NonPublic) {
3445 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
3446 if (bflags & BFLAGS_Static)
3447 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3450 if (bflags & BFLAGS_Instance)
3457 utf8_name = mono_string_to_utf8 (name);
3459 if (compare_func (mono_field_get_name (field), utf8_name)) {
3465 return mono_field_get_object (domain, klass, field);
3467 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3474 ves_icall_Type_GetFields_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3477 MonoClass *startklass, *klass, *refklass;
3482 MonoClassField *field;
3484 MONO_ARCH_SAVE_REGS;
3486 domain = ((MonoObject *)type)->vtable->domain;
3487 if (type->type->byref)
3488 return mono_array_new (domain, mono_defaults.field_info_class, 0);
3489 klass = startklass = mono_class_from_mono_type (type->type);
3490 refklass = mono_class_from_mono_type (reftype->type);
3494 res = mono_array_new (domain, mono_defaults.field_info_class, len);
3496 if (klass->exception_type != MONO_EXCEPTION_NONE)
3497 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3500 while ((field = mono_class_get_fields (klass, &iter))) {
3502 if (mono_field_is_deleted (field))
3504 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3505 if (bflags & BFLAGS_Public)
3507 } else if ((klass == startklass) || (field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
3508 if (bflags & BFLAGS_NonPublic) {
3515 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
3516 if (bflags & BFLAGS_Static)
3517 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3520 if (bflags & BFLAGS_Instance)
3526 member = (MonoObject*)mono_field_get_object (domain, refklass, field);
3528 MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, len * 2);
3529 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3533 mono_array_setref (res, i, member);
3536 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3539 MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, i);
3540 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3543 * Better solution for the new GC.
3544 * res->max_length = i;
3551 method_nonpublic (MonoMethod* method, gboolean start_klass)
3553 switch (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) {
3554 case METHOD_ATTRIBUTE_ASSEM:
3555 return (start_klass || mono_defaults.generic_ilist_class);
3556 case METHOD_ATTRIBUTE_PRIVATE:
3558 case METHOD_ATTRIBUTE_PUBLIC:
3566 ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
3568 static MonoClass *MethodInfo_array;
3570 MonoClass *startklass, *klass, *refklass;
3575 int i, len, match, nslots;
3576 guint32 method_slots_default [8];
3577 guint32 *method_slots;
3578 gchar *mname = NULL;
3579 int (*compare_func) (const char *s1, const char *s2) = NULL;
3580 MonoVTable *array_vtable;
3582 MONO_ARCH_SAVE_REGS;
3584 if (!MethodInfo_array) {
3585 MonoClass *klass = mono_array_class_get (mono_defaults.method_info_class, 1);
3586 mono_memory_barrier ();
3587 MethodInfo_array = klass;
3590 domain = ((MonoObject *)type)->vtable->domain;
3591 array_vtable = mono_class_vtable (domain, MethodInfo_array);
3592 if (type->type->byref)
3593 return mono_array_new_specific (array_vtable, 0);
3594 klass = startklass = mono_class_from_mono_type (type->type);
3595 refklass = mono_class_from_mono_type (reftype->type);
3598 mname = mono_string_to_utf8 (name);
3599 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
3602 mono_class_setup_vtable (klass);
3604 if (is_generic_parameter (type->type))
3605 nslots = klass->parent->vtable_size;
3607 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : klass->vtable_size;
3608 if (nslots >= sizeof (method_slots_default) * 8) {
3609 method_slots = g_new0 (guint32, nslots / 32 + 1);
3611 method_slots = method_slots_default;
3612 memset (method_slots, 0, sizeof (method_slots_default));
3616 res = mono_array_new_specific (array_vtable, len);
3618 mono_class_setup_vtable (klass);
3619 if (klass->exception_type != MONO_EXCEPTION_NONE)
3620 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3623 while ((method = mono_class_get_methods (klass, &iter))) {
3625 if (method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
3627 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3628 if (bflags & BFLAGS_Public)
3630 } else if ((bflags & BFLAGS_NonPublic) && method_nonpublic (method, (klass == startklass))) {
3636 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3637 if (bflags & BFLAGS_Static)
3638 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3641 if (bflags & BFLAGS_Instance)
3649 if (compare_func (mname, method->name))
3654 if (method->slot != -1) {
3655 g_assert (method->slot < nslots);
3656 if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
3658 method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
3661 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
3664 MonoArray *new_res = mono_array_new_specific (array_vtable, len * 2);
3665 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3669 mono_array_setref (res, i, member);
3672 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3676 if (method_slots != method_slots_default)
3677 g_free (method_slots);
3679 MonoArray *new_res = mono_array_new (domain, mono_defaults.method_info_class, i);
3680 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3683 * Better solution for the new GC.
3684 * res->max_length = i;
3691 ves_icall_Type_GetConstructors_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3694 static MonoClass *System_Reflection_ConstructorInfo;
3695 MonoClass *startklass, *klass, *refklass;
3700 gpointer iter = NULL;
3702 MONO_ARCH_SAVE_REGS;
3704 domain = ((MonoObject *)type)->vtable->domain;
3705 if (type->type->byref)
3706 return mono_array_new (domain, mono_defaults.method_info_class, 0);
3707 klass = startklass = mono_class_from_mono_type (type->type);
3708 refklass = mono_class_from_mono_type (reftype->type);
3710 if (klass->exception_type != MONO_EXCEPTION_NONE)
3711 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3713 if (!System_Reflection_ConstructorInfo)
3714 System_Reflection_ConstructorInfo = mono_class_from_name (
3715 mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
3719 res = mono_array_new (domain, System_Reflection_ConstructorInfo, len);
3721 while ((method = mono_class_get_methods (klass, &iter))) {
3723 if (strcmp (method->name, ".ctor") && strcmp (method->name, ".cctor"))
3725 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3726 if (bflags & BFLAGS_Public)
3729 if (bflags & BFLAGS_NonPublic)
3735 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3736 if (bflags & BFLAGS_Static)
3737 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3740 if (bflags & BFLAGS_Instance)
3746 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
3749 MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, len * 2);
3750 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3754 mono_array_setref (res, i, member);
3758 MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, i);
3759 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3762 * Better solution for the new GC.
3763 * res->max_length = i;
3770 property_hash (gconstpointer data)
3772 MonoProperty *prop = (MonoProperty*)data;
3774 return g_str_hash (prop->name);
3778 property_equal (MonoProperty *prop1, MonoProperty *prop2)
3780 // Properties are hide-by-name-and-signature
3781 if (!g_str_equal (prop1->name, prop2->name))
3784 if (prop1->get && prop2->get && !mono_metadata_signature_equal (mono_method_signature (prop1->get), mono_method_signature (prop2->get)))
3786 if (prop1->set && prop2->set && !mono_metadata_signature_equal (mono_method_signature (prop1->set), mono_method_signature (prop2->set)))
3792 property_accessor_nonpublic (MonoMethod* accessor, gboolean start_klass)
3797 return method_nonpublic (accessor, start_klass);
3801 ves_icall_Type_GetPropertiesByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
3804 static MonoClass *System_Reflection_PropertyInfo;
3805 MonoClass *startklass, *klass;
3812 gchar *propname = NULL;
3813 int (*compare_func) (const char *s1, const char *s2) = NULL;
3815 GHashTable *properties;
3817 MONO_ARCH_SAVE_REGS;
3819 if (!System_Reflection_PropertyInfo)
3820 System_Reflection_PropertyInfo = mono_class_from_name (
3821 mono_defaults.corlib, "System.Reflection", "PropertyInfo");
3823 domain = ((MonoObject *)type)->vtable->domain;
3824 if (type->type->byref)
3825 return mono_array_new (domain, System_Reflection_PropertyInfo, 0);
3826 klass = startklass = mono_class_from_mono_type (type->type);
3828 propname = mono_string_to_utf8 (name);
3829 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
3832 mono_class_setup_vtable (klass);
3834 properties = g_hash_table_new (property_hash, (GEqualFunc)property_equal);
3837 res = mono_array_new (domain, System_Reflection_PropertyInfo, len);
3839 mono_class_setup_vtable (klass);
3840 if (klass->exception_type != MONO_EXCEPTION_NONE) {
3841 g_hash_table_destroy (properties);
3844 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3848 while ((prop = mono_class_get_properties (klass, &iter))) {
3854 flags = method->flags;
3857 if ((prop->get && ((prop->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC)) ||
3858 (prop->set && ((prop->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC))) {
3859 if (bflags & BFLAGS_Public)
3861 } else if (bflags & BFLAGS_NonPublic) {
3862 if (property_accessor_nonpublic(prop->get, startklass == klass) ||
3863 property_accessor_nonpublic(prop->set, startklass == klass)) {
3870 if (flags & METHOD_ATTRIBUTE_STATIC) {
3871 if (bflags & BFLAGS_Static)
3872 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3875 if (bflags & BFLAGS_Instance)
3884 if (compare_func (propname, prop->name))
3888 if (g_hash_table_lookup (properties, prop))
3892 MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, len * 2);
3893 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3897 mono_array_setref (res, i, mono_property_get_object (domain, startklass, prop));
3900 g_hash_table_insert (properties, prop, prop);
3902 if ((!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent)))
3905 g_hash_table_destroy (properties);
3908 MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, i);
3909 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3912 * Better solution for the new GC.
3913 * res->max_length = i;
3919 static MonoReflectionEvent *
3920 ves_icall_MonoType_GetEvent (MonoReflectionType *type, MonoString *name, guint32 bflags)
3923 MonoClass *klass, *startklass;
3929 MONO_ARCH_SAVE_REGS;
3931 event_name = mono_string_to_utf8 (name);
3932 if (type->type->byref)
3934 klass = startklass = mono_class_from_mono_type (type->type);
3935 domain = mono_object_domain (type);
3938 if (klass->exception_type != MONO_EXCEPTION_NONE)
3939 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3942 while ((event = mono_class_get_events (klass, &iter))) {
3943 if (strcmp (event->name, event_name))
3946 method = event->add;
3948 method = event->remove;
3950 method = event->raise;
3952 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3953 if (!(bflags & BFLAGS_Public))
3956 if (!(bflags & BFLAGS_NonPublic))
3958 if ((klass != startklass) && (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PRIVATE)
3963 if (!(bflags & BFLAGS_NonPublic))
3966 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3967 if (!(bflags & BFLAGS_Static))
3969 if (!(bflags & BFLAGS_FlattenHierarchy) && (klass != startklass))
3972 if (!(bflags & BFLAGS_Instance))
3976 g_free (event_name);
3977 return mono_event_get_object (domain, startklass, event);
3980 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3983 g_free (event_name);
3988 ves_icall_Type_GetEvents_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3991 static MonoClass *System_Reflection_EventInfo;
3992 MonoClass *startklass, *klass;
3999 MONO_ARCH_SAVE_REGS;
4001 if (!System_Reflection_EventInfo)
4002 System_Reflection_EventInfo = mono_class_from_name (
4003 mono_defaults.corlib, "System.Reflection", "EventInfo");
4005 domain = mono_object_domain (type);
4006 if (type->type->byref)
4007 return mono_array_new (domain, System_Reflection_EventInfo, 0);
4008 klass = startklass = mono_class_from_mono_type (type->type);
4012 res = mono_array_new (domain, System_Reflection_EventInfo, len);
4014 if (klass->exception_type != MONO_EXCEPTION_NONE)
4015 mono_raise_exception (mono_class_get_exception_for_failure (klass));
4018 while ((event = mono_class_get_events (klass, &iter))) {
4020 method = event->add;
4022 method = event->remove;
4024 method = event->raise;
4026 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
4027 if (bflags & BFLAGS_Public)
4029 } else if ((klass == startklass) || (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) {
4030 if (bflags & BFLAGS_NonPublic)
4035 if (bflags & BFLAGS_NonPublic)
4041 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
4042 if (bflags & BFLAGS_Static)
4043 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
4046 if (bflags & BFLAGS_Instance)
4051 if (bflags & BFLAGS_Instance)
4057 MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, len * 2);
4058 mono_array_memcpy_refs (new_res, 0, res, 0, len);
4062 mono_array_setref (res, i, mono_event_get_object (domain, startklass, event));
4065 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
4068 MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, i);
4069 mono_array_memcpy_refs (new_res, 0, res, 0, i);
4072 * Better solution for the new GC.
4073 * res->max_length = i;
4079 static MonoReflectionType *
4080 ves_icall_Type_GetNestedType (MonoReflectionType *type, MonoString *name, guint32 bflags)
4088 MONO_ARCH_SAVE_REGS;
4090 domain = ((MonoObject *)type)->vtable->domain;
4091 if (type->type->byref)
4093 klass = mono_class_from_mono_type (type->type);
4094 str = mono_string_to_utf8 (name);
4097 if (klass->exception_type != MONO_EXCEPTION_NONE)
4098 mono_raise_exception (mono_class_get_exception_for_failure (klass));
4101 * If a nested type is generic, return its generic type definition.
4102 * Note that this means that the return value is essentially a
4103 * nested type of the generic type definition of @klass.
4105 * A note in MSDN claims that a generic type definition can have
4106 * nested types that aren't generic. In any case, the container of that
4107 * nested type would be the generic type definition.
4109 if (klass->generic_class)
4110 klass = klass->generic_class->container_class;
4113 while ((nested = mono_class_get_nested_types (klass, &iter))) {
4115 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
4116 if (bflags & BFLAGS_Public)
4119 if (bflags & BFLAGS_NonPublic)
4124 if (strcmp (nested->name, str) == 0){
4126 return mono_type_get_object (domain, &nested->byval_arg);
4129 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
4136 ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags)
4146 MONO_ARCH_SAVE_REGS;
4148 domain = ((MonoObject *)type)->vtable->domain;
4149 if (type->type->byref)
4150 return mono_array_new (domain, mono_defaults.monotype_class, 0);
4151 klass = mono_class_from_mono_type (type->type);
4152 if (klass->exception_type != MONO_EXCEPTION_NONE)
4153 mono_raise_exception (mono_class_get_exception_for_failure (klass));
4156 * If a nested type is generic, return its generic type definition.
4157 * Note that this means that the return value is essentially the set
4158 * of nested types of the generic type definition of @klass.
4160 * A note in MSDN claims that a generic type definition can have
4161 * nested types that aren't generic. In any case, the container of that
4162 * nested type would be the generic type definition.
4164 if (klass->generic_class)
4165 klass = klass->generic_class->container_class;
4169 res = mono_array_new (domain, mono_defaults.monotype_class, len);
4171 while ((nested = mono_class_get_nested_types (klass, &iter))) {
4173 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
4174 if (bflags & BFLAGS_Public)
4177 if (bflags & BFLAGS_NonPublic)
4182 member = (MonoObject*)mono_type_get_object (domain, &nested->byval_arg);
4184 MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, len * 2);
4185 mono_array_memcpy_refs (new_res, 0, res, 0, len);
4189 mono_array_setref (res, i, member);
4193 MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, i);
4194 mono_array_memcpy_refs (new_res, 0, res, 0, i);
4197 * Better solution for the new GC.
4198 * res->max_length = i;
4204 static MonoReflectionType*
4205 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *assembly, MonoReflectionModule *module, MonoString *name, MonoBoolean throwOnError, MonoBoolean ignoreCase)
4208 MonoType *type = NULL;
4209 MonoTypeNameParse info;
4210 gboolean type_resolve;
4212 MONO_ARCH_SAVE_REGS;
4214 /* On MS.NET, this does not fire a TypeResolve event */
4215 type_resolve = TRUE;
4216 str = mono_string_to_utf8 (name);
4217 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
4218 if (!mono_reflection_parse_type (str, &info)) {
4220 mono_reflection_free_type_info (&info);
4221 if (throwOnError) /* uhm: this is a parse error, though... */
4222 mono_raise_exception (mono_get_exception_type_load (name, NULL));
4223 /*g_print ("failed parse\n");*/
4227 if (info.assembly.name) {
4229 mono_reflection_free_type_info (&info);
4231 /* 1.0 and 2.0 throw different exceptions */
4232 if (mono_defaults.generic_ilist_class)
4233 mono_raise_exception (mono_get_exception_argument (NULL, "Type names passed to Assembly.GetType() must not specify an assembly."));
4235 mono_raise_exception (mono_get_exception_type_load (name, NULL));
4240 if (module != NULL) {
4242 type = mono_reflection_get_type (module->image, &info, ignoreCase, &type_resolve);
4247 if (assembly->assembly->dynamic) {
4248 /* Enumerate all modules */
4249 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
4253 if (abuilder->modules) {
4254 for (i = 0; i < mono_array_length (abuilder->modules); ++i) {
4255 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
4256 type = mono_reflection_get_type (&mb->dynamic_image->image, &info, ignoreCase, &type_resolve);
4262 if (!type && abuilder->loaded_modules) {
4263 for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) {
4264 MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
4265 type = mono_reflection_get_type (mod->image, &info, ignoreCase, &type_resolve);
4272 type = mono_reflection_get_type (assembly->assembly->image, &info, ignoreCase, &type_resolve);
4274 mono_reflection_free_type_info (&info);
4276 MonoException *e = NULL;
4279 e = mono_get_exception_type_load (name, NULL);
4281 mono_loader_clear_error ();
4284 mono_raise_exception (e);
4289 if (type->type == MONO_TYPE_CLASS) {
4290 MonoClass *klass = mono_type_get_class (type);
4292 if (mono_is_security_manager_active () && !klass->exception_type)
4293 /* Some security problems are detected during generic vtable construction */
4294 mono_class_setup_vtable (klass);
4295 /* need to report exceptions ? */
4296 if (throwOnError && klass->exception_type) {
4297 /* report SecurityException (or others) that occured when loading the assembly */
4298 MonoException *exc = mono_class_get_exception_for_failure (klass);
4299 mono_loader_clear_error ();
4300 mono_raise_exception (exc);
4301 } else if (klass->exception_type == MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND) {
4306 /* g_print ("got it\n"); */
4307 return mono_type_get_object (mono_object_domain (assembly), type);
4311 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *assembly, MonoBoolean escaped)
4313 MonoDomain *domain = mono_object_domain (assembly);
4314 MonoAssembly *mass = assembly->assembly;
4315 MonoString *res = NULL;
4319 gchar *shadow_ini_file;
4323 MONO_ARCH_SAVE_REGS;
4325 if (g_path_is_absolute (mass->image->name)) {
4326 absolute = g_strdup (mass->image->name);
4327 dirname = g_path_get_dirname (absolute);
4329 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4330 dirname = g_strdup (mass->basedir);
4333 /* Check for shadow-copied assembly */
4334 if (mono_is_shadow_copy_enabled (domain, dirname)) {
4335 shadow_ini_file = g_build_filename (dirname, "__AssemblyInfo__.ini", NULL);
4337 if (!g_file_get_contents (shadow_ini_file, &content, &len, NULL) ||
4338 !g_file_test (content, G_FILE_TEST_IS_REGULAR)) {
4344 g_free (shadow_ini_file);
4345 if (content != NULL) {
4355 for (i = strlen (absolute) - 1; i >= 0; i--)
4356 if (absolute [i] == '\\')
4361 uri = g_filename_to_uri (absolute, NULL, NULL);
4363 const char *prepend = "file://";
4365 if (*absolute == '/' && *(absolute + 1) == '/') {
4368 prepend = "file:///";
4371 uri = g_strconcat (prepend, absolute, NULL);
4375 res = mono_string_new (domain, uri);
4383 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssembly *assembly)
4385 MonoAssembly *mass = assembly->assembly;
4387 MONO_ARCH_SAVE_REGS;
4389 return mass->in_gac;
4392 static MonoReflectionAssembly*
4393 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoString *mname, MonoObject *evidence)
4397 MonoImageOpenStatus status;
4399 MONO_ARCH_SAVE_REGS;
4401 name = mono_string_to_utf8 (mname);
4402 res = mono_assembly_load_with_partial_name (name, &status);
4408 return mono_assembly_get_object (mono_domain_get (), res);
4412 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssembly *assembly)
4414 MonoDomain *domain = mono_object_domain (assembly);
4417 MONO_ARCH_SAVE_REGS;
4419 res = mono_string_new (domain, mono_image_get_filename (assembly->assembly->image));
4425 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssembly *assembly)
4427 MONO_ARCH_SAVE_REGS;
4429 return assembly->assembly->ref_only;
4433 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssembly *assembly)
4435 MonoDomain *domain = mono_object_domain (assembly);
4437 MONO_ARCH_SAVE_REGS;
4439 return mono_string_new (domain, assembly->assembly->image->version);
4442 static MonoReflectionMethod*
4443 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssembly *assembly)
4445 guint32 token = mono_image_get_entry_point (assembly->assembly->image);
4447 MONO_ARCH_SAVE_REGS;
4451 return mono_method_get_object (mono_object_domain (assembly), mono_get_method (assembly->assembly->image, token, NULL), NULL);
4454 static MonoReflectionModule*
4455 ves_icall_System_Reflection_Assembly_GetManifestModuleInternal (MonoReflectionAssembly *assembly)
4457 return mono_module_get_object (mono_object_domain (assembly), assembly->assembly->image);
4461 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssembly *assembly)
4463 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4464 MonoArray *result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, table->rows);
4468 MONO_ARCH_SAVE_REGS;
4470 for (i = 0; i < table->rows; ++i) {
4471 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_MANIFEST_NAME));
4472 mono_array_setref (result, i, mono_string_new (mono_object_domain (assembly), val));
4478 create_version (MonoDomain *domain, guint32 major, guint32 minor, guint32 build, guint32 revision)
4480 static MonoClass *System_Version = NULL;
4481 static MonoMethod *create_version = NULL;
4485 if (!System_Version) {
4486 System_Version = mono_class_from_name (mono_defaults.corlib, "System", "Version");
4487 g_assert (System_Version);
4490 if (!create_version) {
4491 MonoMethodDesc *desc = mono_method_desc_new (":.ctor(int,int,int,int)", FALSE);
4492 create_version = mono_method_desc_search_in_class (desc, System_Version);
4493 g_assert (create_version);
4494 mono_method_desc_free (desc);
4500 args [3] = &revision;
4501 result = mono_object_new (domain, System_Version);
4502 mono_runtime_invoke (create_version, result, args, NULL);
4508 ves_icall_System_Reflection_Assembly_GetReferencedAssemblies (MonoReflectionAssembly *assembly)
4510 static MonoClass *System_Reflection_AssemblyName;
4512 MonoDomain *domain = mono_object_domain (assembly);
4514 static MonoMethod *create_culture = NULL;
4515 MonoImage *image = assembly->assembly->image;
4518 MONO_ARCH_SAVE_REGS;
4520 if (!System_Reflection_AssemblyName)
4521 System_Reflection_AssemblyName = mono_class_from_name (
4522 mono_defaults.corlib, "System.Reflection", "AssemblyName");
4524 t = &assembly->assembly->image->tables [MONO_TABLE_ASSEMBLYREF];
4527 result = mono_array_new (domain, System_Reflection_AssemblyName, count);
4530 MonoMethodDesc *desc = mono_method_desc_new (
4531 "System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE);
4532 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4533 g_assert (create_culture);
4534 mono_method_desc_free (desc);
4537 for (i = 0; i < count; i++) {
4538 MonoReflectionAssemblyName *aname;
4539 guint32 cols [MONO_ASSEMBLYREF_SIZE];
4541 mono_metadata_decode_row (t, i, cols, MONO_ASSEMBLYREF_SIZE);
4543 aname = (MonoReflectionAssemblyName *) mono_object_new (
4544 domain, System_Reflection_AssemblyName);
4546 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_NAME])));
4548 aname->major = cols [MONO_ASSEMBLYREF_MAJOR_VERSION];
4549 aname->minor = cols [MONO_ASSEMBLYREF_MINOR_VERSION];
4550 aname->build = cols [MONO_ASSEMBLYREF_BUILD_NUMBER];
4551 aname->revision = cols [MONO_ASSEMBLYREF_REV_NUMBER];
4552 aname->flags = cols [MONO_ASSEMBLYREF_FLAGS];
4553 aname->versioncompat = 1; /* SameMachine (default) */
4554 aname->hashalg = ASSEMBLY_HASH_SHA1; /* SHA1 (default) */
4555 MONO_OBJECT_SETREF (aname, version, create_version (domain, aname->major, aname->minor, aname->build, aname->revision));
4557 if (create_culture) {
4559 MonoBoolean assembly_ref = 1;
4560 args [0] = mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_CULTURE]));
4561 args [1] = &assembly_ref;
4562 MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
4565 if (cols [MONO_ASSEMBLYREF_PUBLIC_KEY]) {
4566 const gchar *pkey_ptr = mono_metadata_blob_heap (image, cols [MONO_ASSEMBLYREF_PUBLIC_KEY]);
4567 guint32 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
4569 if ((cols [MONO_ASSEMBLYREF_FLAGS] & ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG)) {
4570 /* public key token isn't copied - the class library will
4571 automatically generate it from the public key if required */
4572 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4573 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
4575 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4576 memcpy (mono_array_addr (aname->keyToken, guint8, 0), pkey_ptr, pkey_len);
4579 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, 0));
4582 /* note: this function doesn't return the codebase on purpose (i.e. it can
4583 be used under partial trust as path information isn't present). */
4585 mono_array_setref (result, i, aname);
4596 foreach_namespace (const char* key, gconstpointer val, NameSpaceInfo *info)
4598 MonoString *name = mono_string_new (mono_object_domain (info->res), key);
4600 mono_array_setref (info->res, info->idx, name);
4605 ves_icall_System_Reflection_Assembly_GetNamespaces (MonoReflectionAssembly *assembly)
4607 MonoImage *img = assembly->assembly->image;
4611 MONO_ARCH_SAVE_REGS;
4613 if (!img->name_cache)
4614 mono_image_init_name_cache (img);
4616 res = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, g_hash_table_size (img->name_cache));
4619 g_hash_table_foreach (img->name_cache, (GHFunc)foreach_namespace, &info);
4624 /* move this in some file in mono/util/ */
4626 g_concat_dir_and_file (const char *dir, const char *file)
4628 g_return_val_if_fail (dir != NULL, NULL);
4629 g_return_val_if_fail (file != NULL, NULL);
4632 * If the directory name doesn't have a / on the end, we need
4633 * to add one so we get a proper path to the file
4635 if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
4636 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
4638 return g_strconcat (dir, file, NULL);
4642 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssembly *assembly, MonoString *name, gint32 *size, MonoReflectionModule **ref_module)
4644 char *n = mono_string_to_utf8 (name);
4645 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4647 guint32 cols [MONO_MANIFEST_SIZE];
4648 guint32 impl, file_idx;
4652 MONO_ARCH_SAVE_REGS;
4654 for (i = 0; i < table->rows; ++i) {
4655 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4656 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4657 if (strcmp (val, n) == 0)
4661 if (i == table->rows)
4664 impl = cols [MONO_MANIFEST_IMPLEMENTATION];
4667 * this code should only be called after obtaining the
4668 * ResourceInfo and handling the other cases.
4670 g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
4671 file_idx = impl >> MONO_IMPLEMENTATION_BITS;
4673 module = mono_image_load_file_for_image (assembly->assembly->image, file_idx);
4678 module = assembly->assembly->image;
4680 *ref_module = mono_module_get_object (mono_domain_get (), module);
4682 return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
4686 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoManifestResourceInfo *info)
4688 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4690 guint32 cols [MONO_MANIFEST_SIZE];
4691 guint32 file_cols [MONO_FILE_SIZE];
4695 MONO_ARCH_SAVE_REGS;
4697 n = mono_string_to_utf8 (name);
4698 for (i = 0; i < table->rows; ++i) {
4699 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4700 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4701 if (strcmp (val, n) == 0)
4705 if (i == table->rows)
4708 if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
4709 info->location = RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST;
4712 switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
4713 case MONO_IMPLEMENTATION_FILE:
4714 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4715 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4716 mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
4717 val = mono_metadata_string_heap (assembly->assembly->image, file_cols [MONO_FILE_NAME]);
4718 MONO_OBJECT_SETREF (info, filename, mono_string_new (mono_object_domain (assembly), val));
4719 if (file_cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA)
4722 info->location = RESOURCE_LOCATION_EMBEDDED;
4725 case MONO_IMPLEMENTATION_ASSEMBLYREF:
4726 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4727 mono_assembly_load_reference (assembly->assembly->image, i - 1);
4728 if (assembly->assembly->image->references [i - 1] == (gpointer)-1) {
4729 char *msg = g_strdup_printf ("Assembly %d referenced from assembly %s not found ", i - 1, assembly->assembly->image->name);
4730 MonoException *ex = mono_get_exception_file_not_found2 (msg, NULL);
4732 mono_raise_exception (ex);
4734 MONO_OBJECT_SETREF (info, assembly, mono_assembly_get_object (mono_domain_get (), assembly->assembly->image->references [i - 1]));
4736 /* Obtain info recursively */
4737 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (info->assembly, name, info);
4738 info->location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
4741 case MONO_IMPLEMENTATION_EXP_TYPE:
4742 g_assert_not_reached ();
4751 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoBoolean resource_modules)
4753 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4754 MonoArray *result = NULL;
4759 MONO_ARCH_SAVE_REGS;
4761 /* check hash if needed */
4763 n = mono_string_to_utf8 (name);
4764 for (i = 0; i < table->rows; ++i) {
4765 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4766 if (strcmp (val, n) == 0) {
4769 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4770 fn = mono_string_new (mono_object_domain (assembly), n);
4772 return (MonoObject*)fn;
4780 for (i = 0; i < table->rows; ++i) {
4781 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA))
4785 result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, count);
4788 for (i = 0; i < table->rows; ++i) {
4789 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4790 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4791 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4792 mono_array_setref (result, count, mono_string_new (mono_object_domain (assembly), n));
4797 return (MonoObject*)result;
4801 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly *assembly)
4803 MonoDomain *domain = mono_domain_get();
4806 int i, j, file_count = 0;
4807 MonoImage **modules;
4808 guint32 module_count, real_module_count;
4809 MonoTableInfo *table;
4810 guint32 cols [MONO_FILE_SIZE];
4811 MonoImage *image = assembly->assembly->image;
4813 g_assert (image != NULL);
4814 g_assert (!assembly->assembly->dynamic);
4816 table = &image->tables [MONO_TABLE_FILE];
4817 file_count = table->rows;
4819 modules = image->modules;
4820 module_count = image->module_count;
4822 real_module_count = 0;
4823 for (i = 0; i < module_count; ++i)
4825 real_module_count ++;
4827 klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "Module");
4828 res = mono_array_new (domain, klass, 1 + real_module_count + file_count);
4830 mono_array_setref (res, 0, mono_module_get_object (domain, image));
4832 for (i = 0; i < module_count; ++i)
4834 mono_array_setref (res, j, mono_module_get_object (domain, modules[i]));
4838 for (i = 0; i < file_count; ++i, ++j) {
4839 mono_metadata_decode_row (table, i, cols, MONO_FILE_SIZE);
4840 if (cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA)
4841 mono_array_setref (res, j, mono_module_file_get_object (domain, image, i));
4843 MonoImage *m = mono_image_load_file_for_image (image, i + 1);
4845 MonoString *fname = mono_string_new (mono_domain_get (), mono_metadata_string_heap (image, cols [MONO_FILE_NAME]));
4846 mono_raise_exception (mono_get_exception_file_not_found2 (NULL, fname));
4848 mono_array_setref (res, j, mono_module_get_object (domain, m));
4855 static MonoReflectionMethod*
4856 ves_icall_GetCurrentMethod (void)
4858 MonoMethod *m = mono_method_get_last_managed ();
4860 MONO_ARCH_SAVE_REGS;
4862 return mono_method_get_object (mono_domain_get (), m, NULL);
4867 mono_method_get_equivalent_method (MonoMethod *method, MonoClass *klass)
4870 if (method->is_inflated && ((MonoMethodInflated*)method)->context.method_inst) {
4871 MonoMethodInflated *inflated = (MonoMethodInflated*)method;
4872 //method is inflated, we should inflate it on the other class
4873 MonoGenericContext ctx;
4874 ctx.method_inst = inflated->context.method_inst;
4875 ctx.class_inst = inflated->context.class_inst;
4876 if (klass->generic_class)
4877 ctx.class_inst = klass->generic_class->context.class_inst;
4878 else if (klass->generic_container)
4879 ctx.class_inst = klass->generic_container->context.class_inst;
4880 return mono_class_inflate_generic_method_full (inflated->declaring, klass, &ctx);
4883 for (i = 0; i < method->klass->method.count; ++i) {
4884 if (method->klass->methods [i] == method) {
4889 mono_class_setup_methods (klass);
4890 g_assert (offset >= 0 && offset < klass->method.count);
4891 return klass->methods [offset];
4894 static MonoReflectionMethod*
4895 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType (MonoMethod *method, MonoType *type)
4899 klass = mono_class_from_mono_type (type);
4900 if (mono_class_get_generic_type_definition (method->klass) != mono_class_get_generic_type_definition (klass))
4902 if (method->klass != klass)
4903 method = mono_method_get_equivalent_method (method, klass);
4905 klass = method->klass;
4906 return mono_method_get_object (mono_domain_get (), method, klass);
4909 static MonoReflectionMethod*
4910 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternal (MonoMethod *method)
4912 return mono_method_get_object (mono_domain_get (), method, NULL);
4915 static MonoReflectionMethodBody*
4916 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod *method)
4918 return mono_method_body_get_object (mono_domain_get (), method);
4921 static MonoReflectionAssembly*
4922 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (void)
4924 MonoMethod *m = mono_method_get_last_managed ();
4926 MONO_ARCH_SAVE_REGS;
4928 return mono_assembly_get_object (mono_domain_get (), m->klass->image->assembly);
4932 static MonoReflectionAssembly*
4933 ves_icall_System_Reflection_Assembly_GetEntryAssembly (void)
4935 MonoDomain* domain = mono_domain_get ();
4937 MONO_ARCH_SAVE_REGS;
4939 if (!domain->entry_assembly)
4942 return mono_assembly_get_object (domain, domain->entry_assembly);
4945 static MonoReflectionAssembly*
4946 ves_icall_System_Reflection_Assembly_GetCallingAssembly (void)
4948 MonoMethod *m = mono_method_get_last_managed ();
4949 MonoMethod *dest = m;
4951 MONO_ARCH_SAVE_REGS;
4953 mono_stack_walk_no_il (get_caller, &dest);
4956 return mono_assembly_get_object (mono_domain_get (), dest->klass->image->assembly);
4960 ves_icall_System_MonoType_getFullName (MonoReflectionType *object, gboolean full_name,
4961 gboolean assembly_qualified)
4963 MonoDomain *domain = mono_object_domain (object);
4964 MonoTypeNameFormat format;
4968 MONO_ARCH_SAVE_REGS;
4970 format = assembly_qualified ?
4971 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
4972 MONO_TYPE_NAME_FORMAT_FULL_NAME;
4974 format = MONO_TYPE_NAME_FORMAT_REFLECTION;
4976 name = mono_type_get_name_full (object->type, format);
4980 if (full_name && (object->type->type == MONO_TYPE_VAR || object->type->type == MONO_TYPE_MVAR)) {
4985 res = mono_string_new (domain, name);
4992 fill_reflection_assembly_name (MonoDomain *domain, MonoReflectionAssemblyName *aname, MonoAssemblyName *name, const char *absolute, gboolean by_default_version, gboolean default_publickey, gboolean default_token)
4994 static MonoMethod *create_culture = NULL;
4997 const char *pkey_ptr;
4999 MonoBoolean assembly_ref = 0;
5001 MONO_ARCH_SAVE_REGS;
5003 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, name->name));
5004 aname->major = name->major;
5005 aname->minor = name->minor;
5006 aname->build = name->build;
5007 aname->flags = name->flags;
5008 aname->revision = name->revision;
5009 aname->hashalg = name->hash_alg;
5010 aname->versioncompat = 1; /* SameMachine (default) */
5012 if (by_default_version)
5013 MONO_OBJECT_SETREF (aname, version, create_version (domain, name->major, name->minor, name->build, name->revision));
5016 if (absolute != NULL && *absolute != '\0') {
5017 const gchar *prepend = "file://";
5020 codebase = g_strdup (absolute);
5025 for (i = strlen (codebase) - 1; i >= 0; i--)
5026 if (codebase [i] == '\\')
5029 if (*codebase == '/' && *(codebase + 1) == '/') {
5032 prepend = "file:///";
5036 result = g_strconcat (prepend, codebase, NULL);
5042 MONO_OBJECT_SETREF (aname, codebase, mono_string_new (domain, codebase));
5046 if (!create_culture) {
5047 MonoMethodDesc *desc = mono_method_desc_new ("System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE);
5048 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
5049 g_assert (create_culture);
5050 mono_method_desc_free (desc);
5053 if (name->culture) {
5054 args [0] = mono_string_new (domain, name->culture);
5055 args [1] = &assembly_ref;
5056 MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
5059 if (name->public_key) {
5060 pkey_ptr = (char*)name->public_key;
5061 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
5063 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
5064 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
5065 aname->flags |= ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG;
5066 } else if (default_publickey) {
5067 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, 0));
5068 aname->flags |= ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG;
5071 /* MonoAssemblyName keeps the public key token as an hexadecimal string */
5072 if (name->public_key_token [0]) {
5076 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, 8));
5077 p = mono_array_addr (aname->keyToken, char, 0);
5079 for (i = 0, j = 0; i < 8; i++) {
5080 *p = g_ascii_xdigit_value (name->public_key_token [j++]) << 4;
5081 *p |= g_ascii_xdigit_value (name->public_key_token [j++]);
5084 } else if (default_token) {
5085 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, 0));
5090 ves_icall_System_Reflection_Assembly_get_fullName (MonoReflectionAssembly *assembly)
5092 MonoDomain *domain = mono_object_domain (assembly);
5093 MonoAssembly *mass = assembly->assembly;
5097 name = g_strdup_printf (
5098 "%s, Version=%d.%d.%d.%d, Culture=%s, PublicKeyToken=%s%s",
5100 mass->aname.major, mass->aname.minor, mass->aname.build, mass->aname.revision,
5101 mass->aname.culture && *mass->aname.culture? mass->aname.culture: "neutral",
5102 mass->aname.public_key_token [0] ? (char *)mass->aname.public_key_token : "null",
5103 (mass->aname.flags & ASSEMBLYREF_RETARGETABLE_FLAG) ? ", Retargetable=Yes" : "");
5105 res = mono_string_new (domain, name);
5112 ves_icall_System_Reflection_Assembly_FillName (MonoReflectionAssembly *assembly, MonoReflectionAssemblyName *aname)
5115 MonoAssembly *mass = assembly->assembly;
5117 MONO_ARCH_SAVE_REGS;
5119 if (g_path_is_absolute (mass->image->name)) {
5120 fill_reflection_assembly_name (mono_object_domain (assembly),
5121 aname, &mass->aname, mass->image->name, TRUE,
5122 TRUE, mono_framework_version () >= 2);
5125 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
5127 fill_reflection_assembly_name (mono_object_domain (assembly),
5128 aname, &mass->aname, absolute, TRUE, TRUE,
5129 mono_framework_version () >= 2);
5135 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoString *fname, MonoReflectionAssemblyName *aname)
5138 MonoImageOpenStatus status = MONO_IMAGE_OK;
5141 MonoAssemblyName name;
5143 MONO_ARCH_SAVE_REGS;
5145 filename = mono_string_to_utf8 (fname);
5147 image = mono_image_open (filename, &status);
5153 if (status == MONO_IMAGE_IMAGE_INVALID)
5154 exc = mono_get_exception_bad_image_format2 (NULL, fname);
5156 exc = mono_get_exception_file_not_found2 (NULL, fname);
5157 mono_raise_exception (exc);
5160 res = mono_assembly_fill_assembly_name (image, &name);
5162 mono_image_close (image);
5164 mono_raise_exception (mono_get_exception_argument ("assemblyFile", "The file does not contain a manifest"));
5167 fill_reflection_assembly_name (mono_domain_get (), aname, &name, filename,
5168 TRUE, mono_framework_version () == 1,
5169 mono_framework_version () >= 2);
5172 mono_image_close (image);
5176 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssembly *assembly,
5177 char **minimum, guint32 *minLength, char **optional, guint32 *optLength, char **refused, guint32 *refLength)
5179 MonoBoolean result = FALSE;
5180 MonoDeclSecurityEntry entry;
5182 /* SecurityAction.RequestMinimum */
5183 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQMIN, &entry)) {
5184 *minimum = entry.blob;
5185 *minLength = entry.size;
5188 /* SecurityAction.RequestOptional */
5189 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQOPT, &entry)) {
5190 *optional = entry.blob;
5191 *optLength = entry.size;
5194 /* SecurityAction.RequestRefuse */
5195 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQREFUSE, &entry)) {
5196 *refused = entry.blob;
5197 *refLength = entry.size;
5205 mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoArray **exceptions, MonoBoolean exportedOnly)
5209 MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
5211 guint32 attrs, visibility;
5213 /* we start the count from 1 because we skip the special type <Module> */
5216 for (i = 1; i < tdef->rows; ++i) {
5217 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
5218 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
5219 if (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)
5223 count = tdef->rows - 1;
5225 res = mono_array_new (domain, mono_defaults.monotype_class, count);
5226 *exceptions = mono_array_new (domain, mono_defaults.exception_class, count);
5228 for (i = 1; i < tdef->rows; ++i) {
5229 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
5230 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
5231 if (!exportedOnly || (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)) {
5232 klass = mono_class_get (image, (i + 1) | MONO_TOKEN_TYPE_DEF);
5234 mono_array_setref (res, count, mono_type_get_object (domain, &klass->byval_arg));
5236 MonoLoaderError *error;
5239 error = mono_loader_get_last_error ();
5240 g_assert (error != NULL);
5242 ex = mono_loader_error_prepare_exception (error);
5243 mono_array_setref (*exceptions, count, ex);
5245 if (mono_loader_get_last_error ())
5246 mono_loader_clear_error ();
5255 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly, MonoBoolean exportedOnly)
5257 MonoArray *res = NULL;
5258 MonoArray *exceptions = NULL;
5259 MonoImage *image = NULL;
5260 MonoTableInfo *table = NULL;
5263 int i, len, ex_count;
5265 MONO_ARCH_SAVE_REGS;
5267 domain = mono_object_domain (assembly);
5269 g_assert (!assembly->assembly->dynamic);
5270 image = assembly->assembly->image;
5271 table = &image->tables [MONO_TABLE_FILE];
5272 res = mono_module_get_types (domain, image, &exceptions, exportedOnly);
5274 /* Append data from all modules in the assembly */
5275 for (i = 0; i < table->rows; ++i) {
5276 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
5277 MonoImage *loaded_image = mono_assembly_load_module (image->assembly, i + 1);
5280 MonoArray *res2 = mono_module_get_types (domain, loaded_image, &ex2, exportedOnly);
5281 /* Append the new types to the end of the array */
5282 if (mono_array_length (res2) > 0) {
5284 MonoArray *res3, *ex3;
5286 len1 = mono_array_length (res);
5287 len2 = mono_array_length (res2);
5289 res3 = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
5290 mono_array_memcpy_refs (res3, 0, res, 0, len1);
5291 mono_array_memcpy_refs (res3, len1, res2, 0, len2);
5294 ex3 = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
5295 mono_array_memcpy_refs (ex3, 0, exceptions, 0, len1);
5296 mono_array_memcpy_refs (ex3, len1, ex2, 0, len2);
5303 /* the ReflectionTypeLoadException must have all the types (Types property),
5304 * NULL replacing types which throws an exception. The LoaderException must
5305 * contain all exceptions for NULL items.
5308 len = mono_array_length (res);
5311 for (i = 0; i < len; i++) {
5312 MonoReflectionType *t = mono_array_get (res, gpointer, i);
5316 klass = mono_type_get_class (t->type);
5317 if ((klass != NULL) && klass->exception_type) {
5318 /* keep the class in the list */
5319 list = g_list_append (list, klass);
5320 /* and replace Type with NULL */
5321 mono_array_setref (res, i, NULL);
5328 if (list || ex_count) {
5330 MonoException *exc = NULL;
5331 MonoArray *exl = NULL;
5332 int j, length = g_list_length (list) + ex_count;
5334 mono_loader_clear_error ();
5336 exl = mono_array_new (domain, mono_defaults.exception_class, length);
5337 /* Types for which mono_class_get () succeeded */
5338 for (i = 0, tmp = list; tmp; i++, tmp = tmp->next) {
5339 MonoException *exc = mono_class_get_exception_for_failure (tmp->data);
5340 mono_array_setref (exl, i, exc);
5342 /* Types for which it don't */
5343 for (j = 0; j < mono_array_length (exceptions); ++j) {
5344 MonoException *exc = mono_array_get (exceptions, MonoException*, j);
5346 g_assert (i < length);
5347 mono_array_setref (exl, i, exc);
5354 exc = mono_get_exception_reflection_type_load (res, exl);
5355 mono_loader_clear_error ();
5356 mono_raise_exception (exc);
5363 ves_icall_System_Reflection_AssemblyName_ParseName (MonoReflectionAssemblyName *name, MonoString *assname)
5365 MonoAssemblyName aname;
5366 MonoDomain *domain = mono_object_domain (name);
5368 gboolean is_version_defined;
5369 gboolean is_token_defined;
5371 aname.public_key = NULL;
5372 val = mono_string_to_utf8 (assname);
5373 if (!mono_assembly_name_parse_full (val, &aname, TRUE, &is_version_defined, &is_token_defined)) {
5374 g_free ((guint8*) aname.public_key);
5379 fill_reflection_assembly_name (domain, name, &aname, "", is_version_defined,
5380 FALSE, is_token_defined);
5382 mono_assembly_name_free (&aname);
5383 g_free ((guint8*) aname.public_key);
5389 static MonoReflectionType*
5390 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModule *module)
5392 MonoDomain *domain = mono_object_domain (module);
5395 MONO_ARCH_SAVE_REGS;
5397 g_assert (module->image);
5399 if (module->image->dynamic && ((MonoDynamicImage*)(module->image))->initial_image)
5400 /* These images do not have a global type */
5403 klass = mono_class_get (module->image, 1 | MONO_TOKEN_TYPE_DEF);
5404 return mono_type_get_object (domain, &klass->byval_arg);
5408 ves_icall_System_Reflection_Module_Close (MonoReflectionModule *module)
5410 /*if (module->image)
5411 mono_image_close (module->image);*/
5415 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModule *module)
5417 MonoDomain *domain = mono_object_domain (module);
5419 MONO_ARCH_SAVE_REGS;
5421 g_assert (module->image);
5422 return mono_string_new (domain, module->image->guid);
5426 ves_icall_System_Reflection_Module_GetHINSTANCE (MonoReflectionModule *module)
5428 #ifdef PLATFORM_WIN32
5429 if (module->image && module->image->is_module_handle)
5430 return module->image->raw_data;
5433 return (gpointer) (-1);
5437 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine)
5439 if (image->dynamic) {
5440 MonoDynamicImage *dyn = (MonoDynamicImage*)image;
5441 *pe_kind = dyn->pe_kind;
5442 *machine = dyn->machine;
5445 *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
5446 *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
5451 ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage *image)
5453 return (image->md_version_major << 16) | (image->md_version_minor);
5457 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModule *module)
5459 MonoArray *exceptions;
5462 MONO_ARCH_SAVE_REGS;
5465 return mono_array_new (mono_object_domain (module), mono_defaults.monotype_class, 0);
5467 MonoArray *res = mono_module_get_types (mono_object_domain (module), module->image, &exceptions, FALSE);
5468 for (i = 0; i < mono_array_length (exceptions); ++i) {
5469 MonoException *ex = mono_array_get (exceptions, MonoException *, i);
5471 mono_raise_exception (ex);
5478 mono_metadata_memberref_is_method (MonoImage *image, guint32 token)
5480 guint32 cols [MONO_MEMBERREF_SIZE];
5482 mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
5483 sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
5484 mono_metadata_decode_blob_size (sig, &sig);
5485 return (*sig != 0x6);
5489 init_generic_context_from_args (MonoGenericContext *context, MonoArray *type_args, MonoArray *method_args)
5492 context->class_inst = mono_metadata_get_generic_inst (mono_array_length (type_args),
5493 mono_array_addr (type_args, MonoType*, 0));
5495 context->class_inst = NULL;
5497 context->method_inst = mono_metadata_get_generic_inst (mono_array_length (method_args),
5498 mono_array_addr (method_args, MonoType*, 0));
5500 context->method_inst = NULL;
5504 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5507 int table = mono_metadata_token_table (token);
5508 int index = mono_metadata_token_index (token);
5509 MonoGenericContext context;
5511 *error = ResolveTokenError_Other;
5513 /* Validate token */
5514 if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) &&
5515 (table != MONO_TABLE_TYPESPEC)) {
5516 *error = ResolveTokenError_BadTable;
5520 if (image->dynamic) {
5521 if (type_args || method_args)
5522 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5523 klass = mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5526 return &klass->byval_arg;
5529 if ((index <= 0) || (index > image->tables [table].rows)) {
5530 *error = ResolveTokenError_OutOfRange;
5534 init_generic_context_from_args (&context, type_args, method_args);
5535 klass = mono_class_get_full (image, token, &context);
5537 if (mono_loader_get_last_error ())
5538 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
5541 return &klass->byval_arg;
5547 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5549 int table = mono_metadata_token_table (token);
5550 int index = mono_metadata_token_index (token);
5551 MonoGenericContext context;
5554 *error = ResolveTokenError_Other;
5556 /* Validate token */
5557 if ((table != MONO_TABLE_METHOD) && (table != MONO_TABLE_METHODSPEC) &&
5558 (table != MONO_TABLE_MEMBERREF)) {
5559 *error = ResolveTokenError_BadTable;
5563 if (image->dynamic) {
5564 if (type_args || method_args)
5565 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5566 /* FIXME: validate memberref token type */
5567 return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5570 if ((index <= 0) || (index > image->tables [table].rows)) {
5571 *error = ResolveTokenError_OutOfRange;
5574 if ((table == MONO_TABLE_MEMBERREF) && (!mono_metadata_memberref_is_method (image, token))) {
5575 *error = ResolveTokenError_BadTable;
5579 init_generic_context_from_args (&context, type_args, method_args);
5580 method = mono_get_method_full (image, token, NULL, &context);
5582 if (mono_loader_get_last_error ())
5583 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
5589 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
5591 int index = mono_metadata_token_index (token);
5593 *error = ResolveTokenError_Other;
5595 /* Validate token */
5596 if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
5597 *error = ResolveTokenError_BadTable;
5602 return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5604 if ((index <= 0) || (index >= image->heap_us.size)) {
5605 *error = ResolveTokenError_OutOfRange;
5609 /* FIXME: What to do if the index points into the middle of a string ? */
5611 return mono_ldstr (mono_domain_get (), image, index);
5614 static MonoClassField*
5615 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5618 int table = mono_metadata_token_table (token);
5619 int index = mono_metadata_token_index (token);
5620 MonoGenericContext context;
5621 MonoClassField *field;
5623 *error = ResolveTokenError_Other;
5625 /* Validate token */
5626 if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
5627 *error = ResolveTokenError_BadTable;
5631 if (image->dynamic) {
5632 if (type_args || method_args)
5633 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5634 /* FIXME: validate memberref token type */
5635 return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5638 if ((index <= 0) || (index > image->tables [table].rows)) {
5639 *error = ResolveTokenError_OutOfRange;
5642 if ((table == MONO_TABLE_MEMBERREF) && (mono_metadata_memberref_is_method (image, token))) {
5643 *error = ResolveTokenError_BadTable;
5647 init_generic_context_from_args (&context, type_args, method_args);
5648 field = mono_field_from_token (image, token, &klass, &context);
5650 if (mono_loader_get_last_error ())
5651 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
5658 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5660 int table = mono_metadata_token_table (token);
5662 *error = ResolveTokenError_Other;
5665 case MONO_TABLE_TYPEDEF:
5666 case MONO_TABLE_TYPEREF:
5667 case MONO_TABLE_TYPESPEC: {
5668 MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, type_args, method_args, error);
5670 return (MonoObject*)mono_type_get_object (mono_domain_get (), t);
5674 case MONO_TABLE_METHOD:
5675 case MONO_TABLE_METHODSPEC: {
5676 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5678 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
5682 case MONO_TABLE_FIELD: {
5683 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5685 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
5689 case MONO_TABLE_MEMBERREF:
5690 if (mono_metadata_memberref_is_method (image, token)) {
5691 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5693 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
5698 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5700 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
5707 *error = ResolveTokenError_BadTable;
5714 ves_icall_System_Reflection_Module_ResolveSignature (MonoImage *image, guint32 token, MonoResolveTokenError *error)
5716 int table = mono_metadata_token_table (token);
5717 int idx = mono_metadata_token_index (token);
5718 MonoTableInfo *tables = image->tables;
5723 *error = ResolveTokenError_OutOfRange;
5725 /* FIXME: Support other tables ? */
5726 if (table != MONO_TABLE_STANDALONESIG)
5732 if ((idx == 0) || (idx > tables [MONO_TABLE_STANDALONESIG].rows))
5735 sig = mono_metadata_decode_row_col (&tables [MONO_TABLE_STANDALONESIG], idx - 1, 0);
5737 ptr = mono_metadata_blob_heap (image, sig);
5738 len = mono_metadata_decode_blob_size (ptr, &ptr);
5740 res = mono_array_new (mono_domain_get (), mono_defaults.byte_class, len);
5741 memcpy (mono_array_addr (res, guint8, 0), ptr, len);
5745 static MonoReflectionType*
5746 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
5749 int isbyref = 0, rank;
5750 char *str = mono_string_to_utf8 (smodifiers);
5753 MONO_ARCH_SAVE_REGS;
5755 klass = mono_class_from_mono_type (tb->type.type);
5757 /* logic taken from mono_reflection_parse_type(): keep in sync */
5761 if (isbyref) { /* only one level allowed by the spec */
5768 return mono_type_get_object (mono_object_domain (tb), &klass->this_arg);
5771 klass = mono_ptr_class_get (&klass->byval_arg);
5772 mono_class_init (klass);
5783 else if (*p != '*') { /* '*' means unknown lower bound */
5794 klass = mono_array_class_get (klass, rank);
5795 mono_class_init (klass);
5802 return mono_type_get_object (mono_object_domain (tb), &klass->byval_arg);
5806 ves_icall_Type_IsArrayImpl (MonoReflectionType *t)
5811 MONO_ARCH_SAVE_REGS;
5814 res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
5819 static MonoReflectionType *
5820 ves_icall_Type_make_array_type (MonoReflectionType *type, int rank)
5822 MonoClass *klass, *aklass;
5824 MONO_ARCH_SAVE_REGS;
5826 klass = mono_class_from_mono_type (type->type);
5827 aklass = mono_array_class_get (klass, rank);
5829 return mono_type_get_object (mono_object_domain (type), &aklass->byval_arg);
5832 static MonoReflectionType *
5833 ves_icall_Type_make_byref_type (MonoReflectionType *type)
5837 MONO_ARCH_SAVE_REGS;
5839 klass = mono_class_from_mono_type (type->type);
5841 return mono_type_get_object (mono_object_domain (type), &klass->this_arg);
5844 static MonoReflectionType *
5845 ves_icall_Type_MakePointerType (MonoReflectionType *type)
5849 MONO_ARCH_SAVE_REGS;
5851 pklass = mono_ptr_class_get (type->type);
5853 return mono_type_get_object (mono_object_domain (type), &pklass->byval_arg);
5857 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
5858 MonoReflectionMethod *info)
5860 MonoClass *delegate_class = mono_class_from_mono_type (type->type);
5861 MonoObject *delegate;
5863 MonoMethod *method = info->method;
5865 MONO_ARCH_SAVE_REGS;
5867 mono_assert (delegate_class->parent == mono_defaults.multicastdelegate_class);
5869 /* FIME: We must check if target is visible to the caller under coreclr.
5870 * The check should be disabled otherwise as it shouldn't raise expection under fulltrust.
5873 delegate = mono_object_new (mono_object_domain (type), delegate_class);
5875 if (mono_method_needs_static_rgctx_invoke (method, FALSE)) {
5876 method = mono_marshal_get_static_rgctx_invoke (method);
5877 func = mono_compile_method (method);
5878 } else if (method->dynamic) {
5879 /* Creating a trampoline would leak memory */
5880 func = mono_compile_method (method);
5882 func = mono_create_ftnptr (mono_domain_get (),
5883 mono_runtime_create_jump_trampoline (mono_domain_get (), method, TRUE));
5886 mono_delegate_ctor_with_method (delegate, target, func, method);
5892 ves_icall_System_Delegate_SetMulticastInvoke (MonoDelegate *this)
5894 /* Reset the invoke impl to the default one */
5895 this->invoke_impl = mono_runtime_create_delegate_trampoline (this->object.vtable->klass);
5899 * Magic number to convert a time which is relative to
5900 * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
5902 #define EPOCH_ADJUST ((guint64)62135596800LL)
5905 * Magic number to convert FILETIME base Jan 1, 1601 to DateTime - base Jan, 1, 0001
5907 #define FILETIME_ADJUST ((guint64)504911232000000000LL)
5909 #ifdef PLATFORM_WIN32
5910 /* convert a SYSTEMTIME which is of the form "last thursday in october" to a real date */
5912 convert_to_absolute_date(SYSTEMTIME *date)
5914 #define IS_LEAP(y) ((y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0))
5915 static int days_in_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5916 static int leap_days_in_month[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5917 /* from the calendar FAQ */
5918 int a = (14 - date->wMonth) / 12;
5919 int y = date->wYear - a;
5920 int m = date->wMonth + 12 * a - 2;
5921 int d = (1 + y + y/4 - y/100 + y/400 + (31*m)/12) % 7;
5923 /* d is now the day of the week for the first of the month (0 == Sunday) */
5925 int day_of_week = date->wDayOfWeek;
5927 /* set day_in_month to the first day in the month which falls on day_of_week */
5928 int day_in_month = 1 + (day_of_week - d);
5929 if (day_in_month <= 0)
5932 /* wDay is 1 for first weekday in month, 2 for 2nd ... 5 means last - so work that out allowing for days in the month */
5933 date->wDay = day_in_month + (date->wDay - 1) * 7;
5934 if (date->wDay > (IS_LEAP(date->wYear) ? leap_days_in_month[date->wMonth - 1] : days_in_month[date->wMonth - 1]))
5939 #ifndef PLATFORM_WIN32
5941 * Return's the offset from GMT of a local time.
5943 * tm is a local time
5944 * t is the same local time as seconds.
5947 gmt_offset(struct tm *tm, time_t t)
5949 #if defined (HAVE_TM_GMTOFF)
5950 return tm->tm_gmtoff;
5955 g.tm_isdst = tm->tm_isdst;
5957 return (int)difftime(t, t2);
5962 * This is heavily based on zdump.c from glibc 2.2.
5964 * * data[0]: start of daylight saving time (in DateTime ticks).
5965 * * data[1]: end of daylight saving time (in DateTime ticks).
5966 * * data[2]: utcoffset (in TimeSpan ticks).
5967 * * data[3]: additional offset when daylight saving (in TimeSpan ticks).
5968 * * name[0]: name of this timezone when not daylight saving.
5969 * * name[1]: name of this timezone when daylight saving.
5971 * FIXME: This only works with "standard" Unix dates (years between 1900 and 2100) while
5972 * the class library allows years between 1 and 9999.
5974 * Returns true on success and zero on failure.
5977 ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year, MonoArray **data, MonoArray **names)
5979 #ifndef PLATFORM_WIN32
5980 MonoDomain *domain = mono_domain_get ();
5981 struct tm start, tt;
5985 int is_daylight = 0, day;
5988 MONO_ARCH_SAVE_REGS;
5990 MONO_CHECK_ARG_NULL (data);
5991 MONO_CHECK_ARG_NULL (names);
5993 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5994 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5997 * no info is better than crashing: we'll need our own tz data
5998 * to make this work properly, anyway. The range is probably
5999 * reduced to 1970 .. 2037 because that is what mktime is
6000 * guaranteed to support (we get into an infinite loop
6004 memset (&start, 0, sizeof (start));
6007 start.tm_year = year-1900;
6009 t = mktime (&start);
6011 if ((year < 1970) || (year > 2037) || (t == -1)) {
6013 tt = *localtime (&t);
6014 strftime (tzone, sizeof (tzone), "%Z", &tt);
6015 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
6016 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
6020 gmtoff = gmt_offset (&start, t);
6022 /* For each day of the year, calculate the tm_gmtoff. */
6023 for (day = 0; day < 365; day++) {
6026 tt = *localtime (&t);
6028 /* Daylight saving starts or ends here. */
6029 if (gmt_offset (&tt, t) != gmtoff) {
6033 /* Try to find the exact hour when daylight saving starts/ends. */
6037 tt1 = *localtime (&t1);
6038 } while (gmt_offset (&tt1, t1) != gmtoff);
6040 /* Try to find the exact minute when daylight saving starts/ends. */
6043 tt1 = *localtime (&t1);
6044 } while (gmt_offset (&tt1, t1) == gmtoff);
6046 strftime (tzone, sizeof (tzone), "%Z", &tt);
6048 /* Write data, if we're already in daylight saving, we're done. */
6050 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
6051 mono_array_set ((*data), gint64, 1, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
6054 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
6055 mono_array_set ((*data), gint64, 0, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
6059 /* This is only set once when we enter daylight saving. */
6060 mono_array_set ((*data), gint64, 2, (gint64)gmtoff * 10000000L);
6061 mono_array_set ((*data), gint64, 3, (gint64)(gmt_offset (&tt, t) - gmtoff) * 10000000L);
6063 gmtoff = gmt_offset (&tt, t);
6068 strftime (tzone, sizeof (tzone), "%Z", &tt);
6069 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
6070 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
6071 mono_array_set ((*data), gint64, 0, 0);
6072 mono_array_set ((*data), gint64, 1, 0);
6073 mono_array_set ((*data), gint64, 2, (gint64) gmtoff * 10000000L);
6074 mono_array_set ((*data), gint64, 3, 0);
6079 MonoDomain *domain = mono_domain_get ();
6080 TIME_ZONE_INFORMATION tz_info;
6085 tz_id = GetTimeZoneInformation (&tz_info);
6086 if (tz_id == TIME_ZONE_ID_INVALID)
6089 MONO_CHECK_ARG_NULL (data);
6090 MONO_CHECK_ARG_NULL (names);
6092 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
6093 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
6095 for (i = 0; i < 32; ++i)
6096 if (!tz_info.DaylightName [i])
6098 mono_array_setref ((*names), 1, mono_string_new_utf16 (domain, tz_info.DaylightName, i));
6099 for (i = 0; i < 32; ++i)
6100 if (!tz_info.StandardName [i])
6102 mono_array_setref ((*names), 0, mono_string_new_utf16 (domain, tz_info.StandardName, i));
6104 if ((year <= 1601) || (year > 30827)) {
6106 * According to MSDN, the MS time functions can't handle dates outside
6112 /* even if the timezone has no daylight savings it may have Bias (e.g. GMT+13 it seems) */
6113 if (tz_id != TIME_ZONE_ID_UNKNOWN) {
6114 tz_info.StandardDate.wYear = year;
6115 convert_to_absolute_date(&tz_info.StandardDate);
6116 err = SystemTimeToFileTime (&tz_info.StandardDate, &ft);
6121 mono_array_set ((*data), gint64, 1, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
6122 tz_info.DaylightDate.wYear = year;
6123 convert_to_absolute_date(&tz_info.DaylightDate);
6124 err = SystemTimeToFileTime (&tz_info.DaylightDate, &ft);
6129 mono_array_set ((*data), gint64, 0, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
6131 mono_array_set ((*data), gint64, 2, (tz_info.Bias + tz_info.StandardBias) * -600000000LL);
6132 mono_array_set ((*data), gint64, 3, (tz_info.DaylightBias - tz_info.StandardBias) * -600000000LL);
6139 ves_icall_System_Object_obj_address (MonoObject *this)
6141 MONO_ARCH_SAVE_REGS;
6148 static inline gint32
6149 mono_array_get_byte_length (MonoArray *array)
6155 klass = array->obj.vtable->klass;
6157 if (array->bounds == NULL)
6158 length = array->max_length;
6161 for (i = 0; i < klass->rank; ++ i)
6162 length *= array->bounds [i].length;
6165 switch (klass->element_class->byval_arg.type) {
6168 case MONO_TYPE_BOOLEAN:
6172 case MONO_TYPE_CHAR:
6180 return length * sizeof (gpointer);
6191 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array)
6193 MONO_ARCH_SAVE_REGS;
6195 return mono_array_get_byte_length (array);
6199 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx)
6201 MONO_ARCH_SAVE_REGS;
6203 return mono_array_get (array, gint8, idx);
6207 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value)
6209 MONO_ARCH_SAVE_REGS;
6211 mono_array_set (array, gint8, idx, value);
6215 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count)
6217 guint8 *src_buf, *dest_buf;
6219 MONO_ARCH_SAVE_REGS;
6221 /* watch out for integer overflow */
6222 if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count))
6225 src_buf = (guint8 *)src->vector + src_offset;
6226 dest_buf = (guint8 *)dest->vector + dest_offset;
6229 memcpy (dest_buf, src_buf, count);
6231 memmove (dest_buf, src_buf, count); /* Source and dest are the same array */
6237 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this, MonoString *class_name)
6239 MonoDomain *domain = mono_object_domain (this);
6241 MonoRealProxy *rp = ((MonoRealProxy *)this);
6242 MonoTransparentProxy *tp;
6246 MONO_ARCH_SAVE_REGS;
6248 res = mono_object_new (domain, mono_defaults.transparent_proxy_class);
6249 tp = (MonoTransparentProxy*) res;
6251 MONO_OBJECT_SETREF (tp, rp, rp);
6252 type = ((MonoReflectionType *)rp->class_to_proxy)->type;
6253 klass = mono_class_from_mono_type (type);
6255 tp->custom_type_info = (mono_object_isinst (this, mono_defaults.iremotingtypeinfo_class) != NULL);
6256 tp->remote_class = mono_remote_class (domain, class_name, klass);
6258 res->vtable = mono_remote_class_vtable (domain, tp->remote_class, rp);
6262 static MonoReflectionType *
6263 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
6265 return mono_type_get_object (mono_object_domain (tp), &tp->remote_class->proxy_class->byval_arg);
6268 /* System.Environment */
6271 ves_icall_System_Environment_get_MachineName (void)
6273 #if defined (PLATFORM_WIN32)
6278 len = MAX_COMPUTERNAME_LENGTH + 1;
6279 buf = g_new (gunichar2, len);
6282 if (GetComputerName (buf, (PDWORD) &len))
6283 result = mono_string_new_utf16 (mono_domain_get (), buf, len);
6291 if (gethostname (buf, sizeof (buf)) == 0)
6292 result = mono_string_new (mono_domain_get (), buf);
6301 ves_icall_System_Environment_get_Platform (void)
6303 #if defined (PLATFORM_WIN32)
6306 #elif defined(__MACH__)
6308 if (mono_framework_version () < 2)
6313 if (mono_framework_version () < 2)
6320 ves_icall_System_Environment_get_NewLine (void)
6322 MONO_ARCH_SAVE_REGS;
6324 #if defined (PLATFORM_WIN32)
6325 return mono_string_new (mono_domain_get (), "\r\n");
6327 return mono_string_new (mono_domain_get (), "\n");
6332 ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name)
6337 MONO_ARCH_SAVE_REGS;
6342 utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
6343 value = g_getenv (utf8_name);
6350 return mono_string_new (mono_domain_get (), value);
6354 * There is no standard way to get at environ.
6357 #ifndef __MINGW32_VERSION
6359 /* Apple defines this in crt_externs.h but doesn't provide that header for
6360 * arm-apple-darwin9. We'll manually define the symbol on Apple as it does
6361 * in fact exist on all implementations (so far)
6363 gchar ***_NSGetEnviron();
6364 #define environ (*_NSGetEnviron())
6373 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
6375 #ifdef PLATFORM_WIN32
6384 env_strings = GetEnvironmentStrings();
6387 env_string = env_strings;
6388 while (*env_string != '\0') {
6389 /* weird case that MS seems to skip */
6390 if (*env_string != '=')
6392 while (*env_string != '\0')
6398 domain = mono_domain_get ();
6399 names = mono_array_new (domain, mono_defaults.string_class, n);
6403 env_string = env_strings;
6404 while (*env_string != '\0') {
6405 /* weird case that MS seems to skip */
6406 if (*env_string != '=') {
6407 equal_str = wcschr(env_string, '=');
6408 g_assert(equal_str);
6409 str = mono_string_new_utf16 (domain, env_string, equal_str-env_string);
6410 mono_array_setref (names, n, str);
6413 while (*env_string != '\0')
6418 FreeEnvironmentStrings (env_strings);
6430 MONO_ARCH_SAVE_REGS;
6433 for (e = environ; *e != 0; ++ e)
6436 domain = mono_domain_get ();
6437 names = mono_array_new (domain, mono_defaults.string_class, n);
6440 for (e = environ; *e != 0; ++ e) {
6441 parts = g_strsplit (*e, "=", 2);
6443 str = mono_string_new (domain, *parts);
6444 mono_array_setref (names, n, str);
6457 * If your platform lacks setenv/unsetenv, you must upgrade your glib.
6459 #if !GLIB_CHECK_VERSION(2,4,0)
6460 #define g_setenv(a,b,c) setenv(a,b,c)
6461 #define g_unsetenv(a) unsetenv(a)
6465 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
6467 #ifdef PLATFORM_WIN32
6468 gunichar2 *utf16_name, *utf16_value;
6470 gchar *utf8_name, *utf8_value;
6473 MONO_ARCH_SAVE_REGS;
6475 #ifdef PLATFORM_WIN32
6476 utf16_name = mono_string_to_utf16 (name);
6477 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
6478 SetEnvironmentVariable (utf16_name, NULL);
6479 g_free (utf16_name);
6483 utf16_value = mono_string_to_utf16 (value);
6485 SetEnvironmentVariable (utf16_name, utf16_value);
6487 g_free (utf16_name);
6488 g_free (utf16_value);
6490 utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
6492 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
6493 g_unsetenv (utf8_name);
6498 utf8_value = mono_string_to_utf8 (value);
6499 g_setenv (utf8_name, utf8_value, TRUE);
6502 g_free (utf8_value);
6507 ves_icall_System_Environment_Exit (int result)
6509 MONO_ARCH_SAVE_REGS;
6511 mono_threads_set_shutting_down ();
6513 mono_runtime_set_shutting_down ();
6515 /* Suspend all managed threads since the runtime is going away */
6516 mono_thread_suspend_all_other_threads ();
6518 mono_runtime_quit ();
6520 /* we may need to do some cleanup here... */
6525 ves_icall_System_Environment_GetGacPath (void)
6527 return mono_string_new (mono_domain_get (), mono_assembly_getrootdir ());
6531 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
6533 #if defined (PLATFORM_WIN32)
6534 #ifndef CSIDL_FLAG_CREATE
6535 #define CSIDL_FLAG_CREATE 0x8000
6538 WCHAR path [MAX_PATH];
6539 /* Create directory if no existing */
6540 if (SUCCEEDED (SHGetFolderPathW (NULL, folder | CSIDL_FLAG_CREATE, NULL, 0, path))) {
6544 return mono_string_new_utf16 (mono_domain_get (), path, len);
6547 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
6549 return mono_string_new (mono_domain_get (), "");
6553 ves_icall_System_Environment_GetLogicalDrives (void)
6555 gunichar2 buf [128], *ptr, *dname;
6557 guint initial_size = 127, size = 128;
6560 MonoString *drivestr;
6561 MonoDomain *domain = mono_domain_get ();
6564 MONO_ARCH_SAVE_REGS;
6569 while (size > initial_size) {
6570 size = (guint) GetLogicalDriveStrings (initial_size, ptr);
6571 if (size > initial_size) {
6574 ptr = g_malloc0 ((size + 1) * sizeof (gunichar2));
6575 initial_size = size;
6589 result = mono_array_new (domain, mono_defaults.string_class, ndrives);
6594 while (*u16) { u16++; len ++; }
6595 drivestr = mono_string_new_utf16 (domain, dname, len);
6596 mono_array_setref (result, ndrives++, drivestr);
6607 ves_icall_System_Environment_InternalGetHome (void)
6609 MONO_ARCH_SAVE_REGS;
6611 return mono_string_new (mono_domain_get (), g_get_home_dir ());
6614 static const char *encodings [] = {
6616 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
6617 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
6618 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
6620 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
6621 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
6622 "x_unicode_2_0_utf_7",
6624 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
6625 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
6627 "utf_16", "UTF_16LE", "ucs_2", "unicode",
6630 "unicodefffe", "utf_16be",
6637 * Returns the internal codepage, if the value of "int_code_page" is
6638 * 1 at entry, and we can not compute a suitable code page number,
6639 * returns the code page as a string
6642 ves_icall_System_Text_Encoding_InternalCodePage (gint32 *int_code_page)
6647 char *codepage = NULL;
6649 int want_name = *int_code_page;
6652 *int_code_page = -1;
6653 MONO_ARCH_SAVE_REGS;
6655 g_get_charset (&cset);
6656 c = codepage = strdup (cset);
6657 for (c = codepage; *c; c++){
6658 if (isascii (*c) && isalpha (*c))
6663 /* g_print ("charset: %s\n", cset); */
6665 /* handle some common aliases */
6668 for (i = 0; p != 0; ){
6669 if ((gssize) p < 7){
6671 p = encodings [++i];
6674 if (strcmp (p, codepage) == 0){
6675 *int_code_page = code;
6678 p = encodings [++i];
6681 if (strstr (codepage, "utf_8") != NULL)
6682 *int_code_page |= 0x10000000;
6685 if (want_name && *int_code_page == -1)
6686 return mono_string_new (mono_domain_get (), cset);
6692 ves_icall_System_Environment_get_HasShutdownStarted (void)
6694 if (mono_runtime_is_shutting_down ())
6697 if (mono_domain_is_unloading (mono_domain_get ()))
6704 ves_icall_MonoMethodMessage_InitMessage (MonoMethodMessage *this,
6705 MonoReflectionMethod *method,
6706 MonoArray *out_args)
6708 MONO_ARCH_SAVE_REGS;
6710 mono_message_init (mono_object_domain (this), this, method, out_args);
6714 ves_icall_IsTransparentProxy (MonoObject *proxy)
6716 MONO_ARCH_SAVE_REGS;
6721 if (proxy->vtable->klass == mono_defaults.transparent_proxy_class)
6727 static MonoReflectionMethod *
6728 ves_icall_Remoting_RemotingServices_GetVirtualMethod (
6729 MonoReflectionType *rtype, MonoReflectionMethod *rmethod)
6733 MonoMethod **vtable;
6734 MonoMethod *res = NULL;
6736 MONO_CHECK_ARG_NULL (rtype);
6737 MONO_CHECK_ARG_NULL (rmethod);
6739 method = rmethod->method;
6740 klass = mono_class_from_mono_type (rtype->type);
6742 if (MONO_CLASS_IS_INTERFACE (klass))
6745 if (method->flags & METHOD_ATTRIBUTE_STATIC)
6748 if ((method->flags & METHOD_ATTRIBUTE_FINAL) || !(method->flags & METHOD_ATTRIBUTE_VIRTUAL)) {
6749 if (klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE))
6755 mono_class_setup_vtable (klass);
6756 vtable = klass->vtable;
6758 if (method->klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
6759 int offs = mono_class_interface_offset (klass, method->klass);
6761 res = vtable [offs + method->slot];
6763 if (!(klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE)))
6766 if (method->slot != -1)
6767 res = vtable [method->slot];
6773 return mono_method_get_object (mono_domain_get (), res, NULL);
6777 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6782 MONO_ARCH_SAVE_REGS;
6784 klass = mono_class_from_mono_type (type->type);
6785 vtable = mono_class_vtable (mono_domain_get (), klass);
6787 if (enable) vtable->remote = 1;
6788 else vtable->remote = 0;
6792 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type)
6797 MONO_ARCH_SAVE_REGS;
6799 domain = mono_object_domain (type);
6800 klass = mono_class_from_mono_type (type->type);
6802 if (klass->rank >= 1) {
6803 g_assert (klass->rank == 1);
6804 return (MonoObject *) mono_array_new (domain, klass->element_class, 0);
6806 /* Bypass remoting object creation check */
6807 return mono_object_new_alloc_specific (mono_class_vtable (domain, klass));
6812 ves_icall_System_IO_get_temp_path (void)
6814 MONO_ARCH_SAVE_REGS;
6816 return mono_string_new (mono_domain_get (), g_get_tmp_dir ());
6820 ves_icall_RuntimeMethod_GetFunctionPointer (MonoMethod *method)
6822 MONO_ARCH_SAVE_REGS;
6824 return mono_compile_method (method);
6828 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
6833 MONO_ARCH_SAVE_REGS;
6835 path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
6837 #if defined (PLATFORM_WIN32)
6838 /* Avoid mixing '/' and '\\' */
6841 for (i = strlen (path) - 1; i >= 0; i--)
6842 if (path [i] == '/')
6846 mcpath = mono_string_new (mono_domain_get (), path);
6853 get_bundled_machine_config (void)
6855 const gchar *machine_config;
6857 MONO_ARCH_SAVE_REGS;
6859 machine_config = mono_get_machine_config ();
6861 if (!machine_config)
6864 return mono_string_new (mono_domain_get (), machine_config);
6868 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
6873 MONO_ARCH_SAVE_REGS;
6875 path = g_path_get_dirname (mono_get_config_dir ());
6877 #if defined (PLATFORM_WIN32)
6878 /* Avoid mixing '/' and '\\' */
6881 for (i = strlen (path) - 1; i >= 0; i--)
6882 if (path [i] == '/')
6886 ipath = mono_string_new (mono_domain_get (), path);
6893 ves_icall_System_Diagnostics_Debugger_IsAttached_internal (void)
6895 return mono_debug_using_mono_debugger ();
6899 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
6901 #if defined (PLATFORM_WIN32)
6902 OutputDebugString (mono_string_chars (message));
6904 g_warning ("WriteWindowsDebugString called and PLATFORM_WIN32 not defined!\n");
6908 /* Only used for value types */
6910 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
6915 MONO_ARCH_SAVE_REGS;
6917 domain = mono_object_domain (type);
6918 klass = mono_class_from_mono_type (type->type);
6920 if (mono_class_is_nullable (klass))
6921 /* No arguments -> null */
6924 return mono_object_new (domain, klass);
6927 static MonoReflectionMethod *
6928 ves_icall_MonoMethod_get_base_definition (MonoReflectionMethod *m)
6930 MonoClass *klass, *parent;
6931 MonoMethod *method = m->method;
6932 MonoMethod *result = NULL;
6934 MONO_ARCH_SAVE_REGS;
6936 if (method->klass == NULL)
6939 if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
6940 MONO_CLASS_IS_INTERFACE (method->klass) ||
6941 method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
6944 klass = method->klass;
6945 if (klass->generic_class)
6946 klass = klass->generic_class->container_class;
6948 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
6949 for (parent = klass->parent; parent != NULL; parent = parent->parent) {
6950 mono_class_setup_vtable (parent);
6951 if (parent->vtable_size <= method->slot)
6956 if (klass == method->klass)
6959 result = klass->vtable [method->slot];
6960 if (result == NULL) {
6961 /* It is an abstract method */
6962 gpointer iter = NULL;
6963 while ((result = mono_class_get_methods (klass, &iter)))
6964 if (result->slot == method->slot)
6971 return mono_method_get_object (mono_domain_get (), result, NULL);
6975 ves_icall_MonoMethod_get_name (MonoReflectionMethod *m)
6977 MonoMethod *method = m->method;
6979 MONO_OBJECT_SETREF (m, name, mono_string_new (mono_object_domain (m), method->name));
6984 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
6986 MONO_ARCH_SAVE_REGS;
6988 iter->sig = *(MonoMethodSignature**)argsp;
6990 g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
6991 g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
6994 /* FIXME: it's not documented what start is exactly... */
6998 guint32 i, arg_size;
7000 iter->args = argsp + sizeof (gpointer);
7001 #ifndef MONO_ARCH_REGPARMS
7002 for (i = 0; i < iter->sig->sentinelpos; ++i) {
7003 arg_size = mono_type_stack_size (iter->sig->params [i], &align);
7004 iter->args = (char*)iter->args + arg_size;
7008 iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
7010 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
7014 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
7016 guint32 i, arg_size;
7019 MONO_ARCH_SAVE_REGS;
7021 i = iter->sig->sentinelpos + iter->next_arg;
7023 g_assert (i < iter->sig->param_count);
7025 res.type = iter->sig->params [i];
7026 res.klass = mono_class_from_mono_type (res.type);
7027 /* FIXME: endianess issue... */
7028 res.value = iter->args;
7029 arg_size = mono_type_stack_size (res.type, &align);
7030 iter->args = (char*)iter->args + arg_size;
7033 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7039 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
7041 guint32 i, arg_size;
7044 MONO_ARCH_SAVE_REGS;
7046 i = iter->sig->sentinelpos + iter->next_arg;
7048 g_assert (i < iter->sig->param_count);
7050 while (i < iter->sig->param_count) {
7051 if (!mono_metadata_type_equal (type, iter->sig->params [i]))
7053 res.type = iter->sig->params [i];
7054 res.klass = mono_class_from_mono_type (res.type);
7055 /* FIXME: endianess issue... */
7056 res.value = iter->args;
7057 arg_size = mono_type_stack_size (res.type, &align);
7058 iter->args = (char*)iter->args + arg_size;
7060 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7063 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
7072 mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
7075 MONO_ARCH_SAVE_REGS;
7077 i = iter->sig->sentinelpos + iter->next_arg;
7079 g_assert (i < iter->sig->param_count);
7081 return iter->sig->params [i];
7085 mono_TypedReference_ToObject (MonoTypedRef tref)
7087 MONO_ARCH_SAVE_REGS;
7089 if (MONO_TYPE_IS_REFERENCE (tref.type)) {
7090 MonoObject** objp = tref.value;
7094 return mono_value_box (mono_domain_get (), tref.klass, tref.value);
7098 mono_TypedReference_ToObjectInternal (MonoType *type, gpointer value, MonoClass *klass)
7100 MONO_ARCH_SAVE_REGS;
7102 if (MONO_TYPE_IS_REFERENCE (type)) {
7103 MonoObject** objp = value;
7107 return mono_value_box (mono_domain_get (), klass, value);
7111 prelink_method (MonoMethod *method)
7113 const char *exc_class, *exc_arg;
7114 if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
7116 mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
7118 mono_raise_exception(
7119 mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg ) );
7121 /* create the wrapper, too? */
7125 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
7127 MONO_ARCH_SAVE_REGS;
7128 prelink_method (method->method);
7132 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
7134 MonoClass *klass = mono_class_from_mono_type (type->type);
7136 gpointer iter = NULL;
7137 MONO_ARCH_SAVE_REGS;
7139 while ((m = mono_class_get_methods (klass, &iter)))
7143 /* These parameters are "readonly" in corlib/System/NumberFormatter.cs */
7145 ves_icall_System_NumberFormatter_GetFormatterTables (guint64 const **mantissas,
7146 gint32 const **exponents,
7147 gunichar2 const **digitLowerTable,
7148 gunichar2 const **digitUpperTable,
7149 gint64 const **tenPowersList,
7150 gint32 const **decHexDigits)
7152 *mantissas = Formatter_MantissaBitsTable;
7153 *exponents = Formatter_TensExponentTable;
7154 *digitLowerTable = Formatter_DigitLowerTable;
7155 *digitUpperTable = Formatter_DigitUpperTable;
7156 *tenPowersList = Formatter_TenPowersList;
7157 *decHexDigits = Formatter_DecHexDigits;
7160 /* These parameters are "readonly" in corlib/System/Char.cs */
7162 ves_icall_System_Char_GetDataTablePointers (guint8 const **category_data,
7163 guint8 const **numeric_data,
7164 gdouble const **numeric_data_values,
7165 guint16 const **to_lower_data_low,
7166 guint16 const **to_lower_data_high,
7167 guint16 const **to_upper_data_low,
7168 guint16 const **to_upper_data_high)
7170 *category_data = CategoryData;
7171 *numeric_data = NumericData;
7172 *numeric_data_values = NumericDataValues;
7173 *to_lower_data_low = ToLowerDataLow;
7174 *to_lower_data_high = ToLowerDataHigh;
7175 *to_upper_data_low = ToUpperDataLow;
7176 *to_upper_data_high = ToUpperDataHigh;
7180 ves_icall_MonoDebugger_GetMethodToken (MonoReflectionMethod *method)
7182 return method->method->token;
7186 * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
7187 * and avoid useless allocations.
7190 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional)
7194 for (i = 0; i < type->num_mods; ++i) {
7195 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
7200 res = mono_array_new (mono_domain_get (), mono_defaults.systemtype_class, count);
7202 for (i = 0; i < type->num_mods; ++i) {
7203 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
7204 MonoClass *klass = mono_class_get (image, type->modifiers [i].token);
7205 mono_array_setref (res, count, mono_type_get_object (mono_domain_get (), &klass->byval_arg));
7213 param_info_get_type_modifiers (MonoReflectionParameter *param, MonoBoolean optional)
7215 MonoType *type = param->ClassImpl->type;
7216 MonoReflectionMethod *method = (MonoReflectionMethod*)param->MemberImpl;
7217 MonoImage *image = method->method->klass->image;
7218 int pos = param->PositionImpl;
7219 MonoMethodSignature *sig = mono_method_signature (method->method);
7223 type = sig->params [pos];
7225 return type_array_from_modifiers (image, type, optional);
7229 get_property_type (MonoProperty *prop)
7231 MonoMethodSignature *sig;
7233 sig = mono_method_signature (prop->get);
7235 } else if (prop->set) {
7236 sig = mono_method_signature (prop->set);
7237 return sig->params [sig->param_count - 1];
7243 property_info_get_type_modifiers (MonoReflectionProperty *property, MonoBoolean optional)
7245 MonoType *type = get_property_type (property->property);
7246 MonoImage *image = property->klass->image;
7250 return type_array_from_modifiers (image, type, optional);
7254 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
7256 MonoCustomAttrInfo *cinfo;
7259 cinfo = mono_reflection_get_custom_attrs_info (obj);
7262 found = mono_custom_attrs_has_attr (cinfo, mono_class_from_mono_type (attr_type->type));
7264 mono_custom_attrs_free (cinfo);
7269 custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
7271 MonoArray *res = mono_reflection_get_custom_attrs_by_type (obj, attr_type ? mono_class_from_mono_type (attr_type->type) : NULL);
7273 if (mono_loader_get_last_error ()) {
7274 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
7275 g_assert_not_reached ();
7282 GCHandle_CheckCurrentDomain (guint32 gchandle)
7284 return mono_gchandle_is_in_domain (gchandle, mono_domain_get ());
7288 ves_icall_Mono_Runtime_GetDisplayName (void)
7290 static const char display_name_str [] = "Mono " VERSION;
7291 MonoString *display_name = mono_string_new (mono_domain_get (), display_name_str);
7292 return display_name;
7296 ves_icall_System_ComponentModel_Win32Exception_W32ErrorMessage (guint32 code)
7298 MonoString *message;
7302 ret = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM |
7303 FORMAT_MESSAGE_IGNORE_INSERTS, NULL, code, 0,
7306 message = mono_string_new (mono_domain_get (), "Error looking up error string");
7308 message = mono_string_new_utf16 (mono_domain_get (), buf, ret);
7316 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
7317 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
7318 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 62, 128, 128, 128, 63,
7319 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 0, 128, 128,
7320 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
7321 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 128, 128, 128, 128, 128,
7322 128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
7323 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
7327 base64_to_byte_array (gunichar2 *start, gint ilength, MonoBoolean allowWhitespaceOnly)
7332 gunichar2 last, prev_last, prev2_last;
7340 last = prev_last = 0, prev2_last = 0;
7341 for (i = 0; i < ilength; i++) {
7343 if (c >= sizeof (dbase64)) {
7344 exc = mono_exception_from_name_msg (mono_get_corlib (),
7345 "System", "FormatException",
7346 "Invalid character found.");
7347 mono_raise_exception (exc);
7348 } else if (isspace (c)) {
7351 prev2_last = prev_last;
7357 olength = ilength - ignored;
7359 if (allowWhitespaceOnly && olength == 0) {
7360 return mono_array_new (mono_domain_get (), mono_defaults.byte_class, 0);
7363 if ((olength & 3) != 0 || olength <= 0) {
7364 exc = mono_exception_from_name_msg (mono_get_corlib (), "System",
7365 "FormatException", "Invalid length.");
7366 mono_raise_exception (exc);
7369 if (prev2_last == '=') {
7370 exc = mono_exception_from_name_msg (mono_get_corlib (), "System", "FormatException", "Invalid format.");
7371 mono_raise_exception (exc);
7374 olength = (olength * 3) / 4;
7378 if (prev_last == '=')
7381 result = mono_array_new (mono_domain_get (), mono_defaults.byte_class, olength);
7382 res_ptr = mono_array_addr (result, guchar, 0);
7383 for (i = 0; i < ilength; ) {
7386 for (k = 0; k < 4 && i < ilength;) {
7392 if (((b [k] = dbase64 [c]) & 0x80) != 0) {
7393 exc = mono_exception_from_name_msg (mono_get_corlib (),
7394 "System", "FormatException",
7395 "Invalid character found.");
7396 mono_raise_exception (exc);
7401 *res_ptr++ = (b [0] << 2) | (b [1] >> 4);
7403 *res_ptr++ = (b [1] << 4) | (b [2] >> 2);
7405 *res_ptr++ = (b [2] << 6) | b [3];
7407 while (i < ilength && isspace (start [i]))
7415 InternalFromBase64String (MonoString *str, MonoBoolean allowWhitespaceOnly)
7417 MONO_ARCH_SAVE_REGS;
7419 return base64_to_byte_array (mono_string_chars (str),
7420 mono_string_length (str), allowWhitespaceOnly);
7424 InternalFromBase64CharArray (MonoArray *input, gint offset, gint length)
7426 MONO_ARCH_SAVE_REGS;
7428 return base64_to_byte_array (mono_array_addr (input, gunichar2, offset),
7432 #define ICALL_TYPE(id,name,first)
7433 #define ICALL(id,name,func) Icall_ ## id,
7436 #include "metadata/icall-def.h"
7442 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
7443 #define ICALL(id,name,func)
7445 #include "metadata/icall-def.h"
7451 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
7452 #define ICALL(id,name,func)
7454 guint16 first_icall;
7457 static const IcallTypeDesc
7458 icall_type_descs [] = {
7459 #include "metadata/icall-def.h"
7463 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
7466 #define ICALL_TYPE(id,name,first)
7469 #ifdef HAVE_ARRAY_ELEM_INIT
7470 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
7471 #define MSGSTRFIELD1(line) str##line
7473 static const struct msgstrtn_t {
7474 #define ICALL(id,name,func)
7476 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7477 #include "metadata/icall-def.h"
7479 } icall_type_names_str = {
7480 #define ICALL_TYPE(id,name,first) (name),
7481 #include "metadata/icall-def.h"
7484 static const guint16 icall_type_names_idx [] = {
7485 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
7486 #include "metadata/icall-def.h"
7489 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
7491 static const struct msgstr_t {
7493 #define ICALL_TYPE(id,name,first)
7494 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7495 #include "metadata/icall-def.h"
7497 } icall_names_str = {
7498 #define ICALL(id,name,func) (name),
7499 #include "metadata/icall-def.h"
7502 static const guint16 icall_names_idx [] = {
7503 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
7504 #include "metadata/icall-def.h"
7507 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
7513 #define ICALL_TYPE(id,name,first) name,
7514 #define ICALL(id,name,func)
7515 static const char* const
7516 icall_type_names [] = {
7517 #include "metadata/icall-def.h"
7521 #define icall_type_name_get(id) (icall_type_names [(id)])
7525 #define ICALL_TYPE(id,name,first)
7526 #define ICALL(id,name,func) name,
7527 static const char* const
7529 #include "metadata/icall-def.h"
7532 #define icall_name_get(id) icall_names [(id)]
7534 #endif /* !HAVE_ARRAY_ELEM_INIT */
7538 #define ICALL_TYPE(id,name,first)
7539 #define ICALL(id,name,func) func,
7540 static const gconstpointer
7541 icall_functions [] = {
7542 #include "metadata/icall-def.h"
7546 static GHashTable *icall_hash = NULL;
7547 static GHashTable *jit_icall_hash_name = NULL;
7548 static GHashTable *jit_icall_hash_addr = NULL;
7551 mono_icall_init (void)
7555 /* check that tables are sorted: disable in release */
7558 const char *prev_class = NULL;
7559 const char *prev_method;
7561 for (i = 0; i < Icall_type_num; ++i) {
7562 const IcallTypeDesc *desc;
7565 if (prev_class && strcmp (prev_class, icall_type_name_get (i)) >= 0)
7566 g_print ("class %s should come before class %s\n", icall_type_name_get (i), prev_class);
7567 prev_class = icall_type_name_get (i);
7568 desc = &icall_type_descs [i];
7569 num_icalls = icall_desc_num_icalls (desc);
7570 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
7571 for (j = 0; j < num_icalls; ++j) {
7572 const char *methodn = icall_name_get (desc->first_icall + j);
7573 if (prev_method && strcmp (prev_method, methodn) >= 0)
7574 g_print ("method %s should come before method %s\n", methodn, prev_method);
7575 prev_method = methodn;
7580 icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
7584 mono_icall_cleanup (void)
7586 g_hash_table_destroy (icall_hash);
7587 g_hash_table_destroy (jit_icall_hash_name);
7588 g_hash_table_destroy (jit_icall_hash_addr);
7592 mono_add_internal_call (const char *name, gconstpointer method)
7594 mono_loader_lock ();
7596 g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
7598 mono_loader_unlock ();
7601 #ifdef HAVE_ARRAY_ELEM_INIT
7603 compare_method_imap (const void *key, const void *elem)
7605 const char* method_name = (const char*)&icall_names_str + (*(guint16*)elem);
7606 return strcmp (key, method_name);
7610 find_method_icall (const IcallTypeDesc *imap, const char *name)
7612 const guint16 *nameslot = bsearch (name, icall_names_idx + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names_idx [0]), compare_method_imap);
7615 return (gpointer)icall_functions [(nameslot - &icall_names_idx [0])];
7619 compare_class_imap (const void *key, const void *elem)
7621 const char* class_name = (const char*)&icall_type_names_str + (*(guint16*)elem);
7622 return strcmp (key, class_name);
7625 static const IcallTypeDesc*
7626 find_class_icalls (const char *name)
7628 const guint16 *nameslot = bsearch (name, icall_type_names_idx, Icall_type_num, sizeof (icall_type_names_idx [0]), compare_class_imap);
7631 return &icall_type_descs [nameslot - &icall_type_names_idx [0]];
7636 compare_method_imap (const void *key, const void *elem)
7638 const char** method_name = (const char**)elem;
7639 return strcmp (key, *method_name);
7643 find_method_icall (const IcallTypeDesc *imap, const char *name)
7645 const char **nameslot = bsearch (name, icall_names + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names [0]), compare_method_imap);
7648 return (gpointer)icall_functions [(nameslot - icall_names)];
7652 compare_class_imap (const void *key, const void *elem)
7654 const char** class_name = (const char**)elem;
7655 return strcmp (key, *class_name);
7658 static const IcallTypeDesc*
7659 find_class_icalls (const char *name)
7661 const char **nameslot = bsearch (name, icall_type_names, Icall_type_num, sizeof (icall_type_names [0]), compare_class_imap);
7664 return &icall_type_descs [nameslot - icall_type_names];
7670 * we should probably export this as an helper (handle nested types).
7671 * Returns the number of chars written in buf.
7674 concat_class_name (char *buf, int bufsize, MonoClass *klass)
7676 int nspacelen, cnamelen;
7677 nspacelen = strlen (klass->name_space);
7678 cnamelen = strlen (klass->name);
7679 if (nspacelen + cnamelen + 2 > bufsize)
7682 memcpy (buf, klass->name_space, nspacelen);
7683 buf [nspacelen ++] = '.';
7685 memcpy (buf + nspacelen, klass->name, cnamelen);
7686 buf [nspacelen + cnamelen] = 0;
7687 return nspacelen + cnamelen;
7691 mono_lookup_internal_call (MonoMethod *method)
7696 int typelen = 0, mlen, siglen;
7698 const IcallTypeDesc *imap;
7700 g_assert (method != NULL);
7702 if (method->is_inflated)
7703 method = ((MonoMethodInflated *) method)->declaring;
7705 if (method->klass->nested_in) {
7706 int pos = concat_class_name (mname, sizeof (mname)-2, method->klass->nested_in);
7710 mname [pos++] = '/';
7713 typelen = concat_class_name (mname+pos, sizeof (mname)-pos-1, method->klass);
7719 typelen = concat_class_name (mname, sizeof (mname), method->klass);
7724 imap = find_class_icalls (mname);
7726 mname [typelen] = ':';
7727 mname [typelen + 1] = ':';
7729 mlen = strlen (method->name);
7730 memcpy (mname + typelen + 2, method->name, mlen);
7731 sigstart = mname + typelen + 2 + mlen;
7734 tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
7735 siglen = strlen (tmpsig);
7736 if (typelen + mlen + siglen + 6 > sizeof (mname))
7739 memcpy (sigstart + 1, tmpsig, siglen);
7740 sigstart [siglen + 1] = ')';
7741 sigstart [siglen + 2] = 0;
7744 mono_loader_lock ();
7746 res = g_hash_table_lookup (icall_hash, mname);
7748 mono_loader_unlock ();
7751 /* try without signature */
7753 res = g_hash_table_lookup (icall_hash, mname);
7755 mono_loader_unlock ();
7759 /* it wasn't found in the static call tables */
7761 mono_loader_unlock ();
7764 res = find_method_icall (imap, sigstart - mlen);
7766 mono_loader_unlock ();
7769 /* try _with_ signature */
7771 res = find_method_icall (imap, sigstart - mlen);
7773 mono_loader_unlock ();
7777 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname);
7778 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
7779 g_print ("The out of sync library is: %s\n", method->klass->image->name);
7780 g_print ("\nWhen you update one from svn you need to update, compile and install\nthe other too.\n");
7781 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");
7782 g_print ("If you see other errors or faults after this message they are probably related\n");
7783 g_print ("and you need to fix your mono install first.\n");
7785 mono_loader_unlock ();
7791 type_from_typename (char *typename)
7793 MonoClass *klass = NULL; /* assignment to shut GCC warning up */
7795 if (!strcmp (typename, "int"))
7796 klass = mono_defaults.int_class;
7797 else if (!strcmp (typename, "ptr"))
7798 klass = mono_defaults.int_class;
7799 else if (!strcmp (typename, "void"))
7800 klass = mono_defaults.void_class;
7801 else if (!strcmp (typename, "int32"))
7802 klass = mono_defaults.int32_class;
7803 else if (!strcmp (typename, "uint32"))
7804 klass = mono_defaults.uint32_class;
7805 else if (!strcmp (typename, "int8"))
7806 klass = mono_defaults.sbyte_class;
7807 else if (!strcmp (typename, "uint8"))
7808 klass = mono_defaults.byte_class;
7809 else if (!strcmp (typename, "int16"))
7810 klass = mono_defaults.int16_class;
7811 else if (!strcmp (typename, "uint16"))
7812 klass = mono_defaults.uint16_class;
7813 else if (!strcmp (typename, "long"))
7814 klass = mono_defaults.int64_class;
7815 else if (!strcmp (typename, "ulong"))
7816 klass = mono_defaults.uint64_class;
7817 else if (!strcmp (typename, "float"))
7818 klass = mono_defaults.single_class;
7819 else if (!strcmp (typename, "double"))
7820 klass = mono_defaults.double_class;
7821 else if (!strcmp (typename, "object"))
7822 klass = mono_defaults.object_class;
7823 else if (!strcmp (typename, "obj"))
7824 klass = mono_defaults.object_class;
7825 else if (!strcmp (typename, "string"))
7826 klass = mono_defaults.string_class;
7827 else if (!strcmp (typename, "bool"))
7828 klass = mono_defaults.boolean_class;
7829 else if (!strcmp (typename, "boolean"))
7830 klass = mono_defaults.boolean_class;
7833 g_assert_not_reached ();
7835 return &klass->byval_arg;
7838 MonoMethodSignature*
7839 mono_create_icall_signature (const char *sigstr)
7844 MonoMethodSignature *res;
7846 mono_loader_lock ();
7847 res = g_hash_table_lookup (mono_defaults.corlib->helper_signatures, sigstr);
7849 mono_loader_unlock ();
7853 parts = g_strsplit (sigstr, " ", 256);
7862 res = mono_metadata_signature_alloc (mono_defaults.corlib, len - 1);
7865 #ifdef PLATFORM_WIN32
7867 * Under windows, the default pinvoke calling convention is STDCALL but
7870 res->call_convention = MONO_CALL_C;
7873 res->ret = type_from_typename (parts [0]);
7874 for (i = 1; i < len; ++i) {
7875 res->params [i - 1] = type_from_typename (parts [i]);
7880 g_hash_table_insert (mono_defaults.corlib->helper_signatures, (gpointer)sigstr, res);
7882 mono_loader_unlock ();
7888 mono_find_jit_icall_by_name (const char *name)
7890 MonoJitICallInfo *info;
7891 g_assert (jit_icall_hash_name);
7893 mono_loader_lock ();
7894 info = g_hash_table_lookup (jit_icall_hash_name, name);
7895 mono_loader_unlock ();
7900 mono_find_jit_icall_by_addr (gconstpointer addr)
7902 MonoJitICallInfo *info;
7903 g_assert (jit_icall_hash_addr);
7905 mono_loader_lock ();
7906 info = g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
7907 mono_loader_unlock ();
7913 * mono_get_jit_icall_info:
7915 * Return the hashtable mapping JIT icall names to MonoJitICallInfo structures. The
7916 * caller should access it while holding the loader lock.
7919 mono_get_jit_icall_info (void)
7921 return jit_icall_hash_name;
7925 mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
7927 mono_loader_lock ();
7928 g_hash_table_insert (jit_icall_hash_addr, (gpointer)wrapper, info);
7929 mono_loader_unlock ();
7933 mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
7935 MonoJitICallInfo *info;
7940 mono_loader_lock ();
7942 if (!jit_icall_hash_name) {
7943 jit_icall_hash_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
7944 jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
7947 if (g_hash_table_lookup (jit_icall_hash_name, name)) {
7948 g_warning ("jit icall already defined \"%s\"\n", name);
7949 g_assert_not_reached ();
7952 info = g_new0 (MonoJitICallInfo, 1);
7959 info->wrapper = func;
7961 info->wrapper = NULL;
7964 g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
7965 g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
7967 mono_loader_unlock ();