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/io-layer/io-layer.h>
66 #include <mono/utils/strtod.h>
67 #include <mono/utils/monobitset.h>
68 #include <mono/utils/mono-time.h>
70 #if defined (PLATFORM_WIN32)
76 static MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void);
79 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional);
81 static inline MonoBoolean
82 is_generic_parameter (MonoType *type)
84 return !type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR);
88 * We expect a pointer to a char, not a string
91 mono_double_ParseImpl (char *ptr, double *result)
100 *result = strtod (ptr, &endptr);
103 *result = mono_strtod (ptr, &endptr);
106 if (!*ptr || (endptr && *endptr))
113 ves_icall_System_Array_GetValueImpl (MonoObject *this, guint32 pos)
122 ao = (MonoArray *)this;
123 ac = (MonoClass *)ao->obj.vtable->klass;
125 esize = mono_array_element_size (ac);
126 ea = (gpointer*)((char*)ao->vector + (pos * esize));
128 if (ac->element_class->valuetype)
129 return mono_value_box (this->vtable->domain, ac->element_class, ea);
135 ves_icall_System_Array_GetValue (MonoObject *this, MonoObject *idxs)
143 MONO_CHECK_ARG_NULL (idxs);
145 io = (MonoArray *)idxs;
146 ic = (MonoClass *)io->obj.vtable->klass;
148 ao = (MonoArray *)this;
149 ac = (MonoClass *)ao->obj.vtable->klass;
151 g_assert (ic->rank == 1);
152 if (io->bounds != NULL || io->max_length != ac->rank)
153 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
155 ind = (gint32 *)io->vector;
157 if (ao->bounds == NULL) {
158 if (*ind < 0 || *ind >= ao->max_length)
159 mono_raise_exception (mono_get_exception_index_out_of_range ());
161 return ves_icall_System_Array_GetValueImpl (this, *ind);
164 for (i = 0; i < ac->rank; i++)
165 if ((ind [i] < ao->bounds [i].lower_bound) ||
166 (ind [i] >= ao->bounds [i].length + ao->bounds [i].lower_bound))
167 mono_raise_exception (mono_get_exception_index_out_of_range ());
169 pos = ind [0] - ao->bounds [0].lower_bound;
170 for (i = 1; i < ac->rank; i++)
171 pos = pos*ao->bounds [i].length + ind [i] -
172 ao->bounds [i].lower_bound;
174 return ves_icall_System_Array_GetValueImpl (this, pos);
178 ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32 pos)
180 MonoClass *ac, *vc, *ec;
192 vc = value->vtable->klass;
196 ac = this->obj.vtable->klass;
197 ec = ac->element_class;
199 esize = mono_array_element_size (ac);
200 ea = (gpointer*)((char*)this->vector + (pos * esize));
201 va = (gpointer*)((char*)value + sizeof (MonoObject));
204 memset (ea, 0, esize);
208 #define NO_WIDENING_CONVERSION G_STMT_START{\
209 mono_raise_exception (mono_get_exception_argument ( \
210 "value", "not a widening conversion")); \
213 #define CHECK_WIDENING_CONVERSION(extra) G_STMT_START{\
214 if (esize < vsize + (extra)) \
215 mono_raise_exception (mono_get_exception_argument ( \
216 "value", "not a widening conversion")); \
219 #define INVALID_CAST G_STMT_START{\
220 mono_raise_exception (mono_get_exception_invalid_cast ()); \
223 /* Check element (destination) type. */
224 switch (ec->byval_arg.type) {
225 case MONO_TYPE_STRING:
226 switch (vc->byval_arg.type) {
227 case MONO_TYPE_STRING:
233 case MONO_TYPE_BOOLEAN:
234 switch (vc->byval_arg.type) {
235 case MONO_TYPE_BOOLEAN:
248 NO_WIDENING_CONVERSION;
255 if (!ec->valuetype) {
256 if (!mono_object_isinst (value, ec))
258 mono_gc_wbarrier_set_arrayref (this, ea, (MonoObject*)value);
262 if (mono_object_isinst (value, ec)) {
263 if (ec->has_references)
264 mono_value_copy (ea, (char*)value + sizeof (MonoObject), ec);
266 memcpy (ea, (char *)value + sizeof (MonoObject), esize);
273 vsize = mono_class_instance_size (vc) - sizeof (MonoObject);
275 et = ec->byval_arg.type;
276 if (et == MONO_TYPE_VALUETYPE && ec->byval_arg.data.klass->enumtype)
277 et = ec->byval_arg.data.klass->enum_basetype->type;
279 vt = vc->byval_arg.type;
280 if (vt == MONO_TYPE_VALUETYPE && vc->byval_arg.data.klass->enumtype)
281 vt = vc->byval_arg.data.klass->enum_basetype->type;
283 #define ASSIGN_UNSIGNED(etype) G_STMT_START{\
289 case MONO_TYPE_CHAR: \
290 CHECK_WIDENING_CONVERSION(0); \
291 *(etype *) ea = (etype) u64; \
293 /* You can't assign a signed value to an unsigned array. */ \
298 /* You can't assign a floating point number to an integer array. */ \
301 NO_WIDENING_CONVERSION; \
305 #define ASSIGN_SIGNED(etype) G_STMT_START{\
311 CHECK_WIDENING_CONVERSION(0); \
312 *(etype *) ea = (etype) i64; \
314 /* You can assign an unsigned value to a signed array if the array's */ \
315 /* element size is larger than the value size. */ \
320 case MONO_TYPE_CHAR: \
321 CHECK_WIDENING_CONVERSION(1); \
322 *(etype *) ea = (etype) u64; \
324 /* You can't assign a floating point number to an integer array. */ \
327 NO_WIDENING_CONVERSION; \
331 #define ASSIGN_REAL(etype) G_STMT_START{\
335 CHECK_WIDENING_CONVERSION(0); \
336 *(etype *) ea = (etype) r64; \
338 /* All integer values fit into a floating point array, so we don't */ \
339 /* need to CHECK_WIDENING_CONVERSION here. */ \
344 *(etype *) ea = (etype) i64; \
350 case MONO_TYPE_CHAR: \
351 *(etype *) ea = (etype) u64; \
358 u64 = *(guint8 *) va;
361 u64 = *(guint16 *) va;
364 u64 = *(guint32 *) va;
367 u64 = *(guint64 *) va;
373 i64 = *(gint16 *) va;
376 i64 = *(gint32 *) va;
379 i64 = *(gint64 *) va;
382 r64 = *(gfloat *) va;
385 r64 = *(gdouble *) va;
388 u64 = *(guint16 *) va;
390 case MONO_TYPE_BOOLEAN:
391 /* Boolean is only compatible with itself. */
404 NO_WIDENING_CONVERSION;
411 /* If we can't do a direct copy, let's try a widening conversion. */
414 ASSIGN_UNSIGNED (guint16);
416 ASSIGN_UNSIGNED (guint8);
418 ASSIGN_UNSIGNED (guint16);
420 ASSIGN_UNSIGNED (guint32);
422 ASSIGN_UNSIGNED (guint64);
424 ASSIGN_SIGNED (gint8);
426 ASSIGN_SIGNED (gint16);
428 ASSIGN_SIGNED (gint32);
430 ASSIGN_SIGNED (gint64);
432 ASSIGN_REAL (gfloat);
434 ASSIGN_REAL (gdouble);
438 /* Not reached, INVALID_CAST does not return. Just to avoid a compiler warning ... */
442 #undef NO_WIDENING_CONVERSION
443 #undef CHECK_WIDENING_CONVERSION
444 #undef ASSIGN_UNSIGNED
450 ves_icall_System_Array_SetValue (MonoArray *this, MonoObject *value,
458 MONO_CHECK_ARG_NULL (idxs);
460 ic = idxs->obj.vtable->klass;
461 ac = this->obj.vtable->klass;
463 g_assert (ic->rank == 1);
464 if (idxs->bounds != NULL || idxs->max_length != ac->rank)
465 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
467 ind = (gint32 *)idxs->vector;
469 if (this->bounds == NULL) {
470 if (*ind < 0 || *ind >= this->max_length)
471 mono_raise_exception (mono_get_exception_index_out_of_range ());
473 ves_icall_System_Array_SetValueImpl (this, value, *ind);
477 for (i = 0; i < ac->rank; i++)
478 if ((ind [i] < this->bounds [i].lower_bound) ||
479 (ind [i] >= this->bounds [i].length + this->bounds [i].lower_bound))
480 mono_raise_exception (mono_get_exception_index_out_of_range ());
482 pos = ind [0] - this->bounds [0].lower_bound;
483 for (i = 1; i < ac->rank; i++)
484 pos = pos * this->bounds [i].length + ind [i] -
485 this->bounds [i].lower_bound;
487 ves_icall_System_Array_SetValueImpl (this, value, pos);
491 ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
495 mono_array_size_t *sizes, i;
496 gboolean bounded = FALSE;
500 MONO_CHECK_ARG_NULL (type);
501 MONO_CHECK_ARG_NULL (lengths);
503 MONO_CHECK_ARG (lengths, mono_array_length (lengths) > 0);
505 MONO_CHECK_ARG (bounds, mono_array_length (lengths) == mono_array_length (bounds));
507 for (i = 0; i < mono_array_length (lengths); i++)
508 if (mono_array_get (lengths, gint32, i) < 0)
509 mono_raise_exception (mono_get_exception_argument_out_of_range (NULL));
511 if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint32, 0) != 0))
512 /* vectors are not the same as one dimensional arrays with no-zero bounds */
517 aklass = mono_bounded_array_class_get (mono_class_from_mono_type (type->type), mono_array_length (lengths), bounded);
519 sizes = alloca (aklass->rank * sizeof(mono_array_size_t) * 2);
520 for (i = 0; i < aklass->rank; ++i) {
521 sizes [i] = mono_array_get (lengths, guint32, i);
523 sizes [i + aklass->rank] = mono_array_get (bounds, guint32, i);
525 sizes [i + aklass->rank] = 0;
528 array = mono_array_new_full (mono_object_domain (type), aklass, sizes, sizes + aklass->rank);
534 ves_icall_System_Array_CreateInstanceImpl64 (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
538 mono_array_size_t *sizes, i;
539 gboolean bounded = FALSE;
543 MONO_CHECK_ARG_NULL (type);
544 MONO_CHECK_ARG_NULL (lengths);
546 MONO_CHECK_ARG (lengths, mono_array_length (lengths) > 0);
548 MONO_CHECK_ARG (bounds, mono_array_length (lengths) == mono_array_length (bounds));
550 for (i = 0; i < mono_array_length (lengths); i++)
551 if ((mono_array_get (lengths, gint64, i) < 0) ||
552 (mono_array_get (lengths, gint64, i) > MONO_ARRAY_MAX_INDEX))
553 mono_raise_exception (mono_get_exception_argument_out_of_range (NULL));
555 if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint64, 0) != 0))
556 /* vectors are not the same as one dimensional arrays with no-zero bounds */
561 aklass = mono_bounded_array_class_get (mono_class_from_mono_type (type->type), mono_array_length (lengths), bounded);
563 sizes = alloca (aklass->rank * sizeof(mono_array_size_t) * 2);
564 for (i = 0; i < aklass->rank; ++i) {
565 sizes [i] = mono_array_get (lengths, guint64, i);
567 sizes [i + aklass->rank] = (mono_array_size_t) mono_array_get (bounds, guint64, i);
569 sizes [i + aklass->rank] = 0;
572 array = mono_array_new_full (mono_object_domain (type), aklass, sizes, sizes + aklass->rank);
578 ves_icall_System_Array_GetRank (MonoObject *this)
582 return this->vtable->klass->rank;
586 ves_icall_System_Array_GetLength (MonoArray *this, gint32 dimension)
588 gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
589 mono_array_size_t length;
593 if ((dimension < 0) || (dimension >= rank))
594 mono_raise_exception (mono_get_exception_index_out_of_range ());
596 if (this->bounds == NULL)
597 length = this->max_length;
599 length = this->bounds [dimension].length;
601 #ifdef MONO_BIG_ARRAYS
602 if (length > G_MAXINT32)
603 mono_raise_exception (mono_get_exception_overflow ());
609 ves_icall_System_Array_GetLongLength (MonoArray *this, gint32 dimension)
611 gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
615 if ((dimension < 0) || (dimension >= rank))
616 mono_raise_exception (mono_get_exception_index_out_of_range ());
618 if (this->bounds == NULL)
619 return this->max_length;
621 return this->bounds [dimension].length;
625 ves_icall_System_Array_GetLowerBound (MonoArray *this, gint32 dimension)
627 gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
631 if ((dimension < 0) || (dimension >= rank))
632 mono_raise_exception (mono_get_exception_index_out_of_range ());
634 if (this->bounds == NULL)
637 return this->bounds [dimension].lower_bound;
641 ves_icall_System_Array_ClearInternal (MonoArray *arr, int idx, int length)
643 int sz = mono_array_element_size (mono_object_class (arr));
644 memset (mono_array_addr_with_size (arr, sz, idx), 0, length * sz);
648 ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* dest, int dest_idx, int length)
653 MonoClass *src_class;
654 MonoClass *dest_class;
659 if (source->obj.vtable->klass->rank != dest->obj.vtable->klass->rank)
662 if (source->bounds || dest->bounds)
665 if ((dest_idx + length > mono_array_length (dest)) ||
666 (source_idx + length > mono_array_length (source)))
669 src_class = source->obj.vtable->klass->element_class;
670 dest_class = dest->obj.vtable->klass->element_class;
673 * Handle common cases.
676 /* Case1: object[] -> valuetype[] (ArrayList::ToArray) */
677 if (src_class == mono_defaults.object_class && dest_class->valuetype) {
678 int has_refs = dest_class->has_references;
679 for (i = source_idx; i < source_idx + length; ++i) {
680 MonoObject *elem = mono_array_get (source, MonoObject*, i);
681 if (elem && !mono_object_isinst (elem, dest_class))
685 element_size = mono_array_element_size (dest->obj.vtable->klass);
686 memset (mono_array_addr_with_size (dest, element_size, dest_idx), 0, element_size * length);
687 for (i = 0; i < length; ++i) {
688 MonoObject *elem = mono_array_get (source, MonoObject*, source_idx + i);
689 void *addr = mono_array_addr_with_size (dest, element_size, dest_idx + i);
693 mono_value_copy (addr, (char *)elem + sizeof (MonoObject), dest_class);
695 memcpy (addr, (char *)elem + sizeof (MonoObject), element_size);
700 /* Check if we're copying a char[] <==> (u)short[] */
701 if (src_class != dest_class) {
702 if (dest_class->valuetype || dest_class->enumtype || src_class->valuetype || src_class->enumtype)
705 if (mono_class_is_subclass_of (src_class, dest_class, FALSE))
707 /* Case2: object[] -> reftype[] (ArrayList::ToArray) */
708 else if (mono_class_is_subclass_of (dest_class, src_class, FALSE))
709 for (i = source_idx; i < source_idx + length; ++i) {
710 MonoObject *elem = mono_array_get (source, MonoObject*, i);
711 if (elem && !mono_object_isinst (elem, dest_class))
718 if (dest_class->valuetype) {
719 element_size = mono_array_element_size (source->obj.vtable->klass);
720 source_addr = mono_array_addr_with_size (source, element_size, source_idx);
721 if (dest_class->has_references) {
722 mono_value_copy_array (dest, dest_idx, source_addr, length);
724 dest_addr = mono_array_addr_with_size (dest, element_size, dest_idx);
725 memmove (dest_addr, source_addr, element_size * length);
728 mono_array_memcpy_refs (dest, dest_idx, source, source_idx, length);
735 ves_icall_System_Array_GetGenericValueImpl (MonoObject *this, guint32 pos, gpointer value)
744 ao = (MonoArray *)this;
745 ac = (MonoClass *)ao->obj.vtable->klass;
747 esize = mono_array_element_size (ac);
748 ea = (gpointer*)((char*)ao->vector + (pos * esize));
750 memcpy (value, ea, esize);
754 ves_icall_System_Array_SetGenericValueImpl (MonoObject *this, guint32 pos, gpointer value)
763 ao = (MonoArray *)this;
764 ac = (MonoClass *)ao->obj.vtable->klass;
766 esize = mono_array_element_size (ac);
767 ea = (gpointer*)((char*)ao->vector + (pos * esize));
769 memcpy (ea, value, esize);
773 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoArray *array, MonoClassField *field_handle)
775 MonoClass *klass = array->obj.vtable->klass;
776 guint32 size = mono_array_element_size (klass);
777 MonoType *type = mono_type_get_underlying_type (&klass->element_class->byval_arg);
780 if (MONO_TYPE_IS_REFERENCE (type) ||
781 (type->type == MONO_TYPE_VALUETYPE &&
782 (!mono_type_get_class (type) ||
783 mono_type_get_class (type)->has_references))) {
784 MonoException *exc = mono_get_exception_argument("array",
785 "Cannot initialize array containing references");
786 mono_raise_exception (exc);
789 if (!(field_handle->type->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA)) {
790 MonoException *exc = mono_get_exception_argument("field_handle",
791 "Field doesn't have an RVA");
792 mono_raise_exception (exc);
795 size *= array->max_length;
797 if (size > mono_type_size (field_handle->type, &align)) {
798 MonoException *exc = mono_get_exception_argument("field_handle",
799 "Field not large enough to fill array");
800 mono_raise_exception (exc);
803 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
805 guint ## n *data = (guint ## n *) mono_array_addr (array, char, 0); \
806 guint ## n *src = (guint ## n *) field_handle->data; \
807 guint ## n *end = (guint ## n *)((char*)src + size); \
809 for (; src < end; data++, src++) { \
810 *data = read ## n (src); \
814 /* printf ("Initialize array with elements of %s type\n", klass->element_class->name); */
816 switch (type->type) {
833 memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
837 memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
839 if (klass->element_class->byval_arg.type == MONO_TYPE_R8) {
842 double *data = (double*)mono_array_addr (array, double, 0);
844 for (i = 0; i < size; i++, data++) {
854 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData (void)
858 return offsetof (MonoString, chars);
862 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue (MonoObject *obj)
866 if ((obj == NULL) || (! (obj->vtable->klass->valuetype)))
869 return mono_object_clone (obj);
873 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (MonoType *handle)
879 MONO_CHECK_ARG_NULL (handle);
881 klass = mono_class_from_mono_type (handle);
882 MONO_CHECK_ARG (handle, klass);
884 /* This will call the type constructor */
885 mono_runtime_class_init (mono_class_vtable (mono_domain_get (), klass));
889 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunModuleConstructor (MonoImage *image)
893 mono_image_check_for_module_cctor (image);
894 if (image->has_module_cctor) {
895 MonoClass *module_klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | 1);
896 mono_runtime_class_init (mono_class_vtable (mono_domain_get (), module_klass));
901 ves_icall_System_Object_MemberwiseClone (MonoObject *this)
905 return mono_object_clone (this);
909 ves_icall_System_ValueType_InternalGetHashCode (MonoObject *this, MonoArray **fields)
912 MonoObject **values = NULL;
916 MonoClassField* field;
921 klass = mono_object_class (this);
923 if (mono_class_num_fields (klass) == 0)
924 return mono_object_hash (this);
927 * Compute the starting value of the hashcode for fields of primitive
928 * types, and return the remaining fields in an array to the managed side.
929 * This way, we can avoid costly reflection operations in managed code.
932 while ((field = mono_class_get_fields (klass, &iter))) {
933 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
935 if (mono_field_is_deleted (field))
937 /* FIXME: Add more types */
938 switch (field->type->type) {
940 result ^= *(gint32*)((guint8*)this + field->offset);
942 case MONO_TYPE_STRING: {
944 s = *(MonoString**)((guint8*)this + field->offset);
946 result ^= mono_string_hash (s);
951 values = g_newa (MonoObject*, mono_class_num_fields (klass));
952 o = mono_field_get_value_object (mono_object_domain (this), field, this);
953 values [count++] = o;
959 *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
960 for (i = 0; i < count; ++i)
961 mono_array_setref (*fields, i, values [i]);
969 ves_icall_System_ValueType_Equals (MonoObject *this, MonoObject *that, MonoArray **fields)
972 MonoObject **values = NULL;
974 MonoClassField* field;
980 MONO_CHECK_ARG_NULL (that);
982 if (this->vtable != that->vtable)
985 klass = mono_object_class (this);
987 if (klass->enumtype && klass->enum_basetype && klass->enum_basetype->type == MONO_TYPE_I4)
988 return (*(gint32*)((guint8*)this + sizeof (MonoObject)) == *(gint32*)((guint8*)that + sizeof (MonoObject)));
991 * Do the comparison for fields of primitive type and return a result if
992 * possible. Otherwise, return the remaining fields in an array to the
993 * managed side. This way, we can avoid costly reflection operations in
998 while ((field = mono_class_get_fields (klass, &iter))) {
999 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
1001 if (mono_field_is_deleted (field))
1003 /* FIXME: Add more types */
1004 switch (field->type->type) {
1007 case MONO_TYPE_BOOLEAN:
1008 if (*((guint8*)this + field->offset) != *((guint8*)that + field->offset))
1013 case MONO_TYPE_CHAR:
1014 if (*(gint16*)((guint8*)this + field->offset) != *(gint16*)((guint8*)that + field->offset))
1019 if (*(gint32*)((guint8*)this + field->offset) != *(gint32*)((guint8*)that + field->offset))
1024 if (*(gint64*)((guint8*)this + field->offset) != *(gint64*)((guint8*)that + field->offset))
1028 if (*(float*)((guint8*)this + field->offset) != *(float*)((guint8*)that + field->offset))
1032 if (*(double*)((guint8*)this + field->offset) != *(double*)((guint8*)that + field->offset))
1037 case MONO_TYPE_STRING: {
1038 MonoString *s1, *s2;
1039 guint32 s1len, s2len;
1040 s1 = *(MonoString**)((guint8*)this + field->offset);
1041 s2 = *(MonoString**)((guint8*)that + field->offset);
1044 if ((s1 == NULL) || (s2 == NULL))
1046 s1len = mono_string_length (s1);
1047 s2len = mono_string_length (s2);
1051 if (memcmp (mono_string_chars (s1), mono_string_chars (s2), s1len * sizeof (gunichar2)) != 0)
1057 values = g_newa (MonoObject*, mono_class_num_fields (klass) * 2);
1058 o = mono_field_get_value_object (mono_object_domain (this), field, this);
1059 values [count++] = o;
1060 o = mono_field_get_value_object (mono_object_domain (this), field, that);
1061 values [count++] = o;
1064 if (klass->enumtype)
1065 /* enums only have one non-static field */
1071 *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
1072 for (i = 0; i < count; ++i)
1073 mono_array_setref (*fields, i, values [i]);
1080 static MonoReflectionType *
1081 ves_icall_System_Object_GetType (MonoObject *obj)
1083 MONO_ARCH_SAVE_REGS;
1085 if (obj->vtable->klass != mono_defaults.transparent_proxy_class)
1086 return mono_type_get_object (mono_object_domain (obj), &obj->vtable->klass->byval_arg);
1088 return mono_type_get_object (mono_object_domain (obj), &((MonoTransparentProxy*)obj)->remote_class->proxy_class->byval_arg);
1092 mono_type_type_from_obj (MonoReflectionType *mtype, MonoObject *obj)
1094 MONO_ARCH_SAVE_REGS;
1096 mtype->type = &obj->vtable->klass->byval_arg;
1097 g_assert (mtype->type->type);
1101 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj)
1103 MONO_ARCH_SAVE_REGS;
1105 MONO_CHECK_ARG_NULL (obj);
1107 return mono_image_create_token (mb->dynamic_image, obj, TRUE, TRUE);
1111 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder *mb,
1112 MonoReflectionMethod *method,
1113 MonoArray *opt_param_types)
1115 MONO_ARCH_SAVE_REGS;
1117 MONO_CHECK_ARG_NULL (method);
1119 return mono_image_create_method_token (
1120 mb->dynamic_image, (MonoObject *) method, opt_param_types);
1124 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder *mb, HANDLE file)
1126 MONO_ARCH_SAVE_REGS;
1128 mono_image_create_pefile (mb, file);
1132 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
1134 MONO_ARCH_SAVE_REGS;
1136 mono_image_build_metadata (mb);
1140 ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, guint32 token)
1142 MONO_ARCH_SAVE_REGS;
1144 mono_image_register_token (mb->dynamic_image, token, obj);
1148 get_caller (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1150 MonoMethod **dest = data;
1152 /* skip unmanaged frames */
1167 static MonoReflectionType *
1168 type_from_name (const char *str, MonoBoolean ignoreCase)
1170 MonoType *type = NULL;
1171 MonoAssembly *assembly = NULL;
1172 MonoTypeNameParse info;
1173 char *temp_str = g_strdup (str);
1174 gboolean type_resolve = FALSE;
1176 MONO_ARCH_SAVE_REGS;
1178 /* mono_reflection_parse_type() mangles the string */
1179 if (!mono_reflection_parse_type (temp_str, &info)) {
1180 mono_reflection_free_type_info (&info);
1185 if (info.assembly.name) {
1186 assembly = mono_assembly_load (&info.assembly, NULL, NULL);
1188 MonoMethod *m = mono_method_get_last_managed ();
1189 MonoMethod *dest = m;
1191 mono_stack_walk_no_il (get_caller, &dest);
1196 * FIXME: mono_method_get_last_managed() sometimes returns NULL, thus
1197 * causing ves_icall_System_Reflection_Assembly_GetCallingAssembly()
1198 * to crash. This only seems to happen in some strange remoting
1199 * scenarios and I was unable to figure out what's happening there.
1200 * Dec 10, 2005 - Martin.
1204 assembly = dest->klass->image->assembly;
1206 g_warning (G_STRLOC);
1211 type = mono_reflection_get_type (assembly->image, &info, ignoreCase, &type_resolve);
1213 if (!info.assembly.name && !type) /* try mscorlib */
1214 type = mono_reflection_get_type (NULL, &info, ignoreCase, &type_resolve);
1216 mono_reflection_free_type_info (&info);
1222 return mono_type_get_object (mono_domain_get (), type);
1226 MonoReflectionType *
1227 mono_type_get (const char *str)
1229 char *copy = g_strdup (str);
1230 MonoReflectionType *type = type_from_name (copy, FALSE);
1237 static MonoReflectionType*
1238 ves_icall_type_from_name (MonoString *name,
1239 MonoBoolean throwOnError,
1240 MonoBoolean ignoreCase)
1242 char *str = mono_string_to_utf8 (name);
1243 MonoReflectionType *type;
1245 type = type_from_name (str, ignoreCase);
1248 MonoException *e = NULL;
1251 e = mono_get_exception_type_load (name, NULL);
1253 mono_loader_clear_error ();
1255 mono_raise_exception (e);
1262 static MonoReflectionType*
1263 ves_icall_type_from_handle (MonoType *handle)
1265 MonoDomain *domain = mono_domain_get ();
1266 MonoClass *klass = mono_class_from_mono_type (handle);
1268 MONO_ARCH_SAVE_REGS;
1270 mono_class_init (klass);
1271 return mono_type_get_object (domain, handle);
1275 ves_icall_System_Type_EqualsInternal (MonoReflectionType *type, MonoReflectionType *c)
1277 MONO_ARCH_SAVE_REGS;
1279 if (c && type->type && c->type)
1280 return mono_metadata_type_equal (type->type, c->type);
1285 /* System.TypeCode */
1304 TYPECODE_STRING = 18
1308 ves_icall_type_GetTypeCodeInternal (MonoReflectionType *type)
1310 int t = type->type->type;
1312 MONO_ARCH_SAVE_REGS;
1314 if (type->type->byref)
1315 return TYPECODE_OBJECT;
1319 case MONO_TYPE_VOID:
1320 return TYPECODE_OBJECT;
1321 case MONO_TYPE_BOOLEAN:
1322 return TYPECODE_BOOLEAN;
1324 return TYPECODE_BYTE;
1326 return TYPECODE_SBYTE;
1328 return TYPECODE_UINT16;
1330 return TYPECODE_INT16;
1331 case MONO_TYPE_CHAR:
1332 return TYPECODE_CHAR;
1336 return TYPECODE_OBJECT;
1338 return TYPECODE_UINT32;
1340 return TYPECODE_INT32;
1342 return TYPECODE_UINT64;
1344 return TYPECODE_INT64;
1346 return TYPECODE_SINGLE;
1348 return TYPECODE_DOUBLE;
1349 case MONO_TYPE_VALUETYPE:
1350 if (type->type->data.klass->enumtype) {
1351 t = type->type->data.klass->enum_basetype->type;
1354 MonoClass *k = type->type->data.klass;
1355 if (strcmp (k->name_space, "System") == 0) {
1356 if (strcmp (k->name, "Decimal") == 0)
1357 return TYPECODE_DECIMAL;
1358 else if (strcmp (k->name, "DateTime") == 0)
1359 return TYPECODE_DATETIME;
1362 return TYPECODE_OBJECT;
1363 case MONO_TYPE_STRING:
1364 return TYPECODE_STRING;
1365 case MONO_TYPE_SZARRAY:
1366 case MONO_TYPE_ARRAY:
1367 case MONO_TYPE_OBJECT:
1369 case MONO_TYPE_MVAR:
1370 case MONO_TYPE_TYPEDBYREF:
1371 return TYPECODE_OBJECT;
1372 case MONO_TYPE_CLASS:
1374 MonoClass *k = type->type->data.klass;
1375 if (strcmp (k->name_space, "System") == 0) {
1376 if (strcmp (k->name, "DBNull") == 0)
1377 return TYPECODE_DBNULL;
1380 return TYPECODE_OBJECT;
1381 case MONO_TYPE_GENERICINST:
1382 return TYPECODE_OBJECT;
1384 g_error ("type 0x%02x not handled in GetTypeCode()", t);
1390 ves_icall_type_is_subtype_of (MonoReflectionType *type, MonoReflectionType *c, MonoBoolean check_interfaces)
1396 MONO_ARCH_SAVE_REGS;
1398 g_assert (type != NULL);
1400 domain = ((MonoObject *)type)->vtable->domain;
1402 if (!c) /* FIXME: dont know what do do here */
1405 klass = mono_class_from_mono_type (type->type);
1406 klassc = mono_class_from_mono_type (c->type);
1408 if (type->type->byref)
1409 return klassc == mono_defaults.object_class;
1411 return mono_class_is_subclass_of (klass, klassc, check_interfaces);
1415 ves_icall_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType *c)
1421 MONO_ARCH_SAVE_REGS;
1423 g_assert (type != NULL);
1425 domain = ((MonoObject *)type)->vtable->domain;
1427 klass = mono_class_from_mono_type (type->type);
1428 klassc = mono_class_from_mono_type (c->type);
1430 if (type->type->byref && !c->type->byref)
1433 return mono_class_is_assignable_from (klass, klassc);
1437 ves_icall_type_IsInstanceOfType (MonoReflectionType *type, MonoObject *obj)
1439 MonoClass *klass = mono_class_from_mono_type (type->type);
1440 return mono_object_isinst (obj, klass) != NULL;
1444 ves_icall_get_attributes (MonoReflectionType *type)
1446 MonoClass *klass = mono_class_from_mono_type (type->type);
1448 MONO_ARCH_SAVE_REGS;
1450 return klass->flags;
1453 static MonoReflectionMarshal*
1454 ves_icall_System_Reflection_FieldInfo_GetUnmanagedMarshal (MonoReflectionField *field)
1456 MonoClass *klass = field->field->parent;
1457 MonoMarshalType *info;
1460 if (klass->generic_container ||
1461 (klass->generic_class && klass->generic_class->context.class_inst->is_open))
1464 info = mono_marshal_load_type_info (klass);
1466 for (i = 0; i < info->num_fields; ++i) {
1467 if (info->fields [i].field == field->field) {
1468 if (!info->fields [i].mspec)
1471 return mono_reflection_marshal_from_marshal_spec (field->object.vtable->domain, klass, info->fields [i].mspec);
1478 static MonoReflectionField*
1479 ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoClass *klass)
1484 klass = handle->parent;
1486 /* FIXME: check that handle is a field of klass or of a parent: return null
1487 * and throw the exception in managed code.
1489 return mono_field_get_object (mono_domain_get (), klass, handle);
1492 static MonoReflectionField*
1493 ves_icall_System_Reflection_FieldInfo_internal_from_handle (MonoClassField *handle)
1495 MONO_ARCH_SAVE_REGS;
1499 return mono_field_get_object (mono_domain_get (), handle->parent, handle);
1503 ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionField *field, MonoBoolean optional)
1505 MonoType *type = field->field->type;
1507 return type_array_from_modifiers (field->field->parent->image, type, optional);
1511 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
1513 MonoDomain *domain = mono_domain_get ();
1514 MonoMethodSignature* sig;
1515 MONO_ARCH_SAVE_REGS;
1517 sig = mono_method_signature (method);
1519 g_assert (mono_loader_get_last_error ());
1520 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
1523 info->parent = mono_type_get_object (domain, &method->klass->byval_arg);
1524 info->ret = mono_type_get_object (domain, sig->ret);
1525 info->attrs = method->flags;
1526 info->implattrs = method->iflags;
1527 if (sig->call_convention == MONO_CALL_DEFAULT)
1528 info->callconv = sig->sentinelpos >= 0 ? 2 : 1;
1530 if (sig->call_convention == MONO_CALL_VARARG || sig->sentinelpos >= 0)
1535 info->callconv |= (sig->hasthis << 5) | (sig->explicit_this << 6);
1539 ves_icall_get_parameter_info (MonoMethod *method)
1541 MonoDomain *domain = mono_domain_get ();
1543 return mono_param_get_objects (domain, method);
1546 static MonoReflectionMarshal*
1547 ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod *method)
1549 MonoDomain *domain = mono_domain_get ();
1550 MonoReflectionMarshal* res = NULL;
1551 MonoMarshalSpec **mspecs;
1554 mspecs = g_new (MonoMarshalSpec*, mono_method_signature (method)->param_count + 1);
1555 mono_method_get_marshal_info (method, mspecs);
1558 res = mono_reflection_marshal_from_marshal_spec (domain, method->klass, mspecs [0]);
1560 for (i = mono_method_signature (method)->param_count; i >= 0; i--)
1562 mono_metadata_free_marshal_spec (mspecs [i]);
1569 ves_icall_MonoField_GetFieldOffset (MonoReflectionField *field)
1571 return field->field->offset - sizeof (MonoObject);
1574 static MonoReflectionType*
1575 ves_icall_MonoField_GetParentType (MonoReflectionField *field, MonoBoolean declaring)
1578 MONO_ARCH_SAVE_REGS;
1580 parent = declaring? field->field->parent: field->klass;
1582 return mono_type_get_object (mono_object_domain (field), &parent->byval_arg);
1586 ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj)
1589 MonoClassField *cf = field->field;
1593 MonoDomain *domain = mono_object_domain (field);
1595 gboolean is_static = FALSE;
1596 gboolean is_ref = FALSE;
1598 MONO_ARCH_SAVE_REGS;
1600 if (field->klass->image->assembly->ref_only)
1601 mono_raise_exception (mono_get_exception_invalid_operation (
1602 "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
1604 mono_class_init (field->klass);
1606 if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC)
1609 if (obj && !is_static) {
1610 /* Check that the field belongs to the object */
1611 gboolean found = FALSE;
1614 for (k = obj->vtable->klass; k; k = k->parent) {
1615 if (k == cf->parent) {
1622 char *msg = g_strdup_printf ("Field '%s' defined on type '%s' is not a field on the target object which is of type '%s'.", cf->name, cf->parent->name, obj->vtable->klass->name);
1623 MonoException *ex = mono_get_exception_argument (NULL, msg);
1625 mono_raise_exception (ex);
1629 t = mono_type_get_underlying_type (cf->type);
1631 case MONO_TYPE_STRING:
1632 case MONO_TYPE_OBJECT:
1633 case MONO_TYPE_CLASS:
1634 case MONO_TYPE_ARRAY:
1635 case MONO_TYPE_SZARRAY:
1640 case MONO_TYPE_BOOLEAN:
1643 case MONO_TYPE_CHAR:
1652 case MONO_TYPE_VALUETYPE:
1655 case MONO_TYPE_GENERICINST:
1656 if (mono_type_generic_inst_is_valuetype (t)) {
1663 g_error ("type 0x%x not handled in "
1664 "ves_icall_Monofield_GetValue", t->type);
1670 vtable = mono_class_vtable (domain, cf->parent);
1671 if (!vtable->initialized && !(cf->type->attrs & FIELD_ATTRIBUTE_LITERAL))
1672 mono_runtime_class_init (vtable);
1677 mono_field_static_get_value (vtable, cf, &o);
1679 mono_field_get_value (obj, cf, &o);
1684 if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) {
1685 MonoClass *nklass = mono_class_from_mono_type (cf->type);
1688 /* Convert the Nullable structure into a boxed vtype */
1690 buf = (guint8*)vtable->data + cf->offset;
1692 buf = (guint8*)obj + cf->offset;
1694 return mono_nullable_box (buf, nklass);
1697 /* boxed value type */
1698 klass = mono_class_from_mono_type (cf->type);
1699 o = mono_object_new (domain, klass);
1700 v = ((gchar *) o) + sizeof (MonoObject);
1702 mono_field_static_get_value (vtable, cf, v);
1704 mono_field_get_value (obj, cf, v);
1711 ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value)
1713 MonoClassField *cf = field->field;
1716 MONO_ARCH_SAVE_REGS;
1718 if (field->klass->image->assembly->ref_only)
1719 mono_raise_exception (mono_get_exception_invalid_operation (
1720 "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
1722 v = (gchar *) value;
1723 if (!cf->type->byref) {
1724 switch (cf->type->type) {
1727 case MONO_TYPE_BOOLEAN:
1730 case MONO_TYPE_CHAR:
1739 case MONO_TYPE_VALUETYPE:
1741 v += sizeof (MonoObject);
1743 case MONO_TYPE_STRING:
1744 case MONO_TYPE_OBJECT:
1745 case MONO_TYPE_CLASS:
1746 case MONO_TYPE_ARRAY:
1747 case MONO_TYPE_SZARRAY:
1750 case MONO_TYPE_GENERICINST: {
1751 MonoGenericClass *gclass = cf->type->data.generic_class;
1752 g_assert (!gclass->context.class_inst->is_open);
1754 if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) {
1755 MonoClass *nklass = mono_class_from_mono_type (cf->type);
1756 MonoObject *nullable;
1759 * Convert the boxed vtype into a Nullable structure.
1760 * This is complicated by the fact that Nullables have
1761 * a variable structure.
1763 nullable = mono_object_new (mono_domain_get (), nklass);
1765 mono_nullable_init (mono_object_unbox (nullable), value, nklass);
1767 v = mono_object_unbox (nullable);
1770 if (gclass->container_class->valuetype && (v != NULL))
1771 v += sizeof (MonoObject);
1775 g_error ("type 0x%x not handled in "
1776 "ves_icall_FieldInfo_SetValueInternal", cf->type->type);
1781 if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) {
1782 MonoVTable *vtable = mono_class_vtable (mono_object_domain (field), cf->parent);
1783 if (!vtable->initialized)
1784 mono_runtime_class_init (vtable);
1785 mono_field_static_set_value (vtable, cf, v);
1787 mono_field_set_value (obj, cf, v);
1792 ves_icall_MonoField_GetRawConstantValue (MonoReflectionField *this)
1794 MonoObject *o = NULL;
1795 MonoClassField *field = this->field;
1797 MonoDomain *domain = mono_object_domain (this);
1799 MonoTypeEnum def_type;
1800 const char *def_value;
1802 MONO_ARCH_SAVE_REGS;
1804 mono_class_init (field->parent);
1806 if (!(field->type->attrs & FIELD_ATTRIBUTE_HAS_DEFAULT))
1807 mono_raise_exception (mono_get_exception_invalid_operation (NULL));
1809 if (field->parent->image->dynamic) {
1811 g_assert_not_reached ();
1814 def_value = mono_class_get_field_default_value (field, &def_type);
1819 case MONO_TYPE_BOOLEAN:
1822 case MONO_TYPE_CHAR:
1830 case MONO_TYPE_R8: {
1833 /* boxed value type */
1834 t = g_new0 (MonoType, 1);
1836 klass = mono_class_from_mono_type (t);
1838 o = mono_object_new (domain, klass);
1839 v = ((gchar *) o) + sizeof (MonoObject);
1840 mono_get_constant_value_from_blob (domain, def_type, def_value, v);
1843 case MONO_TYPE_STRING:
1844 case MONO_TYPE_CLASS:
1845 mono_get_constant_value_from_blob (domain, def_type, def_value, &o);
1848 g_assert_not_reached ();
1854 static MonoReflectionType*
1855 ves_icall_MonoGenericMethod_get_ReflectedType (MonoReflectionGenericMethod *rmethod)
1857 MonoMethod *method = rmethod->method.method;
1859 return mono_type_get_object (mono_object_domain (rmethod), &method->klass->byval_arg);
1862 /* From MonoProperty.cs */
1864 PInfo_Attributes = 1,
1865 PInfo_GetMethod = 1 << 1,
1866 PInfo_SetMethod = 1 << 2,
1867 PInfo_ReflectedType = 1 << 3,
1868 PInfo_DeclaringType = 1 << 4,
1873 ves_icall_get_property_info (MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
1875 MonoDomain *domain = mono_object_domain (property);
1877 MONO_ARCH_SAVE_REGS;
1879 if ((req_info & PInfo_ReflectedType) != 0)
1880 MONO_STRUCT_SETREF (info, parent, mono_type_get_object (domain, &property->klass->byval_arg));
1881 else if ((req_info & PInfo_DeclaringType) != 0)
1882 MONO_STRUCT_SETREF (info, parent, mono_type_get_object (domain, &property->property->parent->byval_arg));
1884 if ((req_info & PInfo_Name) != 0)
1885 MONO_STRUCT_SETREF (info, name, mono_string_new (domain, property->property->name));
1887 if ((req_info & PInfo_Attributes) != 0)
1888 info->attrs = property->property->attrs;
1890 if ((req_info & PInfo_GetMethod) != 0)
1891 MONO_STRUCT_SETREF (info, get, property->property->get ?
1892 mono_method_get_object (domain, property->property->get, property->klass): NULL);
1894 if ((req_info & PInfo_SetMethod) != 0)
1895 MONO_STRUCT_SETREF (info, set, property->property->set ?
1896 mono_method_get_object (domain, property->property->set, property->klass): NULL);
1898 * There may be other methods defined for properties, though, it seems they are not exposed
1899 * in the reflection API
1904 ves_icall_get_event_info (MonoReflectionEvent *event, MonoEventInfo *info)
1906 MonoDomain *domain = mono_object_domain (event);
1908 MONO_ARCH_SAVE_REGS;
1910 info->reflected_type = mono_type_get_object (domain, &event->klass->byval_arg);
1911 info->declaring_type = mono_type_get_object (domain, &event->event->parent->byval_arg);
1913 info->name = mono_string_new (domain, event->event->name);
1914 info->attrs = event->event->attrs;
1915 info->add_method = event->event->add ? mono_method_get_object (domain, event->event->add, NULL): NULL;
1916 info->remove_method = event->event->remove ? mono_method_get_object (domain, event->event->remove, NULL): NULL;
1917 info->raise_method = event->event->raise ? mono_method_get_object (domain, event->event->raise, NULL): NULL;
1919 if (event->event->other) {
1921 while (event->event->other [n])
1923 info->other_methods = mono_array_new (domain, mono_defaults.method_info_class, n);
1925 for (i = 0; i < n; i++)
1926 mono_array_setref (info->other_methods, i, mono_method_get_object (domain, event->event->other [i], NULL));
1931 ves_icall_Type_GetInterfaces (MonoReflectionType* type)
1933 MonoDomain *domain = mono_object_domain (type);
1935 GPtrArray *ifaces = NULL;
1937 MonoClass *class = mono_class_from_mono_type (type->type);
1940 MonoGenericContext *context = NULL;
1942 MONO_ARCH_SAVE_REGS;
1944 if (class->generic_class && class->generic_class->context.class_inst->is_open) {
1945 context = mono_class_get_context (class);
1946 class = class->generic_class->container_class;
1949 mono_class_setup_vtable (class);
1951 slots = mono_bitset_new (class->max_interface_id + 1, 0);
1953 for (parent = class; parent; parent = parent->parent) {
1954 GPtrArray *tmp_ifaces = mono_class_get_implemented_interfaces (parent);
1956 for (i = 0; i < tmp_ifaces->len; ++i) {
1957 MonoClass *ic = g_ptr_array_index (tmp_ifaces, i);
1959 if (mono_bitset_test (slots, ic->interface_id))
1962 mono_bitset_set (slots, ic->interface_id);
1964 ifaces = g_ptr_array_new ();
1965 g_ptr_array_add (ifaces, ic);
1967 g_ptr_array_free (tmp_ifaces, TRUE);
1970 mono_bitset_free (slots);
1973 return mono_array_new (domain, mono_defaults.monotype_class, 0);
1975 intf = mono_array_new (domain, mono_defaults.monotype_class, ifaces->len);
1976 for (i = 0; i < ifaces->len; ++i) {
1977 MonoClass *ic = g_ptr_array_index (ifaces, i);
1978 MonoType *ret = &ic->byval_arg, *inflated = NULL;
1979 if (context && ic->generic_class && ic->generic_class->context.class_inst->is_open)
1980 inflated = ret = mono_class_inflate_generic_type (ret, context);
1982 mono_array_setref (intf, i, mono_type_get_object (domain, ret));
1984 mono_metadata_free_type (inflated);
1986 g_ptr_array_free (ifaces, TRUE);
1992 ves_icall_Type_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType *iface, MonoArray **targets, MonoArray **methods)
1994 MonoClass *class = mono_class_from_mono_type (type->type);
1995 MonoClass *iclass = mono_class_from_mono_type (iface->type);
1996 MonoReflectionMethod *member;
1999 int i = 0, len, ioffset;
2002 MONO_ARCH_SAVE_REGS;
2004 mono_class_setup_vtable (class);
2006 /* type doesn't implement iface: the exception is thrown in managed code */
2007 if (! MONO_CLASS_IMPLEMENTS_INTERFACE (class, iclass->interface_id))
2010 len = mono_class_num_methods (iclass);
2011 ioffset = mono_class_interface_offset (class, iclass);
2012 domain = mono_object_domain (type);
2013 *targets = mono_array_new (domain, mono_defaults.method_info_class, len);
2014 *methods = mono_array_new (domain, mono_defaults.method_info_class, len);
2017 while ((method = mono_class_get_methods (iclass, &iter))) {
2018 member = mono_method_get_object (domain, method, iclass);
2019 mono_array_setref (*methods, i, member);
2020 member = mono_method_get_object (domain, class->vtable [i + ioffset], class);
2021 mono_array_setref (*targets, i, member);
2028 ves_icall_Type_GetPacking (MonoReflectionType *type, guint32 *packing, guint32 *size)
2030 MonoClass *klass = mono_class_from_mono_type (type->type);
2032 if (klass->image->dynamic) {
2033 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)type;
2034 *packing = tb->packing_size;
2035 *size = tb->class_size;
2037 mono_metadata_packing_from_typedef (klass->image, klass->type_token, packing, size);
2041 static MonoReflectionType*
2042 ves_icall_MonoType_GetElementType (MonoReflectionType *type)
2044 MonoClass *class = mono_class_from_mono_type (type->type);
2046 MONO_ARCH_SAVE_REGS;
2048 // GetElementType should only return a type for:
2049 // Array Pointer PassedByRef
2050 if (type->type->byref)
2051 return mono_type_get_object (mono_object_domain (type), &class->byval_arg);
2052 else if (class->element_class && MONO_CLASS_IS_ARRAY (class))
2053 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
2054 else if (class->element_class && type->type->type == MONO_TYPE_PTR)
2055 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
2060 static MonoReflectionType*
2061 ves_icall_get_type_parent (MonoReflectionType *type)
2063 MonoClass *class = mono_class_from_mono_type (type->type);
2065 MONO_ARCH_SAVE_REGS;
2067 return class->parent ? mono_type_get_object (mono_object_domain (type), &class->parent->byval_arg): NULL;
2071 ves_icall_type_ispointer (MonoReflectionType *type)
2073 MONO_ARCH_SAVE_REGS;
2075 return type->type->type == MONO_TYPE_PTR;
2079 ves_icall_type_isprimitive (MonoReflectionType *type)
2081 MONO_ARCH_SAVE_REGS;
2083 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)));
2087 ves_icall_type_isbyref (MonoReflectionType *type)
2089 MONO_ARCH_SAVE_REGS;
2091 return type->type->byref;
2095 ves_icall_type_iscomobject (MonoReflectionType *type)
2097 MonoClass *klass = mono_class_from_mono_type (type->type);
2098 MONO_ARCH_SAVE_REGS;
2100 return (klass && klass->is_com_object);
2103 static MonoReflectionModule*
2104 ves_icall_MonoType_get_Module (MonoReflectionType *type)
2106 MonoClass *class = mono_class_from_mono_type (type->type);
2108 MONO_ARCH_SAVE_REGS;
2110 return mono_module_get_object (mono_object_domain (type), class->image);
2113 static MonoReflectionAssembly*
2114 ves_icall_MonoType_get_Assembly (MonoReflectionType *type)
2116 MonoDomain *domain = mono_domain_get ();
2117 MonoClass *class = mono_class_from_mono_type (type->type);
2119 MONO_ARCH_SAVE_REGS;
2121 return mono_assembly_get_object (domain, class->image->assembly);
2124 static MonoReflectionType*
2125 ves_icall_MonoType_get_DeclaringType (MonoReflectionType *type)
2127 MonoDomain *domain = mono_domain_get ();
2130 MONO_ARCH_SAVE_REGS;
2132 if (type->type->byref)
2134 if (type->type->type == MONO_TYPE_VAR)
2135 class = type->type->data.generic_param->owner->owner.klass;
2136 else if (type->type->type == MONO_TYPE_MVAR)
2137 class = type->type->data.generic_param->owner->owner.method->klass;
2139 class = mono_class_from_mono_type (type->type)->nested_in;
2141 return class ? mono_type_get_object (domain, &class->byval_arg) : NULL;
2144 static MonoReflectionType*
2145 ves_icall_MonoType_get_UnderlyingSystemType (MonoReflectionType *type)
2147 MonoDomain *domain = mono_domain_get ();
2148 MonoClass *class = mono_class_from_mono_type (type->type);
2150 MONO_ARCH_SAVE_REGS;
2152 if (class->enumtype && class->enum_basetype) /* types that are modified typebuilders may not have enum_basetype set */
2153 return mono_type_get_object (domain, class->enum_basetype);
2154 else if (class->element_class)
2155 return mono_type_get_object (domain, &class->element_class->byval_arg);
2161 ves_icall_MonoType_get_Name (MonoReflectionType *type)
2163 MonoDomain *domain = mono_domain_get ();
2164 MonoClass *class = mono_class_from_mono_type (type->type);
2166 MONO_ARCH_SAVE_REGS;
2168 if (type->type->byref) {
2169 char *n = g_strdup_printf ("%s&", class->name);
2170 MonoString *res = mono_string_new (domain, n);
2176 return mono_string_new (domain, class->name);
2181 ves_icall_MonoType_get_Namespace (MonoReflectionType *type)
2183 MonoDomain *domain = mono_domain_get ();
2184 MonoClass *class = mono_class_from_mono_type (type->type);
2186 MONO_ARCH_SAVE_REGS;
2188 while (class->nested_in)
2189 class = class->nested_in;
2191 if (class->name_space [0] == '\0')
2194 return mono_string_new (domain, class->name_space);
2198 ves_icall_MonoType_GetArrayRank (MonoReflectionType *type)
2200 MonoClass *class = mono_class_from_mono_type (type->type);
2202 MONO_ARCH_SAVE_REGS;
2208 ves_icall_MonoType_GetGenericArguments (MonoReflectionType *type)
2211 MonoClass *klass, *pklass;
2213 MONO_ARCH_SAVE_REGS;
2215 klass = mono_class_from_mono_type (type->type);
2217 if (klass->generic_container) {
2218 MonoGenericContainer *container = klass->generic_container;
2219 res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, container->type_argc);
2220 for (i = 0; i < container->type_argc; ++i) {
2221 pklass = mono_class_from_generic_parameter (&container->type_params [i], klass->image, FALSE);
2222 mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), &pklass->byval_arg));
2224 } else if (klass->generic_class) {
2225 MonoGenericInst *inst = klass->generic_class->context.class_inst;
2226 res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, inst->type_argc);
2227 for (i = 0; i < inst->type_argc; ++i)
2228 mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), inst->type_argv [i]));
2230 res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, 0);
2236 ves_icall_Type_get_IsGenericTypeDefinition (MonoReflectionType *type)
2239 MONO_ARCH_SAVE_REGS;
2241 if (type->type->byref)
2244 klass = mono_class_from_mono_type (type->type);
2246 return klass->generic_container != NULL;
2249 static MonoReflectionType*
2250 ves_icall_Type_GetGenericTypeDefinition_impl (MonoReflectionType *type)
2253 MONO_ARCH_SAVE_REGS;
2255 if (type->type->byref)
2258 klass = mono_class_from_mono_type (type->type);
2259 if (klass->generic_container) {
2260 return type; /* check this one */
2262 if (klass->generic_class) {
2263 MonoClass *generic_class = klass->generic_class->container_class;
2265 if (generic_class->wastypebuilder && generic_class->reflection_info)
2266 return generic_class->reflection_info;
2268 return mono_type_get_object (mono_object_domain (type), &generic_class->byval_arg);
2273 static MonoReflectionType*
2274 ves_icall_Type_MakeGenericType (MonoReflectionType *type, MonoArray *type_array)
2276 MonoType *geninst, **types;
2279 MONO_ARCH_SAVE_REGS;
2281 count = mono_array_length (type_array);
2282 types = g_new0 (MonoType *, count);
2284 for (i = 0; i < count; i++) {
2285 MonoReflectionType *t = mono_array_get (type_array, gpointer, i);
2286 types [i] = t->type;
2289 geninst = mono_reflection_bind_generic_parameters (type, count, types);
2294 return mono_type_get_object (mono_object_domain (type), geninst);
2298 ves_icall_Type_get_IsGenericInstance (MonoReflectionType *type)
2301 MONO_ARCH_SAVE_REGS;
2303 if (type->type->byref)
2306 klass = mono_class_from_mono_type (type->type);
2307 return klass->generic_class != NULL;
2311 ves_icall_Type_get_IsGenericType (MonoReflectionType *type)
2314 MONO_ARCH_SAVE_REGS;
2316 if (type->type->byref)
2319 klass = mono_class_from_mono_type (type->type);
2320 return klass->generic_class != NULL || klass->generic_container != NULL;
2324 ves_icall_Type_GetGenericParameterPosition (MonoReflectionType *type)
2326 MONO_ARCH_SAVE_REGS;
2328 if (is_generic_parameter (type->type))
2329 return type->type->data.generic_param->num;
2333 static GenericParameterAttributes
2334 ves_icall_Type_GetGenericParameterAttributes (MonoReflectionType *type)
2336 MONO_ARCH_SAVE_REGS;
2337 g_assert (is_generic_parameter (type->type));
2338 return type->type->data.generic_param->flags;
2342 ves_icall_Type_GetGenericParameterConstraints (MonoReflectionType *type)
2344 MonoGenericParam *param;
2350 MONO_ARCH_SAVE_REGS;
2352 domain = mono_object_domain (type);
2353 param = type->type->data.generic_param;
2354 for (count = 0, ptr = param->constraints; ptr && *ptr; ptr++, count++)
2357 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2358 for (i = 0; i < count; i++)
2359 mono_array_setref (res, i, mono_type_get_object (domain, ¶m->constraints [i]->byval_arg));
2366 ves_icall_MonoType_get_IsGenericParameter (MonoReflectionType *type)
2368 MONO_ARCH_SAVE_REGS;
2369 return is_generic_parameter (type->type);
2373 ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder *tb)
2375 MONO_ARCH_SAVE_REGS;
2376 return is_generic_parameter (tb->type.type);
2380 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
2381 MonoReflectionType *t)
2383 enumtype->type = t->type;
2386 static MonoReflectionType*
2387 ves_icall_MonoGenericClass_GetParentType (MonoReflectionGenericClass *type)
2389 MonoDynamicGenericClass *gclass;
2390 MonoReflectionType *parent = NULL, *res;
2396 MONO_ARCH_SAVE_REGS;
2398 g_assert (type->type.type->data.generic_class->is_dynamic);
2399 gclass = (MonoDynamicGenericClass *) type->type.type->data.generic_class;
2401 domain = mono_object_domain (type);
2402 klass = mono_class_from_mono_type (type->generic_type->type.type);
2404 if (!klass->generic_class && !klass->generic_container)
2407 parent = type->generic_type->parent;
2409 if (!parent || (parent->type->type != MONO_TYPE_GENERICINST))
2412 inflated = mono_class_inflate_generic_type (
2413 parent->type, mono_generic_class_get_context ((MonoGenericClass *) gclass));
2415 res = mono_type_get_object (domain, inflated);
2416 mono_metadata_free_type (inflated);
2421 ves_icall_MonoGenericClass_GetInterfaces (MonoReflectionGenericClass *type)
2423 static MonoClass *System_Reflection_MonoGenericClass;
2424 MonoGenericClass *gclass;
2425 MonoReflectionTypeBuilder *tb = NULL;
2426 MonoClass *klass = NULL;
2431 MONO_ARCH_SAVE_REGS;
2433 if (!System_Reflection_MonoGenericClass) {
2434 System_Reflection_MonoGenericClass = mono_class_from_name (
2435 mono_defaults.corlib, "System.Reflection", "MonoGenericClass");
2436 g_assert (System_Reflection_MonoGenericClass);
2439 domain = mono_object_domain (type);
2441 gclass = type->type.type->data.generic_class;
2442 g_assert (gclass->is_dynamic);
2444 tb = type->generic_type;
2445 icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
2447 res = mono_array_new (domain, System_Reflection_MonoGenericClass, icount);
2449 for (i = 0; i < icount; i++) {
2450 MonoReflectionType *iface;
2454 iface = mono_array_get (tb->interfaces, MonoReflectionType *, i);
2457 it = &klass->interfaces [i]->byval_arg;
2459 it = mono_class_inflate_generic_type (it, mono_generic_class_get_context (gclass));
2461 iface = mono_type_get_object (domain, it);
2462 mono_array_setref (res, i, iface);
2463 mono_metadata_free_type (it);
2469 static MonoReflectionMethod*
2470 ves_icall_MonoGenericClass_GetCorrespondingInflatedMethod (MonoReflectionGenericClass *type,
2471 MonoReflectionMethod* generic)
2473 MonoGenericClass *gclass;
2474 MonoDynamicGenericClass *dgclass;
2478 MONO_ARCH_SAVE_REGS;
2480 gclass = type->type.type->data.generic_class;
2481 g_assert (gclass->is_dynamic);
2483 dgclass = (MonoDynamicGenericClass *) gclass;
2485 domain = mono_object_domain (type);
2487 for (i = 0; i < dgclass->count_methods; i++)
2488 if (generic->method->token == dgclass->methods [i]->token)
2489 return mono_method_get_object (domain, dgclass->methods [i], NULL);
2494 static MonoReflectionMethod*
2495 ves_icall_MonoGenericClass_GetCorrespondingInflatedConstructor (MonoReflectionGenericClass *type,
2496 MonoReflectionMethod* generic)
2498 MonoGenericClass *gclass;
2499 MonoDynamicGenericClass *dgclass;
2503 MONO_ARCH_SAVE_REGS;
2505 gclass = type->type.type->data.generic_class;
2506 g_assert (gclass->is_dynamic);
2508 dgclass = (MonoDynamicGenericClass *) gclass;
2510 domain = mono_object_domain (type);
2512 for (i = 0; i < dgclass->count_ctors; i++)
2513 if (generic->method->token == dgclass->ctors [i]->token)
2514 return mono_method_get_object (domain, dgclass->ctors [i], NULL);
2520 static MonoReflectionField*
2521 ves_icall_MonoGenericClass_GetCorrespondingInflatedField (MonoReflectionGenericClass *type,
2522 MonoString* generic_name)
2524 MonoGenericClass *gclass;
2525 MonoDynamicGenericClass *dgclass;
2527 MonoClass *refclass;
2528 char *utf8_name = mono_string_to_utf8 (generic_name);
2531 MONO_ARCH_SAVE_REGS;
2533 gclass = type->type.type->data.generic_class;
2534 g_assert (gclass->is_dynamic);
2536 dgclass = (MonoDynamicGenericClass *) gclass;
2538 refclass = mono_class_from_mono_type (type->type.type);
2540 domain = mono_object_domain (type);
2542 for (i = 0; i < dgclass->count_fields; i++)
2543 if (strcmp (utf8_name, dgclass->fields [i].name) == 0) {
2545 return mono_field_get_object (domain, refclass, &dgclass->fields [i]);
2554 static MonoReflectionMethod*
2555 ves_icall_MonoType_GetCorrespondingInflatedMethod (MonoReflectionType *type,
2556 MonoReflectionMethod* generic)
2563 MONO_ARCH_SAVE_REGS;
2565 domain = ((MonoObject *)type)->vtable->domain;
2567 klass = mono_class_from_mono_type (type->type);
2570 while ((method = mono_class_get_methods (klass, &iter))) {
2571 if (method->token == generic->method->token)
2572 return mono_method_get_object (domain, method, klass);
2579 ves_icall_MonoGenericClass_GetMethods (MonoReflectionGenericClass *type,
2580 MonoReflectionType *reflected_type)
2582 MonoGenericClass *gclass;
2583 MonoDynamicGenericClass *dgclass;
2585 MonoClass *refclass;
2589 MONO_ARCH_SAVE_REGS;
2591 gclass = type->type.type->data.generic_class;
2592 g_assert (gclass->is_dynamic);
2593 dgclass = (MonoDynamicGenericClass *) gclass;
2595 refclass = mono_class_from_mono_type (reflected_type->type);
2597 domain = mono_object_domain (type);
2598 res = mono_array_new (domain, mono_defaults.method_info_class, dgclass->count_methods);
2600 for (i = 0; i < dgclass->count_methods; i++)
2601 mono_array_setref (res, i, mono_method_get_object (domain, dgclass->methods [i], refclass));
2607 ves_icall_MonoGenericClass_GetConstructors (MonoReflectionGenericClass *type,
2608 MonoReflectionType *reflected_type)
2610 static MonoClass *System_Reflection_ConstructorInfo;
2611 MonoGenericClass *gclass;
2612 MonoDynamicGenericClass *dgclass;
2614 MonoClass *refclass;
2618 MONO_ARCH_SAVE_REGS;
2620 if (!System_Reflection_ConstructorInfo)
2621 System_Reflection_ConstructorInfo = mono_class_from_name (
2622 mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
2624 gclass = type->type.type->data.generic_class;
2625 g_assert (gclass->is_dynamic);
2626 dgclass = (MonoDynamicGenericClass *) gclass;
2628 refclass = mono_class_from_mono_type (reflected_type->type);
2630 domain = mono_object_domain (type);
2631 res = mono_array_new (domain, System_Reflection_ConstructorInfo, dgclass->count_ctors);
2633 for (i = 0; i < dgclass->count_ctors; i++)
2634 mono_array_setref (res, i, mono_method_get_object (domain, dgclass->ctors [i], refclass));
2640 ves_icall_MonoGenericClass_GetFields (MonoReflectionGenericClass *type,
2641 MonoReflectionType *reflected_type)
2643 MonoGenericClass *gclass;
2644 MonoDynamicGenericClass *dgclass;
2646 MonoClass *refclass;
2650 MONO_ARCH_SAVE_REGS;
2652 gclass = type->type.type->data.generic_class;
2653 g_assert (gclass->is_dynamic);
2654 dgclass = (MonoDynamicGenericClass *) gclass;
2656 refclass = mono_class_from_mono_type (reflected_type->type);
2658 domain = mono_object_domain (type);
2659 res = mono_array_new (domain, mono_defaults.field_info_class, dgclass->count_fields);
2661 for (i = 0; i < dgclass->count_fields; i++)
2662 mono_array_setref (res, i, mono_field_get_object (domain, refclass, &dgclass->fields [i]));
2668 ves_icall_MonoGenericClass_GetProperties (MonoReflectionGenericClass *type,
2669 MonoReflectionType *reflected_type)
2671 static MonoClass *System_Reflection_PropertyInfo;
2672 MonoGenericClass *gclass;
2673 MonoDynamicGenericClass *dgclass;
2675 MonoClass *refclass;
2679 MONO_ARCH_SAVE_REGS;
2681 if (!System_Reflection_PropertyInfo)
2682 System_Reflection_PropertyInfo = mono_class_from_name (
2683 mono_defaults.corlib, "System.Reflection", "PropertyInfo");
2685 gclass = type->type.type->data.generic_class;
2686 g_assert (gclass->is_dynamic);
2687 dgclass = (MonoDynamicGenericClass *) gclass;
2689 refclass = mono_class_from_mono_type (reflected_type->type);
2691 domain = mono_object_domain (type);
2692 res = mono_array_new (domain, System_Reflection_PropertyInfo, dgclass->count_properties);
2694 for (i = 0; i < dgclass->count_properties; i++)
2695 mono_array_setref (res, i, mono_property_get_object (domain, refclass, &dgclass->properties [i]));
2701 ves_icall_MonoGenericClass_GetEvents (MonoReflectionGenericClass *type,
2702 MonoReflectionType *reflected_type)
2704 static MonoClass *System_Reflection_EventInfo;
2705 MonoGenericClass *gclass;
2706 MonoDynamicGenericClass *dgclass;
2708 MonoClass *refclass;
2712 MONO_ARCH_SAVE_REGS;
2714 if (!System_Reflection_EventInfo)
2715 System_Reflection_EventInfo = mono_class_from_name (
2716 mono_defaults.corlib, "System.Reflection", "EventInfo");
2718 gclass = type->type.type->data.generic_class;
2719 g_assert (gclass->is_dynamic);
2720 dgclass = (MonoDynamicGenericClass *) gclass;
2722 refclass = mono_class_from_mono_type (reflected_type->type);
2724 domain = mono_object_domain (type);
2725 res = mono_array_new (domain, System_Reflection_EventInfo, dgclass->count_events);
2727 for (i = 0; i < dgclass->count_events; i++)
2728 mono_array_setref (res, i, mono_event_get_object (domain, refclass, &dgclass->events [i]));
2733 static MonoReflectionType*
2734 ves_icall_MonoGenericClass_InflateType (MonoReflectionGenericClass *type,
2735 MonoReflectionType *target)
2739 MonoReflectionType *res;
2741 MONO_ARCH_SAVE_REGS;
2743 gklass = mono_class_from_mono_type (type->type.type);
2744 res_type = mono_class_inflate_generic_type (target->type, mono_class_get_context (gklass));
2745 res = mono_type_get_object (mono_object_domain (type), res_type);
2746 mono_metadata_free_type (res_type);
2750 static MonoReflectionMethod *
2751 ves_icall_MonoType_get_DeclaringMethod (MonoReflectionType *type)
2756 MONO_ARCH_SAVE_REGS;
2758 if (type->type->byref || type->type->type != MONO_TYPE_MVAR)
2761 method = type->type->data.generic_param->owner->owner.method;
2763 klass = mono_class_from_mono_type (type->type);
2764 return mono_method_get_object (mono_object_domain (type), method, klass);
2767 static MonoReflectionDllImportAttribute*
2768 ves_icall_MonoMethod_GetDllImportAttribute (MonoMethod *method)
2770 static MonoClass *DllImportAttributeClass = NULL;
2771 MonoDomain *domain = mono_domain_get ();
2772 MonoReflectionDllImportAttribute *attr;
2773 MonoImage *image = method->klass->image;
2774 MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method;
2775 MonoTableInfo *tables = image->tables;
2776 MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
2777 MonoTableInfo *mr = &tables [MONO_TABLE_MODULEREF];
2778 guint32 im_cols [MONO_IMPLMAP_SIZE];
2779 guint32 scope_token;
2780 const char *import = NULL;
2781 const char *scope = NULL;
2784 if (!method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)
2787 if (!DllImportAttributeClass) {
2788 DllImportAttributeClass =
2789 mono_class_from_name (mono_defaults.corlib,
2790 "System.Runtime.InteropServices", "DllImportAttribute");
2791 g_assert (DllImportAttributeClass);
2794 if (method->klass->image->dynamic) {
2795 MonoReflectionMethodAux *method_aux =
2796 g_hash_table_lookup (
2797 ((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
2799 import = method_aux->dllentry;
2800 scope = method_aux->dll;
2804 if (piinfo->implmap_idx) {
2805 mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
2807 piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
2808 import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
2809 scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
2810 scope = mono_metadata_string_heap (image, scope_token);
2813 flags = piinfo->piflags;
2815 attr = (MonoReflectionDllImportAttribute*)mono_object_new (domain, DllImportAttributeClass);
2817 MONO_OBJECT_SETREF (attr, dll, mono_string_new (domain, scope));
2818 MONO_OBJECT_SETREF (attr, entry_point, mono_string_new (domain, import));
2819 attr->call_conv = (flags & 0x700) >> 8;
2820 attr->charset = ((flags & 0x6) >> 1) + 1;
2821 if (attr->charset == 1)
2823 attr->exact_spelling = (flags & 0x1) != 0;
2824 attr->set_last_error = (flags & 0x40) != 0;
2825 attr->best_fit_mapping = (flags & 0x30) == 0x10;
2826 attr->throw_on_unmappable = (flags & 0x3000) == 0x1000;
2827 attr->preserve_sig = FALSE;
2832 static MonoReflectionMethod *
2833 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
2835 MonoMethodInflated *imethod;
2838 MONO_ARCH_SAVE_REGS;
2840 if (method->method->is_generic)
2843 if (!method->method->is_inflated)
2846 imethod = (MonoMethodInflated *) method->method;
2848 result = imethod->declaring;
2849 /* Not a generic method. */
2850 if (!result->is_generic)
2853 if (method->method->klass->image->dynamic) {
2854 MonoDynamicImage *image = (MonoDynamicImage*)method->method->klass->image;
2855 MonoReflectionMethod *res;
2858 * FIXME: Why is this stuff needed at all ? Why can't the code below work for
2859 * the dynamic case as well ?
2861 mono_loader_lock ();
2862 res = mono_g_hash_table_lookup (image->generic_def_objects, imethod);
2863 mono_loader_unlock ();
2869 if (imethod->context.class_inst) {
2870 MonoClass *klass = ((MonoMethod *) imethod)->klass;
2871 result = mono_class_inflate_generic_method_full (result, klass, mono_class_get_context (klass));
2874 return mono_method_get_object (mono_object_domain (method), result, NULL);
2878 ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethod *method)
2880 MONO_ARCH_SAVE_REGS;
2882 return mono_method_signature (method->method)->generic_param_count != 0;
2886 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method)
2888 MONO_ARCH_SAVE_REGS;
2890 return method->method->is_generic;
2894 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
2899 MONO_ARCH_SAVE_REGS;
2901 domain = mono_object_domain (method);
2903 if (method->method->is_inflated) {
2904 MonoGenericInst *inst = mono_method_get_context (method->method)->method_inst;
2907 count = inst->type_argc;
2908 res = mono_array_new (domain, mono_defaults.systemtype_class, count);
2910 for (i = 0; i < count; i++)
2911 mono_array_setref (res, i, mono_type_get_object (domain, inst->type_argv [i]));
2917 count = mono_method_signature (method->method)->generic_param_count;
2918 res = mono_array_new (domain, mono_defaults.systemtype_class, count);
2920 for (i = 0; i < count; i++) {
2921 MonoGenericContainer *container = mono_method_get_generic_container (method->method);
2922 MonoGenericParam *param = &container->type_params [i];
2923 MonoClass *pklass = mono_class_from_generic_parameter (
2924 param, method->method->klass->image, TRUE);
2925 mono_array_setref (res, i,
2926 mono_type_get_object (domain, &pklass->byval_arg));
2933 ensure_reflection_security (void)
2935 MonoMethod *m = mono_method_get_last_managed ();
2939 g_print ("method %s.%s.%s in image %s\n",
2940 m->klass->name_space, m->klass->name, m->name, m->klass->image->name);
2943 /* We stop at the first method which is not in
2944 System.Reflection or which is not in a platform
2946 if (strcmp (m->klass->name_space, "System.Reflection") != 0 ||
2947 !mono_security_core_clr_is_platform_image (m->klass->image)) {
2948 /* If the method is transparent we throw an exception. */
2949 if (mono_security_core_clr_method_level (m, TRUE) == MONO_SECURITY_CORE_CLR_TRANSPARENT ) {
2950 MonoException *ex = mono_exception_from_name_msg (mono_defaults.corlib, "System", "MethodAccessException", "Reflection called from transparent code");
2952 mono_raise_exception (ex);
2957 mono_stack_walk_no_il (get_caller, &m);
2962 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoArray *params, MonoException **exc)
2965 * Invoke from reflection is supposed to always be a virtual call (the API
2966 * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
2967 * greater flexibility.
2969 MonoMethod *m = method->method;
2973 MONO_ARCH_SAVE_REGS;
2977 if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR &&
2978 mono_security_core_clr_method_level (m, TRUE) == MONO_SECURITY_CORE_CLR_CRITICAL)
2979 ensure_reflection_security ();
2981 if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
2983 if (!mono_object_isinst (this, m->klass)) {
2984 *exc = mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Object does not match target type.");
2987 m = mono_object_get_virtual_method (this, m);
2988 /* must pass the pointer to the value for valuetype methods */
2989 if (m->klass->valuetype)
2990 obj = mono_object_unbox (this);
2991 } else if (strcmp (m->name, ".ctor") && !m->wrapper_type) {
2992 *exc = mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Non-static method requires a target.");
2997 pcount = params? mono_array_length (params): 0;
2998 if (pcount != mono_method_signature (m)->param_count) {
2999 *exc = mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException");
3003 if ((m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) && !strcmp (m->name, ".ctor") && !this) {
3004 *exc = mono_exception_from_name_msg (mono_defaults.corlib, "System", "MethodAccessException", "Cannot invoke constructor of an abstract class.");
3008 if (m->klass->image->assembly->ref_only) {
3009 *exc = mono_get_exception_invalid_operation ("It is illegal to invoke a method on a type loaded using the ReflectionOnly api.");
3013 if (m->klass->rank && !strcmp (m->name, ".ctor")) {
3015 mono_array_size_t *lengths;
3016 mono_array_size_t *lower_bounds;
3017 pcount = mono_array_length (params);
3018 lengths = alloca (sizeof (mono_array_size_t) * pcount);
3019 for (i = 0; i < pcount; ++i)
3020 lengths [i] = *(mono_array_size_t*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
3022 if (m->klass->rank == pcount) {
3023 /* Only lengths provided. */
3024 lower_bounds = NULL;
3026 g_assert (pcount == (m->klass->rank * 2));
3027 /* lower bounds are first. */
3028 lower_bounds = lengths;
3029 lengths += m->klass->rank;
3032 return (MonoObject*)mono_array_new_full (mono_object_domain (params), m->klass, lengths, lower_bounds);
3034 return mono_runtime_invoke_array (m, obj, params, NULL);
3038 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this, MonoArray *params, MonoArray **outArgs)
3040 MonoDomain *domain = mono_object_domain (method);
3041 MonoMethod *m = method->method;
3042 MonoMethodSignature *sig = mono_method_signature (m);
3043 MonoArray *out_args;
3045 int i, j, outarg_count = 0;
3047 MONO_ARCH_SAVE_REGS;
3049 if (m->klass == mono_defaults.object_class) {
3051 if (!strcmp (m->name, "FieldGetter")) {
3052 MonoClass *k = this->vtable->klass;
3056 /* If this is a proxy, then it must be a CBO */
3057 if (k == mono_defaults.transparent_proxy_class) {
3058 MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
3059 this = tp->rp->unwrapped_server;
3061 k = this->vtable->klass;
3064 name = mono_array_get (params, MonoString *, 1);
3065 str = mono_string_to_utf8 (name);
3068 MonoClassField* field = mono_class_get_field_from_name (k, str);
3070 MonoClass *field_klass = mono_class_from_mono_type (field->type);
3071 if (field_klass->valuetype)
3072 result = mono_value_box (domain, field_klass, (char *)this + field->offset);
3074 result = *((gpointer *)((char *)this + field->offset));
3076 out_args = mono_array_new (domain, mono_defaults.object_class, 1);
3077 *outArgs = out_args;
3078 mono_array_setref (out_args, 0, result);
3086 g_assert_not_reached ();
3088 } else if (!strcmp (m->name, "FieldSetter")) {
3089 MonoClass *k = this->vtable->klass;
3095 /* If this is a proxy, then it must be a CBO */
3096 if (k == mono_defaults.transparent_proxy_class) {
3097 MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
3098 this = tp->rp->unwrapped_server;
3100 k = this->vtable->klass;
3103 name = mono_array_get (params, MonoString *, 1);
3104 str = mono_string_to_utf8 (name);
3107 MonoClassField* field = mono_class_get_field_from_name (k, str);
3109 MonoClass *field_klass = mono_class_from_mono_type (field->type);
3110 MonoObject *val = mono_array_get (params, gpointer, 2);
3112 if (field_klass->valuetype) {
3113 size = mono_type_size (field->type, &align);
3114 memcpy ((char *)this + field->offset,
3115 ((char *)val) + sizeof (MonoObject), size);
3117 *(MonoObject**)((char *)this + field->offset) = val;
3119 out_args = mono_array_new (domain, mono_defaults.object_class, 0);
3120 *outArgs = out_args;
3130 g_assert_not_reached ();
3135 for (i = 0; i < mono_array_length (params); i++) {
3136 if (sig->params [i]->byref)
3140 out_args = mono_array_new (domain, mono_defaults.object_class, outarg_count);
3142 /* handle constructors only for objects already allocated */
3143 if (!strcmp (method->method->name, ".ctor"))
3146 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
3147 g_assert (!method->method->klass->valuetype);
3148 result = mono_runtime_invoke_array (method->method, this, params, NULL);
3150 for (i = 0, j = 0; i < mono_array_length (params); i++) {
3151 if (sig->params [i]->byref) {
3153 arg = mono_array_get (params, gpointer, i);
3154 mono_array_setref (out_args, j, arg);
3159 *outArgs = out_args;
3165 read_enum_value (char *mem, int type)
3169 return *(guint8*)mem;
3171 return *(gint8*)mem;
3173 return *(guint16*)mem;
3175 return *(gint16*)mem;
3177 return *(guint32*)mem;
3179 return *(gint32*)mem;
3181 return *(guint64*)mem;
3183 return *(gint64*)mem;
3185 g_assert_not_reached ();
3191 write_enum_value (char *mem, int type, guint64 value)
3195 case MONO_TYPE_I1: {
3196 guint8 *p = (guint8*)mem;
3201 case MONO_TYPE_I2: {
3202 guint16 *p = (void*)mem;
3207 case MONO_TYPE_I4: {
3208 guint32 *p = (void*)mem;
3213 case MONO_TYPE_I8: {
3214 guint64 *p = (void*)mem;
3219 g_assert_not_reached ();
3225 ves_icall_System_Enum_ToObject (MonoReflectionType *enumType, MonoObject *value)
3228 MonoClass *enumc, *objc;
3232 MONO_ARCH_SAVE_REGS;
3234 MONO_CHECK_ARG_NULL (enumType);
3235 MONO_CHECK_ARG_NULL (value);
3237 domain = mono_object_domain (enumType);
3238 enumc = mono_class_from_mono_type (enumType->type);
3239 objc = value->vtable->klass;
3241 if (!enumc->enumtype)
3242 mono_raise_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
3243 if (!((objc->enumtype) || (objc->byval_arg.type >= MONO_TYPE_I1 && objc->byval_arg.type <= MONO_TYPE_U8)))
3244 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."));
3246 res = mono_object_new (domain, enumc);
3247 val = read_enum_value ((char *)value + sizeof (MonoObject), objc->enumtype? objc->enum_basetype->type: objc->byval_arg.type);
3248 write_enum_value ((char *)res + sizeof (MonoObject), enumc->enum_basetype->type, val);
3254 ves_icall_System_Enum_get_value (MonoObject *this)
3262 MONO_ARCH_SAVE_REGS;
3267 g_assert (this->vtable->klass->enumtype);
3269 enumc = mono_class_from_mono_type (this->vtable->klass->enum_basetype);
3270 res = mono_object_new (mono_object_domain (this), enumc);
3271 dst = (char *)res + sizeof (MonoObject);
3272 src = (char *)this + sizeof (MonoObject);
3273 size = mono_class_value_size (enumc, NULL);
3275 memcpy (dst, src, size);
3280 static MonoReflectionType *
3281 ves_icall_System_Enum_get_underlying_type (MonoReflectionType *type)
3283 MONO_ARCH_SAVE_REGS;
3285 return mono_type_get_object (mono_object_domain (type), mono_class_from_mono_type (type->type)->enum_basetype);
3289 ves_icall_System_Enum_get_hashcode (MonoObject *this)
3291 gpointer data = (char *)this + sizeof (MonoObject);
3292 MonoType *basetype = this->vtable->klass->enum_basetype;
3293 g_assert (basetype);
3295 switch (basetype->type) {
3297 return *((gint8*)data);
3299 return *((guint8*)data);
3300 case MONO_TYPE_CHAR:
3302 return *((guint16*)data);
3305 return *((gint16*)data);
3307 return *((guint32*)data);
3309 return *((gint32*)data);
3311 case MONO_TYPE_I8: {
3312 gint64 value = *((gint64*)data);
3313 return (gint)(value & 0xffffffff) ^ (int)(value >> 32);
3316 g_error ("Implement type 0x%02x in get_hashcode", basetype->type);
3322 ves_icall_get_enum_info (MonoReflectionType *type, MonoEnumInfo *info)
3324 MonoDomain *domain = mono_object_domain (type);
3325 MonoClass *enumc = mono_class_from_mono_type (type->type);
3326 guint j = 0, nvalues, crow;
3328 MonoClassField *field;
3330 MONO_ARCH_SAVE_REGS;
3332 info->utype = mono_type_get_object (domain, enumc->enum_basetype);
3333 nvalues = mono_class_num_fields (enumc) ? mono_class_num_fields (enumc) - 1 : 0;
3334 info->names = mono_array_new (domain, mono_defaults.string_class, nvalues);
3335 info->values = mono_array_new (domain, enumc, nvalues);
3339 while ((field = mono_class_get_fields (enumc, &iter))) {
3343 if (strcmp ("value__", field->name) == 0)
3345 if (mono_field_is_deleted (field))
3347 mono_array_setref (info->names, j, mono_string_new (domain, field->name));
3350 crow = mono_metadata_get_constant_index (enumc->image, mono_class_get_field_token (field), crow + 1);
3351 field->def_type = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_TYPE);
3352 crow = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_VALUE);
3353 field->data = (gpointer)mono_metadata_blob_heap (enumc->image, crow);
3357 len = mono_metadata_decode_blob_size (p, &p);
3358 switch (enumc->enum_basetype->type) {
3361 mono_array_set (info->values, gchar, j, *p);
3363 case MONO_TYPE_CHAR:
3366 mono_array_set (info->values, gint16, j, read16 (p));
3370 mono_array_set (info->values, gint32, j, read32 (p));
3374 mono_array_set (info->values, gint64, j, read64 (p));
3377 g_error ("Implement type 0x%02x in get_enum_info", enumc->enum_basetype->type);
3384 BFLAGS_IgnoreCase = 1,
3385 BFLAGS_DeclaredOnly = 2,
3386 BFLAGS_Instance = 4,
3388 BFLAGS_Public = 0x10,
3389 BFLAGS_NonPublic = 0x20,
3390 BFLAGS_FlattenHierarchy = 0x40,
3391 BFLAGS_InvokeMethod = 0x100,
3392 BFLAGS_CreateInstance = 0x200,
3393 BFLAGS_GetField = 0x400,
3394 BFLAGS_SetField = 0x800,
3395 BFLAGS_GetProperty = 0x1000,
3396 BFLAGS_SetProperty = 0x2000,
3397 BFLAGS_ExactBinding = 0x10000,
3398 BFLAGS_SuppressChangeType = 0x20000,
3399 BFLAGS_OptionalParamBinding = 0x40000
3402 static MonoReflectionField *
3403 ves_icall_Type_GetField (MonoReflectionType *type, MonoString *name, guint32 bflags)
3406 MonoClass *startklass, *klass;
3408 MonoClassField *field;
3411 int (*compare_func) (const char *s1, const char *s2) = NULL;
3412 domain = ((MonoObject *)type)->vtable->domain;
3413 klass = startklass = mono_class_from_mono_type (type->type);
3415 MONO_ARCH_SAVE_REGS;
3418 mono_raise_exception (mono_get_exception_argument_null ("name"));
3419 if (type->type->byref)
3422 compare_func = (bflags & BFLAGS_IgnoreCase) ? g_strcasecmp : strcmp;
3425 if (klass->exception_type != MONO_EXCEPTION_NONE)
3426 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3429 while ((field = mono_class_get_fields (klass, &iter))) {
3432 if (field->type == NULL)
3434 if (mono_field_is_deleted (field))
3436 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3437 if (bflags & BFLAGS_Public)
3439 } else if ((klass == startklass) || (field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
3440 if (bflags & BFLAGS_NonPublic) {
3447 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
3448 if (bflags & BFLAGS_Static)
3449 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3452 if (bflags & BFLAGS_Instance)
3459 utf8_name = mono_string_to_utf8 (name);
3461 if (compare_func (field->name, utf8_name)) {
3467 return mono_field_get_object (domain, klass, field);
3469 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3476 ves_icall_Type_GetFields_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3479 MonoClass *startklass, *klass, *refklass;
3484 MonoClassField *field;
3486 MONO_ARCH_SAVE_REGS;
3488 domain = ((MonoObject *)type)->vtable->domain;
3489 if (type->type->byref)
3490 return mono_array_new (domain, mono_defaults.field_info_class, 0);
3491 klass = startklass = mono_class_from_mono_type (type->type);
3492 refklass = mono_class_from_mono_type (reftype->type);
3496 res = mono_array_new (domain, mono_defaults.field_info_class, len);
3498 if (klass->exception_type != MONO_EXCEPTION_NONE)
3499 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3502 while ((field = mono_class_get_fields (klass, &iter))) {
3504 if (mono_field_is_deleted (field))
3506 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3507 if (bflags & BFLAGS_Public)
3509 } else if ((klass == startklass) || (field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
3510 if (bflags & BFLAGS_NonPublic) {
3517 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
3518 if (bflags & BFLAGS_Static)
3519 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3522 if (bflags & BFLAGS_Instance)
3528 member = (MonoObject*)mono_field_get_object (domain, refklass, field);
3530 MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, len * 2);
3531 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3535 mono_array_setref (res, i, member);
3538 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3541 MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, i);
3542 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3545 * Better solution for the new GC.
3546 * res->max_length = i;
3553 method_nonpublic (MonoMethod* method, gboolean start_klass)
3555 switch (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) {
3556 case METHOD_ATTRIBUTE_ASSEM:
3557 return (start_klass || mono_defaults.generic_ilist_class);
3558 case METHOD_ATTRIBUTE_PRIVATE:
3560 case METHOD_ATTRIBUTE_PUBLIC:
3568 ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
3570 static MonoClass *MethodInfo_array;
3572 MonoClass *startklass, *klass, *refklass;
3577 int i, len, match, nslots;
3578 guint32 method_slots_default [8];
3579 guint32 *method_slots;
3580 gchar *mname = NULL;
3581 int (*compare_func) (const char *s1, const char *s2) = NULL;
3582 MonoVTable *array_vtable;
3584 MONO_ARCH_SAVE_REGS;
3586 if (!MethodInfo_array) {
3587 MonoClass *klass = mono_array_class_get (mono_defaults.method_info_class, 1);
3588 mono_memory_barrier ();
3589 MethodInfo_array = klass;
3592 domain = ((MonoObject *)type)->vtable->domain;
3593 array_vtable = mono_class_vtable (domain, MethodInfo_array);
3594 if (type->type->byref)
3595 return mono_array_new_specific (array_vtable, 0);
3596 klass = startklass = mono_class_from_mono_type (type->type);
3597 refklass = mono_class_from_mono_type (reftype->type);
3600 mname = mono_string_to_utf8 (name);
3601 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
3604 mono_class_setup_vtable (klass);
3606 if (is_generic_parameter (type->type))
3607 nslots = klass->parent->vtable_size;
3609 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : klass->vtable_size;
3610 if (nslots >= sizeof (method_slots_default) * 8) {
3611 method_slots = g_new0 (guint32, nslots / 32 + 1);
3613 method_slots = method_slots_default;
3614 memset (method_slots, 0, sizeof (method_slots_default));
3618 res = mono_array_new_specific (array_vtable, len);
3620 mono_class_setup_vtable (klass);
3621 if (klass->exception_type != MONO_EXCEPTION_NONE)
3622 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3625 while ((method = mono_class_get_methods (klass, &iter))) {
3627 if (method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
3629 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3630 if (bflags & BFLAGS_Public)
3632 } else if ((bflags & BFLAGS_NonPublic) && method_nonpublic (method, (klass == startklass))) {
3638 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3639 if (bflags & BFLAGS_Static)
3640 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3643 if (bflags & BFLAGS_Instance)
3651 if (compare_func (mname, method->name))
3656 if (method->slot != -1) {
3657 g_assert (method->slot < nslots);
3658 if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
3660 method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
3663 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
3666 MonoArray *new_res = mono_array_new_specific (array_vtable, len * 2);
3667 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3671 mono_array_setref (res, i, member);
3674 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3678 if (method_slots != method_slots_default)
3679 g_free (method_slots);
3681 MonoArray *new_res = mono_array_new (domain, mono_defaults.method_info_class, i);
3682 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3685 * Better solution for the new GC.
3686 * res->max_length = i;
3693 ves_icall_Type_GetConstructors_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3696 static MonoClass *System_Reflection_ConstructorInfo;
3697 MonoClass *startklass, *klass, *refklass;
3702 gpointer iter = NULL;
3704 MONO_ARCH_SAVE_REGS;
3706 domain = ((MonoObject *)type)->vtable->domain;
3707 if (type->type->byref)
3708 return mono_array_new (domain, mono_defaults.method_info_class, 0);
3709 klass = startklass = mono_class_from_mono_type (type->type);
3710 refklass = mono_class_from_mono_type (reftype->type);
3712 if (klass->exception_type != MONO_EXCEPTION_NONE)
3713 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3715 if (!System_Reflection_ConstructorInfo)
3716 System_Reflection_ConstructorInfo = mono_class_from_name (
3717 mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
3721 res = mono_array_new (domain, System_Reflection_ConstructorInfo, len);
3723 while ((method = mono_class_get_methods (klass, &iter))) {
3725 if (strcmp (method->name, ".ctor") && strcmp (method->name, ".cctor"))
3727 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3728 if (bflags & BFLAGS_Public)
3731 if (bflags & BFLAGS_NonPublic)
3737 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3738 if (bflags & BFLAGS_Static)
3739 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3742 if (bflags & BFLAGS_Instance)
3748 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
3751 MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, len * 2);
3752 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3756 mono_array_setref (res, i, member);
3760 MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, i);
3761 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3764 * Better solution for the new GC.
3765 * res->max_length = i;
3772 property_hash (gconstpointer data)
3774 MonoProperty *prop = (MonoProperty*)data;
3776 return g_str_hash (prop->name);
3780 property_equal (MonoProperty *prop1, MonoProperty *prop2)
3782 // Properties are hide-by-name-and-signature
3783 if (!g_str_equal (prop1->name, prop2->name))
3786 if (prop1->get && prop2->get && !mono_metadata_signature_equal (mono_method_signature (prop1->get), mono_method_signature (prop2->get)))
3788 if (prop1->set && prop2->set && !mono_metadata_signature_equal (mono_method_signature (prop1->set), mono_method_signature (prop2->set)))
3794 property_accessor_nonpublic (MonoMethod* accessor, gboolean start_klass)
3799 return method_nonpublic (accessor, start_klass);
3803 ves_icall_Type_GetPropertiesByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
3806 static MonoClass *System_Reflection_PropertyInfo;
3807 MonoClass *startklass, *klass;
3814 gchar *propname = NULL;
3815 int (*compare_func) (const char *s1, const char *s2) = NULL;
3817 GHashTable *properties;
3819 MONO_ARCH_SAVE_REGS;
3821 if (!System_Reflection_PropertyInfo)
3822 System_Reflection_PropertyInfo = mono_class_from_name (
3823 mono_defaults.corlib, "System.Reflection", "PropertyInfo");
3825 domain = ((MonoObject *)type)->vtable->domain;
3826 if (type->type->byref)
3827 return mono_array_new (domain, System_Reflection_PropertyInfo, 0);
3828 klass = startklass = mono_class_from_mono_type (type->type);
3830 propname = mono_string_to_utf8 (name);
3831 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
3834 mono_class_setup_vtable (klass);
3836 properties = g_hash_table_new (property_hash, (GEqualFunc)property_equal);
3839 res = mono_array_new (domain, System_Reflection_PropertyInfo, len);
3841 mono_class_setup_vtable (klass);
3842 if (klass->exception_type != MONO_EXCEPTION_NONE) {
3843 g_hash_table_destroy (properties);
3846 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3850 while ((prop = mono_class_get_properties (klass, &iter))) {
3856 flags = method->flags;
3859 if ((prop->get && ((prop->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC)) ||
3860 (prop->set && ((prop->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC))) {
3861 if (bflags & BFLAGS_Public)
3863 } else if (bflags & BFLAGS_NonPublic) {
3864 if (property_accessor_nonpublic(prop->get, startklass == klass) ||
3865 property_accessor_nonpublic(prop->set, startklass == klass)) {
3872 if (flags & METHOD_ATTRIBUTE_STATIC) {
3873 if (bflags & BFLAGS_Static)
3874 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3877 if (bflags & BFLAGS_Instance)
3886 if (compare_func (propname, prop->name))
3890 if (g_hash_table_lookup (properties, prop))
3894 MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, len * 2);
3895 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3899 mono_array_setref (res, i, mono_property_get_object (domain, startklass, prop));
3902 g_hash_table_insert (properties, prop, prop);
3904 if ((!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent)))
3907 g_hash_table_destroy (properties);
3910 MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, i);
3911 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3914 * Better solution for the new GC.
3915 * res->max_length = i;
3921 static MonoReflectionEvent *
3922 ves_icall_MonoType_GetEvent (MonoReflectionType *type, MonoString *name, guint32 bflags)
3925 MonoClass *klass, *startklass;
3931 MONO_ARCH_SAVE_REGS;
3933 event_name = mono_string_to_utf8 (name);
3934 if (type->type->byref)
3936 klass = startklass = mono_class_from_mono_type (type->type);
3937 domain = mono_object_domain (type);
3940 if (klass->exception_type != MONO_EXCEPTION_NONE)
3941 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3944 while ((event = mono_class_get_events (klass, &iter))) {
3945 if (strcmp (event->name, event_name))
3948 method = event->add;
3950 method = event->remove;
3952 method = event->raise;
3954 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3955 if (!(bflags & BFLAGS_Public))
3958 if (!(bflags & BFLAGS_NonPublic))
3960 if ((klass != startklass) && (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PRIVATE)
3965 if (!(bflags & BFLAGS_NonPublic))
3968 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3969 if (!(bflags & BFLAGS_Static))
3971 if (!(bflags & BFLAGS_FlattenHierarchy) && (klass != startklass))
3974 if (!(bflags & BFLAGS_Instance))
3978 g_free (event_name);
3979 return mono_event_get_object (domain, startklass, event);
3982 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3985 g_free (event_name);
3990 ves_icall_Type_GetEvents_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3993 static MonoClass *System_Reflection_EventInfo;
3994 MonoClass *startklass, *klass;
4001 MONO_ARCH_SAVE_REGS;
4003 if (!System_Reflection_EventInfo)
4004 System_Reflection_EventInfo = mono_class_from_name (
4005 mono_defaults.corlib, "System.Reflection", "EventInfo");
4007 domain = mono_object_domain (type);
4008 if (type->type->byref)
4009 return mono_array_new (domain, System_Reflection_EventInfo, 0);
4010 klass = startklass = mono_class_from_mono_type (type->type);
4014 res = mono_array_new (domain, System_Reflection_EventInfo, len);
4016 if (klass->exception_type != MONO_EXCEPTION_NONE)
4017 mono_raise_exception (mono_class_get_exception_for_failure (klass));
4020 while ((event = mono_class_get_events (klass, &iter))) {
4022 method = event->add;
4024 method = event->remove;
4026 method = event->raise;
4028 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
4029 if (bflags & BFLAGS_Public)
4031 } else if ((klass == startklass) || (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) {
4032 if (bflags & BFLAGS_NonPublic)
4037 if (bflags & BFLAGS_NonPublic)
4043 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
4044 if (bflags & BFLAGS_Static)
4045 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
4048 if (bflags & BFLAGS_Instance)
4053 if (bflags & BFLAGS_Instance)
4059 MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, len * 2);
4060 mono_array_memcpy_refs (new_res, 0, res, 0, len);
4064 mono_array_setref (res, i, mono_event_get_object (domain, startklass, event));
4067 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
4070 MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, i);
4071 mono_array_memcpy_refs (new_res, 0, res, 0, i);
4074 * Better solution for the new GC.
4075 * res->max_length = i;
4081 static MonoReflectionType *
4082 ves_icall_Type_GetNestedType (MonoReflectionType *type, MonoString *name, guint32 bflags)
4090 MONO_ARCH_SAVE_REGS;
4092 domain = ((MonoObject *)type)->vtable->domain;
4093 if (type->type->byref)
4095 klass = mono_class_from_mono_type (type->type);
4096 str = mono_string_to_utf8 (name);
4099 if (klass->exception_type != MONO_EXCEPTION_NONE)
4100 mono_raise_exception (mono_class_get_exception_for_failure (klass));
4103 * If a nested type is generic, return its generic type definition.
4104 * Note that this means that the return value is essentially a
4105 * nested type of the generic type definition of @klass.
4107 * A note in MSDN claims that a generic type definition can have
4108 * nested types that aren't generic. In any case, the container of that
4109 * nested type would be the generic type definition.
4111 if (klass->generic_class)
4112 klass = klass->generic_class->container_class;
4115 while ((nested = mono_class_get_nested_types (klass, &iter))) {
4117 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
4118 if (bflags & BFLAGS_Public)
4121 if (bflags & BFLAGS_NonPublic)
4126 if (strcmp (nested->name, str) == 0){
4128 return mono_type_get_object (domain, &nested->byval_arg);
4131 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
4138 ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags)
4148 MONO_ARCH_SAVE_REGS;
4150 domain = ((MonoObject *)type)->vtable->domain;
4151 if (type->type->byref)
4152 return mono_array_new (domain, mono_defaults.monotype_class, 0);
4153 klass = mono_class_from_mono_type (type->type);
4154 if (klass->exception_type != MONO_EXCEPTION_NONE)
4155 mono_raise_exception (mono_class_get_exception_for_failure (klass));
4158 * If a nested type is generic, return its generic type definition.
4159 * Note that this means that the return value is essentially the set
4160 * of nested types of the generic type definition of @klass.
4162 * A note in MSDN claims that a generic type definition can have
4163 * nested types that aren't generic. In any case, the container of that
4164 * nested type would be the generic type definition.
4166 if (klass->generic_class)
4167 klass = klass->generic_class->container_class;
4171 res = mono_array_new (domain, mono_defaults.monotype_class, len);
4173 while ((nested = mono_class_get_nested_types (klass, &iter))) {
4175 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
4176 if (bflags & BFLAGS_Public)
4179 if (bflags & BFLAGS_NonPublic)
4184 member = (MonoObject*)mono_type_get_object (domain, &nested->byval_arg);
4186 MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, len * 2);
4187 mono_array_memcpy_refs (new_res, 0, res, 0, len);
4191 mono_array_setref (res, i, member);
4195 MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, i);
4196 mono_array_memcpy_refs (new_res, 0, res, 0, i);
4199 * Better solution for the new GC.
4200 * res->max_length = i;
4206 static MonoReflectionType*
4207 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *assembly, MonoReflectionModule *module, MonoString *name, MonoBoolean throwOnError, MonoBoolean ignoreCase)
4210 MonoType *type = NULL;
4211 MonoTypeNameParse info;
4212 gboolean type_resolve;
4214 MONO_ARCH_SAVE_REGS;
4216 /* On MS.NET, this does not fire a TypeResolve event */
4217 type_resolve = TRUE;
4218 str = mono_string_to_utf8 (name);
4219 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
4220 if (!mono_reflection_parse_type (str, &info)) {
4222 mono_reflection_free_type_info (&info);
4223 if (throwOnError) /* uhm: this is a parse error, though... */
4224 mono_raise_exception (mono_get_exception_type_load (name, NULL));
4225 /*g_print ("failed parse\n");*/
4229 if (info.assembly.name) {
4231 mono_reflection_free_type_info (&info);
4233 /* 1.0 and 2.0 throw different exceptions */
4234 if (mono_defaults.generic_ilist_class)
4235 mono_raise_exception (mono_get_exception_argument (NULL, "Type names passed to Assembly.GetType() must not specify an assembly."));
4237 mono_raise_exception (mono_get_exception_type_load (name, NULL));
4242 if (module != NULL) {
4244 type = mono_reflection_get_type (module->image, &info, ignoreCase, &type_resolve);
4249 if (assembly->assembly->dynamic) {
4250 /* Enumerate all modules */
4251 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
4255 if (abuilder->modules) {
4256 for (i = 0; i < mono_array_length (abuilder->modules); ++i) {
4257 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
4258 type = mono_reflection_get_type (&mb->dynamic_image->image, &info, ignoreCase, &type_resolve);
4264 if (!type && abuilder->loaded_modules) {
4265 for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) {
4266 MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
4267 type = mono_reflection_get_type (mod->image, &info, ignoreCase, &type_resolve);
4274 type = mono_reflection_get_type (assembly->assembly->image, &info, ignoreCase, &type_resolve);
4276 mono_reflection_free_type_info (&info);
4278 MonoException *e = NULL;
4281 e = mono_get_exception_type_load (name, NULL);
4283 mono_loader_clear_error ();
4286 mono_raise_exception (e);
4291 if (type->type == MONO_TYPE_CLASS) {
4292 MonoClass *klass = mono_type_get_class (type);
4294 if (mono_is_security_manager_active () && !klass->exception_type)
4295 /* Some security problems are detected during generic vtable construction */
4296 mono_class_setup_vtable (klass);
4297 /* need to report exceptions ? */
4298 if (throwOnError && klass->exception_type) {
4299 /* report SecurityException (or others) that occured when loading the assembly */
4300 MonoException *exc = mono_class_get_exception_for_failure (klass);
4301 mono_loader_clear_error ();
4302 mono_raise_exception (exc);
4303 } else if (klass->exception_type == MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND) {
4308 /* g_print ("got it\n"); */
4309 return mono_type_get_object (mono_object_domain (assembly), type);
4313 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *assembly, MonoBoolean escaped)
4315 MonoDomain *domain = mono_object_domain (assembly);
4316 MonoAssembly *mass = assembly->assembly;
4317 MonoString *res = NULL;
4321 MONO_ARCH_SAVE_REGS;
4323 if (g_path_is_absolute (mass->image->name))
4324 absolute = g_strdup (mass->image->name);
4326 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4330 for (i = strlen (absolute) - 1; i >= 0; i--)
4331 if (absolute [i] == '\\')
4336 uri = g_filename_to_uri (absolute, NULL, NULL);
4338 uri = g_strconcat ("file://", absolute, NULL);
4342 res = mono_string_new (domain, uri);
4350 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssembly *assembly)
4352 MonoAssembly *mass = assembly->assembly;
4354 MONO_ARCH_SAVE_REGS;
4356 return mass->in_gac;
4359 static MonoReflectionAssembly*
4360 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoString *mname, MonoObject *evidence)
4364 MonoImageOpenStatus status;
4366 MONO_ARCH_SAVE_REGS;
4368 name = mono_string_to_utf8 (mname);
4369 res = mono_assembly_load_with_partial_name (name, &status);
4375 return mono_assembly_get_object (mono_domain_get (), res);
4379 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssembly *assembly)
4381 MonoDomain *domain = mono_object_domain (assembly);
4384 MONO_ARCH_SAVE_REGS;
4386 res = mono_string_new (domain, mono_image_get_filename (assembly->assembly->image));
4392 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssembly *assembly)
4394 MONO_ARCH_SAVE_REGS;
4396 return assembly->assembly->ref_only;
4400 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssembly *assembly)
4402 MonoDomain *domain = mono_object_domain (assembly);
4404 MONO_ARCH_SAVE_REGS;
4406 return mono_string_new (domain, assembly->assembly->image->version);
4409 static MonoReflectionMethod*
4410 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssembly *assembly)
4412 guint32 token = mono_image_get_entry_point (assembly->assembly->image);
4414 MONO_ARCH_SAVE_REGS;
4418 return mono_method_get_object (mono_object_domain (assembly), mono_get_method (assembly->assembly->image, token, NULL), NULL);
4421 static MonoReflectionModule*
4422 ves_icall_System_Reflection_Assembly_GetManifestModuleInternal (MonoReflectionAssembly *assembly)
4424 return mono_module_get_object (mono_object_domain (assembly), assembly->assembly->image);
4428 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssembly *assembly)
4430 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4431 MonoArray *result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, table->rows);
4435 MONO_ARCH_SAVE_REGS;
4437 for (i = 0; i < table->rows; ++i) {
4438 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_MANIFEST_NAME));
4439 mono_array_setref (result, i, mono_string_new (mono_object_domain (assembly), val));
4445 create_version (MonoDomain *domain, guint32 major, guint32 minor, guint32 build, guint32 revision)
4447 static MonoClass *System_Version = NULL;
4448 static MonoMethod *create_version = NULL;
4452 if (!System_Version) {
4453 System_Version = mono_class_from_name (mono_defaults.corlib, "System", "Version");
4454 g_assert (System_Version);
4457 if (!create_version) {
4458 MonoMethodDesc *desc = mono_method_desc_new (":.ctor(int,int,int,int)", FALSE);
4459 create_version = mono_method_desc_search_in_class (desc, System_Version);
4460 g_assert (create_version);
4461 mono_method_desc_free (desc);
4467 args [3] = &revision;
4468 result = mono_object_new (domain, System_Version);
4469 mono_runtime_invoke (create_version, result, args, NULL);
4475 ves_icall_System_Reflection_Assembly_GetReferencedAssemblies (MonoReflectionAssembly *assembly)
4477 static MonoClass *System_Reflection_AssemblyName;
4479 MonoDomain *domain = mono_object_domain (assembly);
4481 static MonoMethod *create_culture = NULL;
4482 MonoImage *image = assembly->assembly->image;
4485 MONO_ARCH_SAVE_REGS;
4487 if (!System_Reflection_AssemblyName)
4488 System_Reflection_AssemblyName = mono_class_from_name (
4489 mono_defaults.corlib, "System.Reflection", "AssemblyName");
4491 t = &assembly->assembly->image->tables [MONO_TABLE_ASSEMBLYREF];
4494 result = mono_array_new (domain, System_Reflection_AssemblyName, count);
4497 MonoMethodDesc *desc = mono_method_desc_new (
4498 "System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE);
4499 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4500 g_assert (create_culture);
4501 mono_method_desc_free (desc);
4504 for (i = 0; i < count; i++) {
4505 MonoReflectionAssemblyName *aname;
4506 guint32 cols [MONO_ASSEMBLYREF_SIZE];
4508 mono_metadata_decode_row (t, i, cols, MONO_ASSEMBLYREF_SIZE);
4510 aname = (MonoReflectionAssemblyName *) mono_object_new (
4511 domain, System_Reflection_AssemblyName);
4513 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_NAME])));
4515 aname->major = cols [MONO_ASSEMBLYREF_MAJOR_VERSION];
4516 aname->minor = cols [MONO_ASSEMBLYREF_MINOR_VERSION];
4517 aname->build = cols [MONO_ASSEMBLYREF_BUILD_NUMBER];
4518 aname->revision = cols [MONO_ASSEMBLYREF_REV_NUMBER];
4519 aname->flags = cols [MONO_ASSEMBLYREF_FLAGS];
4520 aname->versioncompat = 1; /* SameMachine (default) */
4521 aname->hashalg = ASSEMBLY_HASH_SHA1; /* SHA1 (default) */
4522 MONO_OBJECT_SETREF (aname, version, create_version (domain, aname->major, aname->minor, aname->build, aname->revision));
4524 if (create_culture) {
4526 gboolean assembly_ref = TRUE;
4527 args [0] = mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_CULTURE]));
4528 args [1] = &assembly_ref;
4529 MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
4532 if (cols [MONO_ASSEMBLYREF_PUBLIC_KEY]) {
4533 const gchar *pkey_ptr = mono_metadata_blob_heap (image, cols [MONO_ASSEMBLYREF_PUBLIC_KEY]);
4534 guint32 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
4536 if ((cols [MONO_ASSEMBLYREF_FLAGS] & ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG)) {
4537 /* public key token isn't copied - the class library will
4538 automatically generate it from the public key if required */
4539 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4540 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
4542 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4543 memcpy (mono_array_addr (aname->keyToken, guint8, 0), pkey_ptr, pkey_len);
4546 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, 0));
4549 /* note: this function doesn't return the codebase on purpose (i.e. it can
4550 be used under partial trust as path information isn't present). */
4552 mono_array_setref (result, i, aname);
4563 foreach_namespace (const char* key, gconstpointer val, NameSpaceInfo *info)
4565 MonoString *name = mono_string_new (mono_object_domain (info->res), key);
4567 mono_array_setref (info->res, info->idx, name);
4572 ves_icall_System_Reflection_Assembly_GetNamespaces (MonoReflectionAssembly *assembly)
4574 MonoImage *img = assembly->assembly->image;
4578 MONO_ARCH_SAVE_REGS;
4580 if (!img->name_cache)
4581 mono_image_init_name_cache (img);
4583 res = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, g_hash_table_size (img->name_cache));
4586 g_hash_table_foreach (img->name_cache, (GHFunc)foreach_namespace, &info);
4591 /* move this in some file in mono/util/ */
4593 g_concat_dir_and_file (const char *dir, const char *file)
4595 g_return_val_if_fail (dir != NULL, NULL);
4596 g_return_val_if_fail (file != NULL, NULL);
4599 * If the directory name doesn't have a / on the end, we need
4600 * to add one so we get a proper path to the file
4602 if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
4603 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
4605 return g_strconcat (dir, file, NULL);
4609 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssembly *assembly, MonoString *name, gint32 *size, MonoReflectionModule **ref_module)
4611 char *n = mono_string_to_utf8 (name);
4612 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4614 guint32 cols [MONO_MANIFEST_SIZE];
4615 guint32 impl, file_idx;
4619 MONO_ARCH_SAVE_REGS;
4621 for (i = 0; i < table->rows; ++i) {
4622 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4623 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4624 if (strcmp (val, n) == 0)
4628 if (i == table->rows)
4631 impl = cols [MONO_MANIFEST_IMPLEMENTATION];
4634 * this code should only be called after obtaining the
4635 * ResourceInfo and handling the other cases.
4637 g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
4638 file_idx = impl >> MONO_IMPLEMENTATION_BITS;
4640 module = mono_image_load_file_for_image (assembly->assembly->image, file_idx);
4645 module = assembly->assembly->image;
4647 *ref_module = mono_module_get_object (mono_domain_get (), module);
4649 return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
4653 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoManifestResourceInfo *info)
4655 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4657 guint32 cols [MONO_MANIFEST_SIZE];
4658 guint32 file_cols [MONO_FILE_SIZE];
4662 MONO_ARCH_SAVE_REGS;
4664 n = mono_string_to_utf8 (name);
4665 for (i = 0; i < table->rows; ++i) {
4666 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4667 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4668 if (strcmp (val, n) == 0)
4672 if (i == table->rows)
4675 if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
4676 info->location = RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST;
4679 switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
4680 case MONO_IMPLEMENTATION_FILE:
4681 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4682 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4683 mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
4684 val = mono_metadata_string_heap (assembly->assembly->image, file_cols [MONO_FILE_NAME]);
4685 MONO_OBJECT_SETREF (info, filename, mono_string_new (mono_object_domain (assembly), val));
4686 if (file_cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA)
4689 info->location = RESOURCE_LOCATION_EMBEDDED;
4692 case MONO_IMPLEMENTATION_ASSEMBLYREF:
4693 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4694 mono_assembly_load_reference (assembly->assembly->image, i - 1);
4695 if (assembly->assembly->image->references [i - 1] == (gpointer)-1) {
4696 char *msg = g_strdup_printf ("Assembly %d referenced from assembly %s not found ", i - 1, assembly->assembly->image->name);
4697 MonoException *ex = mono_get_exception_file_not_found2 (msg, NULL);
4699 mono_raise_exception (ex);
4701 MONO_OBJECT_SETREF (info, assembly, mono_assembly_get_object (mono_domain_get (), assembly->assembly->image->references [i - 1]));
4703 /* Obtain info recursively */
4704 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (info->assembly, name, info);
4705 info->location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
4708 case MONO_IMPLEMENTATION_EXP_TYPE:
4709 g_assert_not_reached ();
4718 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoBoolean resource_modules)
4720 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4721 MonoArray *result = NULL;
4726 MONO_ARCH_SAVE_REGS;
4728 /* check hash if needed */
4730 n = mono_string_to_utf8 (name);
4731 for (i = 0; i < table->rows; ++i) {
4732 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4733 if (strcmp (val, n) == 0) {
4736 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4737 fn = mono_string_new (mono_object_domain (assembly), n);
4739 return (MonoObject*)fn;
4747 for (i = 0; i < table->rows; ++i) {
4748 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA))
4752 result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, count);
4755 for (i = 0; i < table->rows; ++i) {
4756 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4757 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4758 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4759 mono_array_setref (result, count, mono_string_new (mono_object_domain (assembly), n));
4764 return (MonoObject*)result;
4768 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly *assembly)
4770 MonoDomain *domain = mono_domain_get();
4773 int i, j, file_count = 0;
4774 MonoImage **modules;
4775 guint32 module_count, real_module_count;
4776 MonoTableInfo *table;
4777 guint32 cols [MONO_FILE_SIZE];
4778 MonoImage *image = assembly->assembly->image;
4780 g_assert (image != NULL);
4781 g_assert (!assembly->assembly->dynamic);
4783 table = &image->tables [MONO_TABLE_FILE];
4784 file_count = table->rows;
4786 modules = image->modules;
4787 module_count = image->module_count;
4789 real_module_count = 0;
4790 for (i = 0; i < module_count; ++i)
4792 real_module_count ++;
4794 klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "Module");
4795 res = mono_array_new (domain, klass, 1 + real_module_count + file_count);
4797 mono_array_setref (res, 0, mono_module_get_object (domain, image));
4799 for (i = 0; i < module_count; ++i)
4801 mono_array_setref (res, j, mono_module_get_object (domain, modules[i]));
4805 for (i = 0; i < file_count; ++i, ++j) {
4806 mono_metadata_decode_row (table, i, cols, MONO_FILE_SIZE);
4807 if (cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA)
4808 mono_array_setref (res, j, mono_module_file_get_object (domain, image, i));
4810 MonoImage *m = mono_image_load_file_for_image (image, i + 1);
4812 MonoString *fname = mono_string_new (mono_domain_get (), mono_metadata_string_heap (image, cols [MONO_FILE_NAME]));
4813 mono_raise_exception (mono_get_exception_file_not_found2 (NULL, fname));
4815 mono_array_setref (res, j, mono_module_get_object (domain, m));
4822 static MonoReflectionMethod*
4823 ves_icall_GetCurrentMethod (void)
4825 MonoMethod *m = mono_method_get_last_managed ();
4827 MONO_ARCH_SAVE_REGS;
4829 return mono_method_get_object (mono_domain_get (), m, NULL);
4834 mono_method_get_equivalent_method (MonoMethod *method, MonoClass *klass)
4837 if (method->is_inflated && ((MonoMethodInflated*)method)->context.method_inst) {
4838 MonoMethodInflated *inflated = (MonoMethodInflated*)method;
4839 //method is inflated, we should inflate it on the other class
4840 MonoGenericContext ctx;
4841 ctx.method_inst = inflated->context.method_inst;
4842 ctx.class_inst = inflated->context.class_inst;
4843 if (klass->generic_class)
4844 ctx.class_inst = klass->generic_class->context.class_inst;
4845 else if (klass->generic_container)
4846 ctx.class_inst = klass->generic_container->context.class_inst;
4847 return mono_class_inflate_generic_method_full (inflated->declaring, klass, &ctx);
4850 for (i = 0; i < method->klass->method.count; ++i) {
4851 if (method->klass->methods [i] == method) {
4856 mono_class_setup_methods (klass);
4857 g_assert (offset >= 0 && offset < klass->method.count);
4858 return klass->methods [offset];
4861 static MonoReflectionMethod*
4862 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType (MonoMethod *method, MonoType *type)
4866 klass = mono_class_from_mono_type (type);
4867 if (mono_class_get_generic_type_definition (method->klass) != mono_class_get_generic_type_definition (klass))
4869 if (method->klass != klass)
4870 method = mono_method_get_equivalent_method (method, klass);
4872 klass = method->klass;
4873 return mono_method_get_object (mono_domain_get (), method, klass);
4876 static MonoReflectionMethod*
4877 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternal (MonoMethod *method)
4879 return mono_method_get_object (mono_domain_get (), method, NULL);
4882 static MonoReflectionMethodBody*
4883 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod *method)
4885 return mono_method_body_get_object (mono_domain_get (), method);
4888 static MonoReflectionAssembly*
4889 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (void)
4891 MonoMethod *m = mono_method_get_last_managed ();
4893 MONO_ARCH_SAVE_REGS;
4895 return mono_assembly_get_object (mono_domain_get (), m->klass->image->assembly);
4899 static MonoReflectionAssembly*
4900 ves_icall_System_Reflection_Assembly_GetEntryAssembly (void)
4902 MonoDomain* domain = mono_domain_get ();
4904 MONO_ARCH_SAVE_REGS;
4906 if (!domain->entry_assembly)
4909 return mono_assembly_get_object (domain, domain->entry_assembly);
4912 static MonoReflectionAssembly*
4913 ves_icall_System_Reflection_Assembly_GetCallingAssembly (void)
4915 MonoMethod *m = mono_method_get_last_managed ();
4916 MonoMethod *dest = m;
4918 MONO_ARCH_SAVE_REGS;
4920 mono_stack_walk_no_il (get_caller, &dest);
4923 return mono_assembly_get_object (mono_domain_get (), dest->klass->image->assembly);
4927 ves_icall_System_MonoType_getFullName (MonoReflectionType *object, gboolean full_name,
4928 gboolean assembly_qualified)
4930 MonoDomain *domain = mono_object_domain (object);
4931 MonoTypeNameFormat format;
4935 MONO_ARCH_SAVE_REGS;
4937 format = assembly_qualified ?
4938 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
4939 MONO_TYPE_NAME_FORMAT_FULL_NAME;
4941 format = MONO_TYPE_NAME_FORMAT_REFLECTION;
4943 name = mono_type_get_name_full (object->type, format);
4947 if (full_name && (object->type->type == MONO_TYPE_VAR || object->type->type == MONO_TYPE_MVAR)) {
4952 res = mono_string_new (domain, name);
4959 fill_reflection_assembly_name (MonoDomain *domain, MonoReflectionAssemblyName *aname, MonoAssemblyName *name, const char *absolute, gboolean by_default_version, gboolean default_publickey, gboolean default_token)
4961 static MonoMethod *create_culture = NULL;
4964 const char *pkey_ptr;
4966 gboolean assembly_ref = FALSE;
4968 MONO_ARCH_SAVE_REGS;
4970 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, name->name));
4971 aname->major = name->major;
4972 aname->minor = name->minor;
4973 aname->build = name->build;
4974 aname->flags = name->flags;
4975 aname->revision = name->revision;
4976 aname->hashalg = name->hash_alg;
4977 aname->versioncompat = 1; /* SameMachine (default) */
4979 if (by_default_version)
4980 MONO_OBJECT_SETREF (aname, version, create_version (domain, name->major, name->minor, name->build, name->revision));
4982 codebase = g_filename_to_uri (absolute, NULL, NULL);
4984 MONO_OBJECT_SETREF (aname, codebase, mono_string_new (domain, codebase));
4988 if (!create_culture) {
4989 MonoMethodDesc *desc = mono_method_desc_new ("System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE);
4990 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4991 g_assert (create_culture);
4992 mono_method_desc_free (desc);
4995 if (name->culture) {
4996 args [0] = mono_string_new (domain, name->culture);
4997 args [1] = &assembly_ref;
4998 MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
5001 if (name->public_key) {
5002 pkey_ptr = (char*)name->public_key;
5003 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
5005 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
5006 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
5007 aname->flags |= ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG;
5008 } else if (default_publickey) {
5009 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, 0));
5010 aname->flags |= ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG;
5013 /* MonoAssemblyName keeps the public key token as an hexadecimal string */
5014 if (name->public_key_token [0]) {
5018 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, 8));
5019 p = mono_array_addr (aname->keyToken, char, 0);
5021 for (i = 0, j = 0; i < 8; i++) {
5022 *p = g_ascii_xdigit_value (name->public_key_token [j++]) << 4;
5023 *p |= g_ascii_xdigit_value (name->public_key_token [j++]);
5026 } else if (default_token) {
5027 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, 0));
5032 ves_icall_System_Reflection_Assembly_get_fullName (MonoReflectionAssembly *assembly)
5034 MonoDomain *domain = mono_object_domain (assembly);
5035 MonoAssembly *mass = assembly->assembly;
5039 name = g_strdup_printf (
5040 "%s, Version=%d.%d.%d.%d, Culture=%s, PublicKeyToken=%s%s",
5042 mass->aname.major, mass->aname.minor, mass->aname.build, mass->aname.revision,
5043 mass->aname.culture && *mass->aname.culture? mass->aname.culture: "neutral",
5044 mass->aname.public_key_token [0] ? (char *)mass->aname.public_key_token : "null",
5045 (mass->aname.flags & ASSEMBLYREF_RETARGETABLE_FLAG) ? ", Retargetable=Yes" : "");
5047 res = mono_string_new (domain, name);
5054 ves_icall_System_Reflection_Assembly_FillName (MonoReflectionAssembly *assembly, MonoReflectionAssemblyName *aname)
5057 MonoAssembly *mass = assembly->assembly;
5059 MONO_ARCH_SAVE_REGS;
5061 if (g_path_is_absolute (mass->image->name)) {
5062 fill_reflection_assembly_name (mono_object_domain (assembly),
5063 aname, &mass->aname, mass->image->name, TRUE,
5064 TRUE, mono_get_runtime_info ()->framework_version [0] >= '2');
5067 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
5069 fill_reflection_assembly_name (mono_object_domain (assembly),
5070 aname, &mass->aname, absolute, TRUE, TRUE,
5071 mono_get_runtime_info ()->framework_version [0] >= '2');
5077 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoString *fname, MonoReflectionAssemblyName *aname)
5080 MonoImageOpenStatus status = MONO_IMAGE_OK;
5083 MonoAssemblyName name;
5085 MONO_ARCH_SAVE_REGS;
5087 filename = mono_string_to_utf8 (fname);
5089 image = mono_image_open (filename, &status);
5095 if (status == MONO_IMAGE_IMAGE_INVALID)
5096 exc = mono_get_exception_bad_image_format2 (NULL, fname);
5098 exc = mono_get_exception_file_not_found2 (NULL, fname);
5099 mono_raise_exception (exc);
5102 res = mono_assembly_fill_assembly_name (image, &name);
5104 mono_image_close (image);
5106 mono_raise_exception (mono_get_exception_argument ("assemblyFile", "The file does not contain a manifest"));
5109 fill_reflection_assembly_name (mono_domain_get (), aname, &name, filename,
5110 TRUE, mono_get_runtime_info ()->framework_version [0] == '1',
5111 mono_get_runtime_info ()->framework_version [0] >= '2');
5114 mono_image_close (image);
5118 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssembly *assembly,
5119 char **minimum, guint32 *minLength, char **optional, guint32 *optLength, char **refused, guint32 *refLength)
5121 MonoBoolean result = FALSE;
5122 MonoDeclSecurityEntry entry;
5124 /* SecurityAction.RequestMinimum */
5125 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQMIN, &entry)) {
5126 *minimum = entry.blob;
5127 *minLength = entry.size;
5130 /* SecurityAction.RequestOptional */
5131 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQOPT, &entry)) {
5132 *optional = entry.blob;
5133 *optLength = entry.size;
5136 /* SecurityAction.RequestRefuse */
5137 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQREFUSE, &entry)) {
5138 *refused = entry.blob;
5139 *refLength = entry.size;
5147 mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoArray **exceptions, MonoBoolean exportedOnly)
5151 MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
5153 guint32 attrs, visibility;
5155 /* we start the count from 1 because we skip the special type <Module> */
5158 for (i = 1; i < tdef->rows; ++i) {
5159 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
5160 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
5161 if (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)
5165 count = tdef->rows - 1;
5167 res = mono_array_new (domain, mono_defaults.monotype_class, count);
5168 *exceptions = mono_array_new (domain, mono_defaults.exception_class, count);
5170 for (i = 1; i < tdef->rows; ++i) {
5171 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
5172 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
5173 if (!exportedOnly || (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)) {
5174 klass = mono_class_get (image, (i + 1) | MONO_TOKEN_TYPE_DEF);
5176 mono_array_setref (res, count, mono_type_get_object (domain, &klass->byval_arg));
5178 MonoLoaderError *error;
5181 error = mono_loader_get_last_error ();
5182 g_assert (error != NULL);
5184 ex = mono_loader_error_prepare_exception (error);
5185 mono_array_setref (*exceptions, count, ex);
5187 if (mono_loader_get_last_error ())
5188 mono_loader_clear_error ();
5197 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly, MonoBoolean exportedOnly)
5199 MonoArray *res = NULL;
5200 MonoArray *exceptions = NULL;
5201 MonoImage *image = NULL;
5202 MonoTableInfo *table = NULL;
5205 int i, len, ex_count;
5207 MONO_ARCH_SAVE_REGS;
5209 domain = mono_object_domain (assembly);
5211 g_assert (!assembly->assembly->dynamic);
5212 image = assembly->assembly->image;
5213 table = &image->tables [MONO_TABLE_FILE];
5214 res = mono_module_get_types (domain, image, &exceptions, exportedOnly);
5216 /* Append data from all modules in the assembly */
5217 for (i = 0; i < table->rows; ++i) {
5218 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
5219 MonoImage *loaded_image = mono_assembly_load_module (image->assembly, i + 1);
5222 MonoArray *res2 = mono_module_get_types (domain, loaded_image, &ex2, exportedOnly);
5223 /* Append the new types to the end of the array */
5224 if (mono_array_length (res2) > 0) {
5226 MonoArray *res3, *ex3;
5228 len1 = mono_array_length (res);
5229 len2 = mono_array_length (res2);
5231 res3 = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
5232 mono_array_memcpy_refs (res3, 0, res, 0, len1);
5233 mono_array_memcpy_refs (res3, len1, res2, 0, len2);
5236 ex3 = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
5237 mono_array_memcpy_refs (ex3, 0, exceptions, 0, len1);
5238 mono_array_memcpy_refs (ex3, len1, ex2, 0, len2);
5245 /* the ReflectionTypeLoadException must have all the types (Types property),
5246 * NULL replacing types which throws an exception. The LoaderException must
5247 * contain all exceptions for NULL items.
5250 len = mono_array_length (res);
5253 for (i = 0; i < len; i++) {
5254 MonoReflectionType *t = mono_array_get (res, gpointer, i);
5258 klass = mono_type_get_class (t->type);
5259 if ((klass != NULL) && klass->exception_type) {
5260 /* keep the class in the list */
5261 list = g_list_append (list, klass);
5262 /* and replace Type with NULL */
5263 mono_array_setref (res, i, NULL);
5270 if (list || ex_count) {
5272 MonoException *exc = NULL;
5273 MonoArray *exl = NULL;
5274 int j, length = g_list_length (list) + ex_count;
5276 mono_loader_clear_error ();
5278 exl = mono_array_new (domain, mono_defaults.exception_class, length);
5279 /* Types for which mono_class_get () succeeded */
5280 for (i = 0, tmp = list; tmp; i++, tmp = tmp->next) {
5281 MonoException *exc = mono_class_get_exception_for_failure (tmp->data);
5282 mono_array_setref (exl, i, exc);
5284 /* Types for which it don't */
5285 for (j = 0; j < mono_array_length (exceptions); ++j) {
5286 MonoException *exc = mono_array_get (exceptions, MonoException*, j);
5288 g_assert (i < length);
5289 mono_array_setref (exl, i, exc);
5296 exc = mono_get_exception_reflection_type_load (res, exl);
5297 mono_loader_clear_error ();
5298 mono_raise_exception (exc);
5305 ves_icall_System_Reflection_AssemblyName_ParseName (MonoReflectionAssemblyName *name, MonoString *assname)
5307 MonoAssemblyName aname;
5308 MonoDomain *domain = mono_object_domain (name);
5310 gboolean is_version_defined;
5311 gboolean is_token_defined;
5313 aname.public_key = NULL;
5314 val = mono_string_to_utf8 (assname);
5315 if (!mono_assembly_name_parse_full (val, &aname, TRUE, &is_version_defined, &is_token_defined)) {
5316 g_free ((guint8*) aname.public_key);
5321 fill_reflection_assembly_name (domain, name, &aname, "", is_version_defined,
5322 FALSE, is_token_defined);
5324 mono_assembly_name_free (&aname);
5325 g_free ((guint8*) aname.public_key);
5331 static MonoReflectionType*
5332 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModule *module)
5334 MonoDomain *domain = mono_object_domain (module);
5337 MONO_ARCH_SAVE_REGS;
5339 g_assert (module->image);
5341 if (module->image->dynamic && ((MonoDynamicImage*)(module->image))->initial_image)
5342 /* These images do not have a global type */
5345 klass = mono_class_get (module->image, 1 | MONO_TOKEN_TYPE_DEF);
5346 return mono_type_get_object (domain, &klass->byval_arg);
5350 ves_icall_System_Reflection_Module_Close (MonoReflectionModule *module)
5352 /*if (module->image)
5353 mono_image_close (module->image);*/
5357 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModule *module)
5359 MonoDomain *domain = mono_object_domain (module);
5361 MONO_ARCH_SAVE_REGS;
5363 g_assert (module->image);
5364 return mono_string_new (domain, module->image->guid);
5368 ves_icall_System_Reflection_Module_GetHINSTANCE (MonoReflectionModule *module)
5370 #ifdef PLATFORM_WIN32
5371 if (module->image && module->image->is_module_handle)
5372 return module->image->raw_data;
5375 return (gpointer) (-1);
5379 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine)
5381 if (image->dynamic) {
5382 MonoDynamicImage *dyn = (MonoDynamicImage*)image;
5383 *pe_kind = dyn->pe_kind;
5384 *machine = dyn->machine;
5387 *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
5388 *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
5393 ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage *image)
5395 return (image->md_version_major << 16) | (image->md_version_minor);
5399 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModule *module)
5401 MonoArray *exceptions;
5404 MONO_ARCH_SAVE_REGS;
5407 return mono_array_new (mono_object_domain (module), mono_defaults.monotype_class, 0);
5409 MonoArray *res = mono_module_get_types (mono_object_domain (module), module->image, &exceptions, FALSE);
5410 for (i = 0; i < mono_array_length (exceptions); ++i) {
5411 MonoException *ex = mono_array_get (exceptions, MonoException *, i);
5413 mono_raise_exception (ex);
5420 mono_metadata_memberref_is_method (MonoImage *image, guint32 token)
5422 guint32 cols [MONO_MEMBERREF_SIZE];
5424 mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
5425 sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
5426 mono_metadata_decode_blob_size (sig, &sig);
5427 return (*sig != 0x6);
5431 init_generic_context_from_args (MonoGenericContext *context, MonoArray *type_args, MonoArray *method_args)
5434 context->class_inst = mono_metadata_get_generic_inst (mono_array_length (type_args),
5435 mono_array_addr (type_args, MonoType*, 0));
5437 context->class_inst = NULL;
5439 context->method_inst = mono_metadata_get_generic_inst (mono_array_length (method_args),
5440 mono_array_addr (method_args, MonoType*, 0));
5442 context->method_inst = NULL;
5446 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5449 int table = mono_metadata_token_table (token);
5450 int index = mono_metadata_token_index (token);
5451 MonoGenericContext context;
5453 *error = ResolveTokenError_Other;
5455 /* Validate token */
5456 if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) &&
5457 (table != MONO_TABLE_TYPESPEC)) {
5458 *error = ResolveTokenError_BadTable;
5462 if (image->dynamic) {
5463 if (type_args || method_args)
5464 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5465 klass = mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5468 return &klass->byval_arg;
5471 if ((index <= 0) || (index > image->tables [table].rows)) {
5472 *error = ResolveTokenError_OutOfRange;
5476 init_generic_context_from_args (&context, type_args, method_args);
5477 klass = mono_class_get_full (image, token, &context);
5479 if (mono_loader_get_last_error ())
5480 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
5483 return &klass->byval_arg;
5489 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5491 int table = mono_metadata_token_table (token);
5492 int index = mono_metadata_token_index (token);
5493 MonoGenericContext context;
5496 *error = ResolveTokenError_Other;
5498 /* Validate token */
5499 if ((table != MONO_TABLE_METHOD) && (table != MONO_TABLE_METHODSPEC) &&
5500 (table != MONO_TABLE_MEMBERREF)) {
5501 *error = ResolveTokenError_BadTable;
5505 if (image->dynamic) {
5506 if (type_args || method_args)
5507 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5508 /* FIXME: validate memberref token type */
5509 return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5512 if ((index <= 0) || (index > image->tables [table].rows)) {
5513 *error = ResolveTokenError_OutOfRange;
5516 if ((table == MONO_TABLE_MEMBERREF) && (!mono_metadata_memberref_is_method (image, token))) {
5517 *error = ResolveTokenError_BadTable;
5521 init_generic_context_from_args (&context, type_args, method_args);
5522 method = mono_get_method_full (image, token, NULL, &context);
5524 if (mono_loader_get_last_error ())
5525 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
5531 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
5533 int index = mono_metadata_token_index (token);
5535 *error = ResolveTokenError_Other;
5537 /* Validate token */
5538 if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
5539 *error = ResolveTokenError_BadTable;
5544 return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5546 if ((index <= 0) || (index >= image->heap_us.size)) {
5547 *error = ResolveTokenError_OutOfRange;
5551 /* FIXME: What to do if the index points into the middle of a string ? */
5553 return mono_ldstr (mono_domain_get (), image, index);
5556 static MonoClassField*
5557 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5560 int table = mono_metadata_token_table (token);
5561 int index = mono_metadata_token_index (token);
5562 MonoGenericContext context;
5563 MonoClassField *field;
5565 *error = ResolveTokenError_Other;
5567 /* Validate token */
5568 if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
5569 *error = ResolveTokenError_BadTable;
5573 if (image->dynamic) {
5574 if (type_args || method_args)
5575 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5576 /* FIXME: validate memberref token type */
5577 return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5580 if ((index <= 0) || (index > image->tables [table].rows)) {
5581 *error = ResolveTokenError_OutOfRange;
5584 if ((table == MONO_TABLE_MEMBERREF) && (mono_metadata_memberref_is_method (image, token))) {
5585 *error = ResolveTokenError_BadTable;
5589 init_generic_context_from_args (&context, type_args, method_args);
5590 field = mono_field_from_token (image, token, &klass, &context);
5592 if (mono_loader_get_last_error ())
5593 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
5600 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5602 int table = mono_metadata_token_table (token);
5604 *error = ResolveTokenError_Other;
5607 case MONO_TABLE_TYPEDEF:
5608 case MONO_TABLE_TYPEREF:
5609 case MONO_TABLE_TYPESPEC: {
5610 MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, type_args, method_args, error);
5612 return (MonoObject*)mono_type_get_object (mono_domain_get (), t);
5616 case MONO_TABLE_METHOD:
5617 case MONO_TABLE_METHODSPEC: {
5618 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5620 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
5624 case MONO_TABLE_FIELD: {
5625 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5627 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
5631 case MONO_TABLE_MEMBERREF:
5632 if (mono_metadata_memberref_is_method (image, token)) {
5633 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5635 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
5640 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5642 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
5649 *error = ResolveTokenError_BadTable;
5656 ves_icall_System_Reflection_Module_ResolveSignature (MonoImage *image, guint32 token, MonoResolveTokenError *error)
5658 int table = mono_metadata_token_table (token);
5659 int idx = mono_metadata_token_index (token);
5660 MonoTableInfo *tables = image->tables;
5665 *error = ResolveTokenError_OutOfRange;
5667 /* FIXME: Support other tables ? */
5668 if (table != MONO_TABLE_STANDALONESIG)
5674 if ((idx == 0) || (idx > tables [MONO_TABLE_STANDALONESIG].rows))
5677 sig = mono_metadata_decode_row_col (&tables [MONO_TABLE_STANDALONESIG], idx - 1, 0);
5679 ptr = mono_metadata_blob_heap (image, sig);
5680 len = mono_metadata_decode_blob_size (ptr, &ptr);
5682 res = mono_array_new (mono_domain_get (), mono_defaults.byte_class, len);
5683 memcpy (mono_array_addr (res, guint8, 0), ptr, len);
5687 static MonoReflectionType*
5688 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
5691 int isbyref = 0, rank;
5692 char *str = mono_string_to_utf8 (smodifiers);
5695 MONO_ARCH_SAVE_REGS;
5697 klass = mono_class_from_mono_type (tb->type.type);
5699 /* logic taken from mono_reflection_parse_type(): keep in sync */
5703 if (isbyref) { /* only one level allowed by the spec */
5710 return mono_type_get_object (mono_object_domain (tb), &klass->this_arg);
5713 klass = mono_ptr_class_get (&klass->byval_arg);
5714 mono_class_init (klass);
5725 else if (*p != '*') { /* '*' means unknown lower bound */
5736 klass = mono_array_class_get (klass, rank);
5737 mono_class_init (klass);
5744 return mono_type_get_object (mono_object_domain (tb), &klass->byval_arg);
5748 ves_icall_Type_IsArrayImpl (MonoReflectionType *t)
5753 MONO_ARCH_SAVE_REGS;
5756 res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
5761 static MonoReflectionType *
5762 ves_icall_Type_make_array_type (MonoReflectionType *type, int rank)
5764 MonoClass *klass, *aklass;
5766 MONO_ARCH_SAVE_REGS;
5768 klass = mono_class_from_mono_type (type->type);
5769 aklass = mono_array_class_get (klass, rank);
5771 return mono_type_get_object (mono_object_domain (type), &aklass->byval_arg);
5774 static MonoReflectionType *
5775 ves_icall_Type_make_byref_type (MonoReflectionType *type)
5779 MONO_ARCH_SAVE_REGS;
5781 klass = mono_class_from_mono_type (type->type);
5783 return mono_type_get_object (mono_object_domain (type), &klass->this_arg);
5786 static MonoReflectionType *
5787 ves_icall_Type_MakePointerType (MonoReflectionType *type)
5791 MONO_ARCH_SAVE_REGS;
5793 pklass = mono_ptr_class_get (type->type);
5795 return mono_type_get_object (mono_object_domain (type), &pklass->byval_arg);
5799 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
5800 MonoReflectionMethod *info)
5802 MonoClass *delegate_class = mono_class_from_mono_type (type->type);
5803 MonoObject *delegate;
5805 MonoMethod *method = info->method;
5807 MONO_ARCH_SAVE_REGS;
5809 mono_assert (delegate_class->parent == mono_defaults.multicastdelegate_class);
5811 /* FIME: We must check if target is visible to the caller under coreclr.
5812 * The check should be disabled otherwise as it shouldn't raise expection under fulltrust.
5815 delegate = mono_object_new (mono_object_domain (type), delegate_class);
5817 g_assert (!method->klass->generic_container);
5818 /* FIXME: only do this for methods which can be shared! */
5819 if ((method->is_inflated && mono_method_get_context (method)->method_inst &&
5820 mono_class_generic_sharing_enabled (method->klass)) ||
5821 ((method->flags & METHOD_ATTRIBUTE_STATIC) && method->klass->generic_class)) {
5822 method = mono_marshal_get_static_rgctx_invoke (method);
5823 func = mono_compile_method (method);
5824 } else if (method->dynamic) {
5825 /* Creating a trampoline would leak memory */
5826 func = mono_compile_method (method);
5828 func = mono_create_ftnptr (mono_domain_get (),
5829 mono_runtime_create_jump_trampoline (mono_domain_get (), method, TRUE));
5832 mono_delegate_ctor_with_method (delegate, target, func, method);
5838 ves_icall_System_Delegate_SetMulticastInvoke (MonoDelegate *this)
5840 /* Reset the invoke impl to the default one */
5841 this->invoke_impl = mono_runtime_create_delegate_trampoline (this->object.vtable->klass);
5845 * Magic number to convert a time which is relative to
5846 * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
5848 #define EPOCH_ADJUST ((guint64)62135596800LL)
5851 * Magic number to convert FILETIME base Jan 1, 1601 to DateTime - base Jan, 1, 0001
5853 #define FILETIME_ADJUST ((guint64)504911232000000000LL)
5855 #ifdef PLATFORM_WIN32
5856 /* convert a SYSTEMTIME which is of the form "last thursday in october" to a real date */
5858 convert_to_absolute_date(SYSTEMTIME *date)
5860 #define IS_LEAP(y) ((y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0))
5861 static int days_in_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5862 static int leap_days_in_month[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5863 /* from the calendar FAQ */
5864 int a = (14 - date->wMonth) / 12;
5865 int y = date->wYear - a;
5866 int m = date->wMonth + 12 * a - 2;
5867 int d = (1 + y + y/4 - y/100 + y/400 + (31*m)/12) % 7;
5869 /* d is now the day of the week for the first of the month (0 == Sunday) */
5871 int day_of_week = date->wDayOfWeek;
5873 /* set day_in_month to the first day in the month which falls on day_of_week */
5874 int day_in_month = 1 + (day_of_week - d);
5875 if (day_in_month <= 0)
5878 /* wDay is 1 for first weekday in month, 2 for 2nd ... 5 means last - so work that out allowing for days in the month */
5879 date->wDay = day_in_month + (date->wDay - 1) * 7;
5880 if (date->wDay > (IS_LEAP(date->wYear) ? leap_days_in_month[date->wMonth - 1] : days_in_month[date->wMonth - 1]))
5885 #ifndef PLATFORM_WIN32
5887 * Return's the offset from GMT of a local time.
5889 * tm is a local time
5890 * t is the same local time as seconds.
5893 gmt_offset(struct tm *tm, time_t t)
5895 #if defined (HAVE_TM_GMTOFF)
5896 return tm->tm_gmtoff;
5901 g.tm_isdst = tm->tm_isdst;
5903 return (int)difftime(t, t2);
5908 * This is heavily based on zdump.c from glibc 2.2.
5910 * * data[0]: start of daylight saving time (in DateTime ticks).
5911 * * data[1]: end of daylight saving time (in DateTime ticks).
5912 * * data[2]: utcoffset (in TimeSpan ticks).
5913 * * data[3]: additional offset when daylight saving (in TimeSpan ticks).
5914 * * name[0]: name of this timezone when not daylight saving.
5915 * * name[1]: name of this timezone when daylight saving.
5917 * FIXME: This only works with "standard" Unix dates (years between 1900 and 2100) while
5918 * the class library allows years between 1 and 9999.
5920 * Returns true on success and zero on failure.
5923 ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year, MonoArray **data, MonoArray **names)
5925 #ifndef PLATFORM_WIN32
5926 MonoDomain *domain = mono_domain_get ();
5927 struct tm start, tt;
5931 int is_daylight = 0, day;
5934 MONO_ARCH_SAVE_REGS;
5936 MONO_CHECK_ARG_NULL (data);
5937 MONO_CHECK_ARG_NULL (names);
5939 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5940 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5943 * no info is better than crashing: we'll need our own tz data
5944 * to make this work properly, anyway. The range is probably
5945 * reduced to 1970 .. 2037 because that is what mktime is
5946 * guaranteed to support (we get into an infinite loop
5950 memset (&start, 0, sizeof (start));
5953 start.tm_year = year-1900;
5955 t = mktime (&start);
5957 if ((year < 1970) || (year > 2037) || (t == -1)) {
5959 tt = *localtime (&t);
5960 strftime (tzone, sizeof (tzone), "%Z", &tt);
5961 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5962 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5966 gmtoff = gmt_offset (&start, t);
5968 /* For each day of the year, calculate the tm_gmtoff. */
5969 for (day = 0; day < 365; day++) {
5972 tt = *localtime (&t);
5974 /* Daylight saving starts or ends here. */
5975 if (gmt_offset (&tt, t) != gmtoff) {
5979 /* Try to find the exact hour when daylight saving starts/ends. */
5983 tt1 = *localtime (&t1);
5984 } while (gmt_offset (&tt1, t1) != gmtoff);
5986 /* Try to find the exact minute when daylight saving starts/ends. */
5989 tt1 = *localtime (&t1);
5990 } while (gmt_offset (&tt1, t1) == gmtoff);
5992 strftime (tzone, sizeof (tzone), "%Z", &tt);
5994 /* Write data, if we're already in daylight saving, we're done. */
5996 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5997 mono_array_set ((*data), gint64, 1, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
6000 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
6001 mono_array_set ((*data), gint64, 0, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
6005 /* This is only set once when we enter daylight saving. */
6006 mono_array_set ((*data), gint64, 2, (gint64)gmtoff * 10000000L);
6007 mono_array_set ((*data), gint64, 3, (gint64)(gmt_offset (&tt, t) - gmtoff) * 10000000L);
6009 gmtoff = gmt_offset (&tt, 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));
6017 mono_array_set ((*data), gint64, 0, 0);
6018 mono_array_set ((*data), gint64, 1, 0);
6019 mono_array_set ((*data), gint64, 2, (gint64) gmtoff * 10000000L);
6020 mono_array_set ((*data), gint64, 3, 0);
6025 MonoDomain *domain = mono_domain_get ();
6026 TIME_ZONE_INFORMATION tz_info;
6031 tz_id = GetTimeZoneInformation (&tz_info);
6032 if (tz_id == TIME_ZONE_ID_INVALID)
6035 MONO_CHECK_ARG_NULL (data);
6036 MONO_CHECK_ARG_NULL (names);
6038 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
6039 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
6041 for (i = 0; i < 32; ++i)
6042 if (!tz_info.DaylightName [i])
6044 mono_array_setref ((*names), 1, mono_string_new_utf16 (domain, tz_info.DaylightName, i));
6045 for (i = 0; i < 32; ++i)
6046 if (!tz_info.StandardName [i])
6048 mono_array_setref ((*names), 0, mono_string_new_utf16 (domain, tz_info.StandardName, i));
6050 if ((year <= 1601) || (year > 30827)) {
6052 * According to MSDN, the MS time functions can't handle dates outside
6058 /* even if the timezone has no daylight savings it may have Bias (e.g. GMT+13 it seems) */
6059 if (tz_id != TIME_ZONE_ID_UNKNOWN) {
6060 tz_info.StandardDate.wYear = year;
6061 convert_to_absolute_date(&tz_info.StandardDate);
6062 err = SystemTimeToFileTime (&tz_info.StandardDate, &ft);
6067 mono_array_set ((*data), gint64, 1, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
6068 tz_info.DaylightDate.wYear = year;
6069 convert_to_absolute_date(&tz_info.DaylightDate);
6070 err = SystemTimeToFileTime (&tz_info.DaylightDate, &ft);
6075 mono_array_set ((*data), gint64, 0, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
6077 mono_array_set ((*data), gint64, 2, (tz_info.Bias + tz_info.StandardBias) * -600000000LL);
6078 mono_array_set ((*data), gint64, 3, (tz_info.DaylightBias - tz_info.StandardBias) * -600000000LL);
6085 ves_icall_System_Object_obj_address (MonoObject *this)
6087 MONO_ARCH_SAVE_REGS;
6094 static inline gint32
6095 mono_array_get_byte_length (MonoArray *array)
6101 klass = array->obj.vtable->klass;
6103 if (array->bounds == NULL)
6104 length = array->max_length;
6107 for (i = 0; i < klass->rank; ++ i)
6108 length *= array->bounds [i].length;
6111 switch (klass->element_class->byval_arg.type) {
6114 case MONO_TYPE_BOOLEAN:
6118 case MONO_TYPE_CHAR:
6126 return length * sizeof (gpointer);
6137 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array)
6139 MONO_ARCH_SAVE_REGS;
6141 return mono_array_get_byte_length (array);
6145 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx)
6147 MONO_ARCH_SAVE_REGS;
6149 return mono_array_get (array, gint8, idx);
6153 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value)
6155 MONO_ARCH_SAVE_REGS;
6157 mono_array_set (array, gint8, idx, value);
6161 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count)
6163 guint8 *src_buf, *dest_buf;
6165 MONO_ARCH_SAVE_REGS;
6167 /* watch out for integer overflow */
6168 if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count))
6171 src_buf = (guint8 *)src->vector + src_offset;
6172 dest_buf = (guint8 *)dest->vector + dest_offset;
6175 memcpy (dest_buf, src_buf, count);
6177 memmove (dest_buf, src_buf, count); /* Source and dest are the same array */
6183 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this, MonoString *class_name)
6185 MonoDomain *domain = mono_object_domain (this);
6187 MonoRealProxy *rp = ((MonoRealProxy *)this);
6188 MonoTransparentProxy *tp;
6192 MONO_ARCH_SAVE_REGS;
6194 res = mono_object_new (domain, mono_defaults.transparent_proxy_class);
6195 tp = (MonoTransparentProxy*) res;
6197 MONO_OBJECT_SETREF (tp, rp, rp);
6198 type = ((MonoReflectionType *)rp->class_to_proxy)->type;
6199 klass = mono_class_from_mono_type (type);
6201 tp->custom_type_info = (mono_object_isinst (this, mono_defaults.iremotingtypeinfo_class) != NULL);
6202 tp->remote_class = mono_remote_class (domain, class_name, klass);
6204 res->vtable = mono_remote_class_vtable (domain, tp->remote_class, rp);
6208 static MonoReflectionType *
6209 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
6211 return mono_type_get_object (mono_object_domain (tp), &tp->remote_class->proxy_class->byval_arg);
6214 /* System.Environment */
6217 ves_icall_System_Environment_get_MachineName (void)
6219 #if defined (PLATFORM_WIN32)
6224 len = MAX_COMPUTERNAME_LENGTH + 1;
6225 buf = g_new (gunichar2, len);
6228 if (GetComputerName (buf, (PDWORD) &len))
6229 result = mono_string_new_utf16 (mono_domain_get (), buf, len);
6237 if (gethostname (buf, sizeof (buf)) == 0)
6238 result = mono_string_new (mono_domain_get (), buf);
6247 ves_icall_System_Environment_get_Platform (void)
6249 MONO_ARCH_SAVE_REGS;
6251 #if defined (PLATFORM_WIN32)
6261 ves_icall_System_Environment_get_NewLine (void)
6263 MONO_ARCH_SAVE_REGS;
6265 #if defined (PLATFORM_WIN32)
6266 return mono_string_new (mono_domain_get (), "\r\n");
6268 return mono_string_new (mono_domain_get (), "\n");
6273 ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name)
6278 MONO_ARCH_SAVE_REGS;
6283 utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
6284 value = g_getenv (utf8_name);
6291 return mono_string_new (mono_domain_get (), value);
6295 * There is no standard way to get at environ.
6298 #ifndef __MINGW32_VERSION
6300 /* Apple defines this in crt_externs.h but doesn't provide that header for
6301 * arm-apple-darwin9. We'll manually define the symbol on Apple as it does
6302 * in fact exist on all implementations (so far)
6304 gchar ***_NSGetEnviron();
6305 #define environ (*_NSGetEnviron())
6314 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
6316 #ifdef PLATFORM_WIN32
6325 env_strings = GetEnvironmentStrings();
6328 env_string = env_strings;
6329 while (*env_string != '\0') {
6330 /* weird case that MS seems to skip */
6331 if (*env_string != '=')
6333 while (*env_string != '\0')
6339 domain = mono_domain_get ();
6340 names = mono_array_new (domain, mono_defaults.string_class, n);
6344 env_string = env_strings;
6345 while (*env_string != '\0') {
6346 /* weird case that MS seems to skip */
6347 if (*env_string != '=') {
6348 equal_str = wcschr(env_string, '=');
6349 g_assert(equal_str);
6350 str = mono_string_new_utf16 (domain, env_string, equal_str-env_string);
6351 mono_array_setref (names, n, str);
6354 while (*env_string != '\0')
6359 FreeEnvironmentStrings (env_strings);
6371 MONO_ARCH_SAVE_REGS;
6374 for (e = environ; *e != 0; ++ e)
6377 domain = mono_domain_get ();
6378 names = mono_array_new (domain, mono_defaults.string_class, n);
6381 for (e = environ; *e != 0; ++ e) {
6382 parts = g_strsplit (*e, "=", 2);
6384 str = mono_string_new (domain, *parts);
6385 mono_array_setref (names, n, str);
6398 * If your platform lacks setenv/unsetenv, you must upgrade your glib.
6400 #if !GLIB_CHECK_VERSION(2,4,0)
6401 #define g_setenv(a,b,c) setenv(a,b,c)
6402 #define g_unsetenv(a) unsetenv(a)
6406 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
6408 #ifdef PLATFORM_WIN32
6409 gunichar2 *utf16_name, *utf16_value;
6411 gchar *utf8_name, *utf8_value;
6414 MONO_ARCH_SAVE_REGS;
6416 #ifdef PLATFORM_WIN32
6417 utf16_name = mono_string_to_utf16 (name);
6418 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
6419 SetEnvironmentVariable (utf16_name, NULL);
6420 g_free (utf16_name);
6424 utf16_value = mono_string_to_utf16 (value);
6426 SetEnvironmentVariable (utf16_name, utf16_value);
6428 g_free (utf16_name);
6429 g_free (utf16_value);
6431 utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
6433 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
6434 g_unsetenv (utf8_name);
6439 utf8_value = mono_string_to_utf8 (value);
6440 g_setenv (utf8_name, utf8_value, TRUE);
6443 g_free (utf8_value);
6448 ves_icall_System_Environment_Exit (int result)
6450 MONO_ARCH_SAVE_REGS;
6452 mono_threads_set_shutting_down ();
6454 mono_runtime_set_shutting_down ();
6456 /* Suspend all managed threads since the runtime is going away */
6457 mono_thread_suspend_all_other_threads ();
6459 mono_runtime_quit ();
6461 /* we may need to do some cleanup here... */
6466 ves_icall_System_Environment_GetGacPath (void)
6468 return mono_string_new (mono_domain_get (), mono_assembly_getrootdir ());
6472 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
6474 #if defined (PLATFORM_WIN32)
6475 #ifndef CSIDL_FLAG_CREATE
6476 #define CSIDL_FLAG_CREATE 0x8000
6479 WCHAR path [MAX_PATH];
6480 /* Create directory if no existing */
6481 if (SUCCEEDED (SHGetFolderPathW (NULL, folder | CSIDL_FLAG_CREATE, NULL, 0, path))) {
6485 return mono_string_new_utf16 (mono_domain_get (), path, len);
6488 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
6490 return mono_string_new (mono_domain_get (), "");
6494 ves_icall_System_Environment_GetLogicalDrives (void)
6496 gunichar2 buf [128], *ptr, *dname;
6498 gint initial_size = 127, size = 128;
6501 MonoString *drivestr;
6502 MonoDomain *domain = mono_domain_get ();
6505 MONO_ARCH_SAVE_REGS;
6510 while (size > initial_size) {
6511 size = GetLogicalDriveStrings (initial_size, ptr);
6512 if (size > initial_size) {
6515 ptr = g_malloc0 ((size + 1) * sizeof (gunichar2));
6516 initial_size = size;
6530 result = mono_array_new (domain, mono_defaults.string_class, ndrives);
6535 while (*u16) { u16++; len ++; }
6536 drivestr = mono_string_new_utf16 (domain, dname, len);
6537 mono_array_setref (result, ndrives++, drivestr);
6548 ves_icall_System_Environment_InternalGetHome (void)
6550 MONO_ARCH_SAVE_REGS;
6552 return mono_string_new (mono_domain_get (), g_get_home_dir ());
6555 static const char *encodings [] = {
6557 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
6558 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
6559 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
6561 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
6562 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
6563 "x_unicode_2_0_utf_7",
6565 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
6566 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
6568 "utf_16", "UTF_16LE", "ucs_2", "unicode",
6571 "unicodefffe", "utf_16be",
6578 * Returns the internal codepage, if the value of "int_code_page" is
6579 * 1 at entry, and we can not compute a suitable code page number,
6580 * returns the code page as a string
6583 ves_icall_System_Text_Encoding_InternalCodePage (gint32 *int_code_page)
6588 char *codepage = NULL;
6590 int want_name = *int_code_page;
6593 *int_code_page = -1;
6594 MONO_ARCH_SAVE_REGS;
6596 g_get_charset (&cset);
6597 c = codepage = strdup (cset);
6598 for (c = codepage; *c; c++){
6599 if (isascii (*c) && isalpha (*c))
6604 /* g_print ("charset: %s\n", cset); */
6606 /* handle some common aliases */
6609 for (i = 0; p != 0; ){
6610 if ((gssize) p < 7){
6612 p = encodings [++i];
6615 if (strcmp (p, codepage) == 0){
6616 *int_code_page = code;
6619 p = encodings [++i];
6622 if (strstr (codepage, "utf_8") != NULL)
6623 *int_code_page |= 0x10000000;
6626 if (want_name && *int_code_page == -1)
6627 return mono_string_new (mono_domain_get (), cset);
6633 ves_icall_System_Environment_get_HasShutdownStarted (void)
6635 if (mono_runtime_is_shutting_down ())
6638 if (mono_domain_is_unloading (mono_domain_get ()))
6645 ves_icall_MonoMethodMessage_InitMessage (MonoMethodMessage *this,
6646 MonoReflectionMethod *method,
6647 MonoArray *out_args)
6649 MONO_ARCH_SAVE_REGS;
6651 mono_message_init (mono_object_domain (this), this, method, out_args);
6655 ves_icall_IsTransparentProxy (MonoObject *proxy)
6657 MONO_ARCH_SAVE_REGS;
6662 if (proxy->vtable->klass == mono_defaults.transparent_proxy_class)
6668 static MonoReflectionMethod *
6669 ves_icall_Remoting_RemotingServices_GetVirtualMethod (
6670 MonoReflectionType *rtype, MonoReflectionMethod *rmethod)
6674 MonoMethod **vtable;
6675 MonoMethod *res = NULL;
6677 MONO_CHECK_ARG_NULL (rtype);
6678 MONO_CHECK_ARG_NULL (rmethod);
6680 method = rmethod->method;
6681 klass = mono_class_from_mono_type (rtype->type);
6683 if (MONO_CLASS_IS_INTERFACE (klass))
6686 if (method->flags & METHOD_ATTRIBUTE_STATIC)
6689 if ((method->flags & METHOD_ATTRIBUTE_FINAL) || !(method->flags & METHOD_ATTRIBUTE_VIRTUAL)) {
6690 if (klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE))
6696 mono_class_setup_vtable (klass);
6697 vtable = klass->vtable;
6699 if (method->klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
6700 int offs = mono_class_interface_offset (klass, method->klass);
6702 res = vtable [offs + method->slot];
6704 if (!(klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE)))
6707 if (method->slot != -1)
6708 res = vtable [method->slot];
6714 return mono_method_get_object (mono_domain_get (), res, NULL);
6718 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6723 MONO_ARCH_SAVE_REGS;
6725 klass = mono_class_from_mono_type (type->type);
6726 vtable = mono_class_vtable (mono_domain_get (), klass);
6728 if (enable) vtable->remote = 1;
6729 else vtable->remote = 0;
6733 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type)
6738 MONO_ARCH_SAVE_REGS;
6740 domain = mono_object_domain (type);
6741 klass = mono_class_from_mono_type (type->type);
6743 if (klass->rank >= 1) {
6744 g_assert (klass->rank == 1);
6745 return (MonoObject *) mono_array_new (domain, klass->element_class, 0);
6747 /* Bypass remoting object creation check */
6748 return mono_object_new_alloc_specific (mono_class_vtable (domain, klass));
6753 ves_icall_System_IO_get_temp_path (void)
6755 MONO_ARCH_SAVE_REGS;
6757 return mono_string_new (mono_domain_get (), g_get_tmp_dir ());
6761 ves_icall_RuntimeMethod_GetFunctionPointer (MonoMethod *method)
6763 MONO_ARCH_SAVE_REGS;
6765 return mono_compile_method (method);
6769 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
6774 MONO_ARCH_SAVE_REGS;
6776 path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
6778 #if defined (PLATFORM_WIN32)
6779 /* Avoid mixing '/' and '\\' */
6782 for (i = strlen (path) - 1; i >= 0; i--)
6783 if (path [i] == '/')
6787 mcpath = mono_string_new (mono_domain_get (), path);
6794 get_bundled_machine_config (void)
6796 const gchar *machine_config;
6798 MONO_ARCH_SAVE_REGS;
6800 machine_config = mono_get_machine_config ();
6802 if (!machine_config)
6805 return mono_string_new (mono_domain_get (), machine_config);
6809 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
6814 MONO_ARCH_SAVE_REGS;
6816 path = g_path_get_dirname (mono_get_config_dir ());
6818 #if defined (PLATFORM_WIN32)
6819 /* Avoid mixing '/' and '\\' */
6822 for (i = strlen (path) - 1; i >= 0; i--)
6823 if (path [i] == '/')
6827 ipath = mono_string_new (mono_domain_get (), path);
6834 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
6836 #if defined (PLATFORM_WIN32)
6837 OutputDebugString (mono_string_chars (message));
6839 g_warning ("WriteWindowsDebugString called and PLATFORM_WIN32 not defined!\n");
6843 /* Only used for value types */
6845 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
6850 MONO_ARCH_SAVE_REGS;
6852 domain = mono_object_domain (type);
6853 klass = mono_class_from_mono_type (type->type);
6855 if (mono_class_is_nullable (klass))
6856 /* No arguments -> null */
6859 return mono_object_new (domain, klass);
6862 static MonoReflectionMethod *
6863 ves_icall_MonoMethod_get_base_definition (MonoReflectionMethod *m)
6865 MonoClass *klass, *parent;
6866 MonoMethod *method = m->method;
6867 MonoMethod *result = NULL;
6869 MONO_ARCH_SAVE_REGS;
6871 if (method->klass == NULL)
6874 if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
6875 MONO_CLASS_IS_INTERFACE (method->klass) ||
6876 method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
6879 klass = method->klass;
6880 if (klass->generic_class)
6881 klass = klass->generic_class->container_class;
6883 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
6884 for (parent = klass->parent; parent != NULL; parent = parent->parent) {
6885 mono_class_setup_vtable (parent);
6886 if (parent->vtable_size <= method->slot)
6891 if (klass == method->klass)
6894 result = klass->vtable [method->slot];
6895 if (result == NULL) {
6896 /* It is an abstract method */
6897 gpointer iter = NULL;
6898 while ((result = mono_class_get_methods (klass, &iter)))
6899 if (result->slot == method->slot)
6906 return mono_method_get_object (mono_domain_get (), result, NULL);
6910 ves_icall_MonoMethod_get_name (MonoReflectionMethod *m)
6912 MonoMethod *method = m->method;
6914 MONO_OBJECT_SETREF (m, name, mono_string_new (mono_object_domain (m), method->name));
6919 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
6921 MONO_ARCH_SAVE_REGS;
6923 iter->sig = *(MonoMethodSignature**)argsp;
6925 g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
6926 g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
6929 /* FIXME: it's not documented what start is exactly... */
6933 guint32 i, arg_size;
6935 iter->args = argsp + sizeof (gpointer);
6936 #ifndef MONO_ARCH_REGPARMS
6937 for (i = 0; i < iter->sig->sentinelpos; ++i) {
6938 arg_size = mono_type_stack_size (iter->sig->params [i], &align);
6939 iter->args = (char*)iter->args + arg_size;
6943 iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
6945 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
6949 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
6951 guint32 i, arg_size;
6954 MONO_ARCH_SAVE_REGS;
6956 i = iter->sig->sentinelpos + iter->next_arg;
6958 g_assert (i < iter->sig->param_count);
6960 res.type = iter->sig->params [i];
6961 res.klass = mono_class_from_mono_type (res.type);
6962 /* FIXME: endianess issue... */
6963 res.value = iter->args;
6964 arg_size = mono_type_stack_size (res.type, &align);
6965 iter->args = (char*)iter->args + arg_size;
6968 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6974 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
6976 guint32 i, arg_size;
6979 MONO_ARCH_SAVE_REGS;
6981 i = iter->sig->sentinelpos + iter->next_arg;
6983 g_assert (i < iter->sig->param_count);
6985 while (i < iter->sig->param_count) {
6986 if (!mono_metadata_type_equal (type, iter->sig->params [i]))
6988 res.type = iter->sig->params [i];
6989 res.klass = mono_class_from_mono_type (res.type);
6990 /* FIXME: endianess issue... */
6991 res.value = iter->args;
6992 arg_size = mono_type_stack_size (res.type, &align);
6993 iter->args = (char*)iter->args + arg_size;
6995 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6998 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
7007 mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
7010 MONO_ARCH_SAVE_REGS;
7012 i = iter->sig->sentinelpos + iter->next_arg;
7014 g_assert (i < iter->sig->param_count);
7016 return iter->sig->params [i];
7020 mono_TypedReference_ToObject (MonoTypedRef tref)
7022 MONO_ARCH_SAVE_REGS;
7024 if (MONO_TYPE_IS_REFERENCE (tref.type)) {
7025 MonoObject** objp = tref.value;
7029 return mono_value_box (mono_domain_get (), tref.klass, tref.value);
7033 mono_TypedReference_ToObjectInternal (MonoType *type, gpointer value, MonoClass *klass)
7035 MONO_ARCH_SAVE_REGS;
7037 if (MONO_TYPE_IS_REFERENCE (type)) {
7038 MonoObject** objp = value;
7042 return mono_value_box (mono_domain_get (), klass, value);
7046 prelink_method (MonoMethod *method)
7048 const char *exc_class, *exc_arg;
7049 if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
7051 mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
7053 mono_raise_exception(
7054 mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg ) );
7056 /* create the wrapper, too? */
7060 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
7062 MONO_ARCH_SAVE_REGS;
7063 prelink_method (method->method);
7067 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
7069 MonoClass *klass = mono_class_from_mono_type (type->type);
7071 gpointer iter = NULL;
7072 MONO_ARCH_SAVE_REGS;
7074 while ((m = mono_class_get_methods (klass, &iter)))
7078 /* These parameters are "readonly" in corlib/System/NumberFormatter.cs */
7080 ves_icall_System_NumberFormatter_GetFormatterTables (guint64 const **mantissas,
7081 gint32 const **exponents,
7082 gunichar2 const **digitLowerTable,
7083 gunichar2 const **digitUpperTable,
7084 gint64 const **tenPowersList,
7085 gint32 const **decHexDigits)
7087 *mantissas = Formatter_MantissaBitsTable;
7088 *exponents = Formatter_TensExponentTable;
7089 *digitLowerTable = Formatter_DigitLowerTable;
7090 *digitUpperTable = Formatter_DigitUpperTable;
7091 *tenPowersList = Formatter_TenPowersList;
7092 *decHexDigits = Formatter_DecHexDigits;
7095 /* These parameters are "readonly" in corlib/System/Char.cs */
7097 ves_icall_System_Char_GetDataTablePointers (guint8 const **category_data,
7098 guint8 const **numeric_data,
7099 gdouble const **numeric_data_values,
7100 guint16 const **to_lower_data_low,
7101 guint16 const **to_lower_data_high,
7102 guint16 const **to_upper_data_low,
7103 guint16 const **to_upper_data_high)
7105 *category_data = CategoryData;
7106 *numeric_data = NumericData;
7107 *numeric_data_values = NumericDataValues;
7108 *to_lower_data_low = ToLowerDataLow;
7109 *to_lower_data_high = ToLowerDataHigh;
7110 *to_upper_data_low = ToUpperDataLow;
7111 *to_upper_data_high = ToUpperDataHigh;
7115 ves_icall_MonoDebugger_GetMethodToken (MonoReflectionMethod *method)
7117 return method->method->token;
7121 * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
7122 * and avoid useless allocations.
7125 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional)
7129 for (i = 0; i < type->num_mods; ++i) {
7130 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
7135 res = mono_array_new (mono_domain_get (), mono_defaults.systemtype_class, count);
7137 for (i = 0; i < type->num_mods; ++i) {
7138 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
7139 MonoClass *klass = mono_class_get (image, type->modifiers [i].token);
7140 mono_array_setref (res, count, mono_type_get_object (mono_domain_get (), &klass->byval_arg));
7148 param_info_get_type_modifiers (MonoReflectionParameter *param, MonoBoolean optional)
7150 MonoType *type = param->ClassImpl->type;
7151 MonoReflectionMethod *method = (MonoReflectionMethod*)param->MemberImpl;
7152 MonoImage *image = method->method->klass->image;
7153 int pos = param->PositionImpl;
7154 MonoMethodSignature *sig = mono_method_signature (method->method);
7158 type = sig->params [pos];
7160 return type_array_from_modifiers (image, type, optional);
7164 get_property_type (MonoProperty *prop)
7166 MonoMethodSignature *sig;
7168 sig = mono_method_signature (prop->get);
7170 } else if (prop->set) {
7171 sig = mono_method_signature (prop->set);
7172 return sig->params [sig->param_count - 1];
7178 property_info_get_type_modifiers (MonoReflectionProperty *property, MonoBoolean optional)
7180 MonoType *type = get_property_type (property->property);
7181 MonoImage *image = property->klass->image;
7185 return type_array_from_modifiers (image, type, optional);
7189 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
7191 MonoCustomAttrInfo *cinfo;
7194 cinfo = mono_reflection_get_custom_attrs_info (obj);
7197 found = mono_custom_attrs_has_attr (cinfo, mono_class_from_mono_type (attr_type->type));
7199 mono_custom_attrs_free (cinfo);
7204 custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
7206 MonoArray *res = mono_reflection_get_custom_attrs_by_type (obj, attr_type ? mono_class_from_mono_type (attr_type->type) : NULL);
7208 if (mono_loader_get_last_error ()) {
7209 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
7210 g_assert_not_reached ();
7217 GCHandle_CheckCurrentDomain (guint32 gchandle)
7219 return mono_gchandle_is_in_domain (gchandle, mono_domain_get ());
7223 ves_icall_Mono_Runtime_GetDisplayName (void)
7225 static const char display_name_str [] = "Mono " VERSION;
7226 MonoString *display_name = mono_string_new (mono_domain_get (), display_name_str);
7227 return display_name;
7231 ves_icall_System_ComponentModel_Win32Exception_W32ErrorMessage (guint32 code)
7233 MonoString *message;
7237 ret = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM |
7238 FORMAT_MESSAGE_IGNORE_INSERTS, NULL, code, 0,
7241 message = mono_string_new (mono_domain_get (), "Error looking up error string");
7243 message = mono_string_new_utf16 (mono_domain_get (), buf, ret);
7251 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
7252 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
7253 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 62, 128, 128, 128, 63,
7254 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 0, 128, 128,
7255 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
7256 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 128, 128, 128, 128, 128,
7257 128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
7258 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
7262 base64_to_byte_array (gunichar2 *start, gint ilength, MonoBoolean allowWhitespaceOnly)
7267 gunichar2 last, prev_last, prev2_last;
7275 last = prev_last = 0, prev2_last = 0;
7276 for (i = 0; i < ilength; i++) {
7278 if (c >= sizeof (dbase64)) {
7279 exc = mono_exception_from_name_msg (mono_get_corlib (),
7280 "System", "FormatException",
7281 "Invalid character found.");
7282 mono_raise_exception (exc);
7283 } else if (isspace (c)) {
7286 prev2_last = prev_last;
7292 olength = ilength - ignored;
7294 if (allowWhitespaceOnly && olength == 0) {
7295 return mono_array_new (mono_domain_get (), mono_defaults.byte_class, 0);
7298 if ((olength & 3) != 0 || olength <= 0) {
7299 exc = mono_exception_from_name_msg (mono_get_corlib (), "System",
7300 "FormatException", "Invalid length.");
7301 mono_raise_exception (exc);
7304 if (prev2_last == '=') {
7305 exc = mono_exception_from_name_msg (mono_get_corlib (), "System", "FormatException", "Invalid format.");
7306 mono_raise_exception (exc);
7309 olength = (olength * 3) / 4;
7313 if (prev_last == '=')
7316 result = mono_array_new (mono_domain_get (), mono_defaults.byte_class, olength);
7317 res_ptr = mono_array_addr (result, guchar, 0);
7318 for (i = 0; i < ilength; ) {
7321 for (k = 0; k < 4 && i < ilength;) {
7327 if (((b [k] = dbase64 [c]) & 0x80) != 0) {
7328 exc = mono_exception_from_name_msg (mono_get_corlib (),
7329 "System", "FormatException",
7330 "Invalid character found.");
7331 mono_raise_exception (exc);
7336 *res_ptr++ = (b [0] << 2) | (b [1] >> 4);
7338 *res_ptr++ = (b [1] << 4) | (b [2] >> 2);
7340 *res_ptr++ = (b [2] << 6) | b [3];
7342 while (i < ilength && isspace (start [i]))
7350 InternalFromBase64String (MonoString *str, MonoBoolean allowWhitespaceOnly)
7352 MONO_ARCH_SAVE_REGS;
7354 return base64_to_byte_array (mono_string_chars (str),
7355 mono_string_length (str), allowWhitespaceOnly);
7359 InternalFromBase64CharArray (MonoArray *input, gint offset, gint length)
7361 MONO_ARCH_SAVE_REGS;
7363 return base64_to_byte_array (mono_array_addr (input, gunichar2, offset),
7367 #define ICALL_TYPE(id,name,first)
7368 #define ICALL(id,name,func) Icall_ ## id,
7371 #include "metadata/icall-def.h"
7377 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
7378 #define ICALL(id,name,func)
7380 #include "metadata/icall-def.h"
7386 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
7387 #define ICALL(id,name,func)
7389 guint16 first_icall;
7392 static const IcallTypeDesc
7393 icall_type_descs [] = {
7394 #include "metadata/icall-def.h"
7398 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
7401 #define ICALL_TYPE(id,name,first)
7404 #ifdef HAVE_ARRAY_ELEM_INIT
7405 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
7406 #define MSGSTRFIELD1(line) str##line
7408 static const struct msgstrtn_t {
7409 #define ICALL(id,name,func)
7411 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7412 #include "metadata/icall-def.h"
7414 } icall_type_names_str = {
7415 #define ICALL_TYPE(id,name,first) (name),
7416 #include "metadata/icall-def.h"
7419 static const guint16 icall_type_names_idx [] = {
7420 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
7421 #include "metadata/icall-def.h"
7424 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
7426 static const struct msgstr_t {
7428 #define ICALL_TYPE(id,name,first)
7429 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7430 #include "metadata/icall-def.h"
7432 } icall_names_str = {
7433 #define ICALL(id,name,func) (name),
7434 #include "metadata/icall-def.h"
7437 static const guint16 icall_names_idx [] = {
7438 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
7439 #include "metadata/icall-def.h"
7442 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
7448 #define ICALL_TYPE(id,name,first) name,
7449 #define ICALL(id,name,func)
7450 static const char* const
7451 icall_type_names [] = {
7452 #include "metadata/icall-def.h"
7456 #define icall_type_name_get(id) (icall_type_names [(id)])
7460 #define ICALL_TYPE(id,name,first)
7461 #define ICALL(id,name,func) name,
7462 static const char* const
7464 #include "metadata/icall-def.h"
7467 #define icall_name_get(id) icall_names [(id)]
7469 #endif /* !HAVE_ARRAY_ELEM_INIT */
7473 #define ICALL_TYPE(id,name,first)
7474 #define ICALL(id,name,func) func,
7475 static const gconstpointer
7476 icall_functions [] = {
7477 #include "metadata/icall-def.h"
7481 static GHashTable *icall_hash = NULL;
7482 static GHashTable *jit_icall_hash_name = NULL;
7483 static GHashTable *jit_icall_hash_addr = NULL;
7486 mono_icall_init (void)
7490 /* check that tables are sorted: disable in release */
7493 const char *prev_class = NULL;
7494 const char *prev_method;
7496 for (i = 0; i < Icall_type_num; ++i) {
7497 const IcallTypeDesc *desc;
7500 if (prev_class && strcmp (prev_class, icall_type_name_get (i)) >= 0)
7501 g_print ("class %s should come before class %s\n", icall_type_name_get (i), prev_class);
7502 prev_class = icall_type_name_get (i);
7503 desc = &icall_type_descs [i];
7504 num_icalls = icall_desc_num_icalls (desc);
7505 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
7506 for (j = 0; j < num_icalls; ++j) {
7507 const char *methodn = icall_name_get (desc->first_icall + j);
7508 if (prev_method && strcmp (prev_method, methodn) >= 0)
7509 g_print ("method %s should come before method %s\n", methodn, prev_method);
7510 prev_method = methodn;
7515 icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
7519 mono_icall_cleanup (void)
7521 g_hash_table_destroy (icall_hash);
7522 g_hash_table_destroy (jit_icall_hash_name);
7523 g_hash_table_destroy (jit_icall_hash_addr);
7527 mono_add_internal_call (const char *name, gconstpointer method)
7529 mono_loader_lock ();
7531 g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
7533 mono_loader_unlock ();
7536 #ifdef HAVE_ARRAY_ELEM_INIT
7538 compare_method_imap (const void *key, const void *elem)
7540 const char* method_name = (const char*)&icall_names_str + (*(guint16*)elem);
7541 return strcmp (key, method_name);
7545 find_method_icall (const IcallTypeDesc *imap, const char *name)
7547 const guint16 *nameslot = bsearch (name, icall_names_idx + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names_idx [0]), compare_method_imap);
7550 return (gpointer)icall_functions [(nameslot - &icall_names_idx [0])];
7554 compare_class_imap (const void *key, const void *elem)
7556 const char* class_name = (const char*)&icall_type_names_str + (*(guint16*)elem);
7557 return strcmp (key, class_name);
7560 static const IcallTypeDesc*
7561 find_class_icalls (const char *name)
7563 const guint16 *nameslot = bsearch (name, icall_type_names_idx, Icall_type_num, sizeof (icall_type_names_idx [0]), compare_class_imap);
7566 return &icall_type_descs [nameslot - &icall_type_names_idx [0]];
7571 compare_method_imap (const void *key, const void *elem)
7573 const char** method_name = (const char**)elem;
7574 return strcmp (key, *method_name);
7578 find_method_icall (const IcallTypeDesc *imap, const char *name)
7580 const char **nameslot = bsearch (name, icall_names + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names [0]), compare_method_imap);
7583 return (gpointer)icall_functions [(nameslot - icall_names)];
7587 compare_class_imap (const void *key, const void *elem)
7589 const char** class_name = (const char**)elem;
7590 return strcmp (key, *class_name);
7593 static const IcallTypeDesc*
7594 find_class_icalls (const char *name)
7596 const char **nameslot = bsearch (name, icall_type_names, Icall_type_num, sizeof (icall_type_names [0]), compare_class_imap);
7599 return &icall_type_descs [nameslot - icall_type_names];
7605 * we should probably export this as an helper (handle nested types).
7606 * Returns the number of chars written in buf.
7609 concat_class_name (char *buf, int bufsize, MonoClass *klass)
7611 int nspacelen, cnamelen;
7612 nspacelen = strlen (klass->name_space);
7613 cnamelen = strlen (klass->name);
7614 if (nspacelen + cnamelen + 2 > bufsize)
7617 memcpy (buf, klass->name_space, nspacelen);
7618 buf [nspacelen ++] = '.';
7620 memcpy (buf + nspacelen, klass->name, cnamelen);
7621 buf [nspacelen + cnamelen] = 0;
7622 return nspacelen + cnamelen;
7626 mono_lookup_internal_call (MonoMethod *method)
7631 int typelen = 0, mlen, siglen;
7633 const IcallTypeDesc *imap;
7635 g_assert (method != NULL);
7637 if (method->is_inflated)
7638 method = ((MonoMethodInflated *) method)->declaring;
7640 if (method->klass->nested_in) {
7641 int pos = concat_class_name (mname, sizeof (mname)-2, method->klass->nested_in);
7645 mname [pos++] = '/';
7648 typelen = concat_class_name (mname+pos, sizeof (mname)-pos-1, method->klass);
7654 typelen = concat_class_name (mname, sizeof (mname), method->klass);
7659 imap = find_class_icalls (mname);
7661 mname [typelen] = ':';
7662 mname [typelen + 1] = ':';
7664 mlen = strlen (method->name);
7665 memcpy (mname + typelen + 2, method->name, mlen);
7666 sigstart = mname + typelen + 2 + mlen;
7669 tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
7670 siglen = strlen (tmpsig);
7671 if (typelen + mlen + siglen + 6 > sizeof (mname))
7674 memcpy (sigstart + 1, tmpsig, siglen);
7675 sigstart [siglen + 1] = ')';
7676 sigstart [siglen + 2] = 0;
7679 mono_loader_lock ();
7681 res = g_hash_table_lookup (icall_hash, mname);
7683 mono_loader_unlock ();
7686 /* try without signature */
7688 res = g_hash_table_lookup (icall_hash, mname);
7690 mono_loader_unlock ();
7694 /* it wasn't found in the static call tables */
7696 mono_loader_unlock ();
7699 res = find_method_icall (imap, sigstart - mlen);
7701 mono_loader_unlock ();
7704 /* try _with_ signature */
7706 res = find_method_icall (imap, sigstart - mlen);
7708 mono_loader_unlock ();
7712 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname);
7713 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
7714 g_print ("The out of sync library is: %s\n", method->klass->image->name);
7715 g_print ("\nWhen you update one from svn you need to update, compile and install\nthe other too.\n");
7716 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");
7717 g_print ("If you see other errors or faults after this message they are probably related\n");
7718 g_print ("and you need to fix your mono install first.\n");
7720 mono_loader_unlock ();
7726 type_from_typename (char *typename)
7728 MonoClass *klass = NULL; /* assignment to shut GCC warning up */
7730 if (!strcmp (typename, "int"))
7731 klass = mono_defaults.int_class;
7732 else if (!strcmp (typename, "ptr"))
7733 klass = mono_defaults.int_class;
7734 else if (!strcmp (typename, "void"))
7735 klass = mono_defaults.void_class;
7736 else if (!strcmp (typename, "int32"))
7737 klass = mono_defaults.int32_class;
7738 else if (!strcmp (typename, "uint32"))
7739 klass = mono_defaults.uint32_class;
7740 else if (!strcmp (typename, "int8"))
7741 klass = mono_defaults.sbyte_class;
7742 else if (!strcmp (typename, "uint8"))
7743 klass = mono_defaults.byte_class;
7744 else if (!strcmp (typename, "int16"))
7745 klass = mono_defaults.int16_class;
7746 else if (!strcmp (typename, "uint16"))
7747 klass = mono_defaults.uint16_class;
7748 else if (!strcmp (typename, "long"))
7749 klass = mono_defaults.int64_class;
7750 else if (!strcmp (typename, "ulong"))
7751 klass = mono_defaults.uint64_class;
7752 else if (!strcmp (typename, "float"))
7753 klass = mono_defaults.single_class;
7754 else if (!strcmp (typename, "double"))
7755 klass = mono_defaults.double_class;
7756 else if (!strcmp (typename, "object"))
7757 klass = mono_defaults.object_class;
7758 else if (!strcmp (typename, "obj"))
7759 klass = mono_defaults.object_class;
7760 else if (!strcmp (typename, "string"))
7761 klass = mono_defaults.string_class;
7762 else if (!strcmp (typename, "bool"))
7763 klass = mono_defaults.boolean_class;
7764 else if (!strcmp (typename, "boolean"))
7765 klass = mono_defaults.boolean_class;
7768 g_assert_not_reached ();
7770 return &klass->byval_arg;
7773 MonoMethodSignature*
7774 mono_create_icall_signature (const char *sigstr)
7779 MonoMethodSignature *res;
7781 mono_loader_lock ();
7782 res = g_hash_table_lookup (mono_defaults.corlib->helper_signatures, sigstr);
7784 mono_loader_unlock ();
7788 parts = g_strsplit (sigstr, " ", 256);
7797 res = mono_metadata_signature_alloc (mono_defaults.corlib, len - 1);
7800 #ifdef PLATFORM_WIN32
7802 * Under windows, the default pinvoke calling convention is STDCALL but
7805 res->call_convention = MONO_CALL_C;
7808 res->ret = type_from_typename (parts [0]);
7809 for (i = 1; i < len; ++i) {
7810 res->params [i - 1] = type_from_typename (parts [i]);
7815 g_hash_table_insert (mono_defaults.corlib->helper_signatures, (gpointer)sigstr, res);
7817 mono_loader_unlock ();
7823 mono_find_jit_icall_by_name (const char *name)
7825 MonoJitICallInfo *info;
7826 g_assert (jit_icall_hash_name);
7828 mono_loader_lock ();
7829 info = g_hash_table_lookup (jit_icall_hash_name, name);
7830 mono_loader_unlock ();
7835 mono_find_jit_icall_by_addr (gconstpointer addr)
7837 MonoJitICallInfo *info;
7838 g_assert (jit_icall_hash_addr);
7840 mono_loader_lock ();
7841 info = g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
7842 mono_loader_unlock ();
7848 * mono_get_jit_icall_info:
7850 * Return the hashtable mapping JIT icall names to MonoJitICallInfo structures. The
7851 * caller should access it while holding the loader lock.
7854 mono_get_jit_icall_info (void)
7856 return jit_icall_hash_name;
7860 mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
7862 mono_loader_lock ();
7863 g_hash_table_insert (jit_icall_hash_addr, (gpointer)wrapper, info);
7864 mono_loader_unlock ();
7868 mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
7870 MonoJitICallInfo *info;
7875 mono_loader_lock ();
7877 if (!jit_icall_hash_name) {
7878 jit_icall_hash_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
7879 jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
7882 if (g_hash_table_lookup (jit_icall_hash_name, name)) {
7883 g_warning ("jit icall already defined \"%s\"\n", name);
7884 g_assert_not_reached ();
7887 info = g_new0 (MonoJitICallInfo, 1);
7894 info->wrapper = func;
7896 info->wrapper = NULL;
7899 g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
7900 g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
7902 mono_loader_unlock ();