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_FillName (MonoReflectionAssembly *assembly, MonoReflectionAssemblyName *aname)
4789 MonoAssembly *mass = assembly->assembly;
4791 MONO_ARCH_SAVE_REGS;
4793 if (g_path_is_absolute (mass->image->name)) {
4794 fill_reflection_assembly_name (mono_object_domain (assembly),
4795 aname, &mass->aname, mass->image->name, TRUE,
4796 TRUE, mono_get_runtime_info ()->framework_version [0] >= '2');
4799 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4801 fill_reflection_assembly_name (mono_object_domain (assembly),
4802 aname, &mass->aname, absolute, TRUE, TRUE,
4803 mono_get_runtime_info ()->framework_version [0] >= '2');
4809 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoString *fname, MonoReflectionAssemblyName *aname)
4812 MonoImageOpenStatus status = MONO_IMAGE_OK;
4815 MonoAssemblyName name;
4817 MONO_ARCH_SAVE_REGS;
4819 filename = mono_string_to_utf8 (fname);
4821 image = mono_image_open (filename, &status);
4827 if (status == MONO_IMAGE_IMAGE_INVALID)
4828 exc = mono_get_exception_bad_image_format2 (NULL, fname);
4830 exc = mono_get_exception_file_not_found2 (NULL, fname);
4831 mono_raise_exception (exc);
4834 res = mono_assembly_fill_assembly_name (image, &name);
4836 mono_image_close (image);
4838 mono_raise_exception (mono_get_exception_argument ("assemblyFile", "The file does not contain a manifest"));
4841 fill_reflection_assembly_name (mono_domain_get (), aname, &name, filename,
4842 TRUE, mono_get_runtime_info ()->framework_version [0] == '1',
4843 mono_get_runtime_info ()->framework_version [0] >= '2');
4846 mono_image_close (image);
4850 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssembly *assembly,
4851 char **minimum, guint32 *minLength, char **optional, guint32 *optLength, char **refused, guint32 *refLength)
4853 MonoBoolean result = FALSE;
4854 MonoDeclSecurityEntry entry;
4856 /* SecurityAction.RequestMinimum */
4857 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQMIN, &entry)) {
4858 *minimum = entry.blob;
4859 *minLength = entry.size;
4862 /* SecurityAction.RequestOptional */
4863 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQOPT, &entry)) {
4864 *optional = entry.blob;
4865 *optLength = entry.size;
4868 /* SecurityAction.RequestRefuse */
4869 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQREFUSE, &entry)) {
4870 *refused = entry.blob;
4871 *refLength = entry.size;
4879 mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoBoolean exportedOnly)
4883 MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
4885 guint32 attrs, visibility;
4887 /* we start the count from 1 because we skip the special type <Module> */
4890 for (i = 1; i < tdef->rows; ++i) {
4891 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
4892 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
4893 if (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)
4897 count = tdef->rows - 1;
4899 res = mono_array_new (domain, mono_defaults.monotype_class, count);
4901 for (i = 1; i < tdef->rows; ++i) {
4902 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
4903 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
4904 if (!exportedOnly || (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)) {
4905 klass = mono_class_get_throw (image, (i + 1) | MONO_TOKEN_TYPE_DEF);
4906 if (mono_loader_get_last_error ())
4907 mono_loader_clear_error ();
4908 mono_array_setref (res, count, mono_type_get_object (domain, &klass->byval_arg));
4917 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly, MonoBoolean exportedOnly)
4919 MonoArray *res = NULL;
4920 MonoImage *image = NULL;
4921 MonoTableInfo *table = NULL;
4926 MONO_ARCH_SAVE_REGS;
4928 domain = mono_object_domain (assembly);
4930 g_assert (!assembly->assembly->dynamic);
4931 image = assembly->assembly->image;
4932 table = &image->tables [MONO_TABLE_FILE];
4933 res = mono_module_get_types (domain, image, exportedOnly);
4935 /* Append data from all modules in the assembly */
4936 for (i = 0; i < table->rows; ++i) {
4937 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4938 MonoImage *loaded_image = mono_assembly_load_module (image->assembly, i + 1);
4940 MonoArray *res2 = mono_module_get_types (domain, loaded_image, exportedOnly);
4941 /* Append the new types to the end of the array */
4942 if (mono_array_length (res2) > 0) {
4946 len1 = mono_array_length (res);
4947 len2 = mono_array_length (res2);
4948 res3 = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4949 mono_array_memcpy_refs (res3, 0, res, 0, len1);
4950 mono_array_memcpy_refs (res3, len1, res2, 0, len2);
4957 /* the ReflectionTypeLoadException must have all the types (Types property),
4958 * NULL replacing types which throws an exception. The LoaderException must
4959 * contain all exceptions for NULL items.
4962 len = mono_array_length (res);
4964 for (i = 0; i < len; i++) {
4965 MonoReflectionType *t = mono_array_get (res, gpointer, i);
4966 MonoClass *klass = mono_type_get_class (t->type);
4967 if ((klass != NULL) && klass->exception_type) {
4968 /* keep the class in the list */
4969 list = g_list_append (list, klass);
4970 /* and replace Type with NULL */
4971 mono_array_setref (res, i, NULL);
4977 MonoException *exc = NULL;
4978 MonoArray *exl = NULL;
4979 int length = g_list_length (list);
4981 mono_loader_clear_error ();
4983 exl = mono_array_new (domain, mono_defaults.exception_class, length);
4984 for (i = 0, tmp = list; i < length; i++, tmp = tmp->next) {
4985 MonoException *exc = mono_class_get_exception_for_failure (tmp->data);
4986 mono_array_setref (exl, i, exc);
4991 exc = mono_get_exception_reflection_type_load (res, exl);
4992 mono_loader_clear_error ();
4993 mono_raise_exception (exc);
5000 ves_icall_System_Reflection_AssemblyName_ParseName (MonoReflectionAssemblyName *name, MonoString *assname)
5002 MonoAssemblyName aname;
5003 MonoDomain *domain = mono_object_domain (name);
5005 gboolean is_version_defined;
5006 gboolean is_token_defined;
5008 val = mono_string_to_utf8 (assname);
5009 if (!mono_assembly_name_parse_full (val, &aname, TRUE, &is_version_defined, &is_token_defined))
5012 fill_reflection_assembly_name (domain, name, &aname, "", is_version_defined,
5013 FALSE, is_token_defined);
5015 mono_assembly_name_free (&aname);
5016 g_free ((guint8*) aname.public_key);
5022 static MonoReflectionType*
5023 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModule *module)
5025 MonoDomain *domain = mono_object_domain (module);
5028 MONO_ARCH_SAVE_REGS;
5030 g_assert (module->image);
5032 if (module->image->dynamic && ((MonoDynamicImage*)(module->image))->initial_image)
5033 /* These images do not have a global type */
5036 klass = mono_class_get (module->image, 1 | MONO_TOKEN_TYPE_DEF);
5037 return mono_type_get_object (domain, &klass->byval_arg);
5041 ves_icall_System_Reflection_Module_Close (MonoReflectionModule *module)
5043 /*if (module->image)
5044 mono_image_close (module->image);*/
5048 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModule *module)
5050 MonoDomain *domain = mono_object_domain (module);
5052 MONO_ARCH_SAVE_REGS;
5054 g_assert (module->image);
5055 return mono_string_new (domain, module->image->guid);
5059 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine)
5061 if (image->dynamic) {
5062 MonoDynamicImage *dyn = (MonoDynamicImage*)image;
5063 *pe_kind = dyn->pe_kind;
5064 *machine = dyn->machine;
5067 *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
5068 *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
5073 ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage *image)
5075 return (image->md_version_major << 16) | (image->md_version_minor);
5079 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModule *module)
5081 MONO_ARCH_SAVE_REGS;
5084 return mono_array_new (mono_object_domain (module), mono_defaults.monotype_class, 0);
5086 return mono_module_get_types (mono_object_domain (module), module->image, FALSE);
5090 mono_metadata_memberref_is_method (MonoImage *image, guint32 token)
5092 guint32 cols [MONO_MEMBERREF_SIZE];
5094 mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
5095 sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
5096 mono_metadata_decode_blob_size (sig, &sig);
5097 return (*sig != 0x6);
5101 init_generic_context_from_args (MonoGenericContext *context, MonoArray *type_args, MonoArray *method_args)
5104 context->class_inst = mono_metadata_get_generic_inst (mono_array_length (type_args),
5105 mono_array_addr (type_args, MonoType*, 0));
5107 context->class_inst = NULL;
5109 context->method_inst = mono_metadata_get_generic_inst (mono_array_length (method_args),
5110 mono_array_addr (method_args, MonoType*, 0));
5112 context->method_inst = NULL;
5116 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5119 int table = mono_metadata_token_table (token);
5120 int index = mono_metadata_token_index (token);
5121 MonoGenericContext context;
5123 *error = ResolveTokenError_Other;
5125 /* Validate token */
5126 if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) &&
5127 (table != MONO_TABLE_TYPESPEC)) {
5128 *error = ResolveTokenError_BadTable;
5132 if (image->dynamic) {
5133 if (type_args || method_args)
5134 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5135 return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5138 if ((index <= 0) || (index > image->tables [table].rows)) {
5139 *error = ResolveTokenError_OutOfRange;
5143 init_generic_context_from_args (&context, type_args, method_args);
5144 klass = mono_class_get_full (image, token, &context);
5147 return &klass->byval_arg;
5153 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5155 int table = mono_metadata_token_table (token);
5156 int index = mono_metadata_token_index (token);
5157 MonoGenericContext context;
5160 *error = ResolveTokenError_Other;
5162 /* Validate token */
5163 if ((table != MONO_TABLE_METHOD) && (table != MONO_TABLE_METHODSPEC) &&
5164 (table != MONO_TABLE_MEMBERREF)) {
5165 *error = ResolveTokenError_BadTable;
5169 if (image->dynamic) {
5170 if (type_args || method_args)
5171 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5172 /* FIXME: validate memberref token type */
5173 return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5176 if ((index <= 0) || (index > image->tables [table].rows)) {
5177 *error = ResolveTokenError_OutOfRange;
5180 if ((table == MONO_TABLE_MEMBERREF) && (!mono_metadata_memberref_is_method (image, token))) {
5181 *error = ResolveTokenError_BadTable;
5185 init_generic_context_from_args (&context, type_args, method_args);
5186 method = mono_get_method_full (image, token, NULL, &context);
5192 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
5194 int index = mono_metadata_token_index (token);
5196 *error = ResolveTokenError_Other;
5198 /* Validate token */
5199 if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
5200 *error = ResolveTokenError_BadTable;
5205 return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5207 if ((index <= 0) || (index >= image->heap_us.size)) {
5208 *error = ResolveTokenError_OutOfRange;
5212 /* FIXME: What to do if the index points into the middle of a string ? */
5214 return mono_ldstr (mono_domain_get (), image, index);
5217 static MonoClassField*
5218 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5221 int table = mono_metadata_token_table (token);
5222 int index = mono_metadata_token_index (token);
5223 MonoGenericContext context;
5224 MonoClassField *field;
5226 *error = ResolveTokenError_Other;
5228 /* Validate token */
5229 if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
5230 *error = ResolveTokenError_BadTable;
5234 if (image->dynamic) {
5235 if (type_args || method_args)
5236 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5237 /* FIXME: validate memberref token type */
5238 return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5241 if ((index <= 0) || (index > image->tables [table].rows)) {
5242 *error = ResolveTokenError_OutOfRange;
5245 if ((table == MONO_TABLE_MEMBERREF) && (mono_metadata_memberref_is_method (image, token))) {
5246 *error = ResolveTokenError_BadTable;
5250 init_generic_context_from_args (&context, type_args, method_args);
5251 field = mono_field_from_token (image, token, &klass, &context);
5258 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5260 int table = mono_metadata_token_table (token);
5262 *error = ResolveTokenError_Other;
5265 case MONO_TABLE_TYPEDEF:
5266 case MONO_TABLE_TYPEREF:
5267 case MONO_TABLE_TYPESPEC: {
5268 MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, type_args, method_args, error);
5270 return (MonoObject*)mono_type_get_object (mono_domain_get (), t);
5274 case MONO_TABLE_METHOD:
5275 case MONO_TABLE_METHODSPEC: {
5276 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5278 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
5282 case MONO_TABLE_FIELD: {
5283 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5285 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
5289 case MONO_TABLE_MEMBERREF:
5290 if (mono_metadata_memberref_is_method (image, token)) {
5291 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5293 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
5298 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5300 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
5307 *error = ResolveTokenError_BadTable;
5314 ves_icall_System_Reflection_Module_ResolveSignature (MonoImage *image, guint32 token, MonoResolveTokenError *error)
5316 int table = mono_metadata_token_table (token);
5317 int idx = mono_metadata_token_index (token);
5318 MonoTableInfo *tables = image->tables;
5323 *error = ResolveTokenError_OutOfRange;
5325 /* FIXME: Support other tables ? */
5326 if (table != MONO_TABLE_STANDALONESIG)
5332 if ((idx == 0) || (idx > tables [MONO_TABLE_STANDALONESIG].rows))
5335 sig = mono_metadata_decode_row_col (&tables [MONO_TABLE_STANDALONESIG], idx - 1, 0);
5337 ptr = mono_metadata_blob_heap (image, sig);
5338 len = mono_metadata_decode_blob_size (ptr, &ptr);
5340 res = mono_array_new (mono_domain_get (), mono_defaults.byte_class, len);
5341 memcpy (mono_array_addr (res, guint8, 0), ptr, len);
5345 static MonoReflectionType*
5346 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
5349 int isbyref = 0, rank;
5350 char *str = mono_string_to_utf8 (smodifiers);
5353 MONO_ARCH_SAVE_REGS;
5355 klass = mono_class_from_mono_type (tb->type.type);
5357 /* logic taken from mono_reflection_parse_type(): keep in sync */
5361 if (isbyref) { /* only one level allowed by the spec */
5368 return mono_type_get_object (mono_object_domain (tb), &klass->this_arg);
5371 klass = mono_ptr_class_get (&klass->byval_arg);
5372 mono_class_init (klass);
5383 else if (*p != '*') { /* '*' means unknown lower bound */
5394 klass = mono_array_class_get (klass, rank);
5395 mono_class_init (klass);
5402 return mono_type_get_object (mono_object_domain (tb), &klass->byval_arg);
5406 ves_icall_Type_IsArrayImpl (MonoReflectionType *t)
5411 MONO_ARCH_SAVE_REGS;
5414 res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
5419 static MonoReflectionType *
5420 ves_icall_Type_make_array_type (MonoReflectionType *type, int rank)
5422 MonoClass *klass, *aklass;
5424 MONO_ARCH_SAVE_REGS;
5426 klass = mono_class_from_mono_type (type->type);
5427 aklass = mono_array_class_get (klass, rank);
5429 return mono_type_get_object (mono_object_domain (type), &aklass->byval_arg);
5432 static MonoReflectionType *
5433 ves_icall_Type_make_byref_type (MonoReflectionType *type)
5437 MONO_ARCH_SAVE_REGS;
5439 klass = mono_class_from_mono_type (type->type);
5441 return mono_type_get_object (mono_object_domain (type), &klass->this_arg);
5444 static MonoReflectionType *
5445 ves_icall_Type_MakePointerType (MonoReflectionType *type)
5449 MONO_ARCH_SAVE_REGS;
5451 pklass = mono_ptr_class_get (type->type);
5453 return mono_type_get_object (mono_object_domain (type), &pklass->byval_arg);
5457 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
5458 MonoReflectionMethod *info)
5460 MonoClass *delegate_class = mono_class_from_mono_type (type->type);
5461 MonoObject *delegate;
5464 MONO_ARCH_SAVE_REGS;
5466 mono_assert (delegate_class->parent == mono_defaults.multicastdelegate_class);
5468 delegate = mono_object_new (mono_object_domain (type), delegate_class);
5470 if (info->method->dynamic)
5471 /* Creating a trampoline would leak memory */
5472 func = mono_compile_method (info->method);
5474 func = mono_create_ftnptr (mono_domain_get (), mono_runtime_create_jump_trampoline (mono_domain_get (), info->method, TRUE));
5476 mono_delegate_ctor (delegate, target, func);
5482 ves_icall_System_Delegate_SetMulticastInvoke (MonoDelegate *this)
5484 /* Reset the invoke impl to the default one */
5485 this->invoke_impl = mono_runtime_create_delegate_trampoline (this->object.vtable->klass);
5489 * Magic number to convert a time which is relative to
5490 * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
5492 #define EPOCH_ADJUST ((guint64)62135596800LL)
5495 * Magic number to convert FILETIME base Jan 1, 1601 to DateTime - base Jan, 1, 0001
5497 #define FILETIME_ADJUST ((guint64)504911232000000000LL)
5500 * This returns Now in UTC
5503 ves_icall_System_DateTime_GetNow (void)
5505 #ifdef PLATFORM_WIN32
5509 GetSystemTime (&st);
5510 SystemTimeToFileTime (&st, &ft);
5511 return (gint64) FILETIME_ADJUST + ((((gint64)ft.dwHighDateTime)<<32) | ft.dwLowDateTime);
5513 /* FIXME: put this in io-layer and call it GetLocalTime */
5517 MONO_ARCH_SAVE_REGS;
5519 if (gettimeofday (&tv, NULL) == 0) {
5520 res = (((gint64)tv.tv_sec + EPOCH_ADJUST)* 1000000 + tv.tv_usec)*10;
5523 /* fixme: raise exception */
5528 #ifdef PLATFORM_WIN32
5529 /* convert a SYSTEMTIME which is of the form "last thursday in october" to a real date */
5531 convert_to_absolute_date(SYSTEMTIME *date)
5533 #define IS_LEAP(y) ((y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0))
5534 static int days_in_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5535 static int leap_days_in_month[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5536 /* from the calendar FAQ */
5537 int a = (14 - date->wMonth) / 12;
5538 int y = date->wYear - a;
5539 int m = date->wMonth + 12 * a - 2;
5540 int d = (1 + y + y/4 - y/100 + y/400 + (31*m)/12) % 7;
5542 /* d is now the day of the week for the first of the month (0 == Sunday) */
5544 int day_of_week = date->wDayOfWeek;
5546 /* set day_in_month to the first day in the month which falls on day_of_week */
5547 int day_in_month = 1 + (day_of_week - d);
5548 if (day_in_month <= 0)
5551 /* wDay is 1 for first weekday in month, 2 for 2nd ... 5 means last - so work that out allowing for days in the month */
5552 date->wDay = day_in_month + (date->wDay - 1) * 7;
5553 if (date->wDay > (IS_LEAP(date->wYear) ? leap_days_in_month[date->wMonth - 1] : days_in_month[date->wMonth - 1]))
5558 #ifndef PLATFORM_WIN32
5560 * Return's the offset from GMT of a local time.
5562 * tm is a local time
5563 * t is the same local time as seconds.
5566 gmt_offset(struct tm *tm, time_t t)
5568 #if defined (HAVE_TM_GMTOFF)
5569 return tm->tm_gmtoff;
5574 g.tm_isdst = tm->tm_isdst;
5576 return (int)difftime(t, t2);
5581 * This is heavily based on zdump.c from glibc 2.2.
5583 * * data[0]: start of daylight saving time (in DateTime ticks).
5584 * * data[1]: end of daylight saving time (in DateTime ticks).
5585 * * data[2]: utcoffset (in TimeSpan ticks).
5586 * * data[3]: additional offset when daylight saving (in TimeSpan ticks).
5587 * * name[0]: name of this timezone when not daylight saving.
5588 * * name[1]: name of this timezone when daylight saving.
5590 * FIXME: This only works with "standard" Unix dates (years between 1900 and 2100) while
5591 * the class library allows years between 1 and 9999.
5593 * Returns true on success and zero on failure.
5596 ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year, MonoArray **data, MonoArray **names)
5598 #ifndef PLATFORM_WIN32
5599 MonoDomain *domain = mono_domain_get ();
5600 struct tm start, tt;
5604 int is_daylight = 0, day;
5607 MONO_ARCH_SAVE_REGS;
5609 MONO_CHECK_ARG_NULL (data);
5610 MONO_CHECK_ARG_NULL (names);
5612 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5613 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5616 * no info is better than crashing: we'll need our own tz data
5617 * to make this work properly, anyway. The range is probably
5618 * reduced to 1970 .. 2037 because that is what mktime is
5619 * guaranteed to support (we get into an infinite loop
5623 memset (&start, 0, sizeof (start));
5626 start.tm_year = year-1900;
5628 t = mktime (&start);
5630 if ((year < 1970) || (year > 2037) || (t == -1)) {
5632 tt = *localtime (&t);
5633 strftime (tzone, sizeof (tzone), "%Z", &tt);
5634 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5635 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5639 gmtoff = gmt_offset (&start, t);
5641 /* For each day of the year, calculate the tm_gmtoff. */
5642 for (day = 0; day < 365; day++) {
5645 tt = *localtime (&t);
5647 /* Daylight saving starts or ends here. */
5648 if (gmt_offset (&tt, t) != gmtoff) {
5652 /* Try to find the exact hour when daylight saving starts/ends. */
5656 tt1 = *localtime (&t1);
5657 } while (gmt_offset (&tt1, t1) != gmtoff);
5659 /* Try to find the exact minute when daylight saving starts/ends. */
5662 tt1 = *localtime (&t1);
5663 } while (gmt_offset (&tt1, t1) == gmtoff);
5665 strftime (tzone, sizeof (tzone), "%Z", &tt);
5667 /* Write data, if we're already in daylight saving, we're done. */
5669 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5670 mono_array_set ((*data), gint64, 1, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
5673 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5674 mono_array_set ((*data), gint64, 0, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
5678 /* This is only set once when we enter daylight saving. */
5679 mono_array_set ((*data), gint64, 2, (gint64)gmtoff * 10000000L);
5680 mono_array_set ((*data), gint64, 3, (gint64)(gmt_offset (&tt, t) - gmtoff) * 10000000L);
5682 gmtoff = gmt_offset (&tt, t);
5687 strftime (tzone, sizeof (tzone), "%Z", &tt);
5688 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5689 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5690 mono_array_set ((*data), gint64, 0, 0);
5691 mono_array_set ((*data), gint64, 1, 0);
5692 mono_array_set ((*data), gint64, 2, (gint64) gmtoff * 10000000L);
5693 mono_array_set ((*data), gint64, 3, 0);
5698 MonoDomain *domain = mono_domain_get ();
5699 TIME_ZONE_INFORMATION tz_info;
5704 tz_id = GetTimeZoneInformation (&tz_info);
5705 if (tz_id == TIME_ZONE_ID_INVALID)
5708 MONO_CHECK_ARG_NULL (data);
5709 MONO_CHECK_ARG_NULL (names);
5711 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5712 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5714 for (i = 0; i < 32; ++i)
5715 if (!tz_info.DaylightName [i])
5717 mono_array_setref ((*names), 1, mono_string_new_utf16 (domain, tz_info.DaylightName, i));
5718 for (i = 0; i < 32; ++i)
5719 if (!tz_info.StandardName [i])
5721 mono_array_setref ((*names), 0, mono_string_new_utf16 (domain, tz_info.StandardName, i));
5723 if ((year <= 1601) || (year > 30827)) {
5725 * According to MSDN, the MS time functions can't handle dates outside
5731 /* even if the timezone has no daylight savings it may have Bias (e.g. GMT+13 it seems) */
5732 if (tz_id != TIME_ZONE_ID_UNKNOWN) {
5733 tz_info.StandardDate.wYear = year;
5734 convert_to_absolute_date(&tz_info.StandardDate);
5735 err = SystemTimeToFileTime (&tz_info.StandardDate, &ft);
5740 mono_array_set ((*data), gint64, 1, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
5741 tz_info.DaylightDate.wYear = year;
5742 convert_to_absolute_date(&tz_info.DaylightDate);
5743 err = SystemTimeToFileTime (&tz_info.DaylightDate, &ft);
5748 mono_array_set ((*data), gint64, 0, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
5750 mono_array_set ((*data), gint64, 2, (tz_info.Bias + tz_info.StandardBias) * -600000000LL);
5751 mono_array_set ((*data), gint64, 3, (tz_info.DaylightBias - tz_info.StandardBias) * -600000000LL);
5758 ves_icall_System_Object_obj_address (MonoObject *this)
5760 MONO_ARCH_SAVE_REGS;
5767 static inline gint32
5768 mono_array_get_byte_length (MonoArray *array)
5774 klass = array->obj.vtable->klass;
5776 if (array->bounds == NULL)
5777 length = array->max_length;
5780 for (i = 0; i < klass->rank; ++ i)
5781 length *= array->bounds [i].length;
5784 switch (klass->element_class->byval_arg.type) {
5787 case MONO_TYPE_BOOLEAN:
5791 case MONO_TYPE_CHAR:
5799 return length * sizeof (gpointer);
5810 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array)
5812 MONO_ARCH_SAVE_REGS;
5814 return mono_array_get_byte_length (array);
5818 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx)
5820 MONO_ARCH_SAVE_REGS;
5822 return mono_array_get (array, gint8, idx);
5826 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value)
5828 MONO_ARCH_SAVE_REGS;
5830 mono_array_set (array, gint8, idx, value);
5834 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count)
5836 guint8 *src_buf, *dest_buf;
5838 MONO_ARCH_SAVE_REGS;
5840 /* watch out for integer overflow */
5841 if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count))
5844 src_buf = (guint8 *)src->vector + src_offset;
5845 dest_buf = (guint8 *)dest->vector + dest_offset;
5848 memcpy (dest_buf, src_buf, count);
5850 memmove (dest_buf, src_buf, count); /* Source and dest are the same array */
5856 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this, MonoString *class_name)
5858 MonoDomain *domain = mono_object_domain (this);
5860 MonoRealProxy *rp = ((MonoRealProxy *)this);
5861 MonoTransparentProxy *tp;
5865 MONO_ARCH_SAVE_REGS;
5867 res = mono_object_new (domain, mono_defaults.transparent_proxy_class);
5868 tp = (MonoTransparentProxy*) res;
5870 MONO_OBJECT_SETREF (tp, rp, rp);
5871 type = ((MonoReflectionType *)rp->class_to_proxy)->type;
5872 klass = mono_class_from_mono_type (type);
5874 tp->custom_type_info = (mono_object_isinst (this, mono_defaults.iremotingtypeinfo_class) != NULL);
5875 tp->remote_class = mono_remote_class (domain, class_name, klass);
5877 res->vtable = mono_remote_class_vtable (domain, tp->remote_class, rp);
5881 static MonoReflectionType *
5882 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
5884 return mono_type_get_object (mono_object_domain (tp), &tp->remote_class->proxy_class->byval_arg);
5887 /* System.Environment */
5890 ves_icall_System_Environment_get_MachineName (void)
5892 #if defined (PLATFORM_WIN32)
5897 len = MAX_COMPUTERNAME_LENGTH + 1;
5898 buf = g_new (gunichar2, len);
5901 if (GetComputerName (buf, (PDWORD) &len))
5902 result = mono_string_new_utf16 (mono_domain_get (), buf, len);
5910 if (gethostname (buf, sizeof (buf)) == 0)
5911 result = mono_string_new (mono_domain_get (), buf);
5920 ves_icall_System_Environment_get_Platform (void)
5922 MONO_ARCH_SAVE_REGS;
5924 #if defined (PLATFORM_WIN32)
5934 ves_icall_System_Environment_get_NewLine (void)
5936 MONO_ARCH_SAVE_REGS;
5938 #if defined (PLATFORM_WIN32)
5939 return mono_string_new (mono_domain_get (), "\r\n");
5941 return mono_string_new (mono_domain_get (), "\n");
5946 ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name)
5951 MONO_ARCH_SAVE_REGS;
5956 utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
5957 value = g_getenv (utf8_name);
5964 return mono_string_new (mono_domain_get (), value);
5968 * There is no standard way to get at environ.
5971 #ifndef __MINGW32_VERSION
5978 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
5980 #ifdef PLATFORM_WIN32
5989 env_strings = GetEnvironmentStrings();
5992 env_string = env_strings;
5993 while (*env_string != '\0') {
5994 /* weird case that MS seems to skip */
5995 if (*env_string != '=')
5997 while (*env_string != '\0')
6003 domain = mono_domain_get ();
6004 names = mono_array_new (domain, mono_defaults.string_class, n);
6008 env_string = env_strings;
6009 while (*env_string != '\0') {
6010 /* weird case that MS seems to skip */
6011 if (*env_string != '=') {
6012 equal_str = wcschr(env_string, '=');
6013 g_assert(equal_str);
6014 str = mono_string_new_utf16 (domain, env_string, equal_str-env_string);
6015 mono_array_setref (names, n, str);
6018 while (*env_string != '\0')
6023 FreeEnvironmentStrings (env_strings);
6035 MONO_ARCH_SAVE_REGS;
6038 for (e = environ; *e != 0; ++ e)
6041 domain = mono_domain_get ();
6042 names = mono_array_new (domain, mono_defaults.string_class, n);
6045 for (e = environ; *e != 0; ++ e) {
6046 parts = g_strsplit (*e, "=", 2);
6048 str = mono_string_new (domain, *parts);
6049 mono_array_setref (names, n, str);
6062 * If your platform lacks setenv/unsetenv, you must upgrade your glib.
6064 #if !GLIB_CHECK_VERSION(2,4,0)
6065 #define g_setenv(a,b,c) setenv(a,b,c)
6066 #define g_unsetenv(a) unsetenv(a)
6070 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
6072 #ifdef PLATFORM_WIN32
6073 gunichar2 *utf16_name, *utf16_value;
6075 gchar *utf8_name, *utf8_value;
6078 MONO_ARCH_SAVE_REGS;
6080 #ifdef PLATFORM_WIN32
6081 utf16_name = mono_string_to_utf16 (name);
6082 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
6083 SetEnvironmentVariable (utf16_name, NULL);
6084 g_free (utf16_name);
6088 utf16_value = mono_string_to_utf16 (value);
6090 SetEnvironmentVariable (utf16_name, utf16_value);
6092 g_free (utf16_name);
6093 g_free (utf16_value);
6095 utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
6097 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
6098 g_unsetenv (utf8_name);
6103 utf8_value = mono_string_to_utf8 (value);
6104 g_setenv (utf8_name, utf8_value, TRUE);
6107 g_free (utf8_value);
6112 * Returns: the number of milliseconds elapsed since the system started.
6115 ves_icall_System_Environment_get_TickCount (void)
6117 return GetTickCount ();
6122 ves_icall_System_Environment_Exit (int result)
6124 MONO_ARCH_SAVE_REGS;
6126 if (!mono_threads_set_shutting_down ())
6129 mono_runtime_set_shutting_down ();
6131 /* Suspend all managed threads since the runtime is going away */
6132 mono_thread_suspend_all_other_threads ();
6134 mono_runtime_quit ();
6136 /* we may need to do some cleanup here... */
6141 ves_icall_System_Environment_GetGacPath (void)
6143 return mono_string_new (mono_domain_get (), mono_assembly_getrootdir ());
6147 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
6149 #if defined (PLATFORM_WIN32)
6150 #ifndef CSIDL_FLAG_CREATE
6151 #define CSIDL_FLAG_CREATE 0x8000
6154 WCHAR path [MAX_PATH];
6155 /* Create directory if no existing */
6156 if (SUCCEEDED (SHGetFolderPathW (NULL, folder | CSIDL_FLAG_CREATE, NULL, 0, path))) {
6160 return mono_string_new_utf16 (mono_domain_get (), path, len);
6163 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
6165 return mono_string_new (mono_domain_get (), "");
6169 ves_icall_System_Environment_GetLogicalDrives (void)
6171 gunichar2 buf [128], *ptr, *dname;
6173 gint initial_size = 127, size = 128;
6176 MonoString *drivestr;
6177 MonoDomain *domain = mono_domain_get ();
6180 MONO_ARCH_SAVE_REGS;
6185 while (size > initial_size) {
6186 size = GetLogicalDriveStrings (initial_size, ptr);
6187 if (size > initial_size) {
6190 ptr = g_malloc0 ((size + 1) * sizeof (gunichar2));
6191 initial_size = size;
6205 result = mono_array_new (domain, mono_defaults.string_class, ndrives);
6210 while (*u16) { u16++; len ++; }
6211 drivestr = mono_string_new_utf16 (domain, dname, len);
6212 mono_array_setref (result, ndrives++, drivestr);
6223 ves_icall_System_Environment_InternalGetHome (void)
6225 MONO_ARCH_SAVE_REGS;
6227 return mono_string_new (mono_domain_get (), g_get_home_dir ());
6230 static const char *encodings [] = {
6232 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
6233 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
6234 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
6236 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
6237 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
6238 "x_unicode_2_0_utf_7",
6240 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
6241 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
6243 "utf_16", "UTF_16LE", "ucs_2", "unicode",
6246 "unicodefffe", "utf_16be",
6253 * Returns the internal codepage, if the value of "int_code_page" is
6254 * 1 at entry, and we can not compute a suitable code page number,
6255 * returns the code page as a string
6258 ves_icall_System_Text_Encoding_InternalCodePage (gint32 *int_code_page)
6263 char *codepage = NULL;
6265 int want_name = *int_code_page;
6268 *int_code_page = -1;
6269 MONO_ARCH_SAVE_REGS;
6271 g_get_charset (&cset);
6272 c = codepage = strdup (cset);
6273 for (c = codepage; *c; c++){
6274 if (isascii (*c) && isalpha (*c))
6279 /* g_print ("charset: %s\n", cset); */
6281 /* handle some common aliases */
6284 for (i = 0; p != 0; ){
6285 if ((gssize) p < 7){
6287 p = encodings [++i];
6290 if (strcmp (p, codepage) == 0){
6291 *int_code_page = code;
6294 p = encodings [++i];
6297 if (strstr (codepage, "utf_8") != NULL)
6298 *int_code_page |= 0x10000000;
6301 if (want_name && *int_code_page == -1)
6302 return mono_string_new (mono_domain_get (), cset);
6308 ves_icall_System_Environment_get_HasShutdownStarted (void)
6310 if (mono_runtime_is_shutting_down ())
6313 if (mono_domain_is_unloading (mono_domain_get ()))
6320 ves_icall_MonoMethodMessage_InitMessage (MonoMethodMessage *this,
6321 MonoReflectionMethod *method,
6322 MonoArray *out_args)
6324 MONO_ARCH_SAVE_REGS;
6326 mono_message_init (mono_object_domain (this), this, method, out_args);
6330 ves_icall_IsTransparentProxy (MonoObject *proxy)
6332 MONO_ARCH_SAVE_REGS;
6337 if (proxy->vtable->klass == mono_defaults.transparent_proxy_class)
6343 static MonoReflectionMethod *
6344 ves_icall_Remoting_RemotingServices_GetVirtualMethod (
6345 MonoReflectionType *rtype, MonoReflectionMethod *rmethod)
6349 MonoMethod **vtable;
6350 MonoMethod *res = NULL;
6352 MONO_CHECK_ARG_NULL (rtype);
6353 MONO_CHECK_ARG_NULL (rmethod);
6355 method = rmethod->method;
6356 klass = mono_class_from_mono_type (rtype->type);
6358 if (MONO_CLASS_IS_INTERFACE (klass))
6361 if (method->flags & METHOD_ATTRIBUTE_STATIC)
6364 if ((method->flags & METHOD_ATTRIBUTE_FINAL) || !(method->flags & METHOD_ATTRIBUTE_VIRTUAL)) {
6365 if (klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE))
6371 mono_class_setup_vtable (klass);
6372 vtable = klass->vtable;
6374 if (method->klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
6375 int offs = mono_class_interface_offset (klass, method->klass);
6377 res = vtable [offs + method->slot];
6379 if (!(klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE)))
6382 if (method->slot != -1)
6383 res = vtable [method->slot];
6389 return mono_method_get_object (mono_domain_get (), res, NULL);
6393 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6398 MONO_ARCH_SAVE_REGS;
6400 klass = mono_class_from_mono_type (type->type);
6401 vtable = mono_class_vtable (mono_domain_get (), klass);
6403 if (enable) vtable->remote = 1;
6404 else vtable->remote = 0;
6408 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type)
6413 MONO_ARCH_SAVE_REGS;
6415 domain = mono_object_domain (type);
6416 klass = mono_class_from_mono_type (type->type);
6418 if (klass->rank >= 1) {
6419 g_assert (klass->rank == 1);
6420 return (MonoObject *) mono_array_new (domain, klass->element_class, 0);
6422 /* Bypass remoting object creation check */
6423 return mono_object_new_alloc_specific (mono_class_vtable (domain, klass));
6428 ves_icall_System_IO_get_temp_path (void)
6430 MONO_ARCH_SAVE_REGS;
6432 return mono_string_new (mono_domain_get (), g_get_tmp_dir ());
6436 ves_icall_RuntimeMethod_GetFunctionPointer (MonoMethod *method)
6438 MONO_ARCH_SAVE_REGS;
6440 return mono_compile_method (method);
6444 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
6449 MONO_ARCH_SAVE_REGS;
6451 path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
6453 #if defined (PLATFORM_WIN32)
6454 /* Avoid mixing '/' and '\\' */
6457 for (i = strlen (path) - 1; i >= 0; i--)
6458 if (path [i] == '/')
6462 mcpath = mono_string_new (mono_domain_get (), path);
6469 get_bundled_machine_config (void)
6471 const gchar *machine_config;
6473 MONO_ARCH_SAVE_REGS;
6475 machine_config = mono_get_machine_config ();
6477 if (!machine_config)
6480 return mono_string_new (mono_domain_get (), machine_config);
6484 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
6489 MONO_ARCH_SAVE_REGS;
6491 path = g_path_get_dirname (mono_get_config_dir ());
6493 #if defined (PLATFORM_WIN32)
6494 /* Avoid mixing '/' and '\\' */
6497 for (i = strlen (path) - 1; i >= 0; i--)
6498 if (path [i] == '/')
6502 ipath = mono_string_new (mono_domain_get (), path);
6509 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
6511 #if defined (PLATFORM_WIN32)
6512 OutputDebugString (mono_string_chars (message));
6514 g_warning ("WriteWindowsDebugString called and PLATFORM_WIN32 not defined!\n");
6518 /* Only used for value types */
6520 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
6525 MONO_ARCH_SAVE_REGS;
6527 domain = mono_object_domain (type);
6528 klass = mono_class_from_mono_type (type->type);
6530 if (mono_class_is_nullable (klass))
6531 /* No arguments -> null */
6534 return mono_object_new (domain, klass);
6537 static MonoReflectionMethod *
6538 ves_icall_MonoMethod_get_base_definition (MonoReflectionMethod *m)
6540 MonoClass *klass, *parent;
6541 MonoMethod *method = m->method;
6542 MonoMethod *result = NULL;
6544 MONO_ARCH_SAVE_REGS;
6546 if (method->klass == NULL)
6549 if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
6550 MONO_CLASS_IS_INTERFACE (method->klass) ||
6551 method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
6554 klass = method->klass;
6555 if (klass->generic_class)
6556 klass = klass->generic_class->container_class;
6558 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
6559 for (parent = klass->parent; parent != NULL; parent = parent->parent) {
6560 mono_class_setup_vtable (parent);
6561 if (parent->vtable_size <= method->slot)
6566 if (klass == method->klass)
6569 result = klass->vtable [method->slot];
6570 if (result == NULL) {
6571 /* It is an abstract method */
6572 gpointer iter = NULL;
6573 while ((result = mono_class_get_methods (klass, &iter)))
6574 if (result->slot == method->slot)
6581 return mono_method_get_object (mono_domain_get (), result, NULL);
6585 ves_icall_MonoMethod_get_name (MonoReflectionMethod *m)
6587 MonoMethod *method = m->method;
6589 MONO_OBJECT_SETREF (m, name, mono_string_new (mono_object_domain (m), method->name));
6594 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
6596 MONO_ARCH_SAVE_REGS;
6598 iter->sig = *(MonoMethodSignature**)argsp;
6600 g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
6601 g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
6604 /* FIXME: it's not documented what start is exactly... */
6608 guint32 i, arg_size;
6610 iter->args = argsp + sizeof (gpointer);
6611 #ifndef MONO_ARCH_REGPARMS
6612 for (i = 0; i < iter->sig->sentinelpos; ++i) {
6613 arg_size = mono_type_stack_size (iter->sig->params [i], &align);
6614 iter->args = (char*)iter->args + arg_size;
6618 iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
6620 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
6624 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
6626 guint32 i, arg_size;
6629 MONO_ARCH_SAVE_REGS;
6631 i = iter->sig->sentinelpos + iter->next_arg;
6633 g_assert (i < iter->sig->param_count);
6635 res.type = iter->sig->params [i];
6636 res.klass = mono_class_from_mono_type (res.type);
6637 /* FIXME: endianess issue... */
6638 res.value = iter->args;
6639 arg_size = mono_type_stack_size (res.type, &align);
6640 iter->args = (char*)iter->args + arg_size;
6643 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6649 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
6651 guint32 i, arg_size;
6654 MONO_ARCH_SAVE_REGS;
6656 i = iter->sig->sentinelpos + iter->next_arg;
6658 g_assert (i < iter->sig->param_count);
6660 while (i < iter->sig->param_count) {
6661 if (!mono_metadata_type_equal (type, iter->sig->params [i]))
6663 res.type = iter->sig->params [i];
6664 res.klass = mono_class_from_mono_type (res.type);
6665 /* FIXME: endianess issue... */
6666 res.value = iter->args;
6667 arg_size = mono_type_stack_size (res.type, &align);
6668 iter->args = (char*)iter->args + arg_size;
6670 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6673 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
6682 mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
6685 MONO_ARCH_SAVE_REGS;
6687 i = iter->sig->sentinelpos + iter->next_arg;
6689 g_assert (i < iter->sig->param_count);
6691 return iter->sig->params [i];
6695 mono_TypedReference_ToObject (MonoTypedRef tref)
6697 MONO_ARCH_SAVE_REGS;
6699 if (MONO_TYPE_IS_REFERENCE (tref.type)) {
6700 MonoObject** objp = tref.value;
6704 return mono_value_box (mono_domain_get (), tref.klass, tref.value);
6708 mono_TypedReference_ToObjectInternal (MonoType *type, gpointer value, MonoClass *klass)
6710 MONO_ARCH_SAVE_REGS;
6712 if (MONO_TYPE_IS_REFERENCE (type)) {
6713 MonoObject** objp = value;
6717 return mono_value_box (mono_domain_get (), klass, value);
6721 prelink_method (MonoMethod *method)
6723 const char *exc_class, *exc_arg;
6724 if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
6726 mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
6728 mono_raise_exception(
6729 mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg ) );
6731 /* create the wrapper, too? */
6735 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
6737 MONO_ARCH_SAVE_REGS;
6738 prelink_method (method->method);
6742 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
6744 MonoClass *klass = mono_class_from_mono_type (type->type);
6746 gpointer iter = NULL;
6747 MONO_ARCH_SAVE_REGS;
6749 while ((m = mono_class_get_methods (klass, &iter)))
6753 /* These parameters are "readonly" in corlib/System/NumberFormatter.cs */
6755 ves_icall_System_NumberFormatter_GetFormatterTables (guint64 const **mantissas,
6756 gint32 const **exponents,
6757 gunichar2 const **digitLowerTable,
6758 gunichar2 const **digitUpperTable,
6759 gint64 const **tenPowersList,
6760 gint32 const **decHexDigits)
6762 *mantissas = Formatter_MantissaBitsTable;
6763 *exponents = Formatter_TensExponentTable;
6764 *digitLowerTable = Formatter_DigitLowerTable;
6765 *digitUpperTable = Formatter_DigitUpperTable;
6766 *tenPowersList = Formatter_TenPowersList;
6767 *decHexDigits = Formatter_DecHexDigits;
6770 /* These parameters are "readonly" in corlib/System/Char.cs */
6772 ves_icall_System_Char_GetDataTablePointers (guint8 const **category_data,
6773 guint8 const **numeric_data,
6774 gdouble const **numeric_data_values,
6775 guint16 const **to_lower_data_low,
6776 guint16 const **to_lower_data_high,
6777 guint16 const **to_upper_data_low,
6778 guint16 const **to_upper_data_high)
6780 *category_data = CategoryData;
6781 *numeric_data = NumericData;
6782 *numeric_data_values = NumericDataValues;
6783 *to_lower_data_low = ToLowerDataLow;
6784 *to_lower_data_high = ToLowerDataHigh;
6785 *to_upper_data_low = ToUpperDataLow;
6786 *to_upper_data_high = ToUpperDataHigh;
6790 ves_icall_MonoDebugger_GetMethodToken (MonoReflectionMethod *method)
6792 return method->method->token;
6796 * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
6797 * and avoid useless allocations.
6800 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional)
6804 for (i = 0; i < type->num_mods; ++i) {
6805 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
6810 res = mono_array_new (mono_domain_get (), mono_defaults.systemtype_class, count);
6812 for (i = 0; i < type->num_mods; ++i) {
6813 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
6814 MonoClass *klass = mono_class_get (image, type->modifiers [i].token);
6815 mono_array_setref (res, count, mono_type_get_object (mono_domain_get (), &klass->byval_arg));
6823 param_info_get_type_modifiers (MonoReflectionParameter *param, MonoBoolean optional)
6825 MonoType *type = param->ClassImpl->type;
6826 MonoReflectionMethod *method = (MonoReflectionMethod*)param->MemberImpl;
6827 MonoImage *image = method->method->klass->image;
6828 int pos = param->PositionImpl;
6829 MonoMethodSignature *sig = mono_method_signature (method->method);
6833 type = sig->params [pos];
6835 return type_array_from_modifiers (image, type, optional);
6839 get_property_type (MonoProperty *prop)
6841 MonoMethodSignature *sig;
6843 sig = mono_method_signature (prop->get);
6845 } else if (prop->set) {
6846 sig = mono_method_signature (prop->set);
6847 return sig->params [sig->param_count - 1];
6853 property_info_get_type_modifiers (MonoReflectionProperty *property, MonoBoolean optional)
6855 MonoType *type = get_property_type (property->property);
6856 MonoImage *image = property->klass->image;
6860 return type_array_from_modifiers (image, type, optional);
6864 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
6866 MonoCustomAttrInfo *cinfo;
6869 cinfo = mono_reflection_get_custom_attrs_info (obj);
6872 found = mono_custom_attrs_has_attr (cinfo, mono_class_from_mono_type (attr_type->type));
6874 mono_custom_attrs_free (cinfo);
6879 custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
6881 MonoArray *res = mono_reflection_get_custom_attrs_by_type (obj, attr_type ? mono_class_from_mono_type (attr_type->type) : NULL);
6883 if (mono_loader_get_last_error ()) {
6884 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
6885 g_assert_not_reached ();
6892 GCHandle_CheckCurrentDomain (guint32 gchandle)
6894 return mono_gchandle_is_in_domain (gchandle, mono_domain_get ());
6898 ves_icall_Mono_Runtime_GetDisplayName (void)
6900 static const char display_name_str [] = "Mono " VERSION;
6901 MonoString *display_name = mono_string_new (mono_domain_get (), display_name_str);
6902 return display_name;
6907 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
6908 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
6909 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 62, 128, 128, 128, 63,
6910 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 0, 128, 128,
6911 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
6912 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 128, 128, 128, 128, 128,
6913 128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
6914 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
6918 base64_to_byte_array (gunichar2 *start, gint ilength, MonoBoolean allowWhitespaceOnly)
6923 gunichar2 last, prev_last;
6931 last = prev_last = 0;
6932 for (i = 0; i < ilength; i++) {
6934 if (c >= sizeof (dbase64)) {
6935 exc = mono_exception_from_name_msg (mono_get_corlib (),
6936 "System", "FormatException",
6937 "Invalid character found.");
6938 mono_raise_exception (exc);
6939 } else if (isspace (c)) {
6947 olength = ilength - ignored;
6949 if (allowWhitespaceOnly && olength == 0) {
6950 return mono_array_new (mono_domain_get (), mono_defaults.byte_class, 0);
6953 if ((olength & 3) != 0 || olength <= 0) {
6954 exc = mono_exception_from_name_msg (mono_get_corlib (), "System",
6955 "FormatException", "Invalid length.");
6956 mono_raise_exception (exc);
6959 olength = (olength * 3) / 4;
6963 if (prev_last == '=')
6966 result = mono_array_new (mono_domain_get (), mono_defaults.byte_class, olength);
6967 res_ptr = mono_array_addr (result, guchar, 0);
6968 for (i = 0; i < ilength; ) {
6971 for (k = 0; k < 4 && i < ilength;) {
6977 if (((b [k] = dbase64 [c]) & 0x80) != 0) {
6978 exc = mono_exception_from_name_msg (mono_get_corlib (),
6979 "System", "FormatException",
6980 "Invalid character found.");
6981 mono_raise_exception (exc);
6986 *res_ptr++ = (b [0] << 2) | (b [1] >> 4);
6988 *res_ptr++ = (b [1] << 4) | (b [2] >> 2);
6990 *res_ptr++ = (b [2] << 6) | b [3];
6992 while (i < ilength && isspace (start [i]))
7000 InternalFromBase64String (MonoString *str, MonoBoolean allowWhitespaceOnly)
7002 MONO_ARCH_SAVE_REGS;
7004 return base64_to_byte_array (mono_string_chars (str),
7005 mono_string_length (str), allowWhitespaceOnly);
7009 InternalFromBase64CharArray (MonoArray *input, gint offset, gint length)
7011 MONO_ARCH_SAVE_REGS;
7013 return base64_to_byte_array (mono_array_addr (input, gunichar2, offset),
7017 #define ICALL_TYPE(id,name,first)
7018 #define ICALL(id,name,func) Icall_ ## id,
7021 #include "metadata/icall-def.h"
7027 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
7028 #define ICALL(id,name,func)
7030 #include "metadata/icall-def.h"
7036 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
7037 #define ICALL(id,name,func)
7039 guint16 first_icall;
7042 static const IcallTypeDesc
7043 icall_type_descs [] = {
7044 #include "metadata/icall-def.h"
7048 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
7051 #define ICALL_TYPE(id,name,first)
7054 #ifdef HAVE_ARRAY_ELEM_INIT
7055 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
7056 #define MSGSTRFIELD1(line) str##line
7058 static const struct msgstrtn_t {
7059 #define ICALL(id,name,func)
7061 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7062 #include "metadata/icall-def.h"
7064 } icall_type_names_str = {
7065 #define ICALL_TYPE(id,name,first) (name),
7066 #include "metadata/icall-def.h"
7069 static const guint16 icall_type_names_idx [] = {
7070 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
7071 #include "metadata/icall-def.h"
7074 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
7076 static const struct msgstr_t {
7078 #define ICALL_TYPE(id,name,first)
7079 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7080 #include "metadata/icall-def.h"
7082 } icall_names_str = {
7083 #define ICALL(id,name,func) (name),
7084 #include "metadata/icall-def.h"
7087 static const guint16 icall_names_idx [] = {
7088 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
7089 #include "metadata/icall-def.h"
7092 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
7098 #define ICALL_TYPE(id,name,first) name,
7099 #define ICALL(id,name,func)
7100 static const char* const
7101 icall_type_names [] = {
7102 #include "metadata/icall-def.h"
7106 #define icall_type_name_get(id) (icall_type_names [(id)])
7110 #define ICALL_TYPE(id,name,first)
7111 #define ICALL(id,name,func) name,
7112 static const char* const
7114 #include "metadata/icall-def.h"
7117 #define icall_name_get(id) icall_names [(id)]
7119 #endif /* !HAVE_ARRAY_ELEM_INIT */
7123 #define ICALL_TYPE(id,name,first)
7124 #define ICALL(id,name,func) func,
7125 static const gconstpointer
7126 icall_functions [] = {
7127 #include "metadata/icall-def.h"
7131 static GHashTable *icall_hash = NULL;
7132 static GHashTable *jit_icall_hash_name = NULL;
7133 static GHashTable *jit_icall_hash_addr = NULL;
7136 mono_icall_init (void)
7140 /* check that tables are sorted: disable in release */
7143 const char *prev_class = NULL;
7144 const char *prev_method;
7146 for (i = 0; i < Icall_type_num; ++i) {
7147 const IcallTypeDesc *desc;
7150 if (prev_class && strcmp (prev_class, icall_type_name_get (i)) >= 0)
7151 g_print ("class %s should come before class %s\n", icall_type_name_get (i), prev_class);
7152 prev_class = icall_type_name_get (i);
7153 desc = &icall_type_descs [i];
7154 num_icalls = icall_desc_num_icalls (desc);
7155 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
7156 for (j = 0; j < num_icalls; ++j) {
7157 const char *methodn = icall_name_get (desc->first_icall + j);
7158 if (prev_method && strcmp (prev_method, methodn) >= 0)
7159 g_print ("method %s should come before method %s\n", methodn, prev_method);
7160 prev_method = methodn;
7165 icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
7169 mono_icall_cleanup (void)
7171 g_hash_table_destroy (icall_hash);
7172 g_hash_table_destroy (jit_icall_hash_name);
7173 g_hash_table_destroy (jit_icall_hash_addr);
7177 mono_add_internal_call (const char *name, gconstpointer method)
7179 mono_loader_lock ();
7181 g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
7183 mono_loader_unlock ();
7186 #ifdef HAVE_ARRAY_ELEM_INIT
7188 compare_method_imap (const void *key, const void *elem)
7190 const char* method_name = (const char*)&icall_names_str + (*(guint16*)elem);
7191 return strcmp (key, method_name);
7195 find_method_icall (const IcallTypeDesc *imap, const char *name)
7197 const guint16 *nameslot = bsearch (name, icall_names_idx + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names_idx [0]), compare_method_imap);
7200 return (gpointer)icall_functions [(nameslot - &icall_names_idx [0])];
7204 compare_class_imap (const void *key, const void *elem)
7206 const char* class_name = (const char*)&icall_type_names_str + (*(guint16*)elem);
7207 return strcmp (key, class_name);
7210 static const IcallTypeDesc*
7211 find_class_icalls (const char *name)
7213 const guint16 *nameslot = bsearch (name, icall_type_names_idx, Icall_type_num, sizeof (icall_type_names_idx [0]), compare_class_imap);
7216 return &icall_type_descs [nameslot - &icall_type_names_idx [0]];
7221 compare_method_imap (const void *key, const void *elem)
7223 const char** method_name = (const char**)elem;
7224 return strcmp (key, *method_name);
7228 find_method_icall (const IcallTypeDesc *imap, const char *name)
7230 const char **nameslot = bsearch (name, icall_names + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names [0]), compare_method_imap);
7233 return (gpointer)icall_functions [(nameslot - icall_names)];
7237 compare_class_imap (const void *key, const void *elem)
7239 const char** class_name = (const char**)elem;
7240 return strcmp (key, *class_name);
7243 static const IcallTypeDesc*
7244 find_class_icalls (const char *name)
7246 const char **nameslot = bsearch (name, icall_type_names, Icall_type_num, sizeof (icall_type_names [0]), compare_class_imap);
7249 return &icall_type_descs [nameslot - icall_type_names];
7255 * we should probably export this as an helper (handle nested types).
7256 * Returns the number of chars written in buf.
7259 concat_class_name (char *buf, int bufsize, MonoClass *klass)
7261 int nspacelen, cnamelen;
7262 nspacelen = strlen (klass->name_space);
7263 cnamelen = strlen (klass->name);
7264 if (nspacelen + cnamelen + 2 > bufsize)
7267 memcpy (buf, klass->name_space, nspacelen);
7268 buf [nspacelen ++] = '.';
7270 memcpy (buf + nspacelen, klass->name, cnamelen);
7271 buf [nspacelen + cnamelen] = 0;
7272 return nspacelen + cnamelen;
7276 mono_lookup_internal_call (MonoMethod *method)
7281 int typelen = 0, mlen, siglen;
7283 const IcallTypeDesc *imap;
7285 g_assert (method != NULL);
7287 if (method->is_inflated)
7288 method = ((MonoMethodInflated *) method)->declaring;
7290 if (method->klass->nested_in) {
7291 int pos = concat_class_name (mname, sizeof (mname)-2, method->klass->nested_in);
7295 mname [pos++] = '/';
7298 typelen = concat_class_name (mname+pos, sizeof (mname)-pos-1, method->klass);
7304 typelen = concat_class_name (mname, sizeof (mname), method->klass);
7309 imap = find_class_icalls (mname);
7311 mname [typelen] = ':';
7312 mname [typelen + 1] = ':';
7314 mlen = strlen (method->name);
7315 memcpy (mname + typelen + 2, method->name, mlen);
7316 sigstart = mname + typelen + 2 + mlen;
7319 tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
7320 siglen = strlen (tmpsig);
7321 if (typelen + mlen + siglen + 6 > sizeof (mname))
7324 memcpy (sigstart + 1, tmpsig, siglen);
7325 sigstart [siglen + 1] = ')';
7326 sigstart [siglen + 2] = 0;
7329 mono_loader_lock ();
7331 res = g_hash_table_lookup (icall_hash, mname);
7333 mono_loader_unlock ();
7336 /* try without signature */
7338 res = g_hash_table_lookup (icall_hash, mname);
7340 mono_loader_unlock ();
7344 /* it wasn't found in the static call tables */
7346 mono_loader_unlock ();
7349 res = find_method_icall (imap, sigstart - mlen);
7351 mono_loader_unlock ();
7354 /* try _with_ signature */
7356 res = find_method_icall (imap, sigstart - mlen);
7358 mono_loader_unlock ();
7362 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname);
7363 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
7364 g_print ("The out of sync library is: %s\n", method->klass->image->name);
7365 g_print ("\nWhen you update one from cvs you need to update, compile and install\nthe other too.\n");
7366 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");
7367 g_print ("If you see other errors or faults after this message they are probably related\n");
7368 g_print ("and you need to fix your mono install first.\n");
7370 mono_loader_unlock ();
7376 type_from_typename (char *typename)
7378 MonoClass *klass = NULL; /* assignment to shut GCC warning up */
7380 if (!strcmp (typename, "int"))
7381 klass = mono_defaults.int_class;
7382 else if (!strcmp (typename, "ptr"))
7383 klass = mono_defaults.int_class;
7384 else if (!strcmp (typename, "void"))
7385 klass = mono_defaults.void_class;
7386 else if (!strcmp (typename, "int32"))
7387 klass = mono_defaults.int32_class;
7388 else if (!strcmp (typename, "uint32"))
7389 klass = mono_defaults.uint32_class;
7390 else if (!strcmp (typename, "int8"))
7391 klass = mono_defaults.sbyte_class;
7392 else if (!strcmp (typename, "uint8"))
7393 klass = mono_defaults.byte_class;
7394 else if (!strcmp (typename, "int16"))
7395 klass = mono_defaults.int16_class;
7396 else if (!strcmp (typename, "uint16"))
7397 klass = mono_defaults.uint16_class;
7398 else if (!strcmp (typename, "long"))
7399 klass = mono_defaults.int64_class;
7400 else if (!strcmp (typename, "ulong"))
7401 klass = mono_defaults.uint64_class;
7402 else if (!strcmp (typename, "float"))
7403 klass = mono_defaults.single_class;
7404 else if (!strcmp (typename, "double"))
7405 klass = mono_defaults.double_class;
7406 else if (!strcmp (typename, "object"))
7407 klass = mono_defaults.object_class;
7408 else if (!strcmp (typename, "obj"))
7409 klass = mono_defaults.object_class;
7412 g_assert_not_reached ();
7414 return &klass->byval_arg;
7417 MonoMethodSignature*
7418 mono_create_icall_signature (const char *sigstr)
7423 MonoMethodSignature *res;
7425 mono_loader_lock ();
7426 res = g_hash_table_lookup (mono_defaults.corlib->helper_signatures, sigstr);
7428 mono_loader_unlock ();
7432 parts = g_strsplit (sigstr, " ", 256);
7441 res = mono_metadata_signature_alloc (mono_defaults.corlib, len - 1);
7444 #ifdef PLATFORM_WIN32
7446 * Under windows, the default pinvoke calling convention is STDCALL but
7449 res->call_convention = MONO_CALL_C;
7452 res->ret = type_from_typename (parts [0]);
7453 for (i = 1; i < len; ++i) {
7454 res->params [i - 1] = type_from_typename (parts [i]);
7459 g_hash_table_insert (mono_defaults.corlib->helper_signatures, (gpointer)sigstr, res);
7461 mono_loader_unlock ();
7467 mono_find_jit_icall_by_name (const char *name)
7469 MonoJitICallInfo *info;
7470 g_assert (jit_icall_hash_name);
7472 mono_loader_lock ();
7473 info = g_hash_table_lookup (jit_icall_hash_name, name);
7474 mono_loader_unlock ();
7479 mono_find_jit_icall_by_addr (gconstpointer addr)
7481 MonoJitICallInfo *info;
7482 g_assert (jit_icall_hash_addr);
7484 mono_loader_lock ();
7485 info = g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
7486 mono_loader_unlock ();
7492 mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
7494 mono_loader_lock ();
7495 g_hash_table_insert (jit_icall_hash_addr, (gpointer)wrapper, info);
7496 mono_loader_unlock ();
7500 mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
7502 MonoJitICallInfo *info;
7507 mono_loader_lock ();
7509 if (!jit_icall_hash_name) {
7510 jit_icall_hash_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
7511 jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
7514 if (g_hash_table_lookup (jit_icall_hash_name, name)) {
7515 g_warning ("jit icall already defined \"%s\"\n", name);
7516 g_assert_not_reached ();
7519 info = g_new0 (MonoJitICallInfo, 1);
7526 info->wrapper = func;
7528 info->wrapper = NULL;
7531 g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
7532 g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
7534 mono_loader_unlock ();