5 * Dietmar Maurer (dietmar@ximian.com)
6 * Paolo Molaro (lupus@ximian.com)
7 * Patrik Torstensson (patrik.torstensson@labs2.com)
9 * (C) 2001 Ximian, Inc.
17 #ifdef HAVE_SYS_TIME_H
23 #if defined (PLATFORM_WIN32)
27 #include <mono/metadata/object.h>
28 #include <mono/metadata/threads.h>
29 #include <mono/metadata/threads-types.h>
30 #include <mono/metadata/threadpool.h>
31 #include <mono/metadata/monitor.h>
32 #include <mono/metadata/reflection.h>
33 #include <mono/metadata/assembly.h>
34 #include <mono/metadata/tabledefs.h>
35 #include <mono/metadata/exception.h>
36 #include <mono/metadata/file-io.h>
37 #include <mono/metadata/console-io.h>
38 #include <mono/metadata/socket-io.h>
39 #include <mono/metadata/mono-endian.h>
40 #include <mono/metadata/tokentype.h>
41 #include <mono/metadata/domain-internals.h>
42 #include <mono/metadata/metadata-internals.h>
43 #include <mono/metadata/class-internals.h>
44 #include <mono/metadata/marshal.h>
45 #include <mono/metadata/gc-internal.h>
46 #include <mono/metadata/mono-gc.h>
47 #include <mono/metadata/rand.h>
48 #include <mono/metadata/sysmath.h>
49 #include <mono/metadata/string-icalls.h>
50 #include <mono/metadata/debug-helpers.h>
51 #include <mono/metadata/process.h>
52 #include <mono/metadata/environment.h>
53 #include <mono/metadata/profiler-private.h>
54 #include <mono/metadata/locales.h>
55 #include <mono/metadata/filewatcher.h>
56 #include <mono/metadata/char-conversions.h>
57 #include <mono/metadata/security.h>
58 #include <mono/metadata/mono-config.h>
59 #include <mono/metadata/cil-coff.h>
60 #include <mono/metadata/number-formatter.h>
61 #include <mono/metadata/security-manager.h>
62 #include <mono/metadata/security-core-clr.h>
63 #include <mono/io-layer/io-layer.h>
64 #include <mono/utils/strtod.h>
65 #include <mono/utils/monobitset.h>
67 #if defined (PLATFORM_WIN32)
73 static MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void);
76 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional);
78 static inline MonoBoolean
79 is_generic_parameter (MonoType *type)
81 return !type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR);
85 * We expect a pointer to a char, not a string
88 mono_double_ParseImpl (char *ptr, double *result)
97 *result = strtod (ptr, &endptr);
100 *result = mono_strtod (ptr, &endptr);
103 if (!*ptr || (endptr && *endptr))
110 mono_class_get_throw (MonoImage *image, guint32 type_token)
112 MonoClass *class = mono_class_get (image, type_token);
113 MonoLoaderError *error;
119 error = mono_loader_get_last_error ();
120 g_assert (error != NULL);
122 ex = mono_loader_error_prepare_exception (error);
123 mono_raise_exception (ex);
128 ves_icall_System_Array_GetValueImpl (MonoObject *this, guint32 pos)
137 ao = (MonoArray *)this;
138 ac = (MonoClass *)ao->obj.vtable->klass;
140 esize = mono_array_element_size (ac);
141 ea = (gpointer*)((char*)ao->vector + (pos * esize));
143 if (ac->element_class->valuetype)
144 return mono_value_box (this->vtable->domain, ac->element_class, ea);
150 ves_icall_System_Array_GetValue (MonoObject *this, MonoObject *idxs)
158 MONO_CHECK_ARG_NULL (idxs);
160 io = (MonoArray *)idxs;
161 ic = (MonoClass *)io->obj.vtable->klass;
163 ao = (MonoArray *)this;
164 ac = (MonoClass *)ao->obj.vtable->klass;
166 g_assert (ic->rank == 1);
167 if (io->bounds != NULL || io->max_length != ac->rank)
168 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
170 ind = (gint32 *)io->vector;
172 if (ao->bounds == NULL) {
173 if (*ind < 0 || *ind >= ao->max_length)
174 mono_raise_exception (mono_get_exception_index_out_of_range ());
176 return ves_icall_System_Array_GetValueImpl (this, *ind);
179 for (i = 0; i < ac->rank; i++)
180 if ((ind [i] < ao->bounds [i].lower_bound) ||
181 (ind [i] >= ao->bounds [i].length + ao->bounds [i].lower_bound))
182 mono_raise_exception (mono_get_exception_index_out_of_range ());
184 pos = ind [0] - ao->bounds [0].lower_bound;
185 for (i = 1; i < ac->rank; i++)
186 pos = pos*ao->bounds [i].length + ind [i] -
187 ao->bounds [i].lower_bound;
189 return ves_icall_System_Array_GetValueImpl (this, pos);
193 ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32 pos)
195 MonoClass *ac, *vc, *ec;
207 vc = value->vtable->klass;
211 ac = this->obj.vtable->klass;
212 ec = ac->element_class;
214 esize = mono_array_element_size (ac);
215 ea = (gpointer*)((char*)this->vector + (pos * esize));
216 va = (gpointer*)((char*)value + sizeof (MonoObject));
219 memset (ea, 0, esize);
223 #define NO_WIDENING_CONVERSION G_STMT_START{\
224 mono_raise_exception (mono_get_exception_argument ( \
225 "value", "not a widening conversion")); \
228 #define CHECK_WIDENING_CONVERSION(extra) G_STMT_START{\
229 if (esize < vsize + (extra)) \
230 mono_raise_exception (mono_get_exception_argument ( \
231 "value", "not a widening conversion")); \
234 #define INVALID_CAST G_STMT_START{\
235 mono_raise_exception (mono_get_exception_invalid_cast ()); \
238 /* Check element (destination) type. */
239 switch (ec->byval_arg.type) {
240 case MONO_TYPE_STRING:
241 switch (vc->byval_arg.type) {
242 case MONO_TYPE_STRING:
248 case MONO_TYPE_BOOLEAN:
249 switch (vc->byval_arg.type) {
250 case MONO_TYPE_BOOLEAN:
263 NO_WIDENING_CONVERSION;
270 if (!ec->valuetype) {
271 if (!mono_object_isinst (value, ec))
273 mono_gc_wbarrier_set_arrayref (this, ea, (MonoObject*)value);
277 if (mono_object_isinst (value, ec)) {
278 if (ec->has_references)
279 mono_value_copy (ea, (char*)value + sizeof (MonoObject), ec);
281 memcpy (ea, (char *)value + sizeof (MonoObject), esize);
288 vsize = mono_class_instance_size (vc) - sizeof (MonoObject);
290 et = ec->byval_arg.type;
291 if (et == MONO_TYPE_VALUETYPE && ec->byval_arg.data.klass->enumtype)
292 et = ec->byval_arg.data.klass->enum_basetype->type;
294 vt = vc->byval_arg.type;
295 if (vt == MONO_TYPE_VALUETYPE && vc->byval_arg.data.klass->enumtype)
296 vt = vc->byval_arg.data.klass->enum_basetype->type;
298 #define ASSIGN_UNSIGNED(etype) G_STMT_START{\
304 case MONO_TYPE_CHAR: \
305 CHECK_WIDENING_CONVERSION(0); \
306 *(etype *) ea = (etype) u64; \
308 /* You can't assign a signed value to an unsigned array. */ \
313 /* You can't assign a floating point number to an integer array. */ \
316 NO_WIDENING_CONVERSION; \
320 #define ASSIGN_SIGNED(etype) G_STMT_START{\
326 CHECK_WIDENING_CONVERSION(0); \
327 *(etype *) ea = (etype) i64; \
329 /* You can assign an unsigned value to a signed array if the array's */ \
330 /* element size is larger than the value size. */ \
335 case MONO_TYPE_CHAR: \
336 CHECK_WIDENING_CONVERSION(1); \
337 *(etype *) ea = (etype) u64; \
339 /* You can't assign a floating point number to an integer array. */ \
342 NO_WIDENING_CONVERSION; \
346 #define ASSIGN_REAL(etype) G_STMT_START{\
350 CHECK_WIDENING_CONVERSION(0); \
351 *(etype *) ea = (etype) r64; \
353 /* All integer values fit into a floating point array, so we don't */ \
354 /* need to CHECK_WIDENING_CONVERSION here. */ \
359 *(etype *) ea = (etype) i64; \
365 case MONO_TYPE_CHAR: \
366 *(etype *) ea = (etype) u64; \
373 u64 = *(guint8 *) va;
376 u64 = *(guint16 *) va;
379 u64 = *(guint32 *) va;
382 u64 = *(guint64 *) va;
388 i64 = *(gint16 *) va;
391 i64 = *(gint32 *) va;
394 i64 = *(gint64 *) va;
397 r64 = *(gfloat *) va;
400 r64 = *(gdouble *) va;
403 u64 = *(guint16 *) va;
405 case MONO_TYPE_BOOLEAN:
406 /* Boolean is only compatible with itself. */
419 NO_WIDENING_CONVERSION;
426 /* If we can't do a direct copy, let's try a widening conversion. */
429 ASSIGN_UNSIGNED (guint16);
431 ASSIGN_UNSIGNED (guint8);
433 ASSIGN_UNSIGNED (guint16);
435 ASSIGN_UNSIGNED (guint32);
437 ASSIGN_UNSIGNED (guint64);
439 ASSIGN_SIGNED (gint8);
441 ASSIGN_SIGNED (gint16);
443 ASSIGN_SIGNED (gint32);
445 ASSIGN_SIGNED (gint64);
447 ASSIGN_REAL (gfloat);
449 ASSIGN_REAL (gdouble);
453 /* Not reached, INVALID_CAST does not return. Just to avoid a compiler warning ... */
457 #undef NO_WIDENING_CONVERSION
458 #undef CHECK_WIDENING_CONVERSION
459 #undef ASSIGN_UNSIGNED
465 ves_icall_System_Array_SetValue (MonoArray *this, MonoObject *value,
473 MONO_CHECK_ARG_NULL (idxs);
475 ic = idxs->obj.vtable->klass;
476 ac = this->obj.vtable->klass;
478 g_assert (ic->rank == 1);
479 if (idxs->bounds != NULL || idxs->max_length != ac->rank)
480 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
482 ind = (gint32 *)idxs->vector;
484 if (this->bounds == NULL) {
485 if (*ind < 0 || *ind >= this->max_length)
486 mono_raise_exception (mono_get_exception_index_out_of_range ());
488 ves_icall_System_Array_SetValueImpl (this, value, *ind);
492 for (i = 0; i < ac->rank; i++)
493 if ((ind [i] < this->bounds [i].lower_bound) ||
494 (ind [i] >= this->bounds [i].length + this->bounds [i].lower_bound))
495 mono_raise_exception (mono_get_exception_index_out_of_range ());
497 pos = ind [0] - this->bounds [0].lower_bound;
498 for (i = 1; i < ac->rank; i++)
499 pos = pos * this->bounds [i].length + ind [i] -
500 this->bounds [i].lower_bound;
502 ves_icall_System_Array_SetValueImpl (this, value, pos);
506 ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
511 gboolean bounded = FALSE;
515 MONO_CHECK_ARG_NULL (type);
516 MONO_CHECK_ARG_NULL (lengths);
518 MONO_CHECK_ARG (lengths, mono_array_length (lengths) > 0);
520 MONO_CHECK_ARG (bounds, mono_array_length (lengths) == mono_array_length (bounds));
522 for (i = 0; i < mono_array_length (lengths); i++)
523 if (mono_array_get (lengths, gint32, i) < 0)
524 mono_raise_exception (mono_get_exception_argument_out_of_range (NULL));
526 if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint32, 0) != 0))
527 /* vectors are not the same as one dimensional arrays with no-zero bounds */
532 aklass = mono_bounded_array_class_get (mono_class_from_mono_type (type->type), mono_array_length (lengths), bounded);
534 sizes = alloca (aklass->rank * sizeof(guint32) * 2);
535 for (i = 0; i < aklass->rank; ++i) {
536 sizes [i] = mono_array_get (lengths, guint32, i);
538 sizes [i + aklass->rank] = mono_array_get (bounds, guint32, i);
540 sizes [i + aklass->rank] = 0;
543 array = mono_array_new_full (mono_object_domain (type), aklass, sizes, sizes + aklass->rank);
549 ves_icall_System_Array_GetRank (MonoObject *this)
553 return this->vtable->klass->rank;
557 ves_icall_System_Array_GetLength (MonoArray *this, gint32 dimension)
559 gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
563 if ((dimension < 0) || (dimension >= rank))
564 mono_raise_exception (mono_get_exception_index_out_of_range ());
566 if (this->bounds == NULL)
567 return this->max_length;
569 return this->bounds [dimension].length;
573 ves_icall_System_Array_GetLowerBound (MonoArray *this, gint32 dimension)
575 gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
579 if ((dimension < 0) || (dimension >= rank))
580 mono_raise_exception (mono_get_exception_index_out_of_range ());
582 if (this->bounds == NULL)
585 return this->bounds [dimension].lower_bound;
589 ves_icall_System_Array_ClearInternal (MonoArray *arr, int idx, int length)
591 int sz = mono_array_element_size (mono_object_class (arr));
592 memset (mono_array_addr_with_size (arr, sz, idx), 0, length * sz);
596 ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* dest, int dest_idx, int length)
601 MonoClass *src_class;
602 MonoClass *dest_class;
607 if (source->obj.vtable->klass->rank != dest->obj.vtable->klass->rank)
610 if (source->bounds || dest->bounds)
613 if ((dest_idx + length > mono_array_length (dest)) ||
614 (source_idx + length > mono_array_length (source)))
617 src_class = source->obj.vtable->klass->element_class;
618 dest_class = dest->obj.vtable->klass->element_class;
621 * Handle common cases.
624 /* Case1: object[] -> valuetype[] (ArrayList::ToArray) */
625 if (src_class == mono_defaults.object_class && dest_class->valuetype) {
626 int has_refs = dest_class->has_references;
627 for (i = source_idx; i < source_idx + length; ++i) {
628 MonoObject *elem = mono_array_get (source, MonoObject*, i);
629 if (elem && !mono_object_isinst (elem, dest_class))
633 element_size = mono_array_element_size (dest->obj.vtable->klass);
634 memset (mono_array_addr_with_size (dest, element_size, dest_idx), 0, element_size * length);
635 for (i = 0; i < length; ++i) {
636 MonoObject *elem = mono_array_get (source, MonoObject*, source_idx + i);
637 void *addr = mono_array_addr_with_size (dest, element_size, dest_idx + i);
641 mono_value_copy (addr, (char *)elem + sizeof (MonoObject), dest_class);
643 memcpy (addr, (char *)elem + sizeof (MonoObject), element_size);
648 /* Check if we're copying a char[] <==> (u)short[] */
649 if (src_class != dest_class) {
650 if (dest_class->valuetype || dest_class->enumtype || src_class->valuetype || src_class->enumtype)
653 if (mono_class_is_subclass_of (src_class, dest_class, FALSE))
655 /* Case2: object[] -> reftype[] (ArrayList::ToArray) */
656 else if (mono_class_is_subclass_of (dest_class, src_class, FALSE))
657 for (i = source_idx; i < source_idx + length; ++i) {
658 MonoObject *elem = mono_array_get (source, MonoObject*, i);
659 if (elem && !mono_object_isinst (elem, dest_class))
666 if (dest_class->valuetype) {
667 element_size = mono_array_element_size (source->obj.vtable->klass);
668 source_addr = mono_array_addr_with_size (source, element_size, source_idx);
669 if (dest_class->has_references) {
670 mono_value_copy_array (dest, dest_idx, source_addr, length);
672 dest_addr = mono_array_addr_with_size (dest, element_size, dest_idx);
673 memmove (dest_addr, source_addr, element_size * length);
676 mono_array_memcpy_refs (dest, dest_idx, source, source_idx, length);
683 ves_icall_System_Array_GetGenericValueImpl (MonoObject *this, guint32 pos, gpointer value)
692 ao = (MonoArray *)this;
693 ac = (MonoClass *)ao->obj.vtable->klass;
695 esize = mono_array_element_size (ac);
696 ea = (gpointer*)((char*)ao->vector + (pos * esize));
698 memcpy (value, ea, esize);
702 ves_icall_System_Array_SetGenericValueImpl (MonoObject *this, guint32 pos, gpointer value)
711 ao = (MonoArray *)this;
712 ac = (MonoClass *)ao->obj.vtable->klass;
714 esize = mono_array_element_size (ac);
715 ea = (gpointer*)((char*)ao->vector + (pos * esize));
717 memcpy (ea, value, esize);
721 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoArray *array, MonoClassField *field_handle)
723 MonoClass *klass = array->obj.vtable->klass;
724 guint32 size = mono_array_element_size (klass);
725 MonoType *type = mono_type_get_underlying_type (&klass->element_class->byval_arg);
728 if (MONO_TYPE_IS_REFERENCE (type) ||
729 (type->type == MONO_TYPE_VALUETYPE &&
730 (!mono_type_get_class (type) ||
731 mono_type_get_class (type)->has_references))) {
732 MonoException *exc = mono_get_exception_argument("array",
733 "Cannot initialize array containing references");
734 mono_raise_exception (exc);
737 if (!(field_handle->type->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA)) {
738 MonoException *exc = mono_get_exception_argument("field_handle",
739 "Field doesn't have an RVA");
740 mono_raise_exception (exc);
743 size *= array->max_length;
745 if (size > mono_type_size (field_handle->type, &align)) {
746 MonoException *exc = mono_get_exception_argument("field_handle",
747 "Field not large enough to fill array");
748 mono_raise_exception (exc);
751 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
753 guint ## n *data = (guint ## n *) mono_array_addr (array, char, 0); \
754 guint ## n *src = (guint ## n *) field_handle->data; \
755 guint ## n *end = (guint ## n *)((char*)src + size); \
757 for (; src < end; data++, src++) { \
758 *data = read ## n (src); \
762 /* printf ("Initialize array with elements of %s type\n", klass->element_class->name); */
764 switch (type->type) {
781 memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
785 memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
787 if (klass->element_class->byval_arg.type == MONO_TYPE_R8) {
790 double *data = (double*)mono_array_addr (array, double, 0);
792 for (i = 0; i < size; i++, data++) {
802 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData (void)
806 return offsetof (MonoString, chars);
810 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue (MonoObject *obj)
814 if ((obj == NULL) || (! (obj->vtable->klass->valuetype)))
817 return mono_object_clone (obj);
821 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (MonoType *handle)
827 MONO_CHECK_ARG_NULL (handle);
829 klass = mono_class_from_mono_type (handle);
830 MONO_CHECK_ARG (handle, klass);
832 /* This will call the type constructor */
833 mono_runtime_class_init (mono_class_vtable (mono_domain_get (), klass));
837 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunModuleConstructor (MonoImage *image)
841 mono_image_check_for_module_cctor (image);
842 if (image->has_module_cctor) {
843 MonoClass *module_klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | 1);
844 mono_runtime_class_init (mono_class_vtable (mono_domain_get (), module_klass));
849 ves_icall_System_Object_MemberwiseClone (MonoObject *this)
853 return mono_object_clone (this);
857 ves_icall_System_ValueType_InternalGetHashCode (MonoObject *this, MonoArray **fields)
860 MonoObject **values = NULL;
864 MonoClassField* field;
869 klass = mono_object_class (this);
871 if (mono_class_num_fields (klass) == 0)
872 return mono_object_hash (this);
875 * Compute the starting value of the hashcode for fields of primitive
876 * types, and return the remaining fields in an array to the managed side.
877 * This way, we can avoid costly reflection operations in managed code.
880 while ((field = mono_class_get_fields (klass, &iter))) {
881 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
883 if (mono_field_is_deleted (field))
885 /* FIXME: Add more types */
886 switch (field->type->type) {
888 result ^= *(gint32*)((guint8*)this + field->offset);
890 case MONO_TYPE_STRING: {
892 s = *(MonoString**)((guint8*)this + field->offset);
894 result ^= mono_string_hash (s);
899 values = g_newa (MonoObject*, mono_class_num_fields (klass));
900 o = mono_field_get_value_object (mono_object_domain (this), field, this);
901 values [count++] = o;
907 *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
908 for (i = 0; i < count; ++i)
909 mono_array_setref (*fields, i, values [i]);
917 ves_icall_System_ValueType_Equals (MonoObject *this, MonoObject *that, MonoArray **fields)
920 MonoObject **values = NULL;
922 MonoClassField* field;
928 MONO_CHECK_ARG_NULL (that);
930 if (this->vtable != that->vtable)
933 klass = mono_object_class (this);
936 * Do the comparison for fields of primitive type and return a result if
937 * possible. Otherwise, return the remaining fields in an array to the
938 * managed side. This way, we can avoid costly reflection operations in
943 while ((field = mono_class_get_fields (klass, &iter))) {
944 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
946 if (mono_field_is_deleted (field))
948 /* FIXME: Add more types */
949 switch (field->type->type) {
951 if (*(gint32*)((guint8*)this + field->offset) != *(gint32*)((guint8*)that + field->offset))
954 case MONO_TYPE_STRING: {
956 guint32 s1len, s2len;
957 s1 = *(MonoString**)((guint8*)this + field->offset);
958 s2 = *(MonoString**)((guint8*)that + field->offset);
961 if ((s1 == NULL) || (s2 == NULL))
963 s1len = mono_string_length (s1);
964 s2len = mono_string_length (s2);
968 if (memcmp (mono_string_chars (s1), mono_string_chars (s2), s1len * sizeof (gunichar2)) != 0)
974 values = g_newa (MonoObject*, mono_class_num_fields (klass) * 2);
975 o = mono_field_get_value_object (mono_object_domain (this), field, this);
976 values [count++] = o;
977 o = mono_field_get_value_object (mono_object_domain (this), field, that);
978 values [count++] = o;
984 *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
985 for (i = 0; i < count; ++i)
986 mono_array_setref (*fields, i, values [i]);
993 static MonoReflectionType *
994 ves_icall_System_Object_GetType (MonoObject *obj)
998 if (obj->vtable->klass != mono_defaults.transparent_proxy_class)
999 return mono_type_get_object (mono_object_domain (obj), &obj->vtable->klass->byval_arg);
1001 return mono_type_get_object (mono_object_domain (obj), &((MonoTransparentProxy*)obj)->remote_class->proxy_class->byval_arg);
1005 mono_type_type_from_obj (MonoReflectionType *mtype, MonoObject *obj)
1007 MONO_ARCH_SAVE_REGS;
1009 mtype->type = &obj->vtable->klass->byval_arg;
1010 g_assert (mtype->type->type);
1014 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj)
1016 MONO_ARCH_SAVE_REGS;
1018 MONO_CHECK_ARG_NULL (obj);
1020 return mono_image_create_token (mb->dynamic_image, obj, TRUE);
1024 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder *mb,
1025 MonoReflectionMethod *method,
1026 MonoArray *opt_param_types)
1028 MONO_ARCH_SAVE_REGS;
1030 MONO_CHECK_ARG_NULL (method);
1032 return mono_image_create_method_token (
1033 mb->dynamic_image, (MonoObject *) method, opt_param_types);
1037 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder *mb, HANDLE file)
1039 MONO_ARCH_SAVE_REGS;
1041 mono_image_create_pefile (mb, file);
1045 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
1047 MONO_ARCH_SAVE_REGS;
1049 mono_image_build_metadata (mb);
1053 get_caller (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1055 MonoMethod **dest = data;
1057 /* skip unmanaged frames */
1072 static MonoReflectionType *
1073 type_from_name (const char *str, MonoBoolean ignoreCase)
1075 MonoType *type = NULL;
1076 MonoAssembly *assembly = NULL;
1077 MonoTypeNameParse info;
1078 char *temp_str = g_strdup (str);
1079 gboolean type_resolve = FALSE;
1081 MONO_ARCH_SAVE_REGS;
1083 /* mono_reflection_parse_type() mangles the string */
1084 if (!mono_reflection_parse_type (temp_str, &info)) {
1085 mono_reflection_free_type_info (&info);
1090 if (info.assembly.name) {
1091 assembly = mono_assembly_load (&info.assembly, NULL, NULL);
1093 MonoMethod *m = mono_method_get_last_managed ();
1094 MonoMethod *dest = m;
1096 mono_stack_walk_no_il (get_caller, &dest);
1101 * FIXME: mono_method_get_last_managed() sometimes returns NULL, thus
1102 * causing ves_icall_System_Reflection_Assembly_GetCallingAssembly()
1103 * to crash. This only seems to happen in some strange remoting
1104 * scenarios and I was unable to figure out what's happening there.
1105 * Dec 10, 2005 - Martin.
1109 assembly = dest->klass->image->assembly;
1111 g_warning (G_STRLOC);
1116 type = mono_reflection_get_type (assembly->image, &info, ignoreCase, &type_resolve);
1118 if (!info.assembly.name && !type) /* try mscorlib */
1119 type = mono_reflection_get_type (NULL, &info, ignoreCase, &type_resolve);
1121 mono_reflection_free_type_info (&info);
1127 return mono_type_get_object (mono_domain_get (), type);
1131 MonoReflectionType *
1132 mono_type_get (const char *str)
1134 char *copy = g_strdup (str);
1135 MonoReflectionType *type = type_from_name (copy, FALSE);
1142 static MonoReflectionType*
1143 ves_icall_type_from_name (MonoString *name,
1144 MonoBoolean throwOnError,
1145 MonoBoolean ignoreCase)
1147 char *str = mono_string_to_utf8 (name);
1148 MonoReflectionType *type;
1150 type = type_from_name (str, ignoreCase);
1153 MonoException *e = NULL;
1156 e = mono_get_exception_type_load (name, NULL);
1158 mono_loader_clear_error ();
1160 mono_raise_exception (e);
1167 static MonoReflectionType*
1168 ves_icall_type_from_handle (MonoType *handle)
1170 MonoDomain *domain = mono_domain_get ();
1171 MonoClass *klass = mono_class_from_mono_type (handle);
1173 MONO_ARCH_SAVE_REGS;
1175 mono_class_init (klass);
1176 return mono_type_get_object (domain, handle);
1180 ves_icall_System_Type_EqualsInternal (MonoReflectionType *type, MonoReflectionType *c)
1182 MONO_ARCH_SAVE_REGS;
1184 if (c && type->type && c->type)
1185 return mono_metadata_type_equal (type->type, c->type);
1190 /* System.TypeCode */
1209 TYPECODE_STRING = 18
1213 ves_icall_type_GetTypeCodeInternal (MonoReflectionType *type)
1215 int t = type->type->type;
1217 MONO_ARCH_SAVE_REGS;
1219 if (type->type->byref)
1220 return TYPECODE_OBJECT;
1224 case MONO_TYPE_VOID:
1225 return TYPECODE_OBJECT;
1226 case MONO_TYPE_BOOLEAN:
1227 return TYPECODE_BOOLEAN;
1229 return TYPECODE_BYTE;
1231 return TYPECODE_SBYTE;
1233 return TYPECODE_UINT16;
1235 return TYPECODE_INT16;
1236 case MONO_TYPE_CHAR:
1237 return TYPECODE_CHAR;
1241 return TYPECODE_OBJECT;
1243 return TYPECODE_UINT32;
1245 return TYPECODE_INT32;
1247 return TYPECODE_UINT64;
1249 return TYPECODE_INT64;
1251 return TYPECODE_SINGLE;
1253 return TYPECODE_DOUBLE;
1254 case MONO_TYPE_VALUETYPE:
1255 if (type->type->data.klass->enumtype) {
1256 t = type->type->data.klass->enum_basetype->type;
1259 MonoClass *k = type->type->data.klass;
1260 if (strcmp (k->name_space, "System") == 0) {
1261 if (strcmp (k->name, "Decimal") == 0)
1262 return TYPECODE_DECIMAL;
1263 else if (strcmp (k->name, "DateTime") == 0)
1264 return TYPECODE_DATETIME;
1267 return TYPECODE_OBJECT;
1268 case MONO_TYPE_STRING:
1269 return TYPECODE_STRING;
1270 case MONO_TYPE_SZARRAY:
1271 case MONO_TYPE_ARRAY:
1272 case MONO_TYPE_OBJECT:
1274 case MONO_TYPE_MVAR:
1275 case MONO_TYPE_TYPEDBYREF:
1276 return TYPECODE_OBJECT;
1277 case MONO_TYPE_CLASS:
1279 MonoClass *k = type->type->data.klass;
1280 if (strcmp (k->name_space, "System") == 0) {
1281 if (strcmp (k->name, "DBNull") == 0)
1282 return TYPECODE_DBNULL;
1285 return TYPECODE_OBJECT;
1286 case MONO_TYPE_GENERICINST:
1287 return TYPECODE_OBJECT;
1289 g_error ("type 0x%02x not handled in GetTypeCode()", t);
1295 ves_icall_type_is_subtype_of (MonoReflectionType *type, MonoReflectionType *c, MonoBoolean check_interfaces)
1301 MONO_ARCH_SAVE_REGS;
1303 g_assert (type != NULL);
1305 domain = ((MonoObject *)type)->vtable->domain;
1307 if (!c) /* FIXME: dont know what do do here */
1310 klass = mono_class_from_mono_type (type->type);
1311 klassc = mono_class_from_mono_type (c->type);
1313 if (type->type->byref)
1314 return klassc == mono_defaults.object_class;
1316 return mono_class_is_subclass_of (klass, klassc, check_interfaces);
1320 ves_icall_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType *c)
1326 MONO_ARCH_SAVE_REGS;
1328 g_assert (type != NULL);
1330 domain = ((MonoObject *)type)->vtable->domain;
1332 klass = mono_class_from_mono_type (type->type);
1333 klassc = mono_class_from_mono_type (c->type);
1335 if (type->type->byref && !c->type->byref)
1338 return mono_class_is_assignable_from (klass, klassc);
1342 ves_icall_type_IsInstanceOfType (MonoReflectionType *type, MonoObject *obj)
1344 MonoClass *klass = mono_class_from_mono_type (type->type);
1345 return mono_object_isinst (obj, klass) != NULL;
1349 ves_icall_get_attributes (MonoReflectionType *type)
1351 MonoClass *klass = mono_class_from_mono_type (type->type);
1353 MONO_ARCH_SAVE_REGS;
1355 return klass->flags;
1358 static MonoReflectionMarshal*
1359 ves_icall_System_Reflection_FieldInfo_GetUnmanagedMarshal (MonoReflectionField *field)
1361 MonoClass *klass = field->field->parent;
1362 MonoMarshalType *info;
1365 if (klass->generic_container ||
1366 (klass->generic_class && klass->generic_class->context.class_inst->is_open))
1369 info = mono_marshal_load_type_info (klass);
1371 for (i = 0; i < info->num_fields; ++i) {
1372 if (info->fields [i].field == field->field) {
1373 if (!info->fields [i].mspec)
1376 return mono_reflection_marshal_from_marshal_spec (field->object.vtable->domain, klass, info->fields [i].mspec);
1383 static MonoReflectionField*
1384 ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoClass *klass)
1389 klass = handle->parent;
1391 /* FIXME: check that handle is a field of klass or of a parent: return null
1392 * and throw the exception in managed code.
1394 return mono_field_get_object (mono_domain_get (), klass, handle);
1397 static MonoReflectionField*
1398 ves_icall_System_Reflection_FieldInfo_internal_from_handle (MonoClassField *handle)
1400 MONO_ARCH_SAVE_REGS;
1404 return mono_field_get_object (mono_domain_get (), handle->parent, handle);
1408 ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionField *field, MonoBoolean optional)
1410 MonoType *type = field->field->type;
1412 return type_array_from_modifiers (field->field->parent->image, type, optional);
1416 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
1418 MonoDomain *domain = mono_domain_get ();
1419 MonoMethodSignature* sig;
1420 MONO_ARCH_SAVE_REGS;
1422 sig = mono_method_signature (method);
1424 g_assert (mono_loader_get_last_error ());
1425 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
1428 info->parent = mono_type_get_object (domain, &method->klass->byval_arg);
1429 info->ret = mono_type_get_object (domain, sig->ret);
1430 info->attrs = method->flags;
1431 info->implattrs = method->iflags;
1432 if (sig->call_convention == MONO_CALL_DEFAULT)
1435 if (sig->call_convention == MONO_CALL_VARARG)
1440 info->callconv |= (sig->hasthis << 5) | (sig->explicit_this << 6);
1444 ves_icall_get_parameter_info (MonoMethod *method)
1446 MonoDomain *domain = mono_domain_get ();
1448 return mono_param_get_objects (domain, method);
1451 static MonoReflectionMarshal*
1452 ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod *method)
1454 MonoDomain *domain = mono_domain_get ();
1455 MonoReflectionMarshal* res = NULL;
1456 MonoMarshalSpec **mspecs;
1459 mspecs = g_new (MonoMarshalSpec*, mono_method_signature (method)->param_count + 1);
1460 mono_method_get_marshal_info (method, mspecs);
1463 res = mono_reflection_marshal_from_marshal_spec (domain, method->klass, mspecs [0]);
1465 for (i = mono_method_signature (method)->param_count; i >= 0; i--)
1467 mono_metadata_free_marshal_spec (mspecs [i]);
1474 ves_icall_MonoField_GetFieldOffset (MonoReflectionField *field)
1476 return field->field->offset - sizeof (MonoObject);
1479 static MonoReflectionType*
1480 ves_icall_MonoField_GetParentType (MonoReflectionField *field, MonoBoolean declaring)
1483 MONO_ARCH_SAVE_REGS;
1485 parent = declaring? field->field->parent: field->klass;
1487 return mono_type_get_object (mono_object_domain (field), &parent->byval_arg);
1491 ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj)
1494 MonoClassField *cf = field->field;
1498 MonoDomain *domain = mono_object_domain (field);
1500 gboolean is_static = FALSE;
1501 gboolean is_ref = FALSE;
1503 MONO_ARCH_SAVE_REGS;
1505 if (field->klass->image->assembly->ref_only)
1506 mono_raise_exception (mono_get_exception_invalid_operation (
1507 "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
1509 mono_class_init (field->klass);
1511 if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC)
1514 if (obj && !is_static) {
1515 /* Check that the field belongs to the object */
1516 gboolean found = FALSE;
1519 for (k = obj->vtable->klass; k; k = k->parent) {
1520 if (k == cf->parent) {
1527 char *msg = g_strdup_printf ("Field '%s' defined on type '%s' is not a field on the target object which is of type '%s'.", cf->name, cf->parent->name, obj->vtable->klass->name);
1528 MonoException *ex = mono_get_exception_argument (NULL, msg);
1530 mono_raise_exception (ex);
1534 t = mono_type_get_underlying_type (cf->type);
1536 case MONO_TYPE_STRING:
1537 case MONO_TYPE_OBJECT:
1538 case MONO_TYPE_CLASS:
1539 case MONO_TYPE_ARRAY:
1540 case MONO_TYPE_SZARRAY:
1545 case MONO_TYPE_BOOLEAN:
1548 case MONO_TYPE_CHAR:
1557 case MONO_TYPE_VALUETYPE:
1560 case MONO_TYPE_GENERICINST:
1561 if (mono_type_generic_inst_is_valuetype (t)) {
1568 g_error ("type 0x%x not handled in "
1569 "ves_icall_Monofield_GetValue", t->type);
1575 vtable = mono_class_vtable (domain, cf->parent);
1576 if (!vtable->initialized && !(cf->type->attrs & FIELD_ATTRIBUTE_LITERAL))
1577 mono_runtime_class_init (vtable);
1582 mono_field_static_get_value (vtable, cf, &o);
1584 mono_field_get_value (obj, cf, &o);
1589 if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) {
1590 MonoClass *nklass = mono_class_from_mono_type (cf->type);
1593 /* Convert the Nullable structure into a boxed vtype */
1595 buf = (guint8*)vtable->data + cf->offset;
1597 buf = (guint8*)obj + cf->offset;
1599 return mono_nullable_box (buf, nklass);
1602 /* boxed value type */
1603 klass = mono_class_from_mono_type (cf->type);
1604 o = mono_object_new (domain, klass);
1605 v = ((gchar *) o) + sizeof (MonoObject);
1607 mono_field_static_get_value (vtable, cf, v);
1609 mono_field_get_value (obj, cf, v);
1616 ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value)
1618 MonoClassField *cf = field->field;
1621 MONO_ARCH_SAVE_REGS;
1623 if (field->klass->image->assembly->ref_only)
1624 mono_raise_exception (mono_get_exception_invalid_operation (
1625 "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
1627 v = (gchar *) value;
1628 if (!cf->type->byref) {
1629 switch (cf->type->type) {
1632 case MONO_TYPE_BOOLEAN:
1635 case MONO_TYPE_CHAR:
1644 case MONO_TYPE_VALUETYPE:
1646 v += sizeof (MonoObject);
1648 case MONO_TYPE_STRING:
1649 case MONO_TYPE_OBJECT:
1650 case MONO_TYPE_CLASS:
1651 case MONO_TYPE_ARRAY:
1652 case MONO_TYPE_SZARRAY:
1655 case MONO_TYPE_GENERICINST: {
1656 MonoGenericClass *gclass = cf->type->data.generic_class;
1657 g_assert (!gclass->context.class_inst->is_open);
1659 if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) {
1660 MonoClass *nklass = mono_class_from_mono_type (cf->type);
1661 MonoObject *nullable;
1664 * Convert the boxed vtype into a Nullable structure.
1665 * This is complicated by the fact that Nullables have
1666 * a variable structure.
1668 nullable = mono_object_new (mono_domain_get (), nklass);
1670 mono_nullable_init (mono_object_unbox (nullable), value, nklass);
1672 v = mono_object_unbox (nullable);
1675 if (gclass->container_class->valuetype && (v != NULL))
1676 v += sizeof (MonoObject);
1680 g_error ("type 0x%x not handled in "
1681 "ves_icall_FieldInfo_SetValueInternal", cf->type->type);
1686 if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) {
1687 MonoVTable *vtable = mono_class_vtable (mono_object_domain (field), cf->parent);
1688 if (!vtable->initialized)
1689 mono_runtime_class_init (vtable);
1690 mono_field_static_set_value (vtable, cf, v);
1692 mono_field_set_value (obj, cf, v);
1697 ves_icall_MonoField_GetRawConstantValue (MonoReflectionField *this)
1699 MonoObject *o = NULL;
1700 MonoClassField *field = this->field;
1702 MonoDomain *domain = mono_object_domain (this);
1704 MonoTypeEnum def_type;
1705 const char *def_value;
1707 MONO_ARCH_SAVE_REGS;
1709 mono_class_init (field->parent);
1711 if (!(field->type->attrs & FIELD_ATTRIBUTE_HAS_DEFAULT))
1712 mono_raise_exception (mono_get_exception_invalid_operation (NULL));
1714 if (field->parent->image->dynamic) {
1716 g_assert_not_reached ();
1719 def_value = mono_class_get_field_default_value (field, &def_type);
1724 case MONO_TYPE_BOOLEAN:
1727 case MONO_TYPE_CHAR:
1735 case MONO_TYPE_R8: {
1738 /* boxed value type */
1739 t = g_new0 (MonoType, 1);
1741 klass = mono_class_from_mono_type (t);
1743 o = mono_object_new (domain, klass);
1744 v = ((gchar *) o) + sizeof (MonoObject);
1745 mono_get_constant_value_from_blob (domain, def_type, def_value, v);
1748 case MONO_TYPE_STRING:
1749 case MONO_TYPE_CLASS:
1750 mono_get_constant_value_from_blob (domain, def_type, def_value, &o);
1753 g_assert_not_reached ();
1759 static MonoReflectionType*
1760 ves_icall_MonoGenericMethod_get_ReflectedType (MonoReflectionGenericMethod *rmethod)
1762 MonoMethod *method = rmethod->method.method;
1764 return mono_type_get_object (mono_object_domain (rmethod), &method->klass->byval_arg);
1767 /* From MonoProperty.cs */
1769 PInfo_Attributes = 1,
1770 PInfo_GetMethod = 1 << 1,
1771 PInfo_SetMethod = 1 << 2,
1772 PInfo_ReflectedType = 1 << 3,
1773 PInfo_DeclaringType = 1 << 4,
1778 ves_icall_get_property_info (MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
1780 MonoDomain *domain = mono_object_domain (property);
1782 MONO_ARCH_SAVE_REGS;
1784 if ((req_info & PInfo_ReflectedType) != 0)
1785 MONO_STRUCT_SETREF (info, parent, mono_type_get_object (domain, &property->klass->byval_arg));
1786 else if ((req_info & PInfo_DeclaringType) != 0)
1787 MONO_STRUCT_SETREF (info, parent, mono_type_get_object (domain, &property->property->parent->byval_arg));
1789 if ((req_info & PInfo_Name) != 0)
1790 MONO_STRUCT_SETREF (info, name, mono_string_new (domain, property->property->name));
1792 if ((req_info & PInfo_Attributes) != 0)
1793 info->attrs = property->property->attrs;
1795 if ((req_info & PInfo_GetMethod) != 0)
1796 MONO_STRUCT_SETREF (info, get, property->property->get ?
1797 mono_method_get_object (domain, property->property->get, property->klass): NULL);
1799 if ((req_info & PInfo_SetMethod) != 0)
1800 MONO_STRUCT_SETREF (info, set, property->property->set ?
1801 mono_method_get_object (domain, property->property->set, property->klass): NULL);
1803 * There may be other methods defined for properties, though, it seems they are not exposed
1804 * in the reflection API
1809 ves_icall_get_event_info (MonoReflectionEvent *event, MonoEventInfo *info)
1811 MonoDomain *domain = mono_object_domain (event);
1813 MONO_ARCH_SAVE_REGS;
1815 info->reflected_type = mono_type_get_object (domain, &event->klass->byval_arg);
1816 info->declaring_type = mono_type_get_object (domain, &event->event->parent->byval_arg);
1818 info->name = mono_string_new (domain, event->event->name);
1819 info->attrs = event->event->attrs;
1820 info->add_method = event->event->add ? mono_method_get_object (domain, event->event->add, NULL): NULL;
1821 info->remove_method = event->event->remove ? mono_method_get_object (domain, event->event->remove, NULL): NULL;
1822 info->raise_method = event->event->raise ? mono_method_get_object (domain, event->event->raise, NULL): NULL;
1824 if (event->event->other) {
1826 while (event->event->other [n])
1828 info->other_methods = mono_array_new (domain, mono_defaults.method_info_class, n);
1830 for (i = 0; i < n; i++)
1831 mono_array_setref (info->other_methods, i, mono_method_get_object (domain, event->event->other [i], NULL));
1836 ves_icall_Type_GetInterfaces (MonoReflectionType* type)
1838 MonoDomain *domain = mono_object_domain (type);
1840 GPtrArray *ifaces = NULL;
1842 MonoClass *class = mono_class_from_mono_type (type->type);
1845 MonoGenericContext *context = NULL;
1847 MONO_ARCH_SAVE_REGS;
1849 if (class->generic_class && class->generic_class->context.class_inst->is_open) {
1850 context = mono_class_get_context (class);
1851 class = class->generic_class->container_class;
1854 mono_class_setup_vtable (class);
1856 slots = mono_bitset_new (class->max_interface_id + 1, 0);
1858 for (parent = class; parent; parent = parent->parent) {
1859 GPtrArray *tmp_ifaces = mono_class_get_implemented_interfaces (parent);
1861 for (i = 0; i < tmp_ifaces->len; ++i) {
1862 MonoClass *ic = g_ptr_array_index (tmp_ifaces, i);
1864 if (mono_bitset_test (slots, ic->interface_id))
1867 mono_bitset_set (slots, ic->interface_id);
1869 ifaces = g_ptr_array_new ();
1870 g_ptr_array_add (ifaces, ic);
1872 g_ptr_array_free (tmp_ifaces, TRUE);
1875 mono_bitset_free (slots);
1878 return mono_array_new (domain, mono_defaults.monotype_class, 0);
1880 intf = mono_array_new (domain, mono_defaults.monotype_class, ifaces->len);
1881 for (i = 0; i < ifaces->len; ++i) {
1882 MonoClass *ic = g_ptr_array_index (ifaces, i);
1883 MonoType *ret = &ic->byval_arg;
1884 if (context && ic->generic_class && ic->generic_class->context.class_inst->is_open)
1885 ret = mono_class_inflate_generic_type (ret, context);
1887 mono_array_setref (intf, i, mono_type_get_object (domain, ret));
1889 g_ptr_array_free (ifaces, TRUE);
1895 ves_icall_Type_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType *iface, MonoArray **targets, MonoArray **methods)
1897 MonoClass *class = mono_class_from_mono_type (type->type);
1898 MonoClass *iclass = mono_class_from_mono_type (iface->type);
1899 MonoReflectionMethod *member;
1902 int i = 0, len, ioffset;
1905 MONO_ARCH_SAVE_REGS;
1907 mono_class_setup_vtable (class);
1909 /* type doesn't implement iface: the exception is thrown in managed code */
1910 if (! MONO_CLASS_IMPLEMENTS_INTERFACE (class, iclass->interface_id))
1913 len = mono_class_num_methods (iclass);
1914 ioffset = mono_class_interface_offset (class, iclass);
1915 domain = mono_object_domain (type);
1916 *targets = mono_array_new (domain, mono_defaults.method_info_class, len);
1917 *methods = mono_array_new (domain, mono_defaults.method_info_class, len);
1920 while ((method = mono_class_get_methods (iclass, &iter))) {
1921 member = mono_method_get_object (domain, method, iclass);
1922 mono_array_setref (*methods, i, member);
1923 member = mono_method_get_object (domain, class->vtable [i + ioffset], class);
1924 mono_array_setref (*targets, i, member);
1931 ves_icall_Type_GetPacking (MonoReflectionType *type, guint32 *packing, guint32 *size)
1933 MonoClass *klass = mono_class_from_mono_type (type->type);
1935 g_assert (!klass->image->dynamic);
1937 mono_metadata_packing_from_typedef (klass->image, klass->type_token, packing, size);
1940 static MonoReflectionType*
1941 ves_icall_MonoType_GetElementType (MonoReflectionType *type)
1943 MonoClass *class = mono_class_from_mono_type (type->type);
1945 MONO_ARCH_SAVE_REGS;
1947 // GetElementType should only return a type for:
1948 // Array Pointer PassedByRef
1949 if (type->type->byref)
1950 return mono_type_get_object (mono_object_domain (type), &class->byval_arg);
1951 else if (class->element_class && MONO_CLASS_IS_ARRAY (class))
1952 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
1953 else if (class->element_class && type->type->type == MONO_TYPE_PTR)
1954 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
1959 static MonoReflectionType*
1960 ves_icall_get_type_parent (MonoReflectionType *type)
1962 MonoClass *class = mono_class_from_mono_type (type->type);
1964 MONO_ARCH_SAVE_REGS;
1966 return class->parent ? mono_type_get_object (mono_object_domain (type), &class->parent->byval_arg): NULL;
1970 ves_icall_type_ispointer (MonoReflectionType *type)
1972 MONO_ARCH_SAVE_REGS;
1974 return type->type->type == MONO_TYPE_PTR;
1978 ves_icall_type_isprimitive (MonoReflectionType *type)
1980 MONO_ARCH_SAVE_REGS;
1982 return (!type->type->byref && (((type->type->type >= MONO_TYPE_BOOLEAN) && (type->type->type <= MONO_TYPE_R8)) || (type->type->type == MONO_TYPE_I) || (type->type->type == MONO_TYPE_U)));
1986 ves_icall_type_isbyref (MonoReflectionType *type)
1988 MONO_ARCH_SAVE_REGS;
1990 return type->type->byref;
1994 ves_icall_type_iscomobject (MonoReflectionType *type)
1996 MonoClass *klass = mono_class_from_mono_type (type->type);
1997 MONO_ARCH_SAVE_REGS;
1999 return (klass && klass->is_com_object);
2002 static MonoReflectionModule*
2003 ves_icall_MonoType_get_Module (MonoReflectionType *type)
2005 MonoClass *class = mono_class_from_mono_type (type->type);
2007 MONO_ARCH_SAVE_REGS;
2009 return mono_module_get_object (mono_object_domain (type), class->image);
2012 static MonoReflectionAssembly*
2013 ves_icall_MonoType_get_Assembly (MonoReflectionType *type)
2015 MonoDomain *domain = mono_domain_get ();
2016 MonoClass *class = mono_class_from_mono_type (type->type);
2018 MONO_ARCH_SAVE_REGS;
2020 return mono_assembly_get_object (domain, class->image->assembly);
2023 static MonoReflectionType*
2024 ves_icall_MonoType_get_DeclaringType (MonoReflectionType *type)
2026 MonoDomain *domain = mono_domain_get ();
2029 MONO_ARCH_SAVE_REGS;
2031 if (type->type->byref)
2033 if (type->type->type == MONO_TYPE_VAR)
2034 class = type->type->data.generic_param->owner->owner.klass;
2035 else if (type->type->type == MONO_TYPE_MVAR)
2036 class = type->type->data.generic_param->owner->owner.method->klass;
2038 class = mono_class_from_mono_type (type->type)->nested_in;
2040 return class ? mono_type_get_object (domain, &class->byval_arg) : NULL;
2043 static MonoReflectionType*
2044 ves_icall_MonoType_get_UnderlyingSystemType (MonoReflectionType *type)
2046 MonoDomain *domain = mono_domain_get ();
2047 MonoClass *class = mono_class_from_mono_type (type->type);
2049 MONO_ARCH_SAVE_REGS;
2051 if (class->enumtype && class->enum_basetype) /* types that are modified typebuilders may not have enum_basetype set */
2052 return mono_type_get_object (domain, class->enum_basetype);
2053 else if (class->element_class)
2054 return mono_type_get_object (domain, &class->element_class->byval_arg);
2060 ves_icall_MonoType_get_Name (MonoReflectionType *type)
2062 MonoDomain *domain = mono_domain_get ();
2063 MonoClass *class = mono_class_from_mono_type (type->type);
2065 MONO_ARCH_SAVE_REGS;
2067 if (type->type->byref) {
2068 char *n = g_strdup_printf ("%s&", class->name);
2069 MonoString *res = mono_string_new (domain, n);
2075 return mono_string_new (domain, class->name);
2080 ves_icall_MonoType_get_Namespace (MonoReflectionType *type)
2082 MonoDomain *domain = mono_domain_get ();
2083 MonoClass *class = mono_class_from_mono_type (type->type);
2085 MONO_ARCH_SAVE_REGS;
2087 while (class->nested_in)
2088 class = class->nested_in;
2090 if (class->name_space [0] == '\0')
2093 return mono_string_new (domain, class->name_space);
2097 ves_icall_MonoType_GetArrayRank (MonoReflectionType *type)
2099 MonoClass *class = mono_class_from_mono_type (type->type);
2101 MONO_ARCH_SAVE_REGS;
2107 ves_icall_MonoType_GetGenericArguments (MonoReflectionType *type)
2110 MonoClass *klass, *pklass;
2112 MONO_ARCH_SAVE_REGS;
2114 klass = mono_class_from_mono_type (type->type);
2116 if (klass->generic_container) {
2117 MonoGenericContainer *container = klass->generic_container;
2118 res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, container->type_argc);
2119 for (i = 0; i < container->type_argc; ++i) {
2120 pklass = mono_class_from_generic_parameter (&container->type_params [i], klass->image, FALSE);
2121 mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), &pklass->byval_arg));
2123 } else if (klass->generic_class) {
2124 MonoGenericInst *inst = klass->generic_class->context.class_inst;
2125 res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, inst->type_argc);
2126 for (i = 0; i < inst->type_argc; ++i)
2127 mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), inst->type_argv [i]));
2129 res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, 0);
2135 ves_icall_Type_get_IsGenericTypeDefinition (MonoReflectionType *type)
2138 MONO_ARCH_SAVE_REGS;
2140 if (type->type->byref)
2143 klass = mono_class_from_mono_type (type->type);
2145 return klass->generic_container != NULL;
2148 static MonoReflectionType*
2149 ves_icall_Type_GetGenericTypeDefinition_impl (MonoReflectionType *type)
2152 MONO_ARCH_SAVE_REGS;
2154 if (type->type->byref)
2157 klass = mono_class_from_mono_type (type->type);
2158 if (klass->generic_container) {
2159 return type; /* check this one */
2161 if (klass->generic_class) {
2162 MonoClass *generic_class = klass->generic_class->container_class;
2164 if (generic_class->wastypebuilder && generic_class->reflection_info)
2165 return generic_class->reflection_info;
2167 return mono_type_get_object (mono_object_domain (type), &generic_class->byval_arg);
2172 static MonoReflectionType*
2173 ves_icall_Type_MakeGenericType (MonoReflectionType *type, MonoArray *type_array)
2175 MonoType *geninst, **types;
2178 MONO_ARCH_SAVE_REGS;
2180 count = mono_array_length (type_array);
2181 types = g_new0 (MonoType *, count);
2183 for (i = 0; i < count; i++) {
2184 MonoReflectionType *t = mono_array_get (type_array, gpointer, i);
2185 types [i] = t->type;
2188 geninst = mono_reflection_bind_generic_parameters (type, count, types);
2193 return mono_type_get_object (mono_object_domain (type), geninst);
2197 ves_icall_Type_get_IsGenericInstance (MonoReflectionType *type)
2200 MONO_ARCH_SAVE_REGS;
2202 if (type->type->byref)
2205 klass = mono_class_from_mono_type (type->type);
2206 return klass->generic_class != NULL;
2210 ves_icall_Type_get_IsGenericType (MonoReflectionType *type)
2213 MONO_ARCH_SAVE_REGS;
2215 if (type->type->byref)
2218 klass = mono_class_from_mono_type (type->type);
2219 return klass->generic_class != NULL || klass->generic_container != NULL;
2223 ves_icall_Type_GetGenericParameterPosition (MonoReflectionType *type)
2225 MONO_ARCH_SAVE_REGS;
2227 if (is_generic_parameter (type->type))
2228 return type->type->data.generic_param->num;
2232 static GenericParameterAttributes
2233 ves_icall_Type_GetGenericParameterAttributes (MonoReflectionType *type)
2235 MONO_ARCH_SAVE_REGS;
2236 g_assert (is_generic_parameter (type->type));
2237 return type->type->data.generic_param->flags;
2241 ves_icall_Type_GetGenericParameterConstraints (MonoReflectionType *type)
2243 MonoGenericParam *param;
2249 MONO_ARCH_SAVE_REGS;
2251 domain = mono_object_domain (type);
2252 param = type->type->data.generic_param;
2253 for (count = 0, ptr = param->constraints; ptr && *ptr; ptr++, count++)
2256 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2257 for (i = 0; i < count; i++)
2258 mono_array_setref (res, i, mono_type_get_object (domain, ¶m->constraints [i]->byval_arg));
2265 ves_icall_MonoType_get_IsGenericParameter (MonoReflectionType *type)
2267 MONO_ARCH_SAVE_REGS;
2268 return is_generic_parameter (type->type);
2272 ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder *tb)
2274 MONO_ARCH_SAVE_REGS;
2275 return is_generic_parameter (tb->type.type);
2279 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
2280 MonoReflectionType *t)
2282 enumtype->type = t->type;
2285 static MonoReflectionType*
2286 ves_icall_MonoGenericClass_GetParentType (MonoReflectionGenericClass *type)
2288 MonoDynamicGenericClass *gclass;
2289 MonoReflectionType *parent = NULL;
2294 MONO_ARCH_SAVE_REGS;
2296 g_assert (type->type.type->data.generic_class->is_dynamic);
2297 gclass = (MonoDynamicGenericClass *) type->type.type->data.generic_class;
2299 domain = mono_object_domain (type);
2300 klass = mono_class_from_mono_type (type->generic_type->type.type);
2302 if (!klass->generic_class && !klass->generic_container)
2305 parent = type->generic_type->parent;
2307 if (!parent || (parent->type->type != MONO_TYPE_GENERICINST))
2310 inflated = mono_class_inflate_generic_type (
2311 parent->type, mono_generic_class_get_context ((MonoGenericClass *) gclass));
2313 return mono_type_get_object (domain, inflated);
2317 ves_icall_MonoGenericClass_GetInterfaces (MonoReflectionGenericClass *type)
2319 static MonoClass *System_Reflection_MonoGenericClass;
2320 MonoGenericClass *gclass;
2321 MonoReflectionTypeBuilder *tb = NULL;
2322 MonoClass *klass = NULL;
2327 MONO_ARCH_SAVE_REGS;
2329 if (!System_Reflection_MonoGenericClass) {
2330 System_Reflection_MonoGenericClass = mono_class_from_name (
2331 mono_defaults.corlib, "System.Reflection", "MonoGenericClass");
2332 g_assert (System_Reflection_MonoGenericClass);
2335 domain = mono_object_domain (type);
2337 gclass = type->type.type->data.generic_class;
2338 g_assert (gclass->is_dynamic);
2340 tb = type->generic_type;
2341 icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
2343 res = mono_array_new (domain, System_Reflection_MonoGenericClass, icount);
2345 for (i = 0; i < icount; i++) {
2346 MonoReflectionType *iface;
2350 iface = mono_array_get (tb->interfaces, MonoReflectionType *, i);
2353 it = &klass->interfaces [i]->byval_arg;
2355 it = mono_class_inflate_generic_type (it, mono_generic_class_get_context (gclass));
2357 iface = mono_type_get_object (domain, it);
2358 mono_array_setref (res, i, iface);
2364 static MonoReflectionMethod*
2365 ves_icall_MonoGenericClass_GetCorrespondingInflatedMethod (MonoReflectionGenericClass *type,
2366 MonoReflectionMethod* generic)
2368 MonoGenericClass *gclass;
2369 MonoDynamicGenericClass *dgclass;
2373 MONO_ARCH_SAVE_REGS;
2375 gclass = type->type.type->data.generic_class;
2376 g_assert (gclass->is_dynamic);
2378 dgclass = (MonoDynamicGenericClass *) gclass;
2380 domain = mono_object_domain (type);
2382 for (i = 0; i < dgclass->count_methods; i++)
2383 if (generic->method->token == dgclass->methods [i]->token)
2384 return mono_method_get_object (domain, dgclass->methods [i], NULL);
2389 static MonoReflectionMethod*
2390 ves_icall_MonoGenericClass_GetCorrespondingInflatedConstructor (MonoReflectionGenericClass *type,
2391 MonoReflectionMethod* generic)
2393 MonoGenericClass *gclass;
2394 MonoDynamicGenericClass *dgclass;
2398 MONO_ARCH_SAVE_REGS;
2400 gclass = type->type.type->data.generic_class;
2401 g_assert (gclass->is_dynamic);
2403 dgclass = (MonoDynamicGenericClass *) gclass;
2405 domain = mono_object_domain (type);
2407 for (i = 0; i < dgclass->count_ctors; i++)
2408 if (generic->method->token == dgclass->ctors [i]->token)
2409 return mono_method_get_object (domain, dgclass->ctors [i], NULL);
2415 static MonoReflectionField*
2416 ves_icall_MonoGenericClass_GetCorrespondingInflatedField (MonoReflectionGenericClass *type,
2417 MonoString* generic_name)
2419 MonoGenericClass *gclass;
2420 MonoDynamicGenericClass *dgclass;
2422 MonoClass *refclass;
2423 char *utf8_name = mono_string_to_utf8 (generic_name);
2426 MONO_ARCH_SAVE_REGS;
2428 gclass = type->type.type->data.generic_class;
2429 g_assert (gclass->is_dynamic);
2431 dgclass = (MonoDynamicGenericClass *) gclass;
2433 refclass = mono_class_from_mono_type (type->type.type);
2435 domain = mono_object_domain (type);
2437 for (i = 0; i < dgclass->count_fields; i++)
2438 if (strcmp (utf8_name, dgclass->fields [i].name) == 0) {
2440 return mono_field_get_object (domain, refclass, &dgclass->fields [i]);
2449 static MonoReflectionMethod*
2450 ves_icall_MonoType_GetCorrespondingInflatedMethod (MonoReflectionType *type,
2451 MonoReflectionMethod* generic)
2458 MONO_ARCH_SAVE_REGS;
2460 domain = ((MonoObject *)type)->vtable->domain;
2462 klass = mono_class_from_mono_type (type->type);
2465 while ((method = mono_class_get_methods (klass, &iter))) {
2466 if (method->token == generic->method->token)
2467 return mono_method_get_object (domain, method, klass);
2474 ves_icall_MonoGenericClass_GetMethods (MonoReflectionGenericClass *type,
2475 MonoReflectionType *reflected_type)
2477 MonoGenericClass *gclass;
2478 MonoDynamicGenericClass *dgclass;
2480 MonoClass *refclass;
2484 MONO_ARCH_SAVE_REGS;
2486 gclass = type->type.type->data.generic_class;
2487 g_assert (gclass->is_dynamic);
2488 dgclass = (MonoDynamicGenericClass *) gclass;
2490 refclass = mono_class_from_mono_type (reflected_type->type);
2492 domain = mono_object_domain (type);
2493 res = mono_array_new (domain, mono_defaults.method_info_class, dgclass->count_methods);
2495 for (i = 0; i < dgclass->count_methods; i++)
2496 mono_array_setref (res, i, mono_method_get_object (domain, dgclass->methods [i], refclass));
2502 ves_icall_MonoGenericClass_GetConstructors (MonoReflectionGenericClass *type,
2503 MonoReflectionType *reflected_type)
2505 static MonoClass *System_Reflection_ConstructorInfo;
2506 MonoGenericClass *gclass;
2507 MonoDynamicGenericClass *dgclass;
2509 MonoClass *refclass;
2513 MONO_ARCH_SAVE_REGS;
2515 if (!System_Reflection_ConstructorInfo)
2516 System_Reflection_ConstructorInfo = mono_class_from_name (
2517 mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
2519 gclass = type->type.type->data.generic_class;
2520 g_assert (gclass->is_dynamic);
2521 dgclass = (MonoDynamicGenericClass *) gclass;
2523 refclass = mono_class_from_mono_type (reflected_type->type);
2525 domain = mono_object_domain (type);
2526 res = mono_array_new (domain, System_Reflection_ConstructorInfo, dgclass->count_ctors);
2528 for (i = 0; i < dgclass->count_ctors; i++)
2529 mono_array_setref (res, i, mono_method_get_object (domain, dgclass->ctors [i], refclass));
2535 ves_icall_MonoGenericClass_GetFields (MonoReflectionGenericClass *type,
2536 MonoReflectionType *reflected_type)
2538 MonoGenericClass *gclass;
2539 MonoDynamicGenericClass *dgclass;
2541 MonoClass *refclass;
2545 MONO_ARCH_SAVE_REGS;
2547 gclass = type->type.type->data.generic_class;
2548 g_assert (gclass->is_dynamic);
2549 dgclass = (MonoDynamicGenericClass *) gclass;
2551 refclass = mono_class_from_mono_type (reflected_type->type);
2553 domain = mono_object_domain (type);
2554 res = mono_array_new (domain, mono_defaults.field_info_class, dgclass->count_fields);
2556 for (i = 0; i < dgclass->count_fields; i++)
2557 mono_array_setref (res, i, mono_field_get_object (domain, refclass, &dgclass->fields [i]));
2563 ves_icall_MonoGenericClass_GetProperties (MonoReflectionGenericClass *type,
2564 MonoReflectionType *reflected_type)
2566 static MonoClass *System_Reflection_PropertyInfo;
2567 MonoGenericClass *gclass;
2568 MonoDynamicGenericClass *dgclass;
2570 MonoClass *refclass;
2574 MONO_ARCH_SAVE_REGS;
2576 if (!System_Reflection_PropertyInfo)
2577 System_Reflection_PropertyInfo = mono_class_from_name (
2578 mono_defaults.corlib, "System.Reflection", "PropertyInfo");
2580 gclass = type->type.type->data.generic_class;
2581 g_assert (gclass->is_dynamic);
2582 dgclass = (MonoDynamicGenericClass *) gclass;
2584 refclass = mono_class_from_mono_type (reflected_type->type);
2586 domain = mono_object_domain (type);
2587 res = mono_array_new (domain, System_Reflection_PropertyInfo, dgclass->count_properties);
2589 for (i = 0; i < dgclass->count_properties; i++)
2590 mono_array_setref (res, i, mono_property_get_object (domain, refclass, &dgclass->properties [i]));
2596 ves_icall_MonoGenericClass_GetEvents (MonoReflectionGenericClass *type,
2597 MonoReflectionType *reflected_type)
2599 static MonoClass *System_Reflection_EventInfo;
2600 MonoGenericClass *gclass;
2601 MonoDynamicGenericClass *dgclass;
2603 MonoClass *refclass;
2607 MONO_ARCH_SAVE_REGS;
2609 if (!System_Reflection_EventInfo)
2610 System_Reflection_EventInfo = mono_class_from_name (
2611 mono_defaults.corlib, "System.Reflection", "EventInfo");
2613 gclass = type->type.type->data.generic_class;
2614 g_assert (gclass->is_dynamic);
2615 dgclass = (MonoDynamicGenericClass *) gclass;
2617 refclass = mono_class_from_mono_type (reflected_type->type);
2619 domain = mono_object_domain (type);
2620 res = mono_array_new (domain, System_Reflection_EventInfo, dgclass->count_events);
2622 for (i = 0; i < dgclass->count_events; i++)
2623 mono_array_setref (res, i, mono_event_get_object (domain, refclass, &dgclass->events [i]));
2628 static MonoReflectionMethod *
2629 ves_icall_MonoType_get_DeclaringMethod (MonoReflectionType *type)
2634 MONO_ARCH_SAVE_REGS;
2636 if (type->type->byref || type->type->type != MONO_TYPE_MVAR)
2639 method = type->type->data.generic_param->owner->owner.method;
2641 klass = mono_class_from_mono_type (type->type);
2642 return mono_method_get_object (mono_object_domain (type), method, klass);
2645 static MonoReflectionDllImportAttribute*
2646 ves_icall_MonoMethod_GetDllImportAttribute (MonoMethod *method)
2648 static MonoClass *DllImportAttributeClass = NULL;
2649 MonoDomain *domain = mono_domain_get ();
2650 MonoReflectionDllImportAttribute *attr;
2651 MonoImage *image = method->klass->image;
2652 MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method;
2653 MonoTableInfo *tables = image->tables;
2654 MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
2655 MonoTableInfo *mr = &tables [MONO_TABLE_MODULEREF];
2656 guint32 im_cols [MONO_IMPLMAP_SIZE];
2657 guint32 scope_token;
2658 const char *import = NULL;
2659 const char *scope = NULL;
2662 if (!method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)
2665 if (!DllImportAttributeClass) {
2666 DllImportAttributeClass =
2667 mono_class_from_name (mono_defaults.corlib,
2668 "System.Runtime.InteropServices", "DllImportAttribute");
2669 g_assert (DllImportAttributeClass);
2672 if (method->klass->image->dynamic) {
2673 MonoReflectionMethodAux *method_aux =
2674 g_hash_table_lookup (
2675 ((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
2677 import = method_aux->dllentry;
2678 scope = method_aux->dll;
2682 if (piinfo->implmap_idx) {
2683 mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
2685 piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
2686 import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
2687 scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
2688 scope = mono_metadata_string_heap (image, scope_token);
2691 flags = piinfo->piflags;
2693 attr = (MonoReflectionDllImportAttribute*)mono_object_new (domain, DllImportAttributeClass);
2695 MONO_OBJECT_SETREF (attr, dll, mono_string_new (domain, scope));
2696 MONO_OBJECT_SETREF (attr, entry_point, mono_string_new (domain, import));
2697 attr->call_conv = (flags & 0x700) >> 8;
2698 attr->charset = ((flags & 0x6) >> 1) + 1;
2699 if (attr->charset == 1)
2701 attr->exact_spelling = (flags & 0x1) != 0;
2702 attr->set_last_error = (flags & 0x40) != 0;
2703 attr->best_fit_mapping = (flags & 0x30) == 0x10;
2704 attr->throw_on_unmappable = (flags & 0x3000) == 0x1000;
2705 attr->preserve_sig = FALSE;
2710 static MonoReflectionMethod *
2711 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
2713 MonoMethodInflated *imethod;
2715 MONO_ARCH_SAVE_REGS;
2717 if (method->method->generic_container)
2720 if (!method->method->is_inflated)
2723 imethod = (MonoMethodInflated *) method->method;
2725 if (imethod->reflection_info)
2726 return imethod->reflection_info;
2728 return mono_method_get_object (
2729 mono_object_domain (method), imethod->declaring, NULL);
2733 ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethod *method)
2735 MONO_ARCH_SAVE_REGS;
2737 return mono_method_signature (method->method)->generic_param_count != 0;
2741 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method)
2743 MONO_ARCH_SAVE_REGS;
2745 return method->method->generic_container != NULL;
2749 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
2754 MONO_ARCH_SAVE_REGS;
2756 domain = mono_object_domain (method);
2758 if (method->method->is_inflated) {
2759 MonoGenericInst *inst = mono_method_get_context (method->method)->method_inst;
2762 count = inst->type_argc;
2763 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2765 for (i = 0; i < count; i++)
2766 mono_array_setref (res, i, mono_type_get_object (domain, inst->type_argv [i]));
2772 count = mono_method_signature (method->method)->generic_param_count;
2773 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2775 for (i = 0; i < count; i++) {
2776 MonoGenericParam *param = &method->method->generic_container->type_params [i];
2777 MonoClass *pklass = mono_class_from_generic_parameter (
2778 param, method->method->klass->image, TRUE);
2779 mono_array_setref (res, i,
2780 mono_type_get_object (domain, &pklass->byval_arg));
2787 ensure_reflection_security (void)
2789 MonoMethod *m = mono_method_get_last_managed ();
2793 g_print ("method %s.%s.%s in image %s\n",
2794 m->klass->name_space, m->klass->name, m->name, m->klass->image->name);
2797 /* We stop at the first method which is not in
2798 System.Reflection or which is not in a platform
2800 if (strcmp (m->klass->name_space, "System.Reflection") != 0 ||
2801 !mono_security_core_clr_is_platform_image (m->klass->image)) {
2802 /* If the method is transparent we throw an exception. */
2803 if (mono_security_core_clr_method_level (m, TRUE) == MONO_SECURITY_CORE_CLR_TRANSPARENT ) {
2804 MonoException *ex = mono_exception_from_name_msg (mono_defaults.corlib, "System", "MethodAccessException", "Reflection called from transparent code");
2806 mono_raise_exception (ex);
2811 mono_stack_walk_no_il (get_caller, &m);
2816 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoArray *params)
2819 * Invoke from reflection is supposed to always be a virtual call (the API
2820 * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
2821 * greater flexibility.
2823 MonoMethod *m = method->method;
2827 MONO_ARCH_SAVE_REGS;
2829 if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR &&
2830 mono_security_core_clr_method_level (m, TRUE) == MONO_SECURITY_CORE_CLR_CRITICAL)
2831 ensure_reflection_security ();
2833 if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
2835 if (!mono_object_isinst (this, m->klass))
2836 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
2837 m = mono_object_get_virtual_method (this, m);
2838 /* must pass the pointer to the value for valuetype methods */
2839 if (m->klass->valuetype)
2840 obj = mono_object_unbox (this);
2841 } else if (strcmp (m->name, ".ctor") && !m->wrapper_type)
2842 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
2845 pcount = params? mono_array_length (params): 0;
2846 if (pcount != mono_method_signature (m)->param_count)
2847 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
2849 if ((m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) && !strcmp (m->name, ".ctor") && !this)
2850 mono_raise_exception (mono_exception_from_name_msg (mono_defaults.corlib, "System", "MethodAccessException", "Cannot invoke constructor of an abstract class."));
2852 if (m->klass->image->assembly->ref_only)
2853 mono_raise_exception (mono_get_exception_invalid_operation ("It is illegal to invoke a method on a type loaded using the ReflectionOnly api."));
2855 if (m->klass->rank && !strcmp (m->name, ".ctor")) {
2858 guint32 *lower_bounds;
2859 pcount = mono_array_length (params);
2860 lengths = alloca (sizeof (guint32) * pcount);
2861 for (i = 0; i < pcount; ++i)
2862 lengths [i] = *(gint32*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
2864 if (m->klass->rank == pcount) {
2865 /* Only lengths provided. */
2866 lower_bounds = NULL;
2868 g_assert (pcount == (m->klass->rank * 2));
2869 /* lower bounds are first. */
2870 lower_bounds = lengths;
2871 lengths += m->klass->rank;
2874 return (MonoObject*)mono_array_new_full (mono_object_domain (params), m->klass, lengths, lower_bounds);
2876 return mono_runtime_invoke_array (m, obj, params, NULL);
2880 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this, MonoArray *params, MonoArray **outArgs)
2882 MonoDomain *domain = mono_object_domain (method);
2883 MonoMethod *m = method->method;
2884 MonoMethodSignature *sig = mono_method_signature (m);
2885 MonoArray *out_args;
2887 int i, j, outarg_count = 0;
2889 MONO_ARCH_SAVE_REGS;
2891 if (m->klass == mono_defaults.object_class) {
2893 if (!strcmp (m->name, "FieldGetter")) {
2894 MonoClass *k = this->vtable->klass;
2898 /* If this is a proxy, then it must be a CBO */
2899 if (k == mono_defaults.transparent_proxy_class) {
2900 MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
2901 this = tp->rp->unwrapped_server;
2903 k = this->vtable->klass;
2906 name = mono_array_get (params, MonoString *, 1);
2907 str = mono_string_to_utf8 (name);
2910 MonoClassField* field = mono_class_get_field_from_name (k, str);
2912 MonoClass *field_klass = mono_class_from_mono_type (field->type);
2913 if (field_klass->valuetype)
2914 result = mono_value_box (domain, field_klass, (char *)this + field->offset);
2916 result = *((gpointer *)((char *)this + field->offset));
2918 out_args = mono_array_new (domain, mono_defaults.object_class, 1);
2919 *outArgs = out_args;
2920 mono_array_setref (out_args, 0, result);
2928 g_assert_not_reached ();
2930 } else if (!strcmp (m->name, "FieldSetter")) {
2931 MonoClass *k = this->vtable->klass;
2937 /* If this is a proxy, then it must be a CBO */
2938 if (k == mono_defaults.transparent_proxy_class) {
2939 MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
2940 this = tp->rp->unwrapped_server;
2942 k = this->vtable->klass;
2945 name = mono_array_get (params, MonoString *, 1);
2946 str = mono_string_to_utf8 (name);
2949 MonoClassField* field = mono_class_get_field_from_name (k, str);
2951 MonoClass *field_klass = mono_class_from_mono_type (field->type);
2952 MonoObject *val = mono_array_get (params, gpointer, 2);
2954 if (field_klass->valuetype) {
2955 size = mono_type_size (field->type, &align);
2956 memcpy ((char *)this + field->offset,
2957 ((char *)val) + sizeof (MonoObject), size);
2959 *(MonoObject**)((char *)this + field->offset) = val;
2961 out_args = mono_array_new (domain, mono_defaults.object_class, 0);
2962 *outArgs = out_args;
2972 g_assert_not_reached ();
2977 for (i = 0; i < mono_array_length (params); i++) {
2978 if (sig->params [i]->byref)
2982 out_args = mono_array_new (domain, mono_defaults.object_class, outarg_count);
2984 /* handle constructors only for objects already allocated */
2985 if (!strcmp (method->method->name, ".ctor"))
2988 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
2989 g_assert (!method->method->klass->valuetype);
2990 result = mono_runtime_invoke_array (method->method, this, params, NULL);
2992 for (i = 0, j = 0; i < mono_array_length (params); i++) {
2993 if (sig->params [i]->byref) {
2995 arg = mono_array_get (params, gpointer, i);
2996 mono_array_setref (out_args, j, arg);
3001 *outArgs = out_args;
3007 read_enum_value (char *mem, int type)
3011 return *(guint8*)mem;
3013 return *(gint8*)mem;
3015 return *(guint16*)mem;
3017 return *(gint16*)mem;
3019 return *(guint32*)mem;
3021 return *(gint32*)mem;
3023 return *(guint64*)mem;
3025 return *(gint64*)mem;
3027 g_assert_not_reached ();
3033 write_enum_value (char *mem, int type, guint64 value)
3037 case MONO_TYPE_I1: {
3038 guint8 *p = (guint8*)mem;
3043 case MONO_TYPE_I2: {
3044 guint16 *p = (void*)mem;
3049 case MONO_TYPE_I4: {
3050 guint32 *p = (void*)mem;
3055 case MONO_TYPE_I8: {
3056 guint64 *p = (void*)mem;
3061 g_assert_not_reached ();
3067 ves_icall_System_Enum_ToObject (MonoReflectionType *enumType, MonoObject *value)
3070 MonoClass *enumc, *objc;
3074 MONO_ARCH_SAVE_REGS;
3076 MONO_CHECK_ARG_NULL (enumType);
3077 MONO_CHECK_ARG_NULL (value);
3079 domain = mono_object_domain (enumType);
3080 enumc = mono_class_from_mono_type (enumType->type);
3081 objc = value->vtable->klass;
3083 if (!enumc->enumtype)
3084 mono_raise_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
3085 if (!((objc->enumtype) || (objc->byval_arg.type >= MONO_TYPE_I1 && objc->byval_arg.type <= MONO_TYPE_U8)))
3086 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."));
3088 res = mono_object_new (domain, enumc);
3089 val = read_enum_value ((char *)value + sizeof (MonoObject), objc->enumtype? objc->enum_basetype->type: objc->byval_arg.type);
3090 write_enum_value ((char *)res + sizeof (MonoObject), enumc->enum_basetype->type, val);
3096 ves_icall_System_Enum_get_value (MonoObject *this)
3104 MONO_ARCH_SAVE_REGS;
3109 g_assert (this->vtable->klass->enumtype);
3111 enumc = mono_class_from_mono_type (this->vtable->klass->enum_basetype);
3112 res = mono_object_new (mono_object_domain (this), enumc);
3113 dst = (char *)res + sizeof (MonoObject);
3114 src = (char *)this + sizeof (MonoObject);
3115 size = mono_class_value_size (enumc, NULL);
3117 memcpy (dst, src, size);
3123 ves_icall_get_enum_info (MonoReflectionType *type, MonoEnumInfo *info)
3125 MonoDomain *domain = mono_object_domain (type);
3126 MonoClass *enumc = mono_class_from_mono_type (type->type);
3127 guint j = 0, nvalues, crow;
3129 MonoClassField *field;
3131 MONO_ARCH_SAVE_REGS;
3133 info->utype = mono_type_get_object (domain, enumc->enum_basetype);
3134 nvalues = mono_class_num_fields (enumc) ? mono_class_num_fields (enumc) - 1 : 0;
3135 info->names = mono_array_new (domain, mono_defaults.string_class, nvalues);
3136 info->values = mono_array_new (domain, enumc, nvalues);
3140 while ((field = mono_class_get_fields (enumc, &iter))) {
3144 if (strcmp ("value__", field->name) == 0)
3146 if (mono_field_is_deleted (field))
3148 mono_array_setref (info->names, j, mono_string_new (domain, field->name));
3151 crow = mono_metadata_get_constant_index (enumc->image, mono_class_get_field_token (field), crow + 1);
3152 field->def_type = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_TYPE);
3153 crow = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_VALUE);
3154 field->data = (gpointer)mono_metadata_blob_heap (enumc->image, crow);
3158 len = mono_metadata_decode_blob_size (p, &p);
3159 switch (enumc->enum_basetype->type) {
3162 mono_array_set (info->values, gchar, j, *p);
3164 case MONO_TYPE_CHAR:
3167 mono_array_set (info->values, gint16, j, read16 (p));
3171 mono_array_set (info->values, gint32, j, read32 (p));
3175 mono_array_set (info->values, gint64, j, read64 (p));
3178 g_error ("Implement type 0x%02x in get_enum_info", enumc->enum_basetype->type);
3185 BFLAGS_IgnoreCase = 1,
3186 BFLAGS_DeclaredOnly = 2,
3187 BFLAGS_Instance = 4,
3189 BFLAGS_Public = 0x10,
3190 BFLAGS_NonPublic = 0x20,
3191 BFLAGS_FlattenHierarchy = 0x40,
3192 BFLAGS_InvokeMethod = 0x100,
3193 BFLAGS_CreateInstance = 0x200,
3194 BFLAGS_GetField = 0x400,
3195 BFLAGS_SetField = 0x800,
3196 BFLAGS_GetProperty = 0x1000,
3197 BFLAGS_SetProperty = 0x2000,
3198 BFLAGS_ExactBinding = 0x10000,
3199 BFLAGS_SuppressChangeType = 0x20000,
3200 BFLAGS_OptionalParamBinding = 0x40000
3203 static MonoReflectionField *
3204 ves_icall_Type_GetField (MonoReflectionType *type, MonoString *name, guint32 bflags)
3207 MonoClass *startklass, *klass;
3209 MonoClassField *field;
3212 int (*compare_func) (const char *s1, const char *s2) = NULL;
3213 domain = ((MonoObject *)type)->vtable->domain;
3214 klass = startklass = mono_class_from_mono_type (type->type);
3216 MONO_ARCH_SAVE_REGS;
3219 mono_raise_exception (mono_get_exception_argument_null ("name"));
3220 if (type->type->byref)
3223 compare_func = (bflags & BFLAGS_IgnoreCase) ? g_strcasecmp : strcmp;
3226 if (klass->exception_type != MONO_EXCEPTION_NONE)
3227 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3230 while ((field = mono_class_get_fields (klass, &iter))) {
3233 if (field->type == NULL)
3235 if (mono_field_is_deleted (field))
3237 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3238 if (bflags & BFLAGS_Public)
3240 } else if ((klass == startklass) || (field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
3241 if (bflags & BFLAGS_NonPublic) {
3248 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
3249 if (bflags & BFLAGS_Static)
3250 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3253 if (bflags & BFLAGS_Instance)
3260 utf8_name = mono_string_to_utf8 (name);
3262 if (compare_func (field->name, utf8_name)) {
3268 return mono_field_get_object (domain, klass, field);
3270 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3277 ves_icall_Type_GetFields_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3280 MonoClass *startklass, *klass, *refklass;
3285 MonoClassField *field;
3287 MONO_ARCH_SAVE_REGS;
3289 domain = ((MonoObject *)type)->vtable->domain;
3290 if (type->type->byref)
3291 return mono_array_new (domain, mono_defaults.field_info_class, 0);
3292 klass = startklass = mono_class_from_mono_type (type->type);
3293 refklass = mono_class_from_mono_type (reftype->type);
3297 res = mono_array_new (domain, mono_defaults.field_info_class, len);
3299 if (klass->exception_type != MONO_EXCEPTION_NONE)
3300 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3303 while ((field = mono_class_get_fields (klass, &iter))) {
3305 if (mono_field_is_deleted (field))
3307 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3308 if (bflags & BFLAGS_Public)
3310 } else if ((klass == startklass) || (field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
3311 if (bflags & BFLAGS_NonPublic) {
3318 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
3319 if (bflags & BFLAGS_Static)
3320 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3323 if (bflags & BFLAGS_Instance)
3329 member = (MonoObject*)mono_field_get_object (domain, refklass, field);
3331 MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, len * 2);
3332 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3336 mono_array_setref (res, i, member);
3339 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3342 MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, i);
3343 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3346 * Better solution for the new GC.
3347 * res->max_length = i;
3354 method_nonpublic (MonoMethod* method, gboolean start_klass)
3356 switch (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) {
3357 case METHOD_ATTRIBUTE_ASSEM:
3358 return (start_klass || mono_defaults.generic_ilist_class);
3359 case METHOD_ATTRIBUTE_PRIVATE:
3361 case METHOD_ATTRIBUTE_PUBLIC:
3369 ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
3372 MonoClass *startklass, *klass, *refklass;
3377 int i, len, match, nslots;
3378 guint32 method_slots_default [8];
3379 guint32 *method_slots;
3380 gchar *mname = NULL;
3381 int (*compare_func) (const char *s1, const char *s2) = NULL;
3383 MONO_ARCH_SAVE_REGS;
3385 domain = ((MonoObject *)type)->vtable->domain;
3386 if (type->type->byref)
3387 return mono_array_new (domain, mono_defaults.method_info_class, 0);
3388 klass = startklass = mono_class_from_mono_type (type->type);
3389 refklass = mono_class_from_mono_type (reftype->type);
3392 mname = mono_string_to_utf8 (name);
3393 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
3396 mono_class_setup_vtable (klass);
3398 if (is_generic_parameter (type->type))
3399 nslots = klass->parent->vtable_size;
3401 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : klass->vtable_size;
3402 if (nslots >= sizeof (method_slots_default) * 8) {
3403 method_slots = g_new0 (guint32, nslots / 32 + 1);
3405 method_slots = method_slots_default;
3406 memset (method_slots, 0, sizeof (method_slots_default));
3410 res = mono_array_new (domain, mono_defaults.method_info_class, len);
3412 mono_class_setup_vtable (klass);
3413 if (klass->exception_type != MONO_EXCEPTION_NONE)
3414 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3417 while ((method = mono_class_get_methods (klass, &iter))) {
3419 if (method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
3421 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3422 if (bflags & BFLAGS_Public)
3424 } else if ((bflags & BFLAGS_NonPublic) && method_nonpublic (method, (klass == startklass))) {
3430 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3431 if (bflags & BFLAGS_Static)
3432 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3435 if (bflags & BFLAGS_Instance)
3443 if (compare_func (mname, method->name))
3448 if (method->slot != -1) {
3449 g_assert (method->slot < nslots);
3450 if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
3452 method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
3455 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
3458 MonoArray *new_res = mono_array_new (domain, mono_defaults.method_info_class, len * 2);
3459 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3463 mono_array_setref (res, i, member);
3466 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3470 if (method_slots != method_slots_default)
3471 g_free (method_slots);
3473 MonoArray *new_res = mono_array_new (domain, mono_defaults.method_info_class, i);
3474 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3477 * Better solution for the new GC.
3478 * res->max_length = i;
3485 ves_icall_Type_GetConstructors_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3488 static MonoClass *System_Reflection_ConstructorInfo;
3489 MonoClass *startklass, *klass, *refklass;
3494 gpointer iter = NULL;
3496 MONO_ARCH_SAVE_REGS;
3498 domain = ((MonoObject *)type)->vtable->domain;
3499 if (type->type->byref)
3500 return mono_array_new (domain, mono_defaults.method_info_class, 0);
3501 klass = startklass = mono_class_from_mono_type (type->type);
3502 refklass = mono_class_from_mono_type (reftype->type);
3504 if (klass->exception_type != MONO_EXCEPTION_NONE)
3505 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3507 if (!System_Reflection_ConstructorInfo)
3508 System_Reflection_ConstructorInfo = mono_class_from_name (
3509 mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
3513 res = mono_array_new (domain, System_Reflection_ConstructorInfo, len);
3515 while ((method = mono_class_get_methods (klass, &iter))) {
3517 if (strcmp (method->name, ".ctor") && strcmp (method->name, ".cctor"))
3519 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3520 if (bflags & BFLAGS_Public)
3523 if (bflags & BFLAGS_NonPublic)
3529 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3530 if (bflags & BFLAGS_Static)
3531 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3534 if (bflags & BFLAGS_Instance)
3540 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
3543 MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, len * 2);
3544 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3548 mono_array_setref (res, i, member);
3552 MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, i);
3553 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3556 * Better solution for the new GC.
3557 * res->max_length = i;
3564 property_hash (gconstpointer data)
3566 MonoProperty *prop = (MonoProperty*)data;
3568 return g_str_hash (prop->name);
3572 property_equal (MonoProperty *prop1, MonoProperty *prop2)
3574 // Properties are hide-by-name-and-signature
3575 if (!g_str_equal (prop1->name, prop2->name))
3578 if (prop1->get && prop2->get && !mono_metadata_signature_equal (mono_method_signature (prop1->get), mono_method_signature (prop2->get)))
3580 if (prop1->set && prop2->set && !mono_metadata_signature_equal (mono_method_signature (prop1->set), mono_method_signature (prop2->set)))
3586 property_accessor_nonpublic (MonoMethod* accessor, gboolean start_klass)
3591 return method_nonpublic (accessor, start_klass);
3595 ves_icall_Type_GetPropertiesByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
3598 static MonoClass *System_Reflection_PropertyInfo;
3599 MonoClass *startklass, *klass;
3606 gchar *propname = NULL;
3607 int (*compare_func) (const char *s1, const char *s2) = NULL;
3609 GHashTable *properties;
3611 MONO_ARCH_SAVE_REGS;
3613 if (!System_Reflection_PropertyInfo)
3614 System_Reflection_PropertyInfo = mono_class_from_name (
3615 mono_defaults.corlib, "System.Reflection", "PropertyInfo");
3617 domain = ((MonoObject *)type)->vtable->domain;
3618 if (type->type->byref)
3619 return mono_array_new (domain, System_Reflection_PropertyInfo, 0);
3620 klass = startklass = mono_class_from_mono_type (type->type);
3622 propname = mono_string_to_utf8 (name);
3623 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
3626 mono_class_setup_vtable (klass);
3628 properties = g_hash_table_new (property_hash, (GEqualFunc)property_equal);
3631 res = mono_array_new (domain, System_Reflection_PropertyInfo, len);
3633 mono_class_setup_vtable (klass);
3634 if (klass->exception_type != MONO_EXCEPTION_NONE) {
3635 g_hash_table_destroy (properties);
3638 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3642 while ((prop = mono_class_get_properties (klass, &iter))) {
3648 flags = method->flags;
3651 if ((prop->get && ((prop->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC)) ||
3652 (prop->set && ((prop->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC))) {
3653 if (bflags & BFLAGS_Public)
3655 } else if (bflags & BFLAGS_NonPublic) {
3656 if (property_accessor_nonpublic(prop->get, startklass == klass) ||
3657 property_accessor_nonpublic(prop->set, startklass == klass)) {
3664 if (flags & METHOD_ATTRIBUTE_STATIC) {
3665 if (bflags & BFLAGS_Static)
3666 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3669 if (bflags & BFLAGS_Instance)
3678 if (compare_func (propname, prop->name))
3682 if (g_hash_table_lookup (properties, prop))
3686 MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, len * 2);
3687 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3691 mono_array_setref (res, i, mono_property_get_object (domain, startklass, prop));
3694 g_hash_table_insert (properties, prop, prop);
3696 if ((!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent)))
3699 g_hash_table_destroy (properties);
3702 MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, i);
3703 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3706 * Better solution for the new GC.
3707 * res->max_length = i;
3713 static MonoReflectionEvent *
3714 ves_icall_MonoType_GetEvent (MonoReflectionType *type, MonoString *name, guint32 bflags)
3717 MonoClass *klass, *startklass;
3723 MONO_ARCH_SAVE_REGS;
3725 event_name = mono_string_to_utf8 (name);
3726 if (type->type->byref)
3728 klass = startklass = mono_class_from_mono_type (type->type);
3729 domain = mono_object_domain (type);
3732 if (klass->exception_type != MONO_EXCEPTION_NONE)
3733 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3736 while ((event = mono_class_get_events (klass, &iter))) {
3737 if (strcmp (event->name, event_name))
3740 method = event->add;
3742 method = event->remove;
3744 method = event->raise;
3746 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3747 if (!(bflags & BFLAGS_Public))
3750 if (!(bflags & BFLAGS_NonPublic))
3752 if ((klass != startklass) && (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PRIVATE)
3757 if (!(bflags & BFLAGS_NonPublic))
3760 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3761 if (!(bflags & BFLAGS_Static))
3763 if (!(bflags & BFLAGS_FlattenHierarchy) && (klass != startklass))
3766 if (!(bflags & BFLAGS_Instance))
3770 g_free (event_name);
3771 return mono_event_get_object (domain, startklass, event);
3774 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3777 g_free (event_name);
3782 ves_icall_Type_GetEvents_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3785 static MonoClass *System_Reflection_EventInfo;
3786 MonoClass *startklass, *klass;
3793 MONO_ARCH_SAVE_REGS;
3795 if (!System_Reflection_EventInfo)
3796 System_Reflection_EventInfo = mono_class_from_name (
3797 mono_defaults.corlib, "System.Reflection", "EventInfo");
3799 domain = mono_object_domain (type);
3800 if (type->type->byref)
3801 return mono_array_new (domain, System_Reflection_EventInfo, 0);
3802 klass = startklass = mono_class_from_mono_type (type->type);
3806 res = mono_array_new (domain, System_Reflection_EventInfo, len);
3808 if (klass->exception_type != MONO_EXCEPTION_NONE)
3809 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3812 while ((event = mono_class_get_events (klass, &iter))) {
3814 method = event->add;
3816 method = event->remove;
3818 method = event->raise;
3820 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3821 if (bflags & BFLAGS_Public)
3823 } else if ((klass == startklass) || (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) {
3824 if (bflags & BFLAGS_NonPublic)
3829 if (bflags & BFLAGS_NonPublic)
3835 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3836 if (bflags & BFLAGS_Static)
3837 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3840 if (bflags & BFLAGS_Instance)
3845 if (bflags & BFLAGS_Instance)
3851 MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, len * 2);
3852 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3856 mono_array_setref (res, i, mono_event_get_object (domain, startklass, event));
3859 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3862 MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, i);
3863 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3866 * Better solution for the new GC.
3867 * res->max_length = i;
3873 static MonoReflectionType *
3874 ves_icall_Type_GetNestedType (MonoReflectionType *type, MonoString *name, guint32 bflags)
3882 MONO_ARCH_SAVE_REGS;
3884 domain = ((MonoObject *)type)->vtable->domain;
3885 if (type->type->byref)
3887 klass = mono_class_from_mono_type (type->type);
3888 str = mono_string_to_utf8 (name);
3891 if (klass->exception_type != MONO_EXCEPTION_NONE)
3892 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3895 * If a nested type is generic, return its generic type definition.
3896 * Note that this means that the return value is essentially a
3897 * nested type of the generic type definition of @klass.
3899 * A note in MSDN claims that a generic type definition can have
3900 * nested types that aren't generic. In any case, the container of that
3901 * nested type would be the generic type definition.
3903 if (klass->generic_class)
3904 klass = klass->generic_class->container_class;
3906 for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
3908 nested = tmpn->data;
3909 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
3910 if (bflags & BFLAGS_Public)
3913 if (bflags & BFLAGS_NonPublic)
3918 if (strcmp (nested->name, str) == 0){
3920 return mono_type_get_object (domain, &nested->byval_arg);
3923 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3930 ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags)
3940 MONO_ARCH_SAVE_REGS;
3942 domain = ((MonoObject *)type)->vtable->domain;
3943 if (type->type->byref)
3944 return mono_array_new (domain, mono_defaults.monotype_class, 0);
3945 klass = mono_class_from_mono_type (type->type);
3946 if (klass->exception_type != MONO_EXCEPTION_NONE)
3947 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3950 * If a nested type is generic, return its generic type definition.
3951 * Note that this means that the return value is essentially the set
3952 * of nested types of the generic type definition of @klass.
3954 * A note in MSDN claims that a generic type definition can have
3955 * nested types that aren't generic. In any case, the container of that
3956 * nested type would be the generic type definition.
3958 if (klass->generic_class)
3959 klass = klass->generic_class->container_class;
3963 res = mono_array_new (domain, mono_defaults.monotype_class, len);
3964 for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
3966 nested = tmpn->data;
3967 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
3968 if (bflags & BFLAGS_Public)
3971 if (bflags & BFLAGS_NonPublic)
3976 member = (MonoObject*)mono_type_get_object (domain, &nested->byval_arg);
3978 MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, len * 2);
3979 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3983 mono_array_setref (res, i, member);
3987 MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, i);
3988 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3991 * Better solution for the new GC.
3992 * res->max_length = i;
3998 static MonoReflectionType*
3999 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *assembly, MonoReflectionModule *module, MonoString *name, MonoBoolean throwOnError, MonoBoolean ignoreCase)
4002 MonoType *type = NULL;
4003 MonoTypeNameParse info;
4004 gboolean type_resolve;
4006 MONO_ARCH_SAVE_REGS;
4008 /* On MS.NET, this does not fire a TypeResolve event */
4009 type_resolve = TRUE;
4010 str = mono_string_to_utf8 (name);
4011 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
4012 if (!mono_reflection_parse_type (str, &info)) {
4014 mono_reflection_free_type_info (&info);
4015 if (throwOnError) /* uhm: this is a parse error, though... */
4016 mono_raise_exception (mono_get_exception_type_load (name, NULL));
4017 /*g_print ("failed parse\n");*/
4021 if (info.assembly.name) {
4023 /* 1.0 and 2.0 throw different exceptions */
4024 if (mono_defaults.generic_ilist_class)
4025 mono_raise_exception (mono_get_exception_argument (NULL, "Type names passed to Assembly.GetType() must not specify an assembly."));
4027 mono_raise_exception (mono_get_exception_type_load (name, NULL));
4032 if (module != NULL) {
4034 type = mono_reflection_get_type (module->image, &info, ignoreCase, &type_resolve);
4039 if (assembly->assembly->dynamic) {
4040 /* Enumerate all modules */
4041 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
4045 if (abuilder->modules) {
4046 for (i = 0; i < mono_array_length (abuilder->modules); ++i) {
4047 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
4048 type = mono_reflection_get_type (&mb->dynamic_image->image, &info, ignoreCase, &type_resolve);
4054 if (!type && abuilder->loaded_modules) {
4055 for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) {
4056 MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
4057 type = mono_reflection_get_type (mod->image, &info, ignoreCase, &type_resolve);
4064 type = mono_reflection_get_type (assembly->assembly->image, &info, ignoreCase, &type_resolve);
4066 mono_reflection_free_type_info (&info);
4068 MonoException *e = NULL;
4071 e = mono_get_exception_type_load (name, NULL);
4073 mono_loader_clear_error ();
4076 mono_raise_exception (e);
4081 if (type->type == MONO_TYPE_CLASS) {
4082 MonoClass *klass = mono_type_get_class (type);
4083 /* need to report exceptions ? */
4084 if (throwOnError && klass->exception_type) {
4085 /* report SecurityException (or others) that occured when loading the assembly */
4086 MonoException *exc = mono_class_get_exception_for_failure (klass);
4087 mono_loader_clear_error ();
4088 mono_raise_exception (exc);
4089 } else if (klass->exception_type == MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND) {
4094 /* g_print ("got it\n"); */
4095 return mono_type_get_object (mono_object_domain (assembly), type);
4099 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *assembly, MonoBoolean escaped)
4101 MonoDomain *domain = mono_object_domain (assembly);
4102 MonoAssembly *mass = assembly->assembly;
4103 MonoString *res = NULL;
4107 MONO_ARCH_SAVE_REGS;
4109 if (g_path_is_absolute (mass->image->name))
4110 absolute = g_strdup (mass->image->name);
4112 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4116 for (i = strlen (absolute) - 1; i >= 0; i--)
4117 if (absolute [i] == '\\')
4122 uri = g_filename_to_uri (absolute, NULL, NULL);
4124 uri = g_strconcat ("file://", absolute, NULL);
4128 res = mono_string_new (domain, uri);
4136 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssembly *assembly)
4138 MonoAssembly *mass = assembly->assembly;
4140 MONO_ARCH_SAVE_REGS;
4142 return mass->in_gac;
4145 static MonoReflectionAssembly*
4146 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoString *mname, MonoObject *evidence)
4150 MonoImageOpenStatus status;
4152 MONO_ARCH_SAVE_REGS;
4154 name = mono_string_to_utf8 (mname);
4155 res = mono_assembly_load_with_partial_name (name, &status);
4161 return mono_assembly_get_object (mono_domain_get (), res);
4165 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssembly *assembly)
4167 MonoDomain *domain = mono_object_domain (assembly);
4170 MONO_ARCH_SAVE_REGS;
4172 res = mono_string_new (domain, mono_image_get_filename (assembly->assembly->image));
4178 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssembly *assembly)
4180 MONO_ARCH_SAVE_REGS;
4182 return assembly->assembly->ref_only;
4186 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssembly *assembly)
4188 MonoDomain *domain = mono_object_domain (assembly);
4190 MONO_ARCH_SAVE_REGS;
4192 return mono_string_new (domain, assembly->assembly->image->version);
4195 static MonoReflectionMethod*
4196 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssembly *assembly)
4198 guint32 token = mono_image_get_entry_point (assembly->assembly->image);
4200 MONO_ARCH_SAVE_REGS;
4204 return mono_method_get_object (mono_object_domain (assembly), mono_get_method (assembly->assembly->image, token, NULL), NULL);
4207 static MonoReflectionModule*
4208 ves_icall_System_Reflection_Assembly_GetManifestModuleInternal (MonoReflectionAssembly *assembly)
4210 return mono_module_get_object (mono_object_domain (assembly), assembly->assembly->image);
4214 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssembly *assembly)
4216 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4217 MonoArray *result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, table->rows);
4221 MONO_ARCH_SAVE_REGS;
4223 for (i = 0; i < table->rows; ++i) {
4224 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_MANIFEST_NAME));
4225 mono_array_setref (result, i, mono_string_new (mono_object_domain (assembly), val));
4231 create_version (MonoDomain *domain, guint32 major, guint32 minor, guint32 build, guint32 revision)
4233 static MonoClass *System_Version = NULL;
4234 static MonoMethod *create_version = NULL;
4238 if (!System_Version) {
4239 System_Version = mono_class_from_name (mono_defaults.corlib, "System", "Version");
4240 g_assert (System_Version);
4243 if (!create_version) {
4244 MonoMethodDesc *desc = mono_method_desc_new (":.ctor(int,int,int,int)", FALSE);
4245 create_version = mono_method_desc_search_in_class (desc, System_Version);
4246 g_assert (create_version);
4247 mono_method_desc_free (desc);
4253 args [3] = &revision;
4254 result = mono_object_new (domain, System_Version);
4255 mono_runtime_invoke (create_version, result, args, NULL);
4261 ves_icall_System_Reflection_Assembly_GetReferencedAssemblies (MonoReflectionAssembly *assembly)
4263 static MonoClass *System_Reflection_AssemblyName;
4265 MonoDomain *domain = mono_object_domain (assembly);
4267 static MonoMethod *create_culture = NULL;
4268 MonoImage *image = assembly->assembly->image;
4271 MONO_ARCH_SAVE_REGS;
4273 if (!System_Reflection_AssemblyName)
4274 System_Reflection_AssemblyName = mono_class_from_name (
4275 mono_defaults.corlib, "System.Reflection", "AssemblyName");
4277 t = &assembly->assembly->image->tables [MONO_TABLE_ASSEMBLYREF];
4280 result = mono_array_new (domain, System_Reflection_AssemblyName, count);
4283 MonoMethodDesc *desc = mono_method_desc_new (
4284 "System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE);
4285 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4286 g_assert (create_culture);
4287 mono_method_desc_free (desc);
4290 for (i = 0; i < count; i++) {
4291 MonoReflectionAssemblyName *aname;
4292 guint32 cols [MONO_ASSEMBLYREF_SIZE];
4294 mono_metadata_decode_row (t, i, cols, MONO_ASSEMBLYREF_SIZE);
4296 aname = (MonoReflectionAssemblyName *) mono_object_new (
4297 domain, System_Reflection_AssemblyName);
4299 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_NAME])));
4301 aname->major = cols [MONO_ASSEMBLYREF_MAJOR_VERSION];
4302 aname->minor = cols [MONO_ASSEMBLYREF_MINOR_VERSION];
4303 aname->build = cols [MONO_ASSEMBLYREF_BUILD_NUMBER];
4304 aname->revision = cols [MONO_ASSEMBLYREF_REV_NUMBER];
4305 aname->flags = cols [MONO_ASSEMBLYREF_FLAGS];
4306 aname->versioncompat = 1; /* SameMachine (default) */
4307 aname->hashalg = ASSEMBLY_HASH_SHA1; /* SHA1 (default) */
4308 MONO_OBJECT_SETREF (aname, version, create_version (domain, aname->major, aname->minor, aname->build, aname->revision));
4310 if (create_culture) {
4312 gboolean assembly_ref = TRUE;
4313 args [0] = mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_CULTURE]));
4314 args [1] = &assembly_ref;
4315 MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
4318 if (cols [MONO_ASSEMBLYREF_PUBLIC_KEY]) {
4319 const gchar *pkey_ptr = mono_metadata_blob_heap (image, cols [MONO_ASSEMBLYREF_PUBLIC_KEY]);
4320 guint32 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
4322 if ((cols [MONO_ASSEMBLYREF_FLAGS] & ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG)) {
4323 /* public key token isn't copied - the class library will
4324 automatically generate it from the public key if required */
4325 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4326 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
4328 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4329 memcpy (mono_array_addr (aname->keyToken, guint8, 0), pkey_ptr, pkey_len);
4332 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, 0));
4335 /* note: this function doesn't return the codebase on purpose (i.e. it can
4336 be used under partial trust as path information isn't present). */
4338 mono_array_setref (result, i, aname);
4349 foreach_namespace (const char* key, gconstpointer val, NameSpaceInfo *info)
4351 MonoString *name = mono_string_new (mono_object_domain (info->res), key);
4353 mono_array_setref (info->res, info->idx, name);
4358 ves_icall_System_Reflection_Assembly_GetNamespaces (MonoReflectionAssembly *assembly)
4360 MonoImage *img = assembly->assembly->image;
4364 MONO_ARCH_SAVE_REGS;
4366 if (!img->name_cache)
4367 mono_image_init_name_cache (img);
4369 res = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, g_hash_table_size (img->name_cache));
4372 g_hash_table_foreach (img->name_cache, (GHFunc)foreach_namespace, &info);
4377 /* move this in some file in mono/util/ */
4379 g_concat_dir_and_file (const char *dir, const char *file)
4381 g_return_val_if_fail (dir != NULL, NULL);
4382 g_return_val_if_fail (file != NULL, NULL);
4385 * If the directory name doesn't have a / on the end, we need
4386 * to add one so we get a proper path to the file
4388 if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
4389 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
4391 return g_strconcat (dir, file, NULL);
4395 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssembly *assembly, MonoString *name, gint32 *size, MonoReflectionModule **ref_module)
4397 char *n = mono_string_to_utf8 (name);
4398 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4400 guint32 cols [MONO_MANIFEST_SIZE];
4401 guint32 impl, file_idx;
4405 MONO_ARCH_SAVE_REGS;
4407 for (i = 0; i < table->rows; ++i) {
4408 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4409 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4410 if (strcmp (val, n) == 0)
4414 if (i == table->rows)
4417 impl = cols [MONO_MANIFEST_IMPLEMENTATION];
4420 * this code should only be called after obtaining the
4421 * ResourceInfo and handling the other cases.
4423 g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
4424 file_idx = impl >> MONO_IMPLEMENTATION_BITS;
4426 module = mono_image_load_file_for_image (assembly->assembly->image, file_idx);
4431 module = assembly->assembly->image;
4433 *ref_module = mono_module_get_object (mono_domain_get (), module);
4435 return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
4439 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoManifestResourceInfo *info)
4441 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4443 guint32 cols [MONO_MANIFEST_SIZE];
4444 guint32 file_cols [MONO_FILE_SIZE];
4448 MONO_ARCH_SAVE_REGS;
4450 n = mono_string_to_utf8 (name);
4451 for (i = 0; i < table->rows; ++i) {
4452 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4453 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4454 if (strcmp (val, n) == 0)
4458 if (i == table->rows)
4461 if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
4462 info->location = RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST;
4465 switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
4466 case MONO_IMPLEMENTATION_FILE:
4467 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4468 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4469 mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
4470 val = mono_metadata_string_heap (assembly->assembly->image, file_cols [MONO_FILE_NAME]);
4471 MONO_OBJECT_SETREF (info, filename, mono_string_new (mono_object_domain (assembly), val));
4472 if (file_cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA)
4475 info->location = RESOURCE_LOCATION_EMBEDDED;
4478 case MONO_IMPLEMENTATION_ASSEMBLYREF:
4479 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4480 mono_assembly_load_reference (assembly->assembly->image, i - 1);
4481 if (assembly->assembly->image->references [i - 1] == (gpointer)-1) {
4482 char *msg = g_strdup_printf ("Assembly %d referenced from assembly %s not found ", i - 1, assembly->assembly->image->name);
4483 MonoException *ex = mono_get_exception_file_not_found2 (msg, NULL);
4485 mono_raise_exception (ex);
4487 MONO_OBJECT_SETREF (info, assembly, mono_assembly_get_object (mono_domain_get (), assembly->assembly->image->references [i - 1]));
4489 /* Obtain info recursively */
4490 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (info->assembly, name, info);
4491 info->location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
4494 case MONO_IMPLEMENTATION_EXP_TYPE:
4495 g_assert_not_reached ();
4504 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoBoolean resource_modules)
4506 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4507 MonoArray *result = NULL;
4512 MONO_ARCH_SAVE_REGS;
4514 /* check hash if needed */
4516 n = mono_string_to_utf8 (name);
4517 for (i = 0; i < table->rows; ++i) {
4518 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4519 if (strcmp (val, n) == 0) {
4522 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4523 fn = mono_string_new (mono_object_domain (assembly), n);
4525 return (MonoObject*)fn;
4533 for (i = 0; i < table->rows; ++i) {
4534 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA))
4538 result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, count);
4541 for (i = 0; i < table->rows; ++i) {
4542 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4543 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4544 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4545 mono_array_setref (result, count, mono_string_new (mono_object_domain (assembly), n));
4550 return (MonoObject*)result;
4554 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly *assembly)
4556 MonoDomain *domain = mono_domain_get();
4559 int i, j, file_count = 0;
4560 MonoImage **modules;
4561 guint32 module_count, real_module_count;
4562 MonoTableInfo *table;
4563 guint32 cols [MONO_FILE_SIZE];
4564 MonoImage *image = assembly->assembly->image;
4566 g_assert (image != NULL);
4567 g_assert (!assembly->assembly->dynamic);
4569 table = &image->tables [MONO_TABLE_FILE];
4570 file_count = table->rows;
4572 modules = image->modules;
4573 module_count = image->module_count;
4575 real_module_count = 0;
4576 for (i = 0; i < module_count; ++i)
4578 real_module_count ++;
4580 klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "Module");
4581 res = mono_array_new (domain, klass, 1 + real_module_count + file_count);
4583 mono_array_setref (res, 0, mono_module_get_object (domain, image));
4585 for (i = 0; i < module_count; ++i)
4587 mono_array_setref (res, j, mono_module_get_object (domain, modules[i]));
4591 for (i = 0; i < file_count; ++i, ++j) {
4592 mono_metadata_decode_row (table, i, cols, MONO_FILE_SIZE);
4593 if (cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA)
4594 mono_array_setref (res, j, mono_module_file_get_object (domain, image, i));
4596 MonoImage *m = mono_image_load_file_for_image (image, i + 1);
4598 MonoString *fname = mono_string_new (mono_domain_get (), mono_metadata_string_heap (image, cols [MONO_FILE_NAME]));
4599 mono_raise_exception (mono_get_exception_file_not_found2 (NULL, fname));
4601 mono_array_setref (res, j, mono_module_get_object (domain, m));
4608 static MonoReflectionMethod*
4609 ves_icall_GetCurrentMethod (void)
4611 MonoMethod *m = mono_method_get_last_managed ();
4613 MONO_ARCH_SAVE_REGS;
4615 return mono_method_get_object (mono_domain_get (), m, NULL);
4618 static MonoReflectionMethod*
4619 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType (MonoMethod *method, MonoType *type)
4621 /* FIXME check that method belongs to klass or a parent */
4624 klass = mono_class_from_mono_type (type);
4626 klass = method->klass;
4627 return mono_method_get_object (mono_domain_get (), method, klass);
4630 static MonoReflectionMethod*
4631 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternal (MonoMethod *method)
4633 return mono_method_get_object (mono_domain_get (), method, NULL);
4636 static MonoReflectionMethodBody*
4637 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod *method)
4639 return mono_method_body_get_object (mono_domain_get (), method);
4642 static MonoReflectionAssembly*
4643 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (void)
4645 MonoMethod *m = mono_method_get_last_managed ();
4647 MONO_ARCH_SAVE_REGS;
4649 return mono_assembly_get_object (mono_domain_get (), m->klass->image->assembly);
4653 static MonoReflectionAssembly*
4654 ves_icall_System_Reflection_Assembly_GetEntryAssembly (void)
4656 MonoDomain* domain = mono_domain_get ();
4658 MONO_ARCH_SAVE_REGS;
4660 if (!domain->entry_assembly)
4663 return mono_assembly_get_object (domain, domain->entry_assembly);
4666 static MonoReflectionAssembly*
4667 ves_icall_System_Reflection_Assembly_GetCallingAssembly (void)
4669 MonoMethod *m = mono_method_get_last_managed ();
4670 MonoMethod *dest = m;
4672 MONO_ARCH_SAVE_REGS;
4674 mono_stack_walk_no_il (get_caller, &dest);
4677 return mono_assembly_get_object (mono_domain_get (), dest->klass->image->assembly);
4681 ves_icall_System_MonoType_getFullName (MonoReflectionType *object, gboolean full_name,
4682 gboolean assembly_qualified)
4684 MonoDomain *domain = mono_object_domain (object);
4685 MonoTypeNameFormat format;
4689 MONO_ARCH_SAVE_REGS;
4691 format = assembly_qualified ?
4692 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
4693 MONO_TYPE_NAME_FORMAT_FULL_NAME;
4695 format = MONO_TYPE_NAME_FORMAT_REFLECTION;
4697 name = mono_type_get_name_full (object->type, format);
4701 if (full_name && (object->type->type == MONO_TYPE_VAR || object->type->type == MONO_TYPE_MVAR)) {
4706 res = mono_string_new (domain, name);
4713 fill_reflection_assembly_name (MonoDomain *domain, MonoReflectionAssemblyName *aname, MonoAssemblyName *name, const char *absolute, gboolean by_default_version, gboolean default_publickey, gboolean default_token)
4715 static MonoMethod *create_culture = NULL;
4718 const char *pkey_ptr;
4720 gboolean assembly_ref = FALSE;
4722 MONO_ARCH_SAVE_REGS;
4724 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, name->name));
4725 aname->major = name->major;
4726 aname->minor = name->minor;
4727 aname->build = name->build;
4728 aname->flags = name->flags;
4729 aname->revision = name->revision;
4730 aname->hashalg = name->hash_alg;
4731 aname->versioncompat = 1; /* SameMachine (default) */
4733 if (by_default_version)
4734 MONO_OBJECT_SETREF (aname, version, create_version (domain, name->major, name->minor, name->build, name->revision));
4736 codebase = g_filename_to_uri (absolute, NULL, NULL);
4738 MONO_OBJECT_SETREF (aname, codebase, mono_string_new (domain, codebase));
4742 if (!create_culture) {
4743 MonoMethodDesc *desc = mono_method_desc_new ("System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE);
4744 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4745 g_assert (create_culture);
4746 mono_method_desc_free (desc);
4749 if (name->culture) {
4750 args [0] = mono_string_new (domain, name->culture);
4751 args [1] = &assembly_ref;
4752 MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
4755 if (name->public_key) {
4756 pkey_ptr = (char*)name->public_key;
4757 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
4759 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4760 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
4761 aname->flags |= ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG;
4762 } else if (default_publickey) {
4763 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, 0));
4764 aname->flags |= ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG;
4767 /* MonoAssemblyName keeps the public key token as an hexadecimal string */
4768 if (name->public_key_token [0]) {
4772 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, 8));
4773 p = mono_array_addr (aname->keyToken, char, 0);
4775 for (i = 0, j = 0; i < 8; i++) {
4776 *p = g_ascii_xdigit_value (name->public_key_token [j++]) << 4;
4777 *p |= g_ascii_xdigit_value (name->public_key_token [j++]);
4780 } else if (default_token) {
4781 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, 0));
4786 ves_icall_System_Reflection_Assembly_get_fullName (MonoReflectionAssembly *assembly)
4788 MonoDomain *domain = mono_object_domain (assembly);
4789 MonoAssembly *mass = assembly->assembly;
4793 name = g_strdup_printf (
4794 "%s, Version=%d.%d.%d.%d, Culture=%s, PublicKeyToken=%s%s",
4796 mass->aname.major, mass->aname.minor, mass->aname.build, mass->aname.revision,
4797 mass->aname.culture && *mass->aname.culture? mass->aname.culture: "neutral",
4798 mass->aname.public_key_token [0] ? (char *)mass->aname.public_key_token : "null",
4799 (mass->aname.flags & ASSEMBLYREF_RETARGETABLE_FLAG) ? ", Retargetable=Yes" : "");
4801 res = mono_string_new (domain, name);
4808 ves_icall_System_Reflection_Assembly_FillName (MonoReflectionAssembly *assembly, MonoReflectionAssemblyName *aname)
4811 MonoAssembly *mass = assembly->assembly;
4813 MONO_ARCH_SAVE_REGS;
4815 if (g_path_is_absolute (mass->image->name)) {
4816 fill_reflection_assembly_name (mono_object_domain (assembly),
4817 aname, &mass->aname, mass->image->name, TRUE,
4818 TRUE, mono_get_runtime_info ()->framework_version [0] >= '2');
4821 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4823 fill_reflection_assembly_name (mono_object_domain (assembly),
4824 aname, &mass->aname, absolute, TRUE, TRUE,
4825 mono_get_runtime_info ()->framework_version [0] >= '2');
4831 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoString *fname, MonoReflectionAssemblyName *aname)
4834 MonoImageOpenStatus status = MONO_IMAGE_OK;
4837 MonoAssemblyName name;
4839 MONO_ARCH_SAVE_REGS;
4841 filename = mono_string_to_utf8 (fname);
4843 image = mono_image_open (filename, &status);
4849 if (status == MONO_IMAGE_IMAGE_INVALID)
4850 exc = mono_get_exception_bad_image_format2 (NULL, fname);
4852 exc = mono_get_exception_file_not_found2 (NULL, fname);
4853 mono_raise_exception (exc);
4856 res = mono_assembly_fill_assembly_name (image, &name);
4858 mono_image_close (image);
4860 mono_raise_exception (mono_get_exception_argument ("assemblyFile", "The file does not contain a manifest"));
4863 fill_reflection_assembly_name (mono_domain_get (), aname, &name, filename,
4864 TRUE, mono_get_runtime_info ()->framework_version [0] == '1',
4865 mono_get_runtime_info ()->framework_version [0] >= '2');
4868 mono_image_close (image);
4872 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssembly *assembly,
4873 char **minimum, guint32 *minLength, char **optional, guint32 *optLength, char **refused, guint32 *refLength)
4875 MonoBoolean result = FALSE;
4876 MonoDeclSecurityEntry entry;
4878 /* SecurityAction.RequestMinimum */
4879 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQMIN, &entry)) {
4880 *minimum = entry.blob;
4881 *minLength = entry.size;
4884 /* SecurityAction.RequestOptional */
4885 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQOPT, &entry)) {
4886 *optional = entry.blob;
4887 *optLength = entry.size;
4890 /* SecurityAction.RequestRefuse */
4891 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQREFUSE, &entry)) {
4892 *refused = entry.blob;
4893 *refLength = entry.size;
4901 mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoBoolean exportedOnly)
4905 MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
4907 guint32 attrs, visibility;
4909 /* we start the count from 1 because we skip the special type <Module> */
4912 for (i = 1; i < tdef->rows; ++i) {
4913 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
4914 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
4915 if (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)
4919 count = tdef->rows - 1;
4921 res = mono_array_new (domain, mono_defaults.monotype_class, count);
4923 for (i = 1; i < tdef->rows; ++i) {
4924 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
4925 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
4926 if (!exportedOnly || (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)) {
4927 klass = mono_class_get_throw (image, (i + 1) | MONO_TOKEN_TYPE_DEF);
4928 if (mono_loader_get_last_error ())
4929 mono_loader_clear_error ();
4930 mono_array_setref (res, count, mono_type_get_object (domain, &klass->byval_arg));
4939 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly, MonoBoolean exportedOnly)
4941 MonoArray *res = NULL;
4942 MonoImage *image = NULL;
4943 MonoTableInfo *table = NULL;
4948 MONO_ARCH_SAVE_REGS;
4950 domain = mono_object_domain (assembly);
4952 g_assert (!assembly->assembly->dynamic);
4953 image = assembly->assembly->image;
4954 table = &image->tables [MONO_TABLE_FILE];
4955 res = mono_module_get_types (domain, image, exportedOnly);
4957 /* Append data from all modules in the assembly */
4958 for (i = 0; i < table->rows; ++i) {
4959 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4960 MonoImage *loaded_image = mono_assembly_load_module (image->assembly, i + 1);
4962 MonoArray *res2 = mono_module_get_types (domain, loaded_image, exportedOnly);
4963 /* Append the new types to the end of the array */
4964 if (mono_array_length (res2) > 0) {
4968 len1 = mono_array_length (res);
4969 len2 = mono_array_length (res2);
4970 res3 = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4971 mono_array_memcpy_refs (res3, 0, res, 0, len1);
4972 mono_array_memcpy_refs (res3, len1, res2, 0, len2);
4979 /* the ReflectionTypeLoadException must have all the types (Types property),
4980 * NULL replacing types which throws an exception. The LoaderException must
4981 * contain all exceptions for NULL items.
4984 len = mono_array_length (res);
4986 for (i = 0; i < len; i++) {
4987 MonoReflectionType *t = mono_array_get (res, gpointer, i);
4988 MonoClass *klass = mono_type_get_class (t->type);
4989 if ((klass != NULL) && klass->exception_type) {
4990 /* keep the class in the list */
4991 list = g_list_append (list, klass);
4992 /* and replace Type with NULL */
4993 mono_array_setref (res, i, NULL);
4999 MonoException *exc = NULL;
5000 MonoArray *exl = NULL;
5001 int length = g_list_length (list);
5003 mono_loader_clear_error ();
5005 exl = mono_array_new (domain, mono_defaults.exception_class, length);
5006 for (i = 0, tmp = list; i < length; i++, tmp = tmp->next) {
5007 MonoException *exc = mono_class_get_exception_for_failure (tmp->data);
5008 mono_array_setref (exl, i, exc);
5013 exc = mono_get_exception_reflection_type_load (res, exl);
5014 mono_loader_clear_error ();
5015 mono_raise_exception (exc);
5022 ves_icall_System_Reflection_AssemblyName_ParseName (MonoReflectionAssemblyName *name, MonoString *assname)
5024 MonoAssemblyName aname;
5025 MonoDomain *domain = mono_object_domain (name);
5027 gboolean is_version_defined;
5028 gboolean is_token_defined;
5030 val = mono_string_to_utf8 (assname);
5031 if (!mono_assembly_name_parse_full (val, &aname, TRUE, &is_version_defined, &is_token_defined))
5034 fill_reflection_assembly_name (domain, name, &aname, "", is_version_defined,
5035 FALSE, is_token_defined);
5037 mono_assembly_name_free (&aname);
5038 g_free ((guint8*) aname.public_key);
5044 static MonoReflectionType*
5045 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModule *module)
5047 MonoDomain *domain = mono_object_domain (module);
5050 MONO_ARCH_SAVE_REGS;
5052 g_assert (module->image);
5054 if (module->image->dynamic && ((MonoDynamicImage*)(module->image))->initial_image)
5055 /* These images do not have a global type */
5058 klass = mono_class_get (module->image, 1 | MONO_TOKEN_TYPE_DEF);
5059 return mono_type_get_object (domain, &klass->byval_arg);
5063 ves_icall_System_Reflection_Module_Close (MonoReflectionModule *module)
5065 /*if (module->image)
5066 mono_image_close (module->image);*/
5070 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModule *module)
5072 MonoDomain *domain = mono_object_domain (module);
5074 MONO_ARCH_SAVE_REGS;
5076 g_assert (module->image);
5077 return mono_string_new (domain, module->image->guid);
5081 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine)
5083 if (image->dynamic) {
5084 MonoDynamicImage *dyn = (MonoDynamicImage*)image;
5085 *pe_kind = dyn->pe_kind;
5086 *machine = dyn->machine;
5089 *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
5090 *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
5095 ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage *image)
5097 return (image->md_version_major << 16) | (image->md_version_minor);
5101 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModule *module)
5103 MONO_ARCH_SAVE_REGS;
5106 return mono_array_new (mono_object_domain (module), mono_defaults.monotype_class, 0);
5108 return mono_module_get_types (mono_object_domain (module), module->image, FALSE);
5112 mono_metadata_memberref_is_method (MonoImage *image, guint32 token)
5114 guint32 cols [MONO_MEMBERREF_SIZE];
5116 mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
5117 sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
5118 mono_metadata_decode_blob_size (sig, &sig);
5119 return (*sig != 0x6);
5123 init_generic_context_from_args (MonoGenericContext *context, MonoArray *type_args, MonoArray *method_args)
5126 context->class_inst = mono_metadata_get_generic_inst (mono_array_length (type_args),
5127 mono_array_addr (type_args, MonoType*, 0));
5129 context->class_inst = NULL;
5131 context->method_inst = mono_metadata_get_generic_inst (mono_array_length (method_args),
5132 mono_array_addr (method_args, MonoType*, 0));
5134 context->method_inst = NULL;
5138 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5141 int table = mono_metadata_token_table (token);
5142 int index = mono_metadata_token_index (token);
5143 MonoGenericContext context;
5145 *error = ResolveTokenError_Other;
5147 /* Validate token */
5148 if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) &&
5149 (table != MONO_TABLE_TYPESPEC)) {
5150 *error = ResolveTokenError_BadTable;
5154 if (image->dynamic) {
5155 if (type_args || method_args)
5156 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5157 return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5160 if ((index <= 0) || (index > image->tables [table].rows)) {
5161 *error = ResolveTokenError_OutOfRange;
5165 init_generic_context_from_args (&context, type_args, method_args);
5166 klass = mono_class_get_full (image, token, &context);
5169 return &klass->byval_arg;
5175 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5177 int table = mono_metadata_token_table (token);
5178 int index = mono_metadata_token_index (token);
5179 MonoGenericContext context;
5182 *error = ResolveTokenError_Other;
5184 /* Validate token */
5185 if ((table != MONO_TABLE_METHOD) && (table != MONO_TABLE_METHODSPEC) &&
5186 (table != MONO_TABLE_MEMBERREF)) {
5187 *error = ResolveTokenError_BadTable;
5191 if (image->dynamic) {
5192 if (type_args || method_args)
5193 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5194 /* FIXME: validate memberref token type */
5195 return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5198 if ((index <= 0) || (index > image->tables [table].rows)) {
5199 *error = ResolveTokenError_OutOfRange;
5202 if ((table == MONO_TABLE_MEMBERREF) && (!mono_metadata_memberref_is_method (image, token))) {
5203 *error = ResolveTokenError_BadTable;
5207 init_generic_context_from_args (&context, type_args, method_args);
5208 method = mono_get_method_full (image, token, NULL, &context);
5214 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
5216 int index = mono_metadata_token_index (token);
5218 *error = ResolveTokenError_Other;
5220 /* Validate token */
5221 if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
5222 *error = ResolveTokenError_BadTable;
5227 return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5229 if ((index <= 0) || (index >= image->heap_us.size)) {
5230 *error = ResolveTokenError_OutOfRange;
5234 /* FIXME: What to do if the index points into the middle of a string ? */
5236 return mono_ldstr (mono_domain_get (), image, index);
5239 static MonoClassField*
5240 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5243 int table = mono_metadata_token_table (token);
5244 int index = mono_metadata_token_index (token);
5245 MonoGenericContext context;
5246 MonoClassField *field;
5248 *error = ResolveTokenError_Other;
5250 /* Validate token */
5251 if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
5252 *error = ResolveTokenError_BadTable;
5256 if (image->dynamic) {
5257 if (type_args || method_args)
5258 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5259 /* FIXME: validate memberref token type */
5260 return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5263 if ((index <= 0) || (index > image->tables [table].rows)) {
5264 *error = ResolveTokenError_OutOfRange;
5267 if ((table == MONO_TABLE_MEMBERREF) && (mono_metadata_memberref_is_method (image, token))) {
5268 *error = ResolveTokenError_BadTable;
5272 init_generic_context_from_args (&context, type_args, method_args);
5273 field = mono_field_from_token (image, token, &klass, &context);
5280 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5282 int table = mono_metadata_token_table (token);
5284 *error = ResolveTokenError_Other;
5287 case MONO_TABLE_TYPEDEF:
5288 case MONO_TABLE_TYPEREF:
5289 case MONO_TABLE_TYPESPEC: {
5290 MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, type_args, method_args, error);
5292 return (MonoObject*)mono_type_get_object (mono_domain_get (), t);
5296 case MONO_TABLE_METHOD:
5297 case MONO_TABLE_METHODSPEC: {
5298 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5300 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
5304 case MONO_TABLE_FIELD: {
5305 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5307 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
5311 case MONO_TABLE_MEMBERREF:
5312 if (mono_metadata_memberref_is_method (image, token)) {
5313 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5315 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
5320 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5322 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
5329 *error = ResolveTokenError_BadTable;
5336 ves_icall_System_Reflection_Module_ResolveSignature (MonoImage *image, guint32 token, MonoResolveTokenError *error)
5338 int table = mono_metadata_token_table (token);
5339 int idx = mono_metadata_token_index (token);
5340 MonoTableInfo *tables = image->tables;
5345 *error = ResolveTokenError_OutOfRange;
5347 /* FIXME: Support other tables ? */
5348 if (table != MONO_TABLE_STANDALONESIG)
5354 if ((idx == 0) || (idx > tables [MONO_TABLE_STANDALONESIG].rows))
5357 sig = mono_metadata_decode_row_col (&tables [MONO_TABLE_STANDALONESIG], idx - 1, 0);
5359 ptr = mono_metadata_blob_heap (image, sig);
5360 len = mono_metadata_decode_blob_size (ptr, &ptr);
5362 res = mono_array_new (mono_domain_get (), mono_defaults.byte_class, len);
5363 memcpy (mono_array_addr (res, guint8, 0), ptr, len);
5367 static MonoReflectionType*
5368 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
5371 int isbyref = 0, rank;
5372 char *str = mono_string_to_utf8 (smodifiers);
5375 MONO_ARCH_SAVE_REGS;
5377 klass = mono_class_from_mono_type (tb->type.type);
5379 /* logic taken from mono_reflection_parse_type(): keep in sync */
5383 if (isbyref) { /* only one level allowed by the spec */
5390 return mono_type_get_object (mono_object_domain (tb), &klass->this_arg);
5393 klass = mono_ptr_class_get (&klass->byval_arg);
5394 mono_class_init (klass);
5405 else if (*p != '*') { /* '*' means unknown lower bound */
5416 klass = mono_array_class_get (klass, rank);
5417 mono_class_init (klass);
5424 return mono_type_get_object (mono_object_domain (tb), &klass->byval_arg);
5428 ves_icall_Type_IsArrayImpl (MonoReflectionType *t)
5433 MONO_ARCH_SAVE_REGS;
5436 res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
5441 static MonoReflectionType *
5442 ves_icall_Type_make_array_type (MonoReflectionType *type, int rank)
5444 MonoClass *klass, *aklass;
5446 MONO_ARCH_SAVE_REGS;
5448 klass = mono_class_from_mono_type (type->type);
5449 aklass = mono_array_class_get (klass, rank);
5451 return mono_type_get_object (mono_object_domain (type), &aklass->byval_arg);
5454 static MonoReflectionType *
5455 ves_icall_Type_make_byref_type (MonoReflectionType *type)
5459 MONO_ARCH_SAVE_REGS;
5461 klass = mono_class_from_mono_type (type->type);
5463 return mono_type_get_object (mono_object_domain (type), &klass->this_arg);
5466 static MonoReflectionType *
5467 ves_icall_Type_MakePointerType (MonoReflectionType *type)
5471 MONO_ARCH_SAVE_REGS;
5473 pklass = mono_ptr_class_get (type->type);
5475 return mono_type_get_object (mono_object_domain (type), &pklass->byval_arg);
5479 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
5480 MonoReflectionMethod *info)
5482 MonoClass *delegate_class = mono_class_from_mono_type (type->type);
5483 MonoObject *delegate;
5486 MONO_ARCH_SAVE_REGS;
5488 mono_assert (delegate_class->parent == mono_defaults.multicastdelegate_class);
5490 delegate = mono_object_new (mono_object_domain (type), delegate_class);
5492 if (info->method->dynamic)
5493 /* Creating a trampoline would leak memory */
5494 func = mono_compile_method (info->method);
5496 func = mono_create_ftnptr (mono_domain_get (), mono_runtime_create_jump_trampoline (mono_domain_get (), info->method, TRUE));
5498 mono_delegate_ctor (delegate, target, func);
5504 ves_icall_System_Delegate_SetMulticastInvoke (MonoDelegate *this)
5506 /* Reset the invoke impl to the default one */
5507 this->invoke_impl = mono_runtime_create_delegate_trampoline (this->object.vtable->klass);
5511 * Magic number to convert a time which is relative to
5512 * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
5514 #define EPOCH_ADJUST ((guint64)62135596800LL)
5517 * Magic number to convert FILETIME base Jan 1, 1601 to DateTime - base Jan, 1, 0001
5519 #define FILETIME_ADJUST ((guint64)504911232000000000LL)
5522 * This returns Now in UTC
5525 ves_icall_System_DateTime_GetNow (void)
5527 #ifdef PLATFORM_WIN32
5531 GetSystemTime (&st);
5532 SystemTimeToFileTime (&st, &ft);
5533 return (gint64) FILETIME_ADJUST + ((((gint64)ft.dwHighDateTime)<<32) | ft.dwLowDateTime);
5535 /* FIXME: put this in io-layer and call it GetLocalTime */
5539 MONO_ARCH_SAVE_REGS;
5541 if (gettimeofday (&tv, NULL) == 0) {
5542 res = (((gint64)tv.tv_sec + EPOCH_ADJUST)* 1000000 + tv.tv_usec)*10;
5545 /* fixme: raise exception */
5550 #ifdef PLATFORM_WIN32
5551 /* convert a SYSTEMTIME which is of the form "last thursday in october" to a real date */
5553 convert_to_absolute_date(SYSTEMTIME *date)
5555 #define IS_LEAP(y) ((y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0))
5556 static int days_in_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5557 static int leap_days_in_month[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5558 /* from the calendar FAQ */
5559 int a = (14 - date->wMonth) / 12;
5560 int y = date->wYear - a;
5561 int m = date->wMonth + 12 * a - 2;
5562 int d = (1 + y + y/4 - y/100 + y/400 + (31*m)/12) % 7;
5564 /* d is now the day of the week for the first of the month (0 == Sunday) */
5566 int day_of_week = date->wDayOfWeek;
5568 /* set day_in_month to the first day in the month which falls on day_of_week */
5569 int day_in_month = 1 + (day_of_week - d);
5570 if (day_in_month <= 0)
5573 /* wDay is 1 for first weekday in month, 2 for 2nd ... 5 means last - so work that out allowing for days in the month */
5574 date->wDay = day_in_month + (date->wDay - 1) * 7;
5575 if (date->wDay > (IS_LEAP(date->wYear) ? leap_days_in_month[date->wMonth - 1] : days_in_month[date->wMonth - 1]))
5580 #ifndef PLATFORM_WIN32
5582 * Return's the offset from GMT of a local time.
5584 * tm is a local time
5585 * t is the same local time as seconds.
5588 gmt_offset(struct tm *tm, time_t t)
5590 #if defined (HAVE_TM_GMTOFF)
5591 return tm->tm_gmtoff;
5596 g.tm_isdst = tm->tm_isdst;
5598 return (int)difftime(t, t2);
5603 * This is heavily based on zdump.c from glibc 2.2.
5605 * * data[0]: start of daylight saving time (in DateTime ticks).
5606 * * data[1]: end of daylight saving time (in DateTime ticks).
5607 * * data[2]: utcoffset (in TimeSpan ticks).
5608 * * data[3]: additional offset when daylight saving (in TimeSpan ticks).
5609 * * name[0]: name of this timezone when not daylight saving.
5610 * * name[1]: name of this timezone when daylight saving.
5612 * FIXME: This only works with "standard" Unix dates (years between 1900 and 2100) while
5613 * the class library allows years between 1 and 9999.
5615 * Returns true on success and zero on failure.
5618 ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year, MonoArray **data, MonoArray **names)
5620 #ifndef PLATFORM_WIN32
5621 MonoDomain *domain = mono_domain_get ();
5622 struct tm start, tt;
5626 int is_daylight = 0, day;
5629 MONO_ARCH_SAVE_REGS;
5631 MONO_CHECK_ARG_NULL (data);
5632 MONO_CHECK_ARG_NULL (names);
5634 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5635 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5638 * no info is better than crashing: we'll need our own tz data
5639 * to make this work properly, anyway. The range is probably
5640 * reduced to 1970 .. 2037 because that is what mktime is
5641 * guaranteed to support (we get into an infinite loop
5645 memset (&start, 0, sizeof (start));
5648 start.tm_year = year-1900;
5650 t = mktime (&start);
5652 if ((year < 1970) || (year > 2037) || (t == -1)) {
5654 tt = *localtime (&t);
5655 strftime (tzone, sizeof (tzone), "%Z", &tt);
5656 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5657 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5661 gmtoff = gmt_offset (&start, t);
5663 /* For each day of the year, calculate the tm_gmtoff. */
5664 for (day = 0; day < 365; day++) {
5667 tt = *localtime (&t);
5669 /* Daylight saving starts or ends here. */
5670 if (gmt_offset (&tt, t) != gmtoff) {
5674 /* Try to find the exact hour when daylight saving starts/ends. */
5678 tt1 = *localtime (&t1);
5679 } while (gmt_offset (&tt1, t1) != gmtoff);
5681 /* Try to find the exact minute when daylight saving starts/ends. */
5684 tt1 = *localtime (&t1);
5685 } while (gmt_offset (&tt1, t1) == gmtoff);
5687 strftime (tzone, sizeof (tzone), "%Z", &tt);
5689 /* Write data, if we're already in daylight saving, we're done. */
5691 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5692 mono_array_set ((*data), gint64, 1, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
5695 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5696 mono_array_set ((*data), gint64, 0, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
5700 /* This is only set once when we enter daylight saving. */
5701 mono_array_set ((*data), gint64, 2, (gint64)gmtoff * 10000000L);
5702 mono_array_set ((*data), gint64, 3, (gint64)(gmt_offset (&tt, t) - gmtoff) * 10000000L);
5704 gmtoff = gmt_offset (&tt, t);
5709 strftime (tzone, sizeof (tzone), "%Z", &tt);
5710 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5711 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5712 mono_array_set ((*data), gint64, 0, 0);
5713 mono_array_set ((*data), gint64, 1, 0);
5714 mono_array_set ((*data), gint64, 2, (gint64) gmtoff * 10000000L);
5715 mono_array_set ((*data), gint64, 3, 0);
5720 MonoDomain *domain = mono_domain_get ();
5721 TIME_ZONE_INFORMATION tz_info;
5726 tz_id = GetTimeZoneInformation (&tz_info);
5727 if (tz_id == TIME_ZONE_ID_INVALID)
5730 MONO_CHECK_ARG_NULL (data);
5731 MONO_CHECK_ARG_NULL (names);
5733 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5734 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5736 for (i = 0; i < 32; ++i)
5737 if (!tz_info.DaylightName [i])
5739 mono_array_setref ((*names), 1, mono_string_new_utf16 (domain, tz_info.DaylightName, i));
5740 for (i = 0; i < 32; ++i)
5741 if (!tz_info.StandardName [i])
5743 mono_array_setref ((*names), 0, mono_string_new_utf16 (domain, tz_info.StandardName, i));
5745 if ((year <= 1601) || (year > 30827)) {
5747 * According to MSDN, the MS time functions can't handle dates outside
5753 /* even if the timezone has no daylight savings it may have Bias (e.g. GMT+13 it seems) */
5754 if (tz_id != TIME_ZONE_ID_UNKNOWN) {
5755 tz_info.StandardDate.wYear = year;
5756 convert_to_absolute_date(&tz_info.StandardDate);
5757 err = SystemTimeToFileTime (&tz_info.StandardDate, &ft);
5762 mono_array_set ((*data), gint64, 1, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
5763 tz_info.DaylightDate.wYear = year;
5764 convert_to_absolute_date(&tz_info.DaylightDate);
5765 err = SystemTimeToFileTime (&tz_info.DaylightDate, &ft);
5770 mono_array_set ((*data), gint64, 0, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
5772 mono_array_set ((*data), gint64, 2, (tz_info.Bias + tz_info.StandardBias) * -600000000LL);
5773 mono_array_set ((*data), gint64, 3, (tz_info.DaylightBias - tz_info.StandardBias) * -600000000LL);
5780 ves_icall_System_Object_obj_address (MonoObject *this)
5782 MONO_ARCH_SAVE_REGS;
5789 static inline gint32
5790 mono_array_get_byte_length (MonoArray *array)
5796 klass = array->obj.vtable->klass;
5798 if (array->bounds == NULL)
5799 length = array->max_length;
5802 for (i = 0; i < klass->rank; ++ i)
5803 length *= array->bounds [i].length;
5806 switch (klass->element_class->byval_arg.type) {
5809 case MONO_TYPE_BOOLEAN:
5813 case MONO_TYPE_CHAR:
5821 return length * sizeof (gpointer);
5832 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array)
5834 MONO_ARCH_SAVE_REGS;
5836 return mono_array_get_byte_length (array);
5840 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx)
5842 MONO_ARCH_SAVE_REGS;
5844 return mono_array_get (array, gint8, idx);
5848 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value)
5850 MONO_ARCH_SAVE_REGS;
5852 mono_array_set (array, gint8, idx, value);
5856 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count)
5858 guint8 *src_buf, *dest_buf;
5860 MONO_ARCH_SAVE_REGS;
5862 /* watch out for integer overflow */
5863 if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count))
5866 src_buf = (guint8 *)src->vector + src_offset;
5867 dest_buf = (guint8 *)dest->vector + dest_offset;
5870 memcpy (dest_buf, src_buf, count);
5872 memmove (dest_buf, src_buf, count); /* Source and dest are the same array */
5878 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this, MonoString *class_name)
5880 MonoDomain *domain = mono_object_domain (this);
5882 MonoRealProxy *rp = ((MonoRealProxy *)this);
5883 MonoTransparentProxy *tp;
5887 MONO_ARCH_SAVE_REGS;
5889 res = mono_object_new (domain, mono_defaults.transparent_proxy_class);
5890 tp = (MonoTransparentProxy*) res;
5892 MONO_OBJECT_SETREF (tp, rp, rp);
5893 type = ((MonoReflectionType *)rp->class_to_proxy)->type;
5894 klass = mono_class_from_mono_type (type);
5896 tp->custom_type_info = (mono_object_isinst (this, mono_defaults.iremotingtypeinfo_class) != NULL);
5897 tp->remote_class = mono_remote_class (domain, class_name, klass);
5899 res->vtable = mono_remote_class_vtable (domain, tp->remote_class, rp);
5903 static MonoReflectionType *
5904 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
5906 return mono_type_get_object (mono_object_domain (tp), &tp->remote_class->proxy_class->byval_arg);
5909 /* System.Environment */
5912 ves_icall_System_Environment_get_MachineName (void)
5914 #if defined (PLATFORM_WIN32)
5919 len = MAX_COMPUTERNAME_LENGTH + 1;
5920 buf = g_new (gunichar2, len);
5923 if (GetComputerName (buf, (PDWORD) &len))
5924 result = mono_string_new_utf16 (mono_domain_get (), buf, len);
5932 if (gethostname (buf, sizeof (buf)) == 0)
5933 result = mono_string_new (mono_domain_get (), buf);
5942 ves_icall_System_Environment_get_Platform (void)
5944 MONO_ARCH_SAVE_REGS;
5946 #if defined (PLATFORM_WIN32)
5956 ves_icall_System_Environment_get_NewLine (void)
5958 MONO_ARCH_SAVE_REGS;
5960 #if defined (PLATFORM_WIN32)
5961 return mono_string_new (mono_domain_get (), "\r\n");
5963 return mono_string_new (mono_domain_get (), "\n");
5968 ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name)
5973 MONO_ARCH_SAVE_REGS;
5978 utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
5979 value = g_getenv (utf8_name);
5986 return mono_string_new (mono_domain_get (), value);
5990 * There is no standard way to get at environ.
5993 #ifndef __MINGW32_VERSION
6000 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
6002 #ifdef PLATFORM_WIN32
6011 env_strings = GetEnvironmentStrings();
6014 env_string = env_strings;
6015 while (*env_string != '\0') {
6016 /* weird case that MS seems to skip */
6017 if (*env_string != '=')
6019 while (*env_string != '\0')
6025 domain = mono_domain_get ();
6026 names = mono_array_new (domain, mono_defaults.string_class, n);
6030 env_string = env_strings;
6031 while (*env_string != '\0') {
6032 /* weird case that MS seems to skip */
6033 if (*env_string != '=') {
6034 equal_str = wcschr(env_string, '=');
6035 g_assert(equal_str);
6036 str = mono_string_new_utf16 (domain, env_string, equal_str-env_string);
6037 mono_array_setref (names, n, str);
6040 while (*env_string != '\0')
6045 FreeEnvironmentStrings (env_strings);
6057 MONO_ARCH_SAVE_REGS;
6060 for (e = environ; *e != 0; ++ e)
6063 domain = mono_domain_get ();
6064 names = mono_array_new (domain, mono_defaults.string_class, n);
6067 for (e = environ; *e != 0; ++ e) {
6068 parts = g_strsplit (*e, "=", 2);
6070 str = mono_string_new (domain, *parts);
6071 mono_array_setref (names, n, str);
6084 * If your platform lacks setenv/unsetenv, you must upgrade your glib.
6086 #if !GLIB_CHECK_VERSION(2,4,0)
6087 #define g_setenv(a,b,c) setenv(a,b,c)
6088 #define g_unsetenv(a) unsetenv(a)
6092 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
6094 #ifdef PLATFORM_WIN32
6095 gunichar2 *utf16_name, *utf16_value;
6097 gchar *utf8_name, *utf8_value;
6100 MONO_ARCH_SAVE_REGS;
6102 #ifdef PLATFORM_WIN32
6103 utf16_name = mono_string_to_utf16 (name);
6104 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
6105 SetEnvironmentVariable (utf16_name, NULL);
6106 g_free (utf16_name);
6110 utf16_value = mono_string_to_utf16 (value);
6112 SetEnvironmentVariable (utf16_name, utf16_value);
6114 g_free (utf16_name);
6115 g_free (utf16_value);
6117 utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
6119 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
6120 g_unsetenv (utf8_name);
6125 utf8_value = mono_string_to_utf8 (value);
6126 g_setenv (utf8_name, utf8_value, TRUE);
6129 g_free (utf8_value);
6134 * Returns: the number of milliseconds elapsed since the system started.
6137 ves_icall_System_Environment_get_TickCount (void)
6139 return GetTickCount ();
6144 ves_icall_System_Environment_Exit (int result)
6146 MONO_ARCH_SAVE_REGS;
6148 if (!mono_threads_set_shutting_down ())
6151 mono_runtime_set_shutting_down ();
6153 /* Suspend all managed threads since the runtime is going away */
6154 mono_thread_suspend_all_other_threads ();
6156 mono_runtime_quit ();
6158 /* we may need to do some cleanup here... */
6163 ves_icall_System_Environment_GetGacPath (void)
6165 return mono_string_new (mono_domain_get (), mono_assembly_getrootdir ());
6169 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
6171 #if defined (PLATFORM_WIN32)
6172 #ifndef CSIDL_FLAG_CREATE
6173 #define CSIDL_FLAG_CREATE 0x8000
6176 WCHAR path [MAX_PATH];
6177 /* Create directory if no existing */
6178 if (SUCCEEDED (SHGetFolderPathW (NULL, folder | CSIDL_FLAG_CREATE, NULL, 0, path))) {
6182 return mono_string_new_utf16 (mono_domain_get (), path, len);
6185 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
6187 return mono_string_new (mono_domain_get (), "");
6191 ves_icall_System_Environment_GetLogicalDrives (void)
6193 gunichar2 buf [128], *ptr, *dname;
6195 gint initial_size = 127, size = 128;
6198 MonoString *drivestr;
6199 MonoDomain *domain = mono_domain_get ();
6202 MONO_ARCH_SAVE_REGS;
6207 while (size > initial_size) {
6208 size = GetLogicalDriveStrings (initial_size, ptr);
6209 if (size > initial_size) {
6212 ptr = g_malloc0 ((size + 1) * sizeof (gunichar2));
6213 initial_size = size;
6227 result = mono_array_new (domain, mono_defaults.string_class, ndrives);
6232 while (*u16) { u16++; len ++; }
6233 drivestr = mono_string_new_utf16 (domain, dname, len);
6234 mono_array_setref (result, ndrives++, drivestr);
6245 ves_icall_System_Environment_InternalGetHome (void)
6247 MONO_ARCH_SAVE_REGS;
6249 return mono_string_new (mono_domain_get (), g_get_home_dir ());
6252 static const char *encodings [] = {
6254 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
6255 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
6256 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
6258 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
6259 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
6260 "x_unicode_2_0_utf_7",
6262 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
6263 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
6265 "utf_16", "UTF_16LE", "ucs_2", "unicode",
6268 "unicodefffe", "utf_16be",
6275 * Returns the internal codepage, if the value of "int_code_page" is
6276 * 1 at entry, and we can not compute a suitable code page number,
6277 * returns the code page as a string
6280 ves_icall_System_Text_Encoding_InternalCodePage (gint32 *int_code_page)
6285 char *codepage = NULL;
6287 int want_name = *int_code_page;
6290 *int_code_page = -1;
6291 MONO_ARCH_SAVE_REGS;
6293 g_get_charset (&cset);
6294 c = codepage = strdup (cset);
6295 for (c = codepage; *c; c++){
6296 if (isascii (*c) && isalpha (*c))
6301 /* g_print ("charset: %s\n", cset); */
6303 /* handle some common aliases */
6306 for (i = 0; p != 0; ){
6307 if ((gssize) p < 7){
6309 p = encodings [++i];
6312 if (strcmp (p, codepage) == 0){
6313 *int_code_page = code;
6316 p = encodings [++i];
6319 if (strstr (codepage, "utf_8") != NULL)
6320 *int_code_page |= 0x10000000;
6323 if (want_name && *int_code_page == -1)
6324 return mono_string_new (mono_domain_get (), cset);
6330 ves_icall_System_Environment_get_HasShutdownStarted (void)
6332 if (mono_runtime_is_shutting_down ())
6335 if (mono_domain_is_unloading (mono_domain_get ()))
6342 ves_icall_MonoMethodMessage_InitMessage (MonoMethodMessage *this,
6343 MonoReflectionMethod *method,
6344 MonoArray *out_args)
6346 MONO_ARCH_SAVE_REGS;
6348 mono_message_init (mono_object_domain (this), this, method, out_args);
6352 ves_icall_IsTransparentProxy (MonoObject *proxy)
6354 MONO_ARCH_SAVE_REGS;
6359 if (proxy->vtable->klass == mono_defaults.transparent_proxy_class)
6365 static MonoReflectionMethod *
6366 ves_icall_Remoting_RemotingServices_GetVirtualMethod (
6367 MonoReflectionType *rtype, MonoReflectionMethod *rmethod)
6371 MonoMethod **vtable;
6372 MonoMethod *res = NULL;
6374 MONO_CHECK_ARG_NULL (rtype);
6375 MONO_CHECK_ARG_NULL (rmethod);
6377 method = rmethod->method;
6378 klass = mono_class_from_mono_type (rtype->type);
6380 if (MONO_CLASS_IS_INTERFACE (klass))
6383 if (method->flags & METHOD_ATTRIBUTE_STATIC)
6386 if ((method->flags & METHOD_ATTRIBUTE_FINAL) || !(method->flags & METHOD_ATTRIBUTE_VIRTUAL)) {
6387 if (klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE))
6393 mono_class_setup_vtable (klass);
6394 vtable = klass->vtable;
6396 if (method->klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
6397 int offs = mono_class_interface_offset (klass, method->klass);
6399 res = vtable [offs + method->slot];
6401 if (!(klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE)))
6404 if (method->slot != -1)
6405 res = vtable [method->slot];
6411 return mono_method_get_object (mono_domain_get (), res, NULL);
6415 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6420 MONO_ARCH_SAVE_REGS;
6422 klass = mono_class_from_mono_type (type->type);
6423 vtable = mono_class_vtable (mono_domain_get (), klass);
6425 if (enable) vtable->remote = 1;
6426 else vtable->remote = 0;
6430 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type)
6435 MONO_ARCH_SAVE_REGS;
6437 domain = mono_object_domain (type);
6438 klass = mono_class_from_mono_type (type->type);
6440 if (klass->rank >= 1) {
6441 g_assert (klass->rank == 1);
6442 return (MonoObject *) mono_array_new (domain, klass->element_class, 0);
6444 /* Bypass remoting object creation check */
6445 return mono_object_new_alloc_specific (mono_class_vtable (domain, klass));
6450 ves_icall_System_IO_get_temp_path (void)
6452 MONO_ARCH_SAVE_REGS;
6454 return mono_string_new (mono_domain_get (), g_get_tmp_dir ());
6458 ves_icall_RuntimeMethod_GetFunctionPointer (MonoMethod *method)
6460 MONO_ARCH_SAVE_REGS;
6462 return mono_compile_method (method);
6466 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
6471 MONO_ARCH_SAVE_REGS;
6473 path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
6475 #if defined (PLATFORM_WIN32)
6476 /* Avoid mixing '/' and '\\' */
6479 for (i = strlen (path) - 1; i >= 0; i--)
6480 if (path [i] == '/')
6484 mcpath = mono_string_new (mono_domain_get (), path);
6491 get_bundled_machine_config (void)
6493 const gchar *machine_config;
6495 MONO_ARCH_SAVE_REGS;
6497 machine_config = mono_get_machine_config ();
6499 if (!machine_config)
6502 return mono_string_new (mono_domain_get (), machine_config);
6506 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
6511 MONO_ARCH_SAVE_REGS;
6513 path = g_path_get_dirname (mono_get_config_dir ());
6515 #if defined (PLATFORM_WIN32)
6516 /* Avoid mixing '/' and '\\' */
6519 for (i = strlen (path) - 1; i >= 0; i--)
6520 if (path [i] == '/')
6524 ipath = mono_string_new (mono_domain_get (), path);
6531 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
6533 #if defined (PLATFORM_WIN32)
6534 OutputDebugString (mono_string_chars (message));
6536 g_warning ("WriteWindowsDebugString called and PLATFORM_WIN32 not defined!\n");
6540 /* Only used for value types */
6542 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
6547 MONO_ARCH_SAVE_REGS;
6549 domain = mono_object_domain (type);
6550 klass = mono_class_from_mono_type (type->type);
6552 if (mono_class_is_nullable (klass))
6553 /* No arguments -> null */
6556 return mono_object_new (domain, klass);
6559 static MonoReflectionMethod *
6560 ves_icall_MonoMethod_get_base_definition (MonoReflectionMethod *m)
6562 MonoClass *klass, *parent;
6563 MonoMethod *method = m->method;
6564 MonoMethod *result = NULL;
6566 MONO_ARCH_SAVE_REGS;
6568 if (method->klass == NULL)
6571 if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
6572 MONO_CLASS_IS_INTERFACE (method->klass) ||
6573 method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
6576 klass = method->klass;
6577 if (klass->generic_class)
6578 klass = klass->generic_class->container_class;
6580 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
6581 for (parent = klass->parent; parent != NULL; parent = parent->parent) {
6582 mono_class_setup_vtable (parent);
6583 if (parent->vtable_size <= method->slot)
6588 if (klass == method->klass)
6591 result = klass->vtable [method->slot];
6592 if (result == NULL) {
6593 /* It is an abstract method */
6594 gpointer iter = NULL;
6595 while ((result = mono_class_get_methods (klass, &iter)))
6596 if (result->slot == method->slot)
6603 return mono_method_get_object (mono_domain_get (), result, NULL);
6607 ves_icall_MonoMethod_get_name (MonoReflectionMethod *m)
6609 MonoMethod *method = m->method;
6611 MONO_OBJECT_SETREF (m, name, mono_string_new (mono_object_domain (m), method->name));
6616 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
6618 MONO_ARCH_SAVE_REGS;
6620 iter->sig = *(MonoMethodSignature**)argsp;
6622 g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
6623 g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
6626 /* FIXME: it's not documented what start is exactly... */
6630 guint32 i, arg_size;
6632 iter->args = argsp + sizeof (gpointer);
6633 #ifndef MONO_ARCH_REGPARMS
6634 for (i = 0; i < iter->sig->sentinelpos; ++i) {
6635 arg_size = mono_type_stack_size (iter->sig->params [i], &align);
6636 iter->args = (char*)iter->args + arg_size;
6640 iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
6642 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
6646 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
6648 guint32 i, arg_size;
6651 MONO_ARCH_SAVE_REGS;
6653 i = iter->sig->sentinelpos + iter->next_arg;
6655 g_assert (i < iter->sig->param_count);
6657 res.type = iter->sig->params [i];
6658 res.klass = mono_class_from_mono_type (res.type);
6659 /* FIXME: endianess issue... */
6660 res.value = iter->args;
6661 arg_size = mono_type_stack_size (res.type, &align);
6662 iter->args = (char*)iter->args + arg_size;
6665 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6671 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
6673 guint32 i, arg_size;
6676 MONO_ARCH_SAVE_REGS;
6678 i = iter->sig->sentinelpos + iter->next_arg;
6680 g_assert (i < iter->sig->param_count);
6682 while (i < iter->sig->param_count) {
6683 if (!mono_metadata_type_equal (type, iter->sig->params [i]))
6685 res.type = iter->sig->params [i];
6686 res.klass = mono_class_from_mono_type (res.type);
6687 /* FIXME: endianess issue... */
6688 res.value = iter->args;
6689 arg_size = mono_type_stack_size (res.type, &align);
6690 iter->args = (char*)iter->args + arg_size;
6692 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6695 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
6704 mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
6707 MONO_ARCH_SAVE_REGS;
6709 i = iter->sig->sentinelpos + iter->next_arg;
6711 g_assert (i < iter->sig->param_count);
6713 return iter->sig->params [i];
6717 mono_TypedReference_ToObject (MonoTypedRef tref)
6719 MONO_ARCH_SAVE_REGS;
6721 if (MONO_TYPE_IS_REFERENCE (tref.type)) {
6722 MonoObject** objp = tref.value;
6726 return mono_value_box (mono_domain_get (), tref.klass, tref.value);
6730 mono_TypedReference_ToObjectInternal (MonoType *type, gpointer value, MonoClass *klass)
6732 MONO_ARCH_SAVE_REGS;
6734 if (MONO_TYPE_IS_REFERENCE (type)) {
6735 MonoObject** objp = value;
6739 return mono_value_box (mono_domain_get (), klass, value);
6743 prelink_method (MonoMethod *method)
6745 const char *exc_class, *exc_arg;
6746 if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
6748 mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
6750 mono_raise_exception(
6751 mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg ) );
6753 /* create the wrapper, too? */
6757 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
6759 MONO_ARCH_SAVE_REGS;
6760 prelink_method (method->method);
6764 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
6766 MonoClass *klass = mono_class_from_mono_type (type->type);
6768 gpointer iter = NULL;
6769 MONO_ARCH_SAVE_REGS;
6771 while ((m = mono_class_get_methods (klass, &iter)))
6775 /* These parameters are "readonly" in corlib/System/NumberFormatter.cs */
6777 ves_icall_System_NumberFormatter_GetFormatterTables (guint64 const **mantissas,
6778 gint32 const **exponents,
6779 gunichar2 const **digitLowerTable,
6780 gunichar2 const **digitUpperTable,
6781 gint64 const **tenPowersList,
6782 gint32 const **decHexDigits)
6784 *mantissas = Formatter_MantissaBitsTable;
6785 *exponents = Formatter_TensExponentTable;
6786 *digitLowerTable = Formatter_DigitLowerTable;
6787 *digitUpperTable = Formatter_DigitUpperTable;
6788 *tenPowersList = Formatter_TenPowersList;
6789 *decHexDigits = Formatter_DecHexDigits;
6792 /* These parameters are "readonly" in corlib/System/Char.cs */
6794 ves_icall_System_Char_GetDataTablePointers (guint8 const **category_data,
6795 guint8 const **numeric_data,
6796 gdouble const **numeric_data_values,
6797 guint16 const **to_lower_data_low,
6798 guint16 const **to_lower_data_high,
6799 guint16 const **to_upper_data_low,
6800 guint16 const **to_upper_data_high)
6802 *category_data = CategoryData;
6803 *numeric_data = NumericData;
6804 *numeric_data_values = NumericDataValues;
6805 *to_lower_data_low = ToLowerDataLow;
6806 *to_lower_data_high = ToLowerDataHigh;
6807 *to_upper_data_low = ToUpperDataLow;
6808 *to_upper_data_high = ToUpperDataHigh;
6812 ves_icall_MonoDebugger_GetMethodToken (MonoReflectionMethod *method)
6814 return method->method->token;
6818 * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
6819 * and avoid useless allocations.
6822 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional)
6826 for (i = 0; i < type->num_mods; ++i) {
6827 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
6832 res = mono_array_new (mono_domain_get (), mono_defaults.systemtype_class, count);
6834 for (i = 0; i < type->num_mods; ++i) {
6835 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
6836 MonoClass *klass = mono_class_get (image, type->modifiers [i].token);
6837 mono_array_setref (res, count, mono_type_get_object (mono_domain_get (), &klass->byval_arg));
6845 param_info_get_type_modifiers (MonoReflectionParameter *param, MonoBoolean optional)
6847 MonoType *type = param->ClassImpl->type;
6848 MonoReflectionMethod *method = (MonoReflectionMethod*)param->MemberImpl;
6849 MonoImage *image = method->method->klass->image;
6850 int pos = param->PositionImpl;
6851 MonoMethodSignature *sig = mono_method_signature (method->method);
6855 type = sig->params [pos];
6857 return type_array_from_modifiers (image, type, optional);
6861 get_property_type (MonoProperty *prop)
6863 MonoMethodSignature *sig;
6865 sig = mono_method_signature (prop->get);
6867 } else if (prop->set) {
6868 sig = mono_method_signature (prop->set);
6869 return sig->params [sig->param_count - 1];
6875 property_info_get_type_modifiers (MonoReflectionProperty *property, MonoBoolean optional)
6877 MonoType *type = get_property_type (property->property);
6878 MonoImage *image = property->klass->image;
6882 return type_array_from_modifiers (image, type, optional);
6886 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
6888 MonoCustomAttrInfo *cinfo;
6891 cinfo = mono_reflection_get_custom_attrs_info (obj);
6894 found = mono_custom_attrs_has_attr (cinfo, mono_class_from_mono_type (attr_type->type));
6896 mono_custom_attrs_free (cinfo);
6901 custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
6903 MonoArray *res = mono_reflection_get_custom_attrs_by_type (obj, attr_type ? mono_class_from_mono_type (attr_type->type) : NULL);
6905 if (mono_loader_get_last_error ()) {
6906 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
6907 g_assert_not_reached ();
6914 GCHandle_CheckCurrentDomain (guint32 gchandle)
6916 return mono_gchandle_is_in_domain (gchandle, mono_domain_get ());
6920 ves_icall_Mono_Runtime_GetDisplayName (void)
6922 static const char display_name_str [] = "Mono " VERSION;
6923 MonoString *display_name = mono_string_new (mono_domain_get (), display_name_str);
6924 return display_name;
6929 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
6930 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
6931 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 62, 128, 128, 128, 63,
6932 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 0, 128, 128,
6933 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
6934 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 128, 128, 128, 128, 128,
6935 128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
6936 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
6940 base64_to_byte_array (gunichar2 *start, gint ilength, MonoBoolean allowWhitespaceOnly)
6945 gunichar2 last, prev_last;
6953 last = prev_last = 0;
6954 for (i = 0; i < ilength; i++) {
6956 if (c >= sizeof (dbase64)) {
6957 exc = mono_exception_from_name_msg (mono_get_corlib (),
6958 "System", "FormatException",
6959 "Invalid character found.");
6960 mono_raise_exception (exc);
6961 } else if (isspace (c)) {
6969 olength = ilength - ignored;
6971 if (allowWhitespaceOnly && olength == 0) {
6972 return mono_array_new (mono_domain_get (), mono_defaults.byte_class, 0);
6975 if ((olength & 3) != 0 || olength <= 0) {
6976 exc = mono_exception_from_name_msg (mono_get_corlib (), "System",
6977 "FormatException", "Invalid length.");
6978 mono_raise_exception (exc);
6981 olength = (olength * 3) / 4;
6985 if (prev_last == '=')
6988 result = mono_array_new (mono_domain_get (), mono_defaults.byte_class, olength);
6989 res_ptr = mono_array_addr (result, guchar, 0);
6990 for (i = 0; i < ilength; ) {
6993 for (k = 0; k < 4 && i < ilength;) {
6999 if (((b [k] = dbase64 [c]) & 0x80) != 0) {
7000 exc = mono_exception_from_name_msg (mono_get_corlib (),
7001 "System", "FormatException",
7002 "Invalid character found.");
7003 mono_raise_exception (exc);
7008 *res_ptr++ = (b [0] << 2) | (b [1] >> 4);
7010 *res_ptr++ = (b [1] << 4) | (b [2] >> 2);
7012 *res_ptr++ = (b [2] << 6) | b [3];
7014 while (i < ilength && isspace (start [i]))
7022 InternalFromBase64String (MonoString *str, MonoBoolean allowWhitespaceOnly)
7024 MONO_ARCH_SAVE_REGS;
7026 return base64_to_byte_array (mono_string_chars (str),
7027 mono_string_length (str), allowWhitespaceOnly);
7031 InternalFromBase64CharArray (MonoArray *input, gint offset, gint length)
7033 MONO_ARCH_SAVE_REGS;
7035 return base64_to_byte_array (mono_array_addr (input, gunichar2, offset),
7039 #define ICALL_TYPE(id,name,first)
7040 #define ICALL(id,name,func) Icall_ ## id,
7043 #include "metadata/icall-def.h"
7049 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
7050 #define ICALL(id,name,func)
7052 #include "metadata/icall-def.h"
7058 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
7059 #define ICALL(id,name,func)
7061 guint16 first_icall;
7064 static const IcallTypeDesc
7065 icall_type_descs [] = {
7066 #include "metadata/icall-def.h"
7070 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
7073 #define ICALL_TYPE(id,name,first)
7076 #ifdef HAVE_ARRAY_ELEM_INIT
7077 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
7078 #define MSGSTRFIELD1(line) str##line
7080 static const struct msgstrtn_t {
7081 #define ICALL(id,name,func)
7083 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7084 #include "metadata/icall-def.h"
7086 } icall_type_names_str = {
7087 #define ICALL_TYPE(id,name,first) (name),
7088 #include "metadata/icall-def.h"
7091 static const guint16 icall_type_names_idx [] = {
7092 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
7093 #include "metadata/icall-def.h"
7096 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
7098 static const struct msgstr_t {
7100 #define ICALL_TYPE(id,name,first)
7101 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7102 #include "metadata/icall-def.h"
7104 } icall_names_str = {
7105 #define ICALL(id,name,func) (name),
7106 #include "metadata/icall-def.h"
7109 static const guint16 icall_names_idx [] = {
7110 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
7111 #include "metadata/icall-def.h"
7114 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
7120 #define ICALL_TYPE(id,name,first) name,
7121 #define ICALL(id,name,func)
7122 static const char* const
7123 icall_type_names [] = {
7124 #include "metadata/icall-def.h"
7128 #define icall_type_name_get(id) (icall_type_names [(id)])
7132 #define ICALL_TYPE(id,name,first)
7133 #define ICALL(id,name,func) name,
7134 static const char* const
7136 #include "metadata/icall-def.h"
7139 #define icall_name_get(id) icall_names [(id)]
7141 #endif /* !HAVE_ARRAY_ELEM_INIT */
7145 #define ICALL_TYPE(id,name,first)
7146 #define ICALL(id,name,func) func,
7147 static const gconstpointer
7148 icall_functions [] = {
7149 #include "metadata/icall-def.h"
7153 static GHashTable *icall_hash = NULL;
7154 static GHashTable *jit_icall_hash_name = NULL;
7155 static GHashTable *jit_icall_hash_addr = NULL;
7158 mono_icall_init (void)
7162 /* check that tables are sorted: disable in release */
7165 const char *prev_class = NULL;
7166 const char *prev_method;
7168 for (i = 0; i < Icall_type_num; ++i) {
7169 const IcallTypeDesc *desc;
7172 if (prev_class && strcmp (prev_class, icall_type_name_get (i)) >= 0)
7173 g_print ("class %s should come before class %s\n", icall_type_name_get (i), prev_class);
7174 prev_class = icall_type_name_get (i);
7175 desc = &icall_type_descs [i];
7176 num_icalls = icall_desc_num_icalls (desc);
7177 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
7178 for (j = 0; j < num_icalls; ++j) {
7179 const char *methodn = icall_name_get (desc->first_icall + j);
7180 if (prev_method && strcmp (prev_method, methodn) >= 0)
7181 g_print ("method %s should come before method %s\n", methodn, prev_method);
7182 prev_method = methodn;
7187 icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
7191 mono_icall_cleanup (void)
7193 g_hash_table_destroy (icall_hash);
7194 g_hash_table_destroy (jit_icall_hash_name);
7195 g_hash_table_destroy (jit_icall_hash_addr);
7199 mono_add_internal_call (const char *name, gconstpointer method)
7201 mono_loader_lock ();
7203 g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
7205 mono_loader_unlock ();
7208 #ifdef HAVE_ARRAY_ELEM_INIT
7210 compare_method_imap (const void *key, const void *elem)
7212 const char* method_name = (const char*)&icall_names_str + (*(guint16*)elem);
7213 return strcmp (key, method_name);
7217 find_method_icall (const IcallTypeDesc *imap, const char *name)
7219 const guint16 *nameslot = bsearch (name, icall_names_idx + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names_idx [0]), compare_method_imap);
7222 return (gpointer)icall_functions [(nameslot - &icall_names_idx [0])];
7226 compare_class_imap (const void *key, const void *elem)
7228 const char* class_name = (const char*)&icall_type_names_str + (*(guint16*)elem);
7229 return strcmp (key, class_name);
7232 static const IcallTypeDesc*
7233 find_class_icalls (const char *name)
7235 const guint16 *nameslot = bsearch (name, icall_type_names_idx, Icall_type_num, sizeof (icall_type_names_idx [0]), compare_class_imap);
7238 return &icall_type_descs [nameslot - &icall_type_names_idx [0]];
7243 compare_method_imap (const void *key, const void *elem)
7245 const char** method_name = (const char**)elem;
7246 return strcmp (key, *method_name);
7250 find_method_icall (const IcallTypeDesc *imap, const char *name)
7252 const char **nameslot = bsearch (name, icall_names + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names [0]), compare_method_imap);
7255 return (gpointer)icall_functions [(nameslot - icall_names)];
7259 compare_class_imap (const void *key, const void *elem)
7261 const char** class_name = (const char**)elem;
7262 return strcmp (key, *class_name);
7265 static const IcallTypeDesc*
7266 find_class_icalls (const char *name)
7268 const char **nameslot = bsearch (name, icall_type_names, Icall_type_num, sizeof (icall_type_names [0]), compare_class_imap);
7271 return &icall_type_descs [nameslot - icall_type_names];
7277 * we should probably export this as an helper (handle nested types).
7278 * Returns the number of chars written in buf.
7281 concat_class_name (char *buf, int bufsize, MonoClass *klass)
7283 int nspacelen, cnamelen;
7284 nspacelen = strlen (klass->name_space);
7285 cnamelen = strlen (klass->name);
7286 if (nspacelen + cnamelen + 2 > bufsize)
7289 memcpy (buf, klass->name_space, nspacelen);
7290 buf [nspacelen ++] = '.';
7292 memcpy (buf + nspacelen, klass->name, cnamelen);
7293 buf [nspacelen + cnamelen] = 0;
7294 return nspacelen + cnamelen;
7298 mono_lookup_internal_call (MonoMethod *method)
7303 int typelen = 0, mlen, siglen;
7305 const IcallTypeDesc *imap;
7307 g_assert (method != NULL);
7309 if (method->is_inflated)
7310 method = ((MonoMethodInflated *) method)->declaring;
7312 if (method->klass->nested_in) {
7313 int pos = concat_class_name (mname, sizeof (mname)-2, method->klass->nested_in);
7317 mname [pos++] = '/';
7320 typelen = concat_class_name (mname+pos, sizeof (mname)-pos-1, method->klass);
7326 typelen = concat_class_name (mname, sizeof (mname), method->klass);
7331 imap = find_class_icalls (mname);
7333 mname [typelen] = ':';
7334 mname [typelen + 1] = ':';
7336 mlen = strlen (method->name);
7337 memcpy (mname + typelen + 2, method->name, mlen);
7338 sigstart = mname + typelen + 2 + mlen;
7341 tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
7342 siglen = strlen (tmpsig);
7343 if (typelen + mlen + siglen + 6 > sizeof (mname))
7346 memcpy (sigstart + 1, tmpsig, siglen);
7347 sigstart [siglen + 1] = ')';
7348 sigstart [siglen + 2] = 0;
7351 mono_loader_lock ();
7353 res = g_hash_table_lookup (icall_hash, mname);
7355 mono_loader_unlock ();
7358 /* try without signature */
7360 res = g_hash_table_lookup (icall_hash, mname);
7362 mono_loader_unlock ();
7366 /* it wasn't found in the static call tables */
7368 mono_loader_unlock ();
7371 res = find_method_icall (imap, sigstart - mlen);
7373 mono_loader_unlock ();
7376 /* try _with_ signature */
7378 res = find_method_icall (imap, sigstart - mlen);
7380 mono_loader_unlock ();
7384 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname);
7385 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
7386 g_print ("The out of sync library is: %s\n", method->klass->image->name);
7387 g_print ("\nWhen you update one from cvs you need to update, compile and install\nthe other too.\n");
7388 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");
7389 g_print ("If you see other errors or faults after this message they are probably related\n");
7390 g_print ("and you need to fix your mono install first.\n");
7392 mono_loader_unlock ();
7398 type_from_typename (char *typename)
7400 MonoClass *klass = NULL; /* assignment to shut GCC warning up */
7402 if (!strcmp (typename, "int"))
7403 klass = mono_defaults.int_class;
7404 else if (!strcmp (typename, "ptr"))
7405 klass = mono_defaults.int_class;
7406 else if (!strcmp (typename, "void"))
7407 klass = mono_defaults.void_class;
7408 else if (!strcmp (typename, "int32"))
7409 klass = mono_defaults.int32_class;
7410 else if (!strcmp (typename, "uint32"))
7411 klass = mono_defaults.uint32_class;
7412 else if (!strcmp (typename, "int8"))
7413 klass = mono_defaults.sbyte_class;
7414 else if (!strcmp (typename, "uint8"))
7415 klass = mono_defaults.byte_class;
7416 else if (!strcmp (typename, "int16"))
7417 klass = mono_defaults.int16_class;
7418 else if (!strcmp (typename, "uint16"))
7419 klass = mono_defaults.uint16_class;
7420 else if (!strcmp (typename, "long"))
7421 klass = mono_defaults.int64_class;
7422 else if (!strcmp (typename, "ulong"))
7423 klass = mono_defaults.uint64_class;
7424 else if (!strcmp (typename, "float"))
7425 klass = mono_defaults.single_class;
7426 else if (!strcmp (typename, "double"))
7427 klass = mono_defaults.double_class;
7428 else if (!strcmp (typename, "object"))
7429 klass = mono_defaults.object_class;
7430 else if (!strcmp (typename, "obj"))
7431 klass = mono_defaults.object_class;
7434 g_assert_not_reached ();
7436 return &klass->byval_arg;
7439 MonoMethodSignature*
7440 mono_create_icall_signature (const char *sigstr)
7445 MonoMethodSignature *res;
7447 mono_loader_lock ();
7448 res = g_hash_table_lookup (mono_defaults.corlib->helper_signatures, sigstr);
7450 mono_loader_unlock ();
7454 parts = g_strsplit (sigstr, " ", 256);
7463 res = mono_metadata_signature_alloc (mono_defaults.corlib, len - 1);
7466 #ifdef PLATFORM_WIN32
7468 * Under windows, the default pinvoke calling convention is STDCALL but
7471 res->call_convention = MONO_CALL_C;
7474 res->ret = type_from_typename (parts [0]);
7475 for (i = 1; i < len; ++i) {
7476 res->params [i - 1] = type_from_typename (parts [i]);
7481 g_hash_table_insert (mono_defaults.corlib->helper_signatures, (gpointer)sigstr, res);
7483 mono_loader_unlock ();
7489 mono_find_jit_icall_by_name (const char *name)
7491 MonoJitICallInfo *info;
7492 g_assert (jit_icall_hash_name);
7494 mono_loader_lock ();
7495 info = g_hash_table_lookup (jit_icall_hash_name, name);
7496 mono_loader_unlock ();
7501 mono_find_jit_icall_by_addr (gconstpointer addr)
7503 MonoJitICallInfo *info;
7504 g_assert (jit_icall_hash_addr);
7506 mono_loader_lock ();
7507 info = g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
7508 mono_loader_unlock ();
7514 mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
7516 mono_loader_lock ();
7517 g_hash_table_insert (jit_icall_hash_addr, (gpointer)wrapper, info);
7518 mono_loader_unlock ();
7522 mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
7524 MonoJitICallInfo *info;
7529 mono_loader_lock ();
7531 if (!jit_icall_hash_name) {
7532 jit_icall_hash_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
7533 jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
7536 if (g_hash_table_lookup (jit_icall_hash_name, name)) {
7537 g_warning ("jit icall already defined \"%s\"\n", name);
7538 g_assert_not_reached ();
7541 info = g_new0 (MonoJitICallInfo, 1);
7548 info->wrapper = func;
7550 info->wrapper = NULL;
7553 g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
7554 g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
7556 mono_loader_unlock ();