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/metadata/mono-perfcounters.h>
64 #include <mono/io-layer/io-layer.h>
65 #include <mono/utils/strtod.h>
66 #include <mono/utils/monobitset.h>
67 #include <mono/utils/mono-time.h>
69 #if defined (PLATFORM_WIN32)
75 static MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void);
78 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional);
80 static inline MonoBoolean
81 is_generic_parameter (MonoType *type)
83 return !type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR);
87 * We expect a pointer to a char, not a string
90 mono_double_ParseImpl (char *ptr, double *result)
99 *result = strtod (ptr, &endptr);
102 *result = mono_strtod (ptr, &endptr);
105 if (!*ptr || (endptr && *endptr))
112 mono_class_get_throw (MonoImage *image, guint32 type_token)
114 MonoClass *class = mono_class_get (image, type_token);
115 MonoLoaderError *error;
121 error = mono_loader_get_last_error ();
122 g_assert (error != NULL);
124 ex = mono_loader_error_prepare_exception (error);
125 mono_raise_exception (ex);
130 ves_icall_System_Array_GetValueImpl (MonoObject *this, guint32 pos)
139 ao = (MonoArray *)this;
140 ac = (MonoClass *)ao->obj.vtable->klass;
142 esize = mono_array_element_size (ac);
143 ea = (gpointer*)((char*)ao->vector + (pos * esize));
145 if (ac->element_class->valuetype)
146 return mono_value_box (this->vtable->domain, ac->element_class, ea);
152 ves_icall_System_Array_GetValue (MonoObject *this, MonoObject *idxs)
160 MONO_CHECK_ARG_NULL (idxs);
162 io = (MonoArray *)idxs;
163 ic = (MonoClass *)io->obj.vtable->klass;
165 ao = (MonoArray *)this;
166 ac = (MonoClass *)ao->obj.vtable->klass;
168 g_assert (ic->rank == 1);
169 if (io->bounds != NULL || io->max_length != ac->rank)
170 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
172 ind = (gint32 *)io->vector;
174 if (ao->bounds == NULL) {
175 if (*ind < 0 || *ind >= ao->max_length)
176 mono_raise_exception (mono_get_exception_index_out_of_range ());
178 return ves_icall_System_Array_GetValueImpl (this, *ind);
181 for (i = 0; i < ac->rank; i++)
182 if ((ind [i] < ao->bounds [i].lower_bound) ||
183 (ind [i] >= ao->bounds [i].length + ao->bounds [i].lower_bound))
184 mono_raise_exception (mono_get_exception_index_out_of_range ());
186 pos = ind [0] - ao->bounds [0].lower_bound;
187 for (i = 1; i < ac->rank; i++)
188 pos = pos*ao->bounds [i].length + ind [i] -
189 ao->bounds [i].lower_bound;
191 return ves_icall_System_Array_GetValueImpl (this, pos);
195 ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32 pos)
197 MonoClass *ac, *vc, *ec;
209 vc = value->vtable->klass;
213 ac = this->obj.vtable->klass;
214 ec = ac->element_class;
216 esize = mono_array_element_size (ac);
217 ea = (gpointer*)((char*)this->vector + (pos * esize));
218 va = (gpointer*)((char*)value + sizeof (MonoObject));
221 memset (ea, 0, esize);
225 #define NO_WIDENING_CONVERSION G_STMT_START{\
226 mono_raise_exception (mono_get_exception_argument ( \
227 "value", "not a widening conversion")); \
230 #define CHECK_WIDENING_CONVERSION(extra) G_STMT_START{\
231 if (esize < vsize + (extra)) \
232 mono_raise_exception (mono_get_exception_argument ( \
233 "value", "not a widening conversion")); \
236 #define INVALID_CAST G_STMT_START{\
237 mono_raise_exception (mono_get_exception_invalid_cast ()); \
240 /* Check element (destination) type. */
241 switch (ec->byval_arg.type) {
242 case MONO_TYPE_STRING:
243 switch (vc->byval_arg.type) {
244 case MONO_TYPE_STRING:
250 case MONO_TYPE_BOOLEAN:
251 switch (vc->byval_arg.type) {
252 case MONO_TYPE_BOOLEAN:
265 NO_WIDENING_CONVERSION;
272 if (!ec->valuetype) {
273 if (!mono_object_isinst (value, ec))
275 mono_gc_wbarrier_set_arrayref (this, ea, (MonoObject*)value);
279 if (mono_object_isinst (value, ec)) {
280 if (ec->has_references)
281 mono_value_copy (ea, (char*)value + sizeof (MonoObject), ec);
283 memcpy (ea, (char *)value + sizeof (MonoObject), esize);
290 vsize = mono_class_instance_size (vc) - sizeof (MonoObject);
292 et = ec->byval_arg.type;
293 if (et == MONO_TYPE_VALUETYPE && ec->byval_arg.data.klass->enumtype)
294 et = ec->byval_arg.data.klass->enum_basetype->type;
296 vt = vc->byval_arg.type;
297 if (vt == MONO_TYPE_VALUETYPE && vc->byval_arg.data.klass->enumtype)
298 vt = vc->byval_arg.data.klass->enum_basetype->type;
300 #define ASSIGN_UNSIGNED(etype) G_STMT_START{\
306 case MONO_TYPE_CHAR: \
307 CHECK_WIDENING_CONVERSION(0); \
308 *(etype *) ea = (etype) u64; \
310 /* You can't assign a signed value to an unsigned array. */ \
315 /* You can't assign a floating point number to an integer array. */ \
318 NO_WIDENING_CONVERSION; \
322 #define ASSIGN_SIGNED(etype) G_STMT_START{\
328 CHECK_WIDENING_CONVERSION(0); \
329 *(etype *) ea = (etype) i64; \
331 /* You can assign an unsigned value to a signed array if the array's */ \
332 /* element size is larger than the value size. */ \
337 case MONO_TYPE_CHAR: \
338 CHECK_WIDENING_CONVERSION(1); \
339 *(etype *) ea = (etype) u64; \
341 /* You can't assign a floating point number to an integer array. */ \
344 NO_WIDENING_CONVERSION; \
348 #define ASSIGN_REAL(etype) G_STMT_START{\
352 CHECK_WIDENING_CONVERSION(0); \
353 *(etype *) ea = (etype) r64; \
355 /* All integer values fit into a floating point array, so we don't */ \
356 /* need to CHECK_WIDENING_CONVERSION here. */ \
361 *(etype *) ea = (etype) i64; \
367 case MONO_TYPE_CHAR: \
368 *(etype *) ea = (etype) u64; \
375 u64 = *(guint8 *) va;
378 u64 = *(guint16 *) va;
381 u64 = *(guint32 *) va;
384 u64 = *(guint64 *) va;
390 i64 = *(gint16 *) va;
393 i64 = *(gint32 *) va;
396 i64 = *(gint64 *) va;
399 r64 = *(gfloat *) va;
402 r64 = *(gdouble *) va;
405 u64 = *(guint16 *) va;
407 case MONO_TYPE_BOOLEAN:
408 /* Boolean is only compatible with itself. */
421 NO_WIDENING_CONVERSION;
428 /* If we can't do a direct copy, let's try a widening conversion. */
431 ASSIGN_UNSIGNED (guint16);
433 ASSIGN_UNSIGNED (guint8);
435 ASSIGN_UNSIGNED (guint16);
437 ASSIGN_UNSIGNED (guint32);
439 ASSIGN_UNSIGNED (guint64);
441 ASSIGN_SIGNED (gint8);
443 ASSIGN_SIGNED (gint16);
445 ASSIGN_SIGNED (gint32);
447 ASSIGN_SIGNED (gint64);
449 ASSIGN_REAL (gfloat);
451 ASSIGN_REAL (gdouble);
455 /* Not reached, INVALID_CAST does not return. Just to avoid a compiler warning ... */
459 #undef NO_WIDENING_CONVERSION
460 #undef CHECK_WIDENING_CONVERSION
461 #undef ASSIGN_UNSIGNED
467 ves_icall_System_Array_SetValue (MonoArray *this, MonoObject *value,
475 MONO_CHECK_ARG_NULL (idxs);
477 ic = idxs->obj.vtable->klass;
478 ac = this->obj.vtable->klass;
480 g_assert (ic->rank == 1);
481 if (idxs->bounds != NULL || idxs->max_length != ac->rank)
482 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
484 ind = (gint32 *)idxs->vector;
486 if (this->bounds == NULL) {
487 if (*ind < 0 || *ind >= this->max_length)
488 mono_raise_exception (mono_get_exception_index_out_of_range ());
490 ves_icall_System_Array_SetValueImpl (this, value, *ind);
494 for (i = 0; i < ac->rank; i++)
495 if ((ind [i] < this->bounds [i].lower_bound) ||
496 (ind [i] >= this->bounds [i].length + this->bounds [i].lower_bound))
497 mono_raise_exception (mono_get_exception_index_out_of_range ());
499 pos = ind [0] - this->bounds [0].lower_bound;
500 for (i = 1; i < ac->rank; i++)
501 pos = pos * this->bounds [i].length + ind [i] -
502 this->bounds [i].lower_bound;
504 ves_icall_System_Array_SetValueImpl (this, value, pos);
508 ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
513 gboolean bounded = FALSE;
517 MONO_CHECK_ARG_NULL (type);
518 MONO_CHECK_ARG_NULL (lengths);
520 MONO_CHECK_ARG (lengths, mono_array_length (lengths) > 0);
522 MONO_CHECK_ARG (bounds, mono_array_length (lengths) == mono_array_length (bounds));
524 for (i = 0; i < mono_array_length (lengths); i++)
525 if (mono_array_get (lengths, gint32, i) < 0)
526 mono_raise_exception (mono_get_exception_argument_out_of_range (NULL));
528 if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint32, 0) != 0))
529 /* vectors are not the same as one dimensional arrays with no-zero bounds */
534 aklass = mono_bounded_array_class_get (mono_class_from_mono_type (type->type), mono_array_length (lengths), bounded);
536 sizes = alloca (aklass->rank * sizeof(guint32) * 2);
537 for (i = 0; i < aklass->rank; ++i) {
538 sizes [i] = mono_array_get (lengths, guint32, i);
540 sizes [i + aklass->rank] = mono_array_get (bounds, guint32, i);
542 sizes [i + aklass->rank] = 0;
545 array = mono_array_new_full (mono_object_domain (type), aklass, sizes, sizes + aklass->rank);
551 ves_icall_System_Array_GetRank (MonoObject *this)
555 return this->vtable->klass->rank;
559 ves_icall_System_Array_GetLength (MonoArray *this, gint32 dimension)
561 gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
565 if ((dimension < 0) || (dimension >= rank))
566 mono_raise_exception (mono_get_exception_index_out_of_range ());
568 if (this->bounds == NULL)
569 return this->max_length;
571 return this->bounds [dimension].length;
575 ves_icall_System_Array_GetLowerBound (MonoArray *this, gint32 dimension)
577 gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
581 if ((dimension < 0) || (dimension >= rank))
582 mono_raise_exception (mono_get_exception_index_out_of_range ());
584 if (this->bounds == NULL)
587 return this->bounds [dimension].lower_bound;
591 ves_icall_System_Array_ClearInternal (MonoArray *arr, int idx, int length)
593 int sz = mono_array_element_size (mono_object_class (arr));
594 memset (mono_array_addr_with_size (arr, sz, idx), 0, length * sz);
598 ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* dest, int dest_idx, int length)
603 MonoClass *src_class;
604 MonoClass *dest_class;
609 if (source->obj.vtable->klass->rank != dest->obj.vtable->klass->rank)
612 if (source->bounds || dest->bounds)
615 if ((dest_idx + length > mono_array_length (dest)) ||
616 (source_idx + length > mono_array_length (source)))
619 src_class = source->obj.vtable->klass->element_class;
620 dest_class = dest->obj.vtable->klass->element_class;
623 * Handle common cases.
626 /* Case1: object[] -> valuetype[] (ArrayList::ToArray) */
627 if (src_class == mono_defaults.object_class && dest_class->valuetype) {
628 int has_refs = dest_class->has_references;
629 for (i = source_idx; i < source_idx + length; ++i) {
630 MonoObject *elem = mono_array_get (source, MonoObject*, i);
631 if (elem && !mono_object_isinst (elem, dest_class))
635 element_size = mono_array_element_size (dest->obj.vtable->klass);
636 memset (mono_array_addr_with_size (dest, element_size, dest_idx), 0, element_size * length);
637 for (i = 0; i < length; ++i) {
638 MonoObject *elem = mono_array_get (source, MonoObject*, source_idx + i);
639 void *addr = mono_array_addr_with_size (dest, element_size, dest_idx + i);
643 mono_value_copy (addr, (char *)elem + sizeof (MonoObject), dest_class);
645 memcpy (addr, (char *)elem + sizeof (MonoObject), element_size);
650 /* Check if we're copying a char[] <==> (u)short[] */
651 if (src_class != dest_class) {
652 if (dest_class->valuetype || dest_class->enumtype || src_class->valuetype || src_class->enumtype)
655 if (mono_class_is_subclass_of (src_class, dest_class, FALSE))
657 /* Case2: object[] -> reftype[] (ArrayList::ToArray) */
658 else if (mono_class_is_subclass_of (dest_class, src_class, FALSE))
659 for (i = source_idx; i < source_idx + length; ++i) {
660 MonoObject *elem = mono_array_get (source, MonoObject*, i);
661 if (elem && !mono_object_isinst (elem, dest_class))
668 if (dest_class->valuetype) {
669 element_size = mono_array_element_size (source->obj.vtable->klass);
670 source_addr = mono_array_addr_with_size (source, element_size, source_idx);
671 if (dest_class->has_references) {
672 mono_value_copy_array (dest, dest_idx, source_addr, length);
674 dest_addr = mono_array_addr_with_size (dest, element_size, dest_idx);
675 memmove (dest_addr, source_addr, element_size * length);
678 mono_array_memcpy_refs (dest, dest_idx, source, source_idx, length);
685 ves_icall_System_Array_GetGenericValueImpl (MonoObject *this, guint32 pos, gpointer value)
694 ao = (MonoArray *)this;
695 ac = (MonoClass *)ao->obj.vtable->klass;
697 esize = mono_array_element_size (ac);
698 ea = (gpointer*)((char*)ao->vector + (pos * esize));
700 memcpy (value, ea, esize);
704 ves_icall_System_Array_SetGenericValueImpl (MonoObject *this, guint32 pos, gpointer value)
713 ao = (MonoArray *)this;
714 ac = (MonoClass *)ao->obj.vtable->klass;
716 esize = mono_array_element_size (ac);
717 ea = (gpointer*)((char*)ao->vector + (pos * esize));
719 memcpy (ea, value, esize);
723 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoArray *array, MonoClassField *field_handle)
725 MonoClass *klass = array->obj.vtable->klass;
726 guint32 size = mono_array_element_size (klass);
727 MonoType *type = mono_type_get_underlying_type (&klass->element_class->byval_arg);
730 if (MONO_TYPE_IS_REFERENCE (type) ||
731 (type->type == MONO_TYPE_VALUETYPE &&
732 (!mono_type_get_class (type) ||
733 mono_type_get_class (type)->has_references))) {
734 MonoException *exc = mono_get_exception_argument("array",
735 "Cannot initialize array containing references");
736 mono_raise_exception (exc);
739 if (!(field_handle->type->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA)) {
740 MonoException *exc = mono_get_exception_argument("field_handle",
741 "Field doesn't have an RVA");
742 mono_raise_exception (exc);
745 size *= array->max_length;
747 if (size > mono_type_size (field_handle->type, &align)) {
748 MonoException *exc = mono_get_exception_argument("field_handle",
749 "Field not large enough to fill array");
750 mono_raise_exception (exc);
753 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
755 guint ## n *data = (guint ## n *) mono_array_addr (array, char, 0); \
756 guint ## n *src = (guint ## n *) field_handle->data; \
757 guint ## n *end = (guint ## n *)((char*)src + size); \
759 for (; src < end; data++, src++) { \
760 *data = read ## n (src); \
764 /* printf ("Initialize array with elements of %s type\n", klass->element_class->name); */
766 switch (type->type) {
783 memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
787 memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
789 if (klass->element_class->byval_arg.type == MONO_TYPE_R8) {
792 double *data = (double*)mono_array_addr (array, double, 0);
794 for (i = 0; i < size; i++, data++) {
804 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData (void)
808 return offsetof (MonoString, chars);
812 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue (MonoObject *obj)
816 if ((obj == NULL) || (! (obj->vtable->klass->valuetype)))
819 return mono_object_clone (obj);
823 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (MonoType *handle)
829 MONO_CHECK_ARG_NULL (handle);
831 klass = mono_class_from_mono_type (handle);
832 MONO_CHECK_ARG (handle, klass);
834 /* This will call the type constructor */
835 mono_runtime_class_init (mono_class_vtable (mono_domain_get (), klass));
839 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunModuleConstructor (MonoImage *image)
843 mono_image_check_for_module_cctor (image);
844 if (image->has_module_cctor) {
845 MonoClass *module_klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | 1);
846 mono_runtime_class_init (mono_class_vtable (mono_domain_get (), module_klass));
851 ves_icall_System_Object_MemberwiseClone (MonoObject *this)
855 return mono_object_clone (this);
859 ves_icall_System_ValueType_InternalGetHashCode (MonoObject *this, MonoArray **fields)
862 MonoObject **values = NULL;
866 MonoClassField* field;
871 klass = mono_object_class (this);
873 if (mono_class_num_fields (klass) == 0)
874 return mono_object_hash (this);
877 * Compute the starting value of the hashcode for fields of primitive
878 * types, and return the remaining fields in an array to the managed side.
879 * This way, we can avoid costly reflection operations in managed code.
882 while ((field = mono_class_get_fields (klass, &iter))) {
883 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
885 if (mono_field_is_deleted (field))
887 /* FIXME: Add more types */
888 switch (field->type->type) {
890 result ^= *(gint32*)((guint8*)this + field->offset);
892 case MONO_TYPE_STRING: {
894 s = *(MonoString**)((guint8*)this + field->offset);
896 result ^= mono_string_hash (s);
901 values = g_newa (MonoObject*, mono_class_num_fields (klass));
902 o = mono_field_get_value_object (mono_object_domain (this), field, this);
903 values [count++] = o;
909 *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
910 for (i = 0; i < count; ++i)
911 mono_array_setref (*fields, i, values [i]);
919 ves_icall_System_ValueType_Equals (MonoObject *this, MonoObject *that, MonoArray **fields)
922 MonoObject **values = NULL;
924 MonoClassField* field;
930 MONO_CHECK_ARG_NULL (that);
932 if (this->vtable != that->vtable)
935 klass = mono_object_class (this);
938 * Do the comparison for fields of primitive type and return a result if
939 * possible. Otherwise, return the remaining fields in an array to the
940 * managed side. This way, we can avoid costly reflection operations in
945 while ((field = mono_class_get_fields (klass, &iter))) {
946 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
948 if (mono_field_is_deleted (field))
950 /* FIXME: Add more types */
951 switch (field->type->type) {
953 if (*(gint32*)((guint8*)this + field->offset) != *(gint32*)((guint8*)that + field->offset))
956 case MONO_TYPE_STRING: {
958 guint32 s1len, s2len;
959 s1 = *(MonoString**)((guint8*)this + field->offset);
960 s2 = *(MonoString**)((guint8*)that + field->offset);
963 if ((s1 == NULL) || (s2 == NULL))
965 s1len = mono_string_length (s1);
966 s2len = mono_string_length (s2);
970 if (memcmp (mono_string_chars (s1), mono_string_chars (s2), s1len * sizeof (gunichar2)) != 0)
976 values = g_newa (MonoObject*, mono_class_num_fields (klass) * 2);
977 o = mono_field_get_value_object (mono_object_domain (this), field, this);
978 values [count++] = o;
979 o = mono_field_get_value_object (mono_object_domain (this), field, that);
980 values [count++] = o;
986 *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
987 for (i = 0; i < count; ++i)
988 mono_array_setref (*fields, i, values [i]);
995 static MonoReflectionType *
996 ves_icall_System_Object_GetType (MonoObject *obj)
1000 if (obj->vtable->klass != mono_defaults.transparent_proxy_class)
1001 return mono_type_get_object (mono_object_domain (obj), &obj->vtable->klass->byval_arg);
1003 return mono_type_get_object (mono_object_domain (obj), &((MonoTransparentProxy*)obj)->remote_class->proxy_class->byval_arg);
1007 mono_type_type_from_obj (MonoReflectionType *mtype, MonoObject *obj)
1009 MONO_ARCH_SAVE_REGS;
1011 mtype->type = &obj->vtable->klass->byval_arg;
1012 g_assert (mtype->type->type);
1016 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj)
1018 MONO_ARCH_SAVE_REGS;
1020 MONO_CHECK_ARG_NULL (obj);
1022 return mono_image_create_token (mb->dynamic_image, obj, TRUE);
1026 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder *mb,
1027 MonoReflectionMethod *method,
1028 MonoArray *opt_param_types)
1030 MONO_ARCH_SAVE_REGS;
1032 MONO_CHECK_ARG_NULL (method);
1034 return mono_image_create_method_token (
1035 mb->dynamic_image, (MonoObject *) method, opt_param_types);
1039 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder *mb, HANDLE file)
1041 MONO_ARCH_SAVE_REGS;
1043 mono_image_create_pefile (mb, file);
1047 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
1049 MONO_ARCH_SAVE_REGS;
1051 mono_image_build_metadata (mb);
1055 ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilder *mb, MonoObject *obj, guint32 token)
1057 MONO_ARCH_SAVE_REGS;
1059 mono_image_register_token (mb->dynamic_image, token, obj);
1063 get_caller (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1065 MonoMethod **dest = data;
1067 /* skip unmanaged frames */
1082 static MonoReflectionType *
1083 type_from_name (const char *str, MonoBoolean ignoreCase)
1085 MonoType *type = NULL;
1086 MonoAssembly *assembly = NULL;
1087 MonoTypeNameParse info;
1088 char *temp_str = g_strdup (str);
1089 gboolean type_resolve = FALSE;
1091 MONO_ARCH_SAVE_REGS;
1093 /* mono_reflection_parse_type() mangles the string */
1094 if (!mono_reflection_parse_type (temp_str, &info)) {
1095 mono_reflection_free_type_info (&info);
1100 if (info.assembly.name) {
1101 assembly = mono_assembly_load (&info.assembly, NULL, NULL);
1103 MonoMethod *m = mono_method_get_last_managed ();
1104 MonoMethod *dest = m;
1106 mono_stack_walk_no_il (get_caller, &dest);
1111 * FIXME: mono_method_get_last_managed() sometimes returns NULL, thus
1112 * causing ves_icall_System_Reflection_Assembly_GetCallingAssembly()
1113 * to crash. This only seems to happen in some strange remoting
1114 * scenarios and I was unable to figure out what's happening there.
1115 * Dec 10, 2005 - Martin.
1119 assembly = dest->klass->image->assembly;
1121 g_warning (G_STRLOC);
1126 type = mono_reflection_get_type (assembly->image, &info, ignoreCase, &type_resolve);
1128 if (!info.assembly.name && !type) /* try mscorlib */
1129 type = mono_reflection_get_type (NULL, &info, ignoreCase, &type_resolve);
1131 mono_reflection_free_type_info (&info);
1137 return mono_type_get_object (mono_domain_get (), type);
1141 MonoReflectionType *
1142 mono_type_get (const char *str)
1144 char *copy = g_strdup (str);
1145 MonoReflectionType *type = type_from_name (copy, FALSE);
1152 static MonoReflectionType*
1153 ves_icall_type_from_name (MonoString *name,
1154 MonoBoolean throwOnError,
1155 MonoBoolean ignoreCase)
1157 char *str = mono_string_to_utf8 (name);
1158 MonoReflectionType *type;
1160 type = type_from_name (str, ignoreCase);
1163 MonoException *e = NULL;
1166 e = mono_get_exception_type_load (name, NULL);
1168 mono_loader_clear_error ();
1170 mono_raise_exception (e);
1177 static MonoReflectionType*
1178 ves_icall_type_from_handle (MonoType *handle)
1180 MonoDomain *domain = mono_domain_get ();
1181 MonoClass *klass = mono_class_from_mono_type (handle);
1183 MONO_ARCH_SAVE_REGS;
1185 mono_class_init (klass);
1186 return mono_type_get_object (domain, handle);
1190 ves_icall_System_Type_EqualsInternal (MonoReflectionType *type, MonoReflectionType *c)
1192 MONO_ARCH_SAVE_REGS;
1194 if (c && type->type && c->type)
1195 return mono_metadata_type_equal (type->type, c->type);
1200 /* System.TypeCode */
1219 TYPECODE_STRING = 18
1223 ves_icall_type_GetTypeCodeInternal (MonoReflectionType *type)
1225 int t = type->type->type;
1227 MONO_ARCH_SAVE_REGS;
1229 if (type->type->byref)
1230 return TYPECODE_OBJECT;
1234 case MONO_TYPE_VOID:
1235 return TYPECODE_OBJECT;
1236 case MONO_TYPE_BOOLEAN:
1237 return TYPECODE_BOOLEAN;
1239 return TYPECODE_BYTE;
1241 return TYPECODE_SBYTE;
1243 return TYPECODE_UINT16;
1245 return TYPECODE_INT16;
1246 case MONO_TYPE_CHAR:
1247 return TYPECODE_CHAR;
1251 return TYPECODE_OBJECT;
1253 return TYPECODE_UINT32;
1255 return TYPECODE_INT32;
1257 return TYPECODE_UINT64;
1259 return TYPECODE_INT64;
1261 return TYPECODE_SINGLE;
1263 return TYPECODE_DOUBLE;
1264 case MONO_TYPE_VALUETYPE:
1265 if (type->type->data.klass->enumtype) {
1266 t = type->type->data.klass->enum_basetype->type;
1269 MonoClass *k = type->type->data.klass;
1270 if (strcmp (k->name_space, "System") == 0) {
1271 if (strcmp (k->name, "Decimal") == 0)
1272 return TYPECODE_DECIMAL;
1273 else if (strcmp (k->name, "DateTime") == 0)
1274 return TYPECODE_DATETIME;
1277 return TYPECODE_OBJECT;
1278 case MONO_TYPE_STRING:
1279 return TYPECODE_STRING;
1280 case MONO_TYPE_SZARRAY:
1281 case MONO_TYPE_ARRAY:
1282 case MONO_TYPE_OBJECT:
1284 case MONO_TYPE_MVAR:
1285 case MONO_TYPE_TYPEDBYREF:
1286 return TYPECODE_OBJECT;
1287 case MONO_TYPE_CLASS:
1289 MonoClass *k = type->type->data.klass;
1290 if (strcmp (k->name_space, "System") == 0) {
1291 if (strcmp (k->name, "DBNull") == 0)
1292 return TYPECODE_DBNULL;
1295 return TYPECODE_OBJECT;
1296 case MONO_TYPE_GENERICINST:
1297 return TYPECODE_OBJECT;
1299 g_error ("type 0x%02x not handled in GetTypeCode()", t);
1305 ves_icall_type_is_subtype_of (MonoReflectionType *type, MonoReflectionType *c, MonoBoolean check_interfaces)
1311 MONO_ARCH_SAVE_REGS;
1313 g_assert (type != NULL);
1315 domain = ((MonoObject *)type)->vtable->domain;
1317 if (!c) /* FIXME: dont know what do do here */
1320 klass = mono_class_from_mono_type (type->type);
1321 klassc = mono_class_from_mono_type (c->type);
1323 if (type->type->byref)
1324 return klassc == mono_defaults.object_class;
1326 return mono_class_is_subclass_of (klass, klassc, check_interfaces);
1330 ves_icall_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType *c)
1336 MONO_ARCH_SAVE_REGS;
1338 g_assert (type != NULL);
1340 domain = ((MonoObject *)type)->vtable->domain;
1342 klass = mono_class_from_mono_type (type->type);
1343 klassc = mono_class_from_mono_type (c->type);
1345 if (type->type->byref && !c->type->byref)
1348 return mono_class_is_assignable_from (klass, klassc);
1352 ves_icall_type_IsInstanceOfType (MonoReflectionType *type, MonoObject *obj)
1354 MonoClass *klass = mono_class_from_mono_type (type->type);
1355 return mono_object_isinst (obj, klass) != NULL;
1359 ves_icall_get_attributes (MonoReflectionType *type)
1361 MonoClass *klass = mono_class_from_mono_type (type->type);
1363 MONO_ARCH_SAVE_REGS;
1365 return klass->flags;
1368 static MonoReflectionMarshal*
1369 ves_icall_System_Reflection_FieldInfo_GetUnmanagedMarshal (MonoReflectionField *field)
1371 MonoClass *klass = field->field->parent;
1372 MonoMarshalType *info;
1375 if (klass->generic_container ||
1376 (klass->generic_class && klass->generic_class->context.class_inst->is_open))
1379 info = mono_marshal_load_type_info (klass);
1381 for (i = 0; i < info->num_fields; ++i) {
1382 if (info->fields [i].field == field->field) {
1383 if (!info->fields [i].mspec)
1386 return mono_reflection_marshal_from_marshal_spec (field->object.vtable->domain, klass, info->fields [i].mspec);
1393 static MonoReflectionField*
1394 ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoClass *klass)
1399 klass = handle->parent;
1401 /* FIXME: check that handle is a field of klass or of a parent: return null
1402 * and throw the exception in managed code.
1404 return mono_field_get_object (mono_domain_get (), klass, handle);
1407 static MonoReflectionField*
1408 ves_icall_System_Reflection_FieldInfo_internal_from_handle (MonoClassField *handle)
1410 MONO_ARCH_SAVE_REGS;
1414 return mono_field_get_object (mono_domain_get (), handle->parent, handle);
1418 ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionField *field, MonoBoolean optional)
1420 MonoType *type = field->field->type;
1422 return type_array_from_modifiers (field->field->parent->image, type, optional);
1426 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
1428 MonoDomain *domain = mono_domain_get ();
1429 MonoMethodSignature* sig;
1430 MONO_ARCH_SAVE_REGS;
1432 sig = mono_method_signature (method);
1434 g_assert (mono_loader_get_last_error ());
1435 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
1438 info->parent = mono_type_get_object (domain, &method->klass->byval_arg);
1439 info->ret = mono_type_get_object (domain, sig->ret);
1440 info->attrs = method->flags;
1441 info->implattrs = method->iflags;
1442 if (sig->call_convention == MONO_CALL_DEFAULT)
1443 info->callconv = sig->sentinelpos >= 0 ? 2 : 1;
1445 if (sig->call_convention == MONO_CALL_VARARG || sig->sentinelpos >= 0)
1450 info->callconv |= (sig->hasthis << 5) | (sig->explicit_this << 6);
1454 ves_icall_get_parameter_info (MonoMethod *method)
1456 MonoDomain *domain = mono_domain_get ();
1458 return mono_param_get_objects (domain, method);
1461 static MonoReflectionMarshal*
1462 ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod *method)
1464 MonoDomain *domain = mono_domain_get ();
1465 MonoReflectionMarshal* res = NULL;
1466 MonoMarshalSpec **mspecs;
1469 mspecs = g_new (MonoMarshalSpec*, mono_method_signature (method)->param_count + 1);
1470 mono_method_get_marshal_info (method, mspecs);
1473 res = mono_reflection_marshal_from_marshal_spec (domain, method->klass, mspecs [0]);
1475 for (i = mono_method_signature (method)->param_count; i >= 0; i--)
1477 mono_metadata_free_marshal_spec (mspecs [i]);
1484 ves_icall_MonoField_GetFieldOffset (MonoReflectionField *field)
1486 return field->field->offset - sizeof (MonoObject);
1489 static MonoReflectionType*
1490 ves_icall_MonoField_GetParentType (MonoReflectionField *field, MonoBoolean declaring)
1493 MONO_ARCH_SAVE_REGS;
1495 parent = declaring? field->field->parent: field->klass;
1497 return mono_type_get_object (mono_object_domain (field), &parent->byval_arg);
1501 ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj)
1504 MonoClassField *cf = field->field;
1508 MonoDomain *domain = mono_object_domain (field);
1510 gboolean is_static = FALSE;
1511 gboolean is_ref = FALSE;
1513 MONO_ARCH_SAVE_REGS;
1515 if (field->klass->image->assembly->ref_only)
1516 mono_raise_exception (mono_get_exception_invalid_operation (
1517 "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
1519 mono_class_init (field->klass);
1521 if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC)
1524 if (obj && !is_static) {
1525 /* Check that the field belongs to the object */
1526 gboolean found = FALSE;
1529 for (k = obj->vtable->klass; k; k = k->parent) {
1530 if (k == cf->parent) {
1537 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);
1538 MonoException *ex = mono_get_exception_argument (NULL, msg);
1540 mono_raise_exception (ex);
1544 t = mono_type_get_underlying_type (cf->type);
1546 case MONO_TYPE_STRING:
1547 case MONO_TYPE_OBJECT:
1548 case MONO_TYPE_CLASS:
1549 case MONO_TYPE_ARRAY:
1550 case MONO_TYPE_SZARRAY:
1555 case MONO_TYPE_BOOLEAN:
1558 case MONO_TYPE_CHAR:
1567 case MONO_TYPE_VALUETYPE:
1570 case MONO_TYPE_GENERICINST:
1571 if (mono_type_generic_inst_is_valuetype (t)) {
1578 g_error ("type 0x%x not handled in "
1579 "ves_icall_Monofield_GetValue", t->type);
1585 vtable = mono_class_vtable (domain, cf->parent);
1586 if (!vtable->initialized && !(cf->type->attrs & FIELD_ATTRIBUTE_LITERAL))
1587 mono_runtime_class_init (vtable);
1592 mono_field_static_get_value (vtable, cf, &o);
1594 mono_field_get_value (obj, cf, &o);
1599 if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) {
1600 MonoClass *nklass = mono_class_from_mono_type (cf->type);
1603 /* Convert the Nullable structure into a boxed vtype */
1605 buf = (guint8*)vtable->data + cf->offset;
1607 buf = (guint8*)obj + cf->offset;
1609 return mono_nullable_box (buf, nklass);
1612 /* boxed value type */
1613 klass = mono_class_from_mono_type (cf->type);
1614 o = mono_object_new (domain, klass);
1615 v = ((gchar *) o) + sizeof (MonoObject);
1617 mono_field_static_get_value (vtable, cf, v);
1619 mono_field_get_value (obj, cf, v);
1626 ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value)
1628 MonoClassField *cf = field->field;
1631 MONO_ARCH_SAVE_REGS;
1633 if (field->klass->image->assembly->ref_only)
1634 mono_raise_exception (mono_get_exception_invalid_operation (
1635 "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
1637 v = (gchar *) value;
1638 if (!cf->type->byref) {
1639 switch (cf->type->type) {
1642 case MONO_TYPE_BOOLEAN:
1645 case MONO_TYPE_CHAR:
1654 case MONO_TYPE_VALUETYPE:
1656 v += sizeof (MonoObject);
1658 case MONO_TYPE_STRING:
1659 case MONO_TYPE_OBJECT:
1660 case MONO_TYPE_CLASS:
1661 case MONO_TYPE_ARRAY:
1662 case MONO_TYPE_SZARRAY:
1665 case MONO_TYPE_GENERICINST: {
1666 MonoGenericClass *gclass = cf->type->data.generic_class;
1667 g_assert (!gclass->context.class_inst->is_open);
1669 if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) {
1670 MonoClass *nklass = mono_class_from_mono_type (cf->type);
1671 MonoObject *nullable;
1674 * Convert the boxed vtype into a Nullable structure.
1675 * This is complicated by the fact that Nullables have
1676 * a variable structure.
1678 nullable = mono_object_new (mono_domain_get (), nklass);
1680 mono_nullable_init (mono_object_unbox (nullable), value, nklass);
1682 v = mono_object_unbox (nullable);
1685 if (gclass->container_class->valuetype && (v != NULL))
1686 v += sizeof (MonoObject);
1690 g_error ("type 0x%x not handled in "
1691 "ves_icall_FieldInfo_SetValueInternal", cf->type->type);
1696 if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) {
1697 MonoVTable *vtable = mono_class_vtable (mono_object_domain (field), cf->parent);
1698 if (!vtable->initialized)
1699 mono_runtime_class_init (vtable);
1700 mono_field_static_set_value (vtable, cf, v);
1702 mono_field_set_value (obj, cf, v);
1707 ves_icall_MonoField_GetRawConstantValue (MonoReflectionField *this)
1709 MonoObject *o = NULL;
1710 MonoClassField *field = this->field;
1712 MonoDomain *domain = mono_object_domain (this);
1714 MonoTypeEnum def_type;
1715 const char *def_value;
1717 MONO_ARCH_SAVE_REGS;
1719 mono_class_init (field->parent);
1721 if (!(field->type->attrs & FIELD_ATTRIBUTE_HAS_DEFAULT))
1722 mono_raise_exception (mono_get_exception_invalid_operation (NULL));
1724 if (field->parent->image->dynamic) {
1726 g_assert_not_reached ();
1729 def_value = mono_class_get_field_default_value (field, &def_type);
1734 case MONO_TYPE_BOOLEAN:
1737 case MONO_TYPE_CHAR:
1745 case MONO_TYPE_R8: {
1748 /* boxed value type */
1749 t = g_new0 (MonoType, 1);
1751 klass = mono_class_from_mono_type (t);
1753 o = mono_object_new (domain, klass);
1754 v = ((gchar *) o) + sizeof (MonoObject);
1755 mono_get_constant_value_from_blob (domain, def_type, def_value, v);
1758 case MONO_TYPE_STRING:
1759 case MONO_TYPE_CLASS:
1760 mono_get_constant_value_from_blob (domain, def_type, def_value, &o);
1763 g_assert_not_reached ();
1769 static MonoReflectionType*
1770 ves_icall_MonoGenericMethod_get_ReflectedType (MonoReflectionGenericMethod *rmethod)
1772 MonoMethod *method = rmethod->method.method;
1774 return mono_type_get_object (mono_object_domain (rmethod), &method->klass->byval_arg);
1777 /* From MonoProperty.cs */
1779 PInfo_Attributes = 1,
1780 PInfo_GetMethod = 1 << 1,
1781 PInfo_SetMethod = 1 << 2,
1782 PInfo_ReflectedType = 1 << 3,
1783 PInfo_DeclaringType = 1 << 4,
1788 ves_icall_get_property_info (MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
1790 MonoDomain *domain = mono_object_domain (property);
1792 MONO_ARCH_SAVE_REGS;
1794 if ((req_info & PInfo_ReflectedType) != 0)
1795 MONO_STRUCT_SETREF (info, parent, mono_type_get_object (domain, &property->klass->byval_arg));
1796 else if ((req_info & PInfo_DeclaringType) != 0)
1797 MONO_STRUCT_SETREF (info, parent, mono_type_get_object (domain, &property->property->parent->byval_arg));
1799 if ((req_info & PInfo_Name) != 0)
1800 MONO_STRUCT_SETREF (info, name, mono_string_new (domain, property->property->name));
1802 if ((req_info & PInfo_Attributes) != 0)
1803 info->attrs = property->property->attrs;
1805 if ((req_info & PInfo_GetMethod) != 0)
1806 MONO_STRUCT_SETREF (info, get, property->property->get ?
1807 mono_method_get_object (domain, property->property->get, property->klass): NULL);
1809 if ((req_info & PInfo_SetMethod) != 0)
1810 MONO_STRUCT_SETREF (info, set, property->property->set ?
1811 mono_method_get_object (domain, property->property->set, property->klass): NULL);
1813 * There may be other methods defined for properties, though, it seems they are not exposed
1814 * in the reflection API
1819 ves_icall_get_event_info (MonoReflectionEvent *event, MonoEventInfo *info)
1821 MonoDomain *domain = mono_object_domain (event);
1823 MONO_ARCH_SAVE_REGS;
1825 info->reflected_type = mono_type_get_object (domain, &event->klass->byval_arg);
1826 info->declaring_type = mono_type_get_object (domain, &event->event->parent->byval_arg);
1828 info->name = mono_string_new (domain, event->event->name);
1829 info->attrs = event->event->attrs;
1830 info->add_method = event->event->add ? mono_method_get_object (domain, event->event->add, NULL): NULL;
1831 info->remove_method = event->event->remove ? mono_method_get_object (domain, event->event->remove, NULL): NULL;
1832 info->raise_method = event->event->raise ? mono_method_get_object (domain, event->event->raise, NULL): NULL;
1834 if (event->event->other) {
1836 while (event->event->other [n])
1838 info->other_methods = mono_array_new (domain, mono_defaults.method_info_class, n);
1840 for (i = 0; i < n; i++)
1841 mono_array_setref (info->other_methods, i, mono_method_get_object (domain, event->event->other [i], NULL));
1846 ves_icall_Type_GetInterfaces (MonoReflectionType* type)
1848 MonoDomain *domain = mono_object_domain (type);
1850 GPtrArray *ifaces = NULL;
1852 MonoClass *class = mono_class_from_mono_type (type->type);
1855 MonoGenericContext *context = NULL;
1857 MONO_ARCH_SAVE_REGS;
1859 if (class->generic_class && class->generic_class->context.class_inst->is_open) {
1860 context = mono_class_get_context (class);
1861 class = class->generic_class->container_class;
1864 mono_class_setup_vtable (class);
1866 slots = mono_bitset_new (class->max_interface_id + 1, 0);
1868 for (parent = class; parent; parent = parent->parent) {
1869 GPtrArray *tmp_ifaces = mono_class_get_implemented_interfaces (parent);
1871 for (i = 0; i < tmp_ifaces->len; ++i) {
1872 MonoClass *ic = g_ptr_array_index (tmp_ifaces, i);
1874 if (mono_bitset_test (slots, ic->interface_id))
1877 mono_bitset_set (slots, ic->interface_id);
1879 ifaces = g_ptr_array_new ();
1880 g_ptr_array_add (ifaces, ic);
1882 g_ptr_array_free (tmp_ifaces, TRUE);
1885 mono_bitset_free (slots);
1888 return mono_array_new (domain, mono_defaults.monotype_class, 0);
1890 intf = mono_array_new (domain, mono_defaults.monotype_class, ifaces->len);
1891 for (i = 0; i < ifaces->len; ++i) {
1892 MonoClass *ic = g_ptr_array_index (ifaces, i);
1893 MonoType *ret = &ic->byval_arg;
1894 if (context && ic->generic_class && ic->generic_class->context.class_inst->is_open)
1895 ret = mono_class_inflate_generic_type (ret, context);
1897 mono_array_setref (intf, i, mono_type_get_object (domain, ret));
1899 g_ptr_array_free (ifaces, TRUE);
1905 ves_icall_Type_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType *iface, MonoArray **targets, MonoArray **methods)
1907 MonoClass *class = mono_class_from_mono_type (type->type);
1908 MonoClass *iclass = mono_class_from_mono_type (iface->type);
1909 MonoReflectionMethod *member;
1912 int i = 0, len, ioffset;
1915 MONO_ARCH_SAVE_REGS;
1917 mono_class_setup_vtable (class);
1919 /* type doesn't implement iface: the exception is thrown in managed code */
1920 if (! MONO_CLASS_IMPLEMENTS_INTERFACE (class, iclass->interface_id))
1923 len = mono_class_num_methods (iclass);
1924 ioffset = mono_class_interface_offset (class, iclass);
1925 domain = mono_object_domain (type);
1926 *targets = mono_array_new (domain, mono_defaults.method_info_class, len);
1927 *methods = mono_array_new (domain, mono_defaults.method_info_class, len);
1930 while ((method = mono_class_get_methods (iclass, &iter))) {
1931 member = mono_method_get_object (domain, method, iclass);
1932 mono_array_setref (*methods, i, member);
1933 member = mono_method_get_object (domain, class->vtable [i + ioffset], class);
1934 mono_array_setref (*targets, i, member);
1941 ves_icall_Type_GetPacking (MonoReflectionType *type, guint32 *packing, guint32 *size)
1943 MonoClass *klass = mono_class_from_mono_type (type->type);
1945 if (klass->image->dynamic) {
1946 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)type;
1947 *packing = tb->packing_size;
1948 *size = tb->class_size;
1950 mono_metadata_packing_from_typedef (klass->image, klass->type_token, packing, size);
1954 static MonoReflectionType*
1955 ves_icall_MonoType_GetElementType (MonoReflectionType *type)
1957 MonoClass *class = mono_class_from_mono_type (type->type);
1959 MONO_ARCH_SAVE_REGS;
1961 // GetElementType should only return a type for:
1962 // Array Pointer PassedByRef
1963 if (type->type->byref)
1964 return mono_type_get_object (mono_object_domain (type), &class->byval_arg);
1965 else if (class->element_class && MONO_CLASS_IS_ARRAY (class))
1966 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
1967 else if (class->element_class && type->type->type == MONO_TYPE_PTR)
1968 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
1973 static MonoReflectionType*
1974 ves_icall_get_type_parent (MonoReflectionType *type)
1976 MonoClass *class = mono_class_from_mono_type (type->type);
1978 MONO_ARCH_SAVE_REGS;
1980 return class->parent ? mono_type_get_object (mono_object_domain (type), &class->parent->byval_arg): NULL;
1984 ves_icall_type_ispointer (MonoReflectionType *type)
1986 MONO_ARCH_SAVE_REGS;
1988 return type->type->type == MONO_TYPE_PTR;
1992 ves_icall_type_isprimitive (MonoReflectionType *type)
1994 MONO_ARCH_SAVE_REGS;
1996 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)));
2000 ves_icall_type_isbyref (MonoReflectionType *type)
2002 MONO_ARCH_SAVE_REGS;
2004 return type->type->byref;
2008 ves_icall_type_iscomobject (MonoReflectionType *type)
2010 MonoClass *klass = mono_class_from_mono_type (type->type);
2011 MONO_ARCH_SAVE_REGS;
2013 return (klass && klass->is_com_object);
2016 static MonoReflectionModule*
2017 ves_icall_MonoType_get_Module (MonoReflectionType *type)
2019 MonoClass *class = mono_class_from_mono_type (type->type);
2021 MONO_ARCH_SAVE_REGS;
2023 return mono_module_get_object (mono_object_domain (type), class->image);
2026 static MonoReflectionAssembly*
2027 ves_icall_MonoType_get_Assembly (MonoReflectionType *type)
2029 MonoDomain *domain = mono_domain_get ();
2030 MonoClass *class = mono_class_from_mono_type (type->type);
2032 MONO_ARCH_SAVE_REGS;
2034 return mono_assembly_get_object (domain, class->image->assembly);
2037 static MonoReflectionType*
2038 ves_icall_MonoType_get_DeclaringType (MonoReflectionType *type)
2040 MonoDomain *domain = mono_domain_get ();
2043 MONO_ARCH_SAVE_REGS;
2045 if (type->type->byref)
2047 if (type->type->type == MONO_TYPE_VAR)
2048 class = type->type->data.generic_param->owner->owner.klass;
2049 else if (type->type->type == MONO_TYPE_MVAR)
2050 class = type->type->data.generic_param->owner->owner.method->klass;
2052 class = mono_class_from_mono_type (type->type)->nested_in;
2054 return class ? mono_type_get_object (domain, &class->byval_arg) : NULL;
2057 static MonoReflectionType*
2058 ves_icall_MonoType_get_UnderlyingSystemType (MonoReflectionType *type)
2060 MonoDomain *domain = mono_domain_get ();
2061 MonoClass *class = mono_class_from_mono_type (type->type);
2063 MONO_ARCH_SAVE_REGS;
2065 if (class->enumtype && class->enum_basetype) /* types that are modified typebuilders may not have enum_basetype set */
2066 return mono_type_get_object (domain, class->enum_basetype);
2067 else if (class->element_class)
2068 return mono_type_get_object (domain, &class->element_class->byval_arg);
2074 ves_icall_MonoType_get_Name (MonoReflectionType *type)
2076 MonoDomain *domain = mono_domain_get ();
2077 MonoClass *class = mono_class_from_mono_type (type->type);
2079 MONO_ARCH_SAVE_REGS;
2081 if (type->type->byref) {
2082 char *n = g_strdup_printf ("%s&", class->name);
2083 MonoString *res = mono_string_new (domain, n);
2089 return mono_string_new (domain, class->name);
2094 ves_icall_MonoType_get_Namespace (MonoReflectionType *type)
2096 MonoDomain *domain = mono_domain_get ();
2097 MonoClass *class = mono_class_from_mono_type (type->type);
2099 MONO_ARCH_SAVE_REGS;
2101 while (class->nested_in)
2102 class = class->nested_in;
2104 if (class->name_space [0] == '\0')
2107 return mono_string_new (domain, class->name_space);
2111 ves_icall_MonoType_GetArrayRank (MonoReflectionType *type)
2113 MonoClass *class = mono_class_from_mono_type (type->type);
2115 MONO_ARCH_SAVE_REGS;
2121 ves_icall_MonoType_GetGenericArguments (MonoReflectionType *type)
2124 MonoClass *klass, *pklass;
2126 MONO_ARCH_SAVE_REGS;
2128 klass = mono_class_from_mono_type (type->type);
2130 if (klass->generic_container) {
2131 MonoGenericContainer *container = klass->generic_container;
2132 res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, container->type_argc);
2133 for (i = 0; i < container->type_argc; ++i) {
2134 pklass = mono_class_from_generic_parameter (&container->type_params [i], klass->image, FALSE);
2135 mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), &pklass->byval_arg));
2137 } else if (klass->generic_class) {
2138 MonoGenericInst *inst = klass->generic_class->context.class_inst;
2139 res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, inst->type_argc);
2140 for (i = 0; i < inst->type_argc; ++i)
2141 mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), inst->type_argv [i]));
2143 res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, 0);
2149 ves_icall_Type_get_IsGenericTypeDefinition (MonoReflectionType *type)
2152 MONO_ARCH_SAVE_REGS;
2154 if (type->type->byref)
2157 klass = mono_class_from_mono_type (type->type);
2159 return klass->generic_container != NULL;
2162 static MonoReflectionType*
2163 ves_icall_Type_GetGenericTypeDefinition_impl (MonoReflectionType *type)
2166 MONO_ARCH_SAVE_REGS;
2168 if (type->type->byref)
2171 klass = mono_class_from_mono_type (type->type);
2172 if (klass->generic_container) {
2173 return type; /* check this one */
2175 if (klass->generic_class) {
2176 MonoClass *generic_class = klass->generic_class->container_class;
2178 if (generic_class->wastypebuilder && generic_class->reflection_info)
2179 return generic_class->reflection_info;
2181 return mono_type_get_object (mono_object_domain (type), &generic_class->byval_arg);
2186 static MonoReflectionType*
2187 ves_icall_Type_MakeGenericType (MonoReflectionType *type, MonoArray *type_array)
2189 MonoType *geninst, **types;
2192 MONO_ARCH_SAVE_REGS;
2194 count = mono_array_length (type_array);
2195 types = g_new0 (MonoType *, count);
2197 for (i = 0; i < count; i++) {
2198 MonoReflectionType *t = mono_array_get (type_array, gpointer, i);
2199 types [i] = t->type;
2202 geninst = mono_reflection_bind_generic_parameters (type, count, types);
2207 return mono_type_get_object (mono_object_domain (type), geninst);
2211 ves_icall_Type_get_IsGenericInstance (MonoReflectionType *type)
2214 MONO_ARCH_SAVE_REGS;
2216 if (type->type->byref)
2219 klass = mono_class_from_mono_type (type->type);
2220 return klass->generic_class != NULL;
2224 ves_icall_Type_get_IsGenericType (MonoReflectionType *type)
2227 MONO_ARCH_SAVE_REGS;
2229 if (type->type->byref)
2232 klass = mono_class_from_mono_type (type->type);
2233 return klass->generic_class != NULL || klass->generic_container != NULL;
2237 ves_icall_Type_GetGenericParameterPosition (MonoReflectionType *type)
2239 MONO_ARCH_SAVE_REGS;
2241 if (is_generic_parameter (type->type))
2242 return type->type->data.generic_param->num;
2246 static GenericParameterAttributes
2247 ves_icall_Type_GetGenericParameterAttributes (MonoReflectionType *type)
2249 MONO_ARCH_SAVE_REGS;
2250 g_assert (is_generic_parameter (type->type));
2251 return type->type->data.generic_param->flags;
2255 ves_icall_Type_GetGenericParameterConstraints (MonoReflectionType *type)
2257 MonoGenericParam *param;
2263 MONO_ARCH_SAVE_REGS;
2265 domain = mono_object_domain (type);
2266 param = type->type->data.generic_param;
2267 for (count = 0, ptr = param->constraints; ptr && *ptr; ptr++, count++)
2270 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2271 for (i = 0; i < count; i++)
2272 mono_array_setref (res, i, mono_type_get_object (domain, ¶m->constraints [i]->byval_arg));
2279 ves_icall_MonoType_get_IsGenericParameter (MonoReflectionType *type)
2281 MONO_ARCH_SAVE_REGS;
2282 return is_generic_parameter (type->type);
2286 ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder *tb)
2288 MONO_ARCH_SAVE_REGS;
2289 return is_generic_parameter (tb->type.type);
2293 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
2294 MonoReflectionType *t)
2296 enumtype->type = t->type;
2299 static MonoReflectionType*
2300 ves_icall_MonoGenericClass_GetParentType (MonoReflectionGenericClass *type)
2302 MonoDynamicGenericClass *gclass;
2303 MonoReflectionType *parent = NULL;
2308 MONO_ARCH_SAVE_REGS;
2310 g_assert (type->type.type->data.generic_class->is_dynamic);
2311 gclass = (MonoDynamicGenericClass *) type->type.type->data.generic_class;
2313 domain = mono_object_domain (type);
2314 klass = mono_class_from_mono_type (type->generic_type->type.type);
2316 if (!klass->generic_class && !klass->generic_container)
2319 parent = type->generic_type->parent;
2321 if (!parent || (parent->type->type != MONO_TYPE_GENERICINST))
2324 inflated = mono_class_inflate_generic_type (
2325 parent->type, mono_generic_class_get_context ((MonoGenericClass *) gclass));
2327 return mono_type_get_object (domain, inflated);
2331 ves_icall_MonoGenericClass_GetInterfaces (MonoReflectionGenericClass *type)
2333 static MonoClass *System_Reflection_MonoGenericClass;
2334 MonoGenericClass *gclass;
2335 MonoReflectionTypeBuilder *tb = NULL;
2336 MonoClass *klass = NULL;
2341 MONO_ARCH_SAVE_REGS;
2343 if (!System_Reflection_MonoGenericClass) {
2344 System_Reflection_MonoGenericClass = mono_class_from_name (
2345 mono_defaults.corlib, "System.Reflection", "MonoGenericClass");
2346 g_assert (System_Reflection_MonoGenericClass);
2349 domain = mono_object_domain (type);
2351 gclass = type->type.type->data.generic_class;
2352 g_assert (gclass->is_dynamic);
2354 tb = type->generic_type;
2355 icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
2357 res = mono_array_new (domain, System_Reflection_MonoGenericClass, icount);
2359 for (i = 0; i < icount; i++) {
2360 MonoReflectionType *iface;
2364 iface = mono_array_get (tb->interfaces, MonoReflectionType *, i);
2367 it = &klass->interfaces [i]->byval_arg;
2369 it = mono_class_inflate_generic_type (it, mono_generic_class_get_context (gclass));
2371 iface = mono_type_get_object (domain, it);
2372 mono_array_setref (res, i, iface);
2378 static MonoReflectionMethod*
2379 ves_icall_MonoGenericClass_GetCorrespondingInflatedMethod (MonoReflectionGenericClass *type,
2380 MonoReflectionMethod* generic)
2382 MonoGenericClass *gclass;
2383 MonoDynamicGenericClass *dgclass;
2387 MONO_ARCH_SAVE_REGS;
2389 gclass = type->type.type->data.generic_class;
2390 g_assert (gclass->is_dynamic);
2392 dgclass = (MonoDynamicGenericClass *) gclass;
2394 domain = mono_object_domain (type);
2396 for (i = 0; i < dgclass->count_methods; i++)
2397 if (generic->method->token == dgclass->methods [i]->token)
2398 return mono_method_get_object (domain, dgclass->methods [i], NULL);
2403 static MonoReflectionMethod*
2404 ves_icall_MonoGenericClass_GetCorrespondingInflatedConstructor (MonoReflectionGenericClass *type,
2405 MonoReflectionMethod* generic)
2407 MonoGenericClass *gclass;
2408 MonoDynamicGenericClass *dgclass;
2412 MONO_ARCH_SAVE_REGS;
2414 gclass = type->type.type->data.generic_class;
2415 g_assert (gclass->is_dynamic);
2417 dgclass = (MonoDynamicGenericClass *) gclass;
2419 domain = mono_object_domain (type);
2421 for (i = 0; i < dgclass->count_ctors; i++)
2422 if (generic->method->token == dgclass->ctors [i]->token)
2423 return mono_method_get_object (domain, dgclass->ctors [i], NULL);
2429 static MonoReflectionField*
2430 ves_icall_MonoGenericClass_GetCorrespondingInflatedField (MonoReflectionGenericClass *type,
2431 MonoString* generic_name)
2433 MonoGenericClass *gclass;
2434 MonoDynamicGenericClass *dgclass;
2436 MonoClass *refclass;
2437 char *utf8_name = mono_string_to_utf8 (generic_name);
2440 MONO_ARCH_SAVE_REGS;
2442 gclass = type->type.type->data.generic_class;
2443 g_assert (gclass->is_dynamic);
2445 dgclass = (MonoDynamicGenericClass *) gclass;
2447 refclass = mono_class_from_mono_type (type->type.type);
2449 domain = mono_object_domain (type);
2451 for (i = 0; i < dgclass->count_fields; i++)
2452 if (strcmp (utf8_name, dgclass->fields [i].name) == 0) {
2454 return mono_field_get_object (domain, refclass, &dgclass->fields [i]);
2463 static MonoReflectionMethod*
2464 ves_icall_MonoType_GetCorrespondingInflatedMethod (MonoReflectionType *type,
2465 MonoReflectionMethod* generic)
2472 MONO_ARCH_SAVE_REGS;
2474 domain = ((MonoObject *)type)->vtable->domain;
2476 klass = mono_class_from_mono_type (type->type);
2479 while ((method = mono_class_get_methods (klass, &iter))) {
2480 if (method->token == generic->method->token)
2481 return mono_method_get_object (domain, method, klass);
2488 ves_icall_MonoGenericClass_GetMethods (MonoReflectionGenericClass *type,
2489 MonoReflectionType *reflected_type)
2491 MonoGenericClass *gclass;
2492 MonoDynamicGenericClass *dgclass;
2494 MonoClass *refclass;
2498 MONO_ARCH_SAVE_REGS;
2500 gclass = type->type.type->data.generic_class;
2501 g_assert (gclass->is_dynamic);
2502 dgclass = (MonoDynamicGenericClass *) gclass;
2504 refclass = mono_class_from_mono_type (reflected_type->type);
2506 domain = mono_object_domain (type);
2507 res = mono_array_new (domain, mono_defaults.method_info_class, dgclass->count_methods);
2509 for (i = 0; i < dgclass->count_methods; i++)
2510 mono_array_setref (res, i, mono_method_get_object (domain, dgclass->methods [i], refclass));
2516 ves_icall_MonoGenericClass_GetConstructors (MonoReflectionGenericClass *type,
2517 MonoReflectionType *reflected_type)
2519 static MonoClass *System_Reflection_ConstructorInfo;
2520 MonoGenericClass *gclass;
2521 MonoDynamicGenericClass *dgclass;
2523 MonoClass *refclass;
2527 MONO_ARCH_SAVE_REGS;
2529 if (!System_Reflection_ConstructorInfo)
2530 System_Reflection_ConstructorInfo = mono_class_from_name (
2531 mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
2533 gclass = type->type.type->data.generic_class;
2534 g_assert (gclass->is_dynamic);
2535 dgclass = (MonoDynamicGenericClass *) gclass;
2537 refclass = mono_class_from_mono_type (reflected_type->type);
2539 domain = mono_object_domain (type);
2540 res = mono_array_new (domain, System_Reflection_ConstructorInfo, dgclass->count_ctors);
2542 for (i = 0; i < dgclass->count_ctors; i++)
2543 mono_array_setref (res, i, mono_method_get_object (domain, dgclass->ctors [i], refclass));
2549 ves_icall_MonoGenericClass_GetFields (MonoReflectionGenericClass *type,
2550 MonoReflectionType *reflected_type)
2552 MonoGenericClass *gclass;
2553 MonoDynamicGenericClass *dgclass;
2555 MonoClass *refclass;
2559 MONO_ARCH_SAVE_REGS;
2561 gclass = type->type.type->data.generic_class;
2562 g_assert (gclass->is_dynamic);
2563 dgclass = (MonoDynamicGenericClass *) gclass;
2565 refclass = mono_class_from_mono_type (reflected_type->type);
2567 domain = mono_object_domain (type);
2568 res = mono_array_new (domain, mono_defaults.field_info_class, dgclass->count_fields);
2570 for (i = 0; i < dgclass->count_fields; i++)
2571 mono_array_setref (res, i, mono_field_get_object (domain, refclass, &dgclass->fields [i]));
2577 ves_icall_MonoGenericClass_GetProperties (MonoReflectionGenericClass *type,
2578 MonoReflectionType *reflected_type)
2580 static MonoClass *System_Reflection_PropertyInfo;
2581 MonoGenericClass *gclass;
2582 MonoDynamicGenericClass *dgclass;
2584 MonoClass *refclass;
2588 MONO_ARCH_SAVE_REGS;
2590 if (!System_Reflection_PropertyInfo)
2591 System_Reflection_PropertyInfo = mono_class_from_name (
2592 mono_defaults.corlib, "System.Reflection", "PropertyInfo");
2594 gclass = type->type.type->data.generic_class;
2595 g_assert (gclass->is_dynamic);
2596 dgclass = (MonoDynamicGenericClass *) gclass;
2598 refclass = mono_class_from_mono_type (reflected_type->type);
2600 domain = mono_object_domain (type);
2601 res = mono_array_new (domain, System_Reflection_PropertyInfo, dgclass->count_properties);
2603 for (i = 0; i < dgclass->count_properties; i++)
2604 mono_array_setref (res, i, mono_property_get_object (domain, refclass, &dgclass->properties [i]));
2610 ves_icall_MonoGenericClass_GetEvents (MonoReflectionGenericClass *type,
2611 MonoReflectionType *reflected_type)
2613 static MonoClass *System_Reflection_EventInfo;
2614 MonoGenericClass *gclass;
2615 MonoDynamicGenericClass *dgclass;
2617 MonoClass *refclass;
2621 MONO_ARCH_SAVE_REGS;
2623 if (!System_Reflection_EventInfo)
2624 System_Reflection_EventInfo = mono_class_from_name (
2625 mono_defaults.corlib, "System.Reflection", "EventInfo");
2627 gclass = type->type.type->data.generic_class;
2628 g_assert (gclass->is_dynamic);
2629 dgclass = (MonoDynamicGenericClass *) gclass;
2631 refclass = mono_class_from_mono_type (reflected_type->type);
2633 domain = mono_object_domain (type);
2634 res = mono_array_new (domain, System_Reflection_EventInfo, dgclass->count_events);
2636 for (i = 0; i < dgclass->count_events; i++)
2637 mono_array_setref (res, i, mono_event_get_object (domain, refclass, &dgclass->events [i]));
2642 static MonoReflectionMethod *
2643 ves_icall_MonoType_get_DeclaringMethod (MonoReflectionType *type)
2648 MONO_ARCH_SAVE_REGS;
2650 if (type->type->byref || type->type->type != MONO_TYPE_MVAR)
2653 method = type->type->data.generic_param->owner->owner.method;
2655 klass = mono_class_from_mono_type (type->type);
2656 return mono_method_get_object (mono_object_domain (type), method, klass);
2659 static MonoReflectionDllImportAttribute*
2660 ves_icall_MonoMethod_GetDllImportAttribute (MonoMethod *method)
2662 static MonoClass *DllImportAttributeClass = NULL;
2663 MonoDomain *domain = mono_domain_get ();
2664 MonoReflectionDllImportAttribute *attr;
2665 MonoImage *image = method->klass->image;
2666 MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method;
2667 MonoTableInfo *tables = image->tables;
2668 MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
2669 MonoTableInfo *mr = &tables [MONO_TABLE_MODULEREF];
2670 guint32 im_cols [MONO_IMPLMAP_SIZE];
2671 guint32 scope_token;
2672 const char *import = NULL;
2673 const char *scope = NULL;
2676 if (!method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)
2679 if (!DllImportAttributeClass) {
2680 DllImportAttributeClass =
2681 mono_class_from_name (mono_defaults.corlib,
2682 "System.Runtime.InteropServices", "DllImportAttribute");
2683 g_assert (DllImportAttributeClass);
2686 if (method->klass->image->dynamic) {
2687 MonoReflectionMethodAux *method_aux =
2688 g_hash_table_lookup (
2689 ((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
2691 import = method_aux->dllentry;
2692 scope = method_aux->dll;
2696 if (piinfo->implmap_idx) {
2697 mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
2699 piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
2700 import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
2701 scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
2702 scope = mono_metadata_string_heap (image, scope_token);
2705 flags = piinfo->piflags;
2707 attr = (MonoReflectionDllImportAttribute*)mono_object_new (domain, DllImportAttributeClass);
2709 MONO_OBJECT_SETREF (attr, dll, mono_string_new (domain, scope));
2710 MONO_OBJECT_SETREF (attr, entry_point, mono_string_new (domain, import));
2711 attr->call_conv = (flags & 0x700) >> 8;
2712 attr->charset = ((flags & 0x6) >> 1) + 1;
2713 if (attr->charset == 1)
2715 attr->exact_spelling = (flags & 0x1) != 0;
2716 attr->set_last_error = (flags & 0x40) != 0;
2717 attr->best_fit_mapping = (flags & 0x30) == 0x10;
2718 attr->throw_on_unmappable = (flags & 0x3000) == 0x1000;
2719 attr->preserve_sig = FALSE;
2724 static MonoReflectionMethod *
2725 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
2727 MonoMethodInflated *imethod;
2730 MONO_ARCH_SAVE_REGS;
2732 if (method->method->generic_container)
2735 if (!method->method->is_inflated)
2738 imethod = (MonoMethodInflated *) method->method;
2740 result = imethod->declaring;
2741 /* Not a generic method. */
2742 if (!result->generic_container)
2745 if (method->method->klass->image->dynamic) {
2746 MonoDynamicImage *image = (MonoDynamicImage*)method->method->klass->image;
2747 MonoReflectionMethod *res;
2750 * FIXME: Why is this stuff needed at all ? Why can't the code below work for
2751 * the dynamic case as well ?
2753 mono_loader_lock ();
2754 res = mono_g_hash_table_lookup (image->generic_def_objects, imethod);
2755 mono_loader_unlock ();
2761 if (imethod->context.class_inst) {
2762 MonoClass *klass = ((MonoMethod *) imethod)->klass;
2763 result = mono_class_inflate_generic_method_full (result, klass, mono_class_get_context (klass));
2766 return mono_method_get_object (mono_object_domain (method), result, NULL);
2770 ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethod *method)
2772 MONO_ARCH_SAVE_REGS;
2774 return mono_method_signature (method->method)->generic_param_count != 0;
2778 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method)
2780 MONO_ARCH_SAVE_REGS;
2782 return method->method->generic_container != NULL;
2786 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
2791 MONO_ARCH_SAVE_REGS;
2793 domain = mono_object_domain (method);
2795 if (method->method->is_inflated) {
2796 MonoGenericInst *inst = mono_method_get_context (method->method)->method_inst;
2799 count = inst->type_argc;
2800 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2802 for (i = 0; i < count; i++)
2803 mono_array_setref (res, i, mono_type_get_object (domain, inst->type_argv [i]));
2809 count = mono_method_signature (method->method)->generic_param_count;
2810 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2812 for (i = 0; i < count; i++) {
2813 MonoGenericParam *param = &method->method->generic_container->type_params [i];
2814 MonoClass *pklass = mono_class_from_generic_parameter (
2815 param, method->method->klass->image, TRUE);
2816 mono_array_setref (res, i,
2817 mono_type_get_object (domain, &pklass->byval_arg));
2824 ensure_reflection_security (void)
2826 MonoMethod *m = mono_method_get_last_managed ();
2830 g_print ("method %s.%s.%s in image %s\n",
2831 m->klass->name_space, m->klass->name, m->name, m->klass->image->name);
2834 /* We stop at the first method which is not in
2835 System.Reflection or which is not in a platform
2837 if (strcmp (m->klass->name_space, "System.Reflection") != 0 ||
2838 !mono_security_core_clr_is_platform_image (m->klass->image)) {
2839 /* If the method is transparent we throw an exception. */
2840 if (mono_security_core_clr_method_level (m, TRUE) == MONO_SECURITY_CORE_CLR_TRANSPARENT ) {
2841 MonoException *ex = mono_exception_from_name_msg (mono_defaults.corlib, "System", "MethodAccessException", "Reflection called from transparent code");
2843 mono_raise_exception (ex);
2848 mono_stack_walk_no_il (get_caller, &m);
2853 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoArray *params)
2856 * Invoke from reflection is supposed to always be a virtual call (the API
2857 * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
2858 * greater flexibility.
2860 MonoMethod *m = method->method;
2864 MONO_ARCH_SAVE_REGS;
2866 if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR &&
2867 mono_security_core_clr_method_level (m, TRUE) == MONO_SECURITY_CORE_CLR_CRITICAL)
2868 ensure_reflection_security ();
2870 if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
2872 if (!mono_object_isinst (this, m->klass))
2873 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
2874 m = mono_object_get_virtual_method (this, m);
2875 /* must pass the pointer to the value for valuetype methods */
2876 if (m->klass->valuetype)
2877 obj = mono_object_unbox (this);
2878 } else if (strcmp (m->name, ".ctor") && !m->wrapper_type)
2879 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
2882 pcount = params? mono_array_length (params): 0;
2883 if (pcount != mono_method_signature (m)->param_count)
2884 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
2886 if ((m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) && !strcmp (m->name, ".ctor") && !this)
2887 mono_raise_exception (mono_exception_from_name_msg (mono_defaults.corlib, "System", "MethodAccessException", "Cannot invoke constructor of an abstract class."));
2889 if (m->klass->image->assembly->ref_only)
2890 mono_raise_exception (mono_get_exception_invalid_operation ("It is illegal to invoke a method on a type loaded using the ReflectionOnly api."));
2892 if (m->klass->rank && !strcmp (m->name, ".ctor")) {
2895 guint32 *lower_bounds;
2896 pcount = mono_array_length (params);
2897 lengths = alloca (sizeof (guint32) * pcount);
2898 for (i = 0; i < pcount; ++i)
2899 lengths [i] = *(gint32*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
2901 if (m->klass->rank == pcount) {
2902 /* Only lengths provided. */
2903 lower_bounds = NULL;
2905 g_assert (pcount == (m->klass->rank * 2));
2906 /* lower bounds are first. */
2907 lower_bounds = lengths;
2908 lengths += m->klass->rank;
2911 return (MonoObject*)mono_array_new_full (mono_object_domain (params), m->klass, lengths, lower_bounds);
2913 return mono_runtime_invoke_array (m, obj, params, NULL);
2917 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this, MonoArray *params, MonoArray **outArgs)
2919 MonoDomain *domain = mono_object_domain (method);
2920 MonoMethod *m = method->method;
2921 MonoMethodSignature *sig = mono_method_signature (m);
2922 MonoArray *out_args;
2924 int i, j, outarg_count = 0;
2926 MONO_ARCH_SAVE_REGS;
2928 if (m->klass == mono_defaults.object_class) {
2930 if (!strcmp (m->name, "FieldGetter")) {
2931 MonoClass *k = this->vtable->klass;
2935 /* If this is a proxy, then it must be a CBO */
2936 if (k == mono_defaults.transparent_proxy_class) {
2937 MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
2938 this = tp->rp->unwrapped_server;
2940 k = this->vtable->klass;
2943 name = mono_array_get (params, MonoString *, 1);
2944 str = mono_string_to_utf8 (name);
2947 MonoClassField* field = mono_class_get_field_from_name (k, str);
2949 MonoClass *field_klass = mono_class_from_mono_type (field->type);
2950 if (field_klass->valuetype)
2951 result = mono_value_box (domain, field_klass, (char *)this + field->offset);
2953 result = *((gpointer *)((char *)this + field->offset));
2955 out_args = mono_array_new (domain, mono_defaults.object_class, 1);
2956 *outArgs = out_args;
2957 mono_array_setref (out_args, 0, result);
2965 g_assert_not_reached ();
2967 } else if (!strcmp (m->name, "FieldSetter")) {
2968 MonoClass *k = this->vtable->klass;
2974 /* If this is a proxy, then it must be a CBO */
2975 if (k == mono_defaults.transparent_proxy_class) {
2976 MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
2977 this = tp->rp->unwrapped_server;
2979 k = this->vtable->klass;
2982 name = mono_array_get (params, MonoString *, 1);
2983 str = mono_string_to_utf8 (name);
2986 MonoClassField* field = mono_class_get_field_from_name (k, str);
2988 MonoClass *field_klass = mono_class_from_mono_type (field->type);
2989 MonoObject *val = mono_array_get (params, gpointer, 2);
2991 if (field_klass->valuetype) {
2992 size = mono_type_size (field->type, &align);
2993 memcpy ((char *)this + field->offset,
2994 ((char *)val) + sizeof (MonoObject), size);
2996 *(MonoObject**)((char *)this + field->offset) = val;
2998 out_args = mono_array_new (domain, mono_defaults.object_class, 0);
2999 *outArgs = out_args;
3009 g_assert_not_reached ();
3014 for (i = 0; i < mono_array_length (params); i++) {
3015 if (sig->params [i]->byref)
3019 out_args = mono_array_new (domain, mono_defaults.object_class, outarg_count);
3021 /* handle constructors only for objects already allocated */
3022 if (!strcmp (method->method->name, ".ctor"))
3025 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
3026 g_assert (!method->method->klass->valuetype);
3027 result = mono_runtime_invoke_array (method->method, this, params, NULL);
3029 for (i = 0, j = 0; i < mono_array_length (params); i++) {
3030 if (sig->params [i]->byref) {
3032 arg = mono_array_get (params, gpointer, i);
3033 mono_array_setref (out_args, j, arg);
3038 *outArgs = out_args;
3044 read_enum_value (char *mem, int type)
3048 return *(guint8*)mem;
3050 return *(gint8*)mem;
3052 return *(guint16*)mem;
3054 return *(gint16*)mem;
3056 return *(guint32*)mem;
3058 return *(gint32*)mem;
3060 return *(guint64*)mem;
3062 return *(gint64*)mem;
3064 g_assert_not_reached ();
3070 write_enum_value (char *mem, int type, guint64 value)
3074 case MONO_TYPE_I1: {
3075 guint8 *p = (guint8*)mem;
3080 case MONO_TYPE_I2: {
3081 guint16 *p = (void*)mem;
3086 case MONO_TYPE_I4: {
3087 guint32 *p = (void*)mem;
3092 case MONO_TYPE_I8: {
3093 guint64 *p = (void*)mem;
3098 g_assert_not_reached ();
3104 ves_icall_System_Enum_ToObject (MonoReflectionType *enumType, MonoObject *value)
3107 MonoClass *enumc, *objc;
3111 MONO_ARCH_SAVE_REGS;
3113 MONO_CHECK_ARG_NULL (enumType);
3114 MONO_CHECK_ARG_NULL (value);
3116 domain = mono_object_domain (enumType);
3117 enumc = mono_class_from_mono_type (enumType->type);
3118 objc = value->vtable->klass;
3120 if (!enumc->enumtype)
3121 mono_raise_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
3122 if (!((objc->enumtype) || (objc->byval_arg.type >= MONO_TYPE_I1 && objc->byval_arg.type <= MONO_TYPE_U8)))
3123 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."));
3125 res = mono_object_new (domain, enumc);
3126 val = read_enum_value ((char *)value + sizeof (MonoObject), objc->enumtype? objc->enum_basetype->type: objc->byval_arg.type);
3127 write_enum_value ((char *)res + sizeof (MonoObject), enumc->enum_basetype->type, val);
3133 ves_icall_System_Enum_get_value (MonoObject *this)
3141 MONO_ARCH_SAVE_REGS;
3146 g_assert (this->vtable->klass->enumtype);
3148 enumc = mono_class_from_mono_type (this->vtable->klass->enum_basetype);
3149 res = mono_object_new (mono_object_domain (this), enumc);
3150 dst = (char *)res + sizeof (MonoObject);
3151 src = (char *)this + sizeof (MonoObject);
3152 size = mono_class_value_size (enumc, NULL);
3154 memcpy (dst, src, size);
3160 ves_icall_get_enum_info (MonoReflectionType *type, MonoEnumInfo *info)
3162 MonoDomain *domain = mono_object_domain (type);
3163 MonoClass *enumc = mono_class_from_mono_type (type->type);
3164 guint j = 0, nvalues, crow;
3166 MonoClassField *field;
3168 MONO_ARCH_SAVE_REGS;
3170 info->utype = mono_type_get_object (domain, enumc->enum_basetype);
3171 nvalues = mono_class_num_fields (enumc) ? mono_class_num_fields (enumc) - 1 : 0;
3172 info->names = mono_array_new (domain, mono_defaults.string_class, nvalues);
3173 info->values = mono_array_new (domain, enumc, nvalues);
3177 while ((field = mono_class_get_fields (enumc, &iter))) {
3181 if (strcmp ("value__", field->name) == 0)
3183 if (mono_field_is_deleted (field))
3185 mono_array_setref (info->names, j, mono_string_new (domain, field->name));
3188 crow = mono_metadata_get_constant_index (enumc->image, mono_class_get_field_token (field), crow + 1);
3189 field->def_type = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_TYPE);
3190 crow = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_VALUE);
3191 field->data = (gpointer)mono_metadata_blob_heap (enumc->image, crow);
3195 len = mono_metadata_decode_blob_size (p, &p);
3196 switch (enumc->enum_basetype->type) {
3199 mono_array_set (info->values, gchar, j, *p);
3201 case MONO_TYPE_CHAR:
3204 mono_array_set (info->values, gint16, j, read16 (p));
3208 mono_array_set (info->values, gint32, j, read32 (p));
3212 mono_array_set (info->values, gint64, j, read64 (p));
3215 g_error ("Implement type 0x%02x in get_enum_info", enumc->enum_basetype->type);
3222 BFLAGS_IgnoreCase = 1,
3223 BFLAGS_DeclaredOnly = 2,
3224 BFLAGS_Instance = 4,
3226 BFLAGS_Public = 0x10,
3227 BFLAGS_NonPublic = 0x20,
3228 BFLAGS_FlattenHierarchy = 0x40,
3229 BFLAGS_InvokeMethod = 0x100,
3230 BFLAGS_CreateInstance = 0x200,
3231 BFLAGS_GetField = 0x400,
3232 BFLAGS_SetField = 0x800,
3233 BFLAGS_GetProperty = 0x1000,
3234 BFLAGS_SetProperty = 0x2000,
3235 BFLAGS_ExactBinding = 0x10000,
3236 BFLAGS_SuppressChangeType = 0x20000,
3237 BFLAGS_OptionalParamBinding = 0x40000
3240 static MonoReflectionField *
3241 ves_icall_Type_GetField (MonoReflectionType *type, MonoString *name, guint32 bflags)
3244 MonoClass *startklass, *klass;
3246 MonoClassField *field;
3249 int (*compare_func) (const char *s1, const char *s2) = NULL;
3250 domain = ((MonoObject *)type)->vtable->domain;
3251 klass = startklass = mono_class_from_mono_type (type->type);
3253 MONO_ARCH_SAVE_REGS;
3256 mono_raise_exception (mono_get_exception_argument_null ("name"));
3257 if (type->type->byref)
3260 compare_func = (bflags & BFLAGS_IgnoreCase) ? g_strcasecmp : strcmp;
3263 if (klass->exception_type != MONO_EXCEPTION_NONE)
3264 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3267 while ((field = mono_class_get_fields (klass, &iter))) {
3270 if (field->type == NULL)
3272 if (mono_field_is_deleted (field))
3274 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3275 if (bflags & BFLAGS_Public)
3277 } else if ((klass == startklass) || (field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
3278 if (bflags & BFLAGS_NonPublic) {
3285 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
3286 if (bflags & BFLAGS_Static)
3287 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3290 if (bflags & BFLAGS_Instance)
3297 utf8_name = mono_string_to_utf8 (name);
3299 if (compare_func (field->name, utf8_name)) {
3305 return mono_field_get_object (domain, klass, field);
3307 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3314 ves_icall_Type_GetFields_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3317 MonoClass *startklass, *klass, *refklass;
3322 MonoClassField *field;
3324 MONO_ARCH_SAVE_REGS;
3326 domain = ((MonoObject *)type)->vtable->domain;
3327 if (type->type->byref)
3328 return mono_array_new (domain, mono_defaults.field_info_class, 0);
3329 klass = startklass = mono_class_from_mono_type (type->type);
3330 refklass = mono_class_from_mono_type (reftype->type);
3334 res = mono_array_new (domain, mono_defaults.field_info_class, len);
3336 if (klass->exception_type != MONO_EXCEPTION_NONE)
3337 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3340 while ((field = mono_class_get_fields (klass, &iter))) {
3342 if (mono_field_is_deleted (field))
3344 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3345 if (bflags & BFLAGS_Public)
3347 } else if ((klass == startklass) || (field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
3348 if (bflags & BFLAGS_NonPublic) {
3355 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
3356 if (bflags & BFLAGS_Static)
3357 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3360 if (bflags & BFLAGS_Instance)
3366 member = (MonoObject*)mono_field_get_object (domain, refklass, field);
3368 MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, len * 2);
3369 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3373 mono_array_setref (res, i, member);
3376 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3379 MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, i);
3380 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3383 * Better solution for the new GC.
3384 * res->max_length = i;
3391 method_nonpublic (MonoMethod* method, gboolean start_klass)
3393 switch (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) {
3394 case METHOD_ATTRIBUTE_ASSEM:
3395 return (start_klass || mono_defaults.generic_ilist_class);
3396 case METHOD_ATTRIBUTE_PRIVATE:
3398 case METHOD_ATTRIBUTE_PUBLIC:
3406 ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
3409 MonoClass *startklass, *klass, *refklass;
3414 int i, len, match, nslots;
3415 guint32 method_slots_default [8];
3416 guint32 *method_slots;
3417 gchar *mname = NULL;
3418 int (*compare_func) (const char *s1, const char *s2) = NULL;
3420 MONO_ARCH_SAVE_REGS;
3422 domain = ((MonoObject *)type)->vtable->domain;
3423 if (type->type->byref)
3424 return mono_array_new (domain, mono_defaults.method_info_class, 0);
3425 klass = startklass = mono_class_from_mono_type (type->type);
3426 refklass = mono_class_from_mono_type (reftype->type);
3429 mname = mono_string_to_utf8 (name);
3430 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
3433 mono_class_setup_vtable (klass);
3435 if (is_generic_parameter (type->type))
3436 nslots = klass->parent->vtable_size;
3438 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : klass->vtable_size;
3439 if (nslots >= sizeof (method_slots_default) * 8) {
3440 method_slots = g_new0 (guint32, nslots / 32 + 1);
3442 method_slots = method_slots_default;
3443 memset (method_slots, 0, sizeof (method_slots_default));
3447 res = mono_array_new (domain, mono_defaults.method_info_class, len);
3449 mono_class_setup_vtable (klass);
3450 if (klass->exception_type != MONO_EXCEPTION_NONE)
3451 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3454 while ((method = mono_class_get_methods (klass, &iter))) {
3456 if (method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
3458 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3459 if (bflags & BFLAGS_Public)
3461 } else if ((bflags & BFLAGS_NonPublic) && method_nonpublic (method, (klass == startklass))) {
3467 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3468 if (bflags & BFLAGS_Static)
3469 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3472 if (bflags & BFLAGS_Instance)
3480 if (compare_func (mname, method->name))
3485 if (method->slot != -1) {
3486 g_assert (method->slot < nslots);
3487 if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
3489 method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
3492 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
3495 MonoArray *new_res = mono_array_new (domain, mono_defaults.method_info_class, len * 2);
3496 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3500 mono_array_setref (res, i, member);
3503 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3507 if (method_slots != method_slots_default)
3508 g_free (method_slots);
3510 MonoArray *new_res = mono_array_new (domain, mono_defaults.method_info_class, i);
3511 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3514 * Better solution for the new GC.
3515 * res->max_length = i;
3522 ves_icall_Type_GetConstructors_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3525 static MonoClass *System_Reflection_ConstructorInfo;
3526 MonoClass *startklass, *klass, *refklass;
3531 gpointer iter = NULL;
3533 MONO_ARCH_SAVE_REGS;
3535 domain = ((MonoObject *)type)->vtable->domain;
3536 if (type->type->byref)
3537 return mono_array_new (domain, mono_defaults.method_info_class, 0);
3538 klass = startklass = mono_class_from_mono_type (type->type);
3539 refklass = mono_class_from_mono_type (reftype->type);
3541 if (klass->exception_type != MONO_EXCEPTION_NONE)
3542 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3544 if (!System_Reflection_ConstructorInfo)
3545 System_Reflection_ConstructorInfo = mono_class_from_name (
3546 mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
3550 res = mono_array_new (domain, System_Reflection_ConstructorInfo, len);
3552 while ((method = mono_class_get_methods (klass, &iter))) {
3554 if (strcmp (method->name, ".ctor") && strcmp (method->name, ".cctor"))
3556 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3557 if (bflags & BFLAGS_Public)
3560 if (bflags & BFLAGS_NonPublic)
3566 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3567 if (bflags & BFLAGS_Static)
3568 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3571 if (bflags & BFLAGS_Instance)
3577 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
3580 MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, len * 2);
3581 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3585 mono_array_setref (res, i, member);
3589 MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, i);
3590 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3593 * Better solution for the new GC.
3594 * res->max_length = i;
3601 property_hash (gconstpointer data)
3603 MonoProperty *prop = (MonoProperty*)data;
3605 return g_str_hash (prop->name);
3609 property_equal (MonoProperty *prop1, MonoProperty *prop2)
3611 // Properties are hide-by-name-and-signature
3612 if (!g_str_equal (prop1->name, prop2->name))
3615 if (prop1->get && prop2->get && !mono_metadata_signature_equal (mono_method_signature (prop1->get), mono_method_signature (prop2->get)))
3617 if (prop1->set && prop2->set && !mono_metadata_signature_equal (mono_method_signature (prop1->set), mono_method_signature (prop2->set)))
3623 property_accessor_nonpublic (MonoMethod* accessor, gboolean start_klass)
3628 return method_nonpublic (accessor, start_klass);
3632 ves_icall_Type_GetPropertiesByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
3635 static MonoClass *System_Reflection_PropertyInfo;
3636 MonoClass *startklass, *klass;
3643 gchar *propname = NULL;
3644 int (*compare_func) (const char *s1, const char *s2) = NULL;
3646 GHashTable *properties;
3648 MONO_ARCH_SAVE_REGS;
3650 if (!System_Reflection_PropertyInfo)
3651 System_Reflection_PropertyInfo = mono_class_from_name (
3652 mono_defaults.corlib, "System.Reflection", "PropertyInfo");
3654 domain = ((MonoObject *)type)->vtable->domain;
3655 if (type->type->byref)
3656 return mono_array_new (domain, System_Reflection_PropertyInfo, 0);
3657 klass = startklass = mono_class_from_mono_type (type->type);
3659 propname = mono_string_to_utf8 (name);
3660 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
3663 mono_class_setup_vtable (klass);
3665 properties = g_hash_table_new (property_hash, (GEqualFunc)property_equal);
3668 res = mono_array_new (domain, System_Reflection_PropertyInfo, len);
3670 mono_class_setup_vtable (klass);
3671 if (klass->exception_type != MONO_EXCEPTION_NONE) {
3672 g_hash_table_destroy (properties);
3675 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3679 while ((prop = mono_class_get_properties (klass, &iter))) {
3685 flags = method->flags;
3688 if ((prop->get && ((prop->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC)) ||
3689 (prop->set && ((prop->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC))) {
3690 if (bflags & BFLAGS_Public)
3692 } else if (bflags & BFLAGS_NonPublic) {
3693 if (property_accessor_nonpublic(prop->get, startklass == klass) ||
3694 property_accessor_nonpublic(prop->set, startklass == klass)) {
3701 if (flags & METHOD_ATTRIBUTE_STATIC) {
3702 if (bflags & BFLAGS_Static)
3703 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3706 if (bflags & BFLAGS_Instance)
3715 if (compare_func (propname, prop->name))
3719 if (g_hash_table_lookup (properties, prop))
3723 MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, len * 2);
3724 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3728 mono_array_setref (res, i, mono_property_get_object (domain, startklass, prop));
3731 g_hash_table_insert (properties, prop, prop);
3733 if ((!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent)))
3736 g_hash_table_destroy (properties);
3739 MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, i);
3740 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3743 * Better solution for the new GC.
3744 * res->max_length = i;
3750 static MonoReflectionEvent *
3751 ves_icall_MonoType_GetEvent (MonoReflectionType *type, MonoString *name, guint32 bflags)
3754 MonoClass *klass, *startklass;
3760 MONO_ARCH_SAVE_REGS;
3762 event_name = mono_string_to_utf8 (name);
3763 if (type->type->byref)
3765 klass = startklass = mono_class_from_mono_type (type->type);
3766 domain = mono_object_domain (type);
3769 if (klass->exception_type != MONO_EXCEPTION_NONE)
3770 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3773 while ((event = mono_class_get_events (klass, &iter))) {
3774 if (strcmp (event->name, event_name))
3777 method = event->add;
3779 method = event->remove;
3781 method = event->raise;
3783 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3784 if (!(bflags & BFLAGS_Public))
3787 if (!(bflags & BFLAGS_NonPublic))
3789 if ((klass != startklass) && (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PRIVATE)
3794 if (!(bflags & BFLAGS_NonPublic))
3797 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3798 if (!(bflags & BFLAGS_Static))
3800 if (!(bflags & BFLAGS_FlattenHierarchy) && (klass != startklass))
3803 if (!(bflags & BFLAGS_Instance))
3807 g_free (event_name);
3808 return mono_event_get_object (domain, startklass, event);
3811 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3814 g_free (event_name);
3819 ves_icall_Type_GetEvents_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3822 static MonoClass *System_Reflection_EventInfo;
3823 MonoClass *startklass, *klass;
3830 MONO_ARCH_SAVE_REGS;
3832 if (!System_Reflection_EventInfo)
3833 System_Reflection_EventInfo = mono_class_from_name (
3834 mono_defaults.corlib, "System.Reflection", "EventInfo");
3836 domain = mono_object_domain (type);
3837 if (type->type->byref)
3838 return mono_array_new (domain, System_Reflection_EventInfo, 0);
3839 klass = startklass = mono_class_from_mono_type (type->type);
3843 res = mono_array_new (domain, System_Reflection_EventInfo, len);
3845 if (klass->exception_type != MONO_EXCEPTION_NONE)
3846 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3849 while ((event = mono_class_get_events (klass, &iter))) {
3851 method = event->add;
3853 method = event->remove;
3855 method = event->raise;
3857 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3858 if (bflags & BFLAGS_Public)
3860 } else if ((klass == startklass) || (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) {
3861 if (bflags & BFLAGS_NonPublic)
3866 if (bflags & BFLAGS_NonPublic)
3872 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3873 if (bflags & BFLAGS_Static)
3874 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3877 if (bflags & BFLAGS_Instance)
3882 if (bflags & BFLAGS_Instance)
3888 MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, len * 2);
3889 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3893 mono_array_setref (res, i, mono_event_get_object (domain, startklass, event));
3896 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3899 MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, i);
3900 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3903 * Better solution for the new GC.
3904 * res->max_length = i;
3910 static MonoReflectionType *
3911 ves_icall_Type_GetNestedType (MonoReflectionType *type, MonoString *name, guint32 bflags)
3919 MONO_ARCH_SAVE_REGS;
3921 domain = ((MonoObject *)type)->vtable->domain;
3922 if (type->type->byref)
3924 klass = mono_class_from_mono_type (type->type);
3925 str = mono_string_to_utf8 (name);
3928 if (klass->exception_type != MONO_EXCEPTION_NONE)
3929 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3932 * If a nested type is generic, return its generic type definition.
3933 * Note that this means that the return value is essentially a
3934 * nested type of the generic type definition of @klass.
3936 * A note in MSDN claims that a generic type definition can have
3937 * nested types that aren't generic. In any case, the container of that
3938 * nested type would be the generic type definition.
3940 if (klass->generic_class)
3941 klass = klass->generic_class->container_class;
3943 for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
3945 nested = tmpn->data;
3946 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
3947 if (bflags & BFLAGS_Public)
3950 if (bflags & BFLAGS_NonPublic)
3955 if (strcmp (nested->name, str) == 0){
3957 return mono_type_get_object (domain, &nested->byval_arg);
3960 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3967 ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags)
3977 MONO_ARCH_SAVE_REGS;
3979 domain = ((MonoObject *)type)->vtable->domain;
3980 if (type->type->byref)
3981 return mono_array_new (domain, mono_defaults.monotype_class, 0);
3982 klass = mono_class_from_mono_type (type->type);
3983 if (klass->exception_type != MONO_EXCEPTION_NONE)
3984 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3987 * If a nested type is generic, return its generic type definition.
3988 * Note that this means that the return value is essentially the set
3989 * of nested types of the generic type definition of @klass.
3991 * A note in MSDN claims that a generic type definition can have
3992 * nested types that aren't generic. In any case, the container of that
3993 * nested type would be the generic type definition.
3995 if (klass->generic_class)
3996 klass = klass->generic_class->container_class;
4000 res = mono_array_new (domain, mono_defaults.monotype_class, len);
4001 for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
4003 nested = tmpn->data;
4004 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
4005 if (bflags & BFLAGS_Public)
4008 if (bflags & BFLAGS_NonPublic)
4013 member = (MonoObject*)mono_type_get_object (domain, &nested->byval_arg);
4015 MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, len * 2);
4016 mono_array_memcpy_refs (new_res, 0, res, 0, len);
4020 mono_array_setref (res, i, member);
4024 MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, i);
4025 mono_array_memcpy_refs (new_res, 0, res, 0, i);
4028 * Better solution for the new GC.
4029 * res->max_length = i;
4035 static MonoReflectionType*
4036 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *assembly, MonoReflectionModule *module, MonoString *name, MonoBoolean throwOnError, MonoBoolean ignoreCase)
4039 MonoType *type = NULL;
4040 MonoTypeNameParse info;
4041 gboolean type_resolve;
4043 MONO_ARCH_SAVE_REGS;
4045 /* On MS.NET, this does not fire a TypeResolve event */
4046 type_resolve = TRUE;
4047 str = mono_string_to_utf8 (name);
4048 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
4049 if (!mono_reflection_parse_type (str, &info)) {
4051 mono_reflection_free_type_info (&info);
4052 if (throwOnError) /* uhm: this is a parse error, though... */
4053 mono_raise_exception (mono_get_exception_type_load (name, NULL));
4054 /*g_print ("failed parse\n");*/
4058 if (info.assembly.name) {
4060 /* 1.0 and 2.0 throw different exceptions */
4061 if (mono_defaults.generic_ilist_class)
4062 mono_raise_exception (mono_get_exception_argument (NULL, "Type names passed to Assembly.GetType() must not specify an assembly."));
4064 mono_raise_exception (mono_get_exception_type_load (name, NULL));
4069 if (module != NULL) {
4071 type = mono_reflection_get_type (module->image, &info, ignoreCase, &type_resolve);
4076 if (assembly->assembly->dynamic) {
4077 /* Enumerate all modules */
4078 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
4082 if (abuilder->modules) {
4083 for (i = 0; i < mono_array_length (abuilder->modules); ++i) {
4084 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
4085 type = mono_reflection_get_type (&mb->dynamic_image->image, &info, ignoreCase, &type_resolve);
4091 if (!type && abuilder->loaded_modules) {
4092 for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) {
4093 MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
4094 type = mono_reflection_get_type (mod->image, &info, ignoreCase, &type_resolve);
4101 type = mono_reflection_get_type (assembly->assembly->image, &info, ignoreCase, &type_resolve);
4103 mono_reflection_free_type_info (&info);
4105 MonoException *e = NULL;
4108 e = mono_get_exception_type_load (name, NULL);
4110 mono_loader_clear_error ();
4113 mono_raise_exception (e);
4118 if (type->type == MONO_TYPE_CLASS) {
4119 MonoClass *klass = mono_type_get_class (type);
4120 /* need to report exceptions ? */
4121 if (throwOnError && klass->exception_type) {
4122 /* report SecurityException (or others) that occured when loading the assembly */
4123 MonoException *exc = mono_class_get_exception_for_failure (klass);
4124 mono_loader_clear_error ();
4125 mono_raise_exception (exc);
4126 } else if (klass->exception_type == MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND) {
4131 /* g_print ("got it\n"); */
4132 return mono_type_get_object (mono_object_domain (assembly), type);
4136 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *assembly, MonoBoolean escaped)
4138 MonoDomain *domain = mono_object_domain (assembly);
4139 MonoAssembly *mass = assembly->assembly;
4140 MonoString *res = NULL;
4144 MONO_ARCH_SAVE_REGS;
4146 if (g_path_is_absolute (mass->image->name))
4147 absolute = g_strdup (mass->image->name);
4149 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4153 for (i = strlen (absolute) - 1; i >= 0; i--)
4154 if (absolute [i] == '\\')
4159 uri = g_filename_to_uri (absolute, NULL, NULL);
4161 uri = g_strconcat ("file://", absolute, NULL);
4165 res = mono_string_new (domain, uri);
4173 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssembly *assembly)
4175 MonoAssembly *mass = assembly->assembly;
4177 MONO_ARCH_SAVE_REGS;
4179 return mass->in_gac;
4182 static MonoReflectionAssembly*
4183 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoString *mname, MonoObject *evidence)
4187 MonoImageOpenStatus status;
4189 MONO_ARCH_SAVE_REGS;
4191 name = mono_string_to_utf8 (mname);
4192 res = mono_assembly_load_with_partial_name (name, &status);
4198 return mono_assembly_get_object (mono_domain_get (), res);
4202 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssembly *assembly)
4204 MonoDomain *domain = mono_object_domain (assembly);
4207 MONO_ARCH_SAVE_REGS;
4209 res = mono_string_new (domain, mono_image_get_filename (assembly->assembly->image));
4215 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssembly *assembly)
4217 MONO_ARCH_SAVE_REGS;
4219 return assembly->assembly->ref_only;
4223 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssembly *assembly)
4225 MonoDomain *domain = mono_object_domain (assembly);
4227 MONO_ARCH_SAVE_REGS;
4229 return mono_string_new (domain, assembly->assembly->image->version);
4232 static MonoReflectionMethod*
4233 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssembly *assembly)
4235 guint32 token = mono_image_get_entry_point (assembly->assembly->image);
4237 MONO_ARCH_SAVE_REGS;
4241 return mono_method_get_object (mono_object_domain (assembly), mono_get_method (assembly->assembly->image, token, NULL), NULL);
4244 static MonoReflectionModule*
4245 ves_icall_System_Reflection_Assembly_GetManifestModuleInternal (MonoReflectionAssembly *assembly)
4247 return mono_module_get_object (mono_object_domain (assembly), assembly->assembly->image);
4251 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssembly *assembly)
4253 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4254 MonoArray *result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, table->rows);
4258 MONO_ARCH_SAVE_REGS;
4260 for (i = 0; i < table->rows; ++i) {
4261 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_MANIFEST_NAME));
4262 mono_array_setref (result, i, mono_string_new (mono_object_domain (assembly), val));
4268 create_version (MonoDomain *domain, guint32 major, guint32 minor, guint32 build, guint32 revision)
4270 static MonoClass *System_Version = NULL;
4271 static MonoMethod *create_version = NULL;
4275 if (!System_Version) {
4276 System_Version = mono_class_from_name (mono_defaults.corlib, "System", "Version");
4277 g_assert (System_Version);
4280 if (!create_version) {
4281 MonoMethodDesc *desc = mono_method_desc_new (":.ctor(int,int,int,int)", FALSE);
4282 create_version = mono_method_desc_search_in_class (desc, System_Version);
4283 g_assert (create_version);
4284 mono_method_desc_free (desc);
4290 args [3] = &revision;
4291 result = mono_object_new (domain, System_Version);
4292 mono_runtime_invoke (create_version, result, args, NULL);
4298 ves_icall_System_Reflection_Assembly_GetReferencedAssemblies (MonoReflectionAssembly *assembly)
4300 static MonoClass *System_Reflection_AssemblyName;
4302 MonoDomain *domain = mono_object_domain (assembly);
4304 static MonoMethod *create_culture = NULL;
4305 MonoImage *image = assembly->assembly->image;
4308 MONO_ARCH_SAVE_REGS;
4310 if (!System_Reflection_AssemblyName)
4311 System_Reflection_AssemblyName = mono_class_from_name (
4312 mono_defaults.corlib, "System.Reflection", "AssemblyName");
4314 t = &assembly->assembly->image->tables [MONO_TABLE_ASSEMBLYREF];
4317 result = mono_array_new (domain, System_Reflection_AssemblyName, count);
4320 MonoMethodDesc *desc = mono_method_desc_new (
4321 "System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE);
4322 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4323 g_assert (create_culture);
4324 mono_method_desc_free (desc);
4327 for (i = 0; i < count; i++) {
4328 MonoReflectionAssemblyName *aname;
4329 guint32 cols [MONO_ASSEMBLYREF_SIZE];
4331 mono_metadata_decode_row (t, i, cols, MONO_ASSEMBLYREF_SIZE);
4333 aname = (MonoReflectionAssemblyName *) mono_object_new (
4334 domain, System_Reflection_AssemblyName);
4336 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_NAME])));
4338 aname->major = cols [MONO_ASSEMBLYREF_MAJOR_VERSION];
4339 aname->minor = cols [MONO_ASSEMBLYREF_MINOR_VERSION];
4340 aname->build = cols [MONO_ASSEMBLYREF_BUILD_NUMBER];
4341 aname->revision = cols [MONO_ASSEMBLYREF_REV_NUMBER];
4342 aname->flags = cols [MONO_ASSEMBLYREF_FLAGS];
4343 aname->versioncompat = 1; /* SameMachine (default) */
4344 aname->hashalg = ASSEMBLY_HASH_SHA1; /* SHA1 (default) */
4345 MONO_OBJECT_SETREF (aname, version, create_version (domain, aname->major, aname->minor, aname->build, aname->revision));
4347 if (create_culture) {
4349 gboolean assembly_ref = TRUE;
4350 args [0] = mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_CULTURE]));
4351 args [1] = &assembly_ref;
4352 MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
4355 if (cols [MONO_ASSEMBLYREF_PUBLIC_KEY]) {
4356 const gchar *pkey_ptr = mono_metadata_blob_heap (image, cols [MONO_ASSEMBLYREF_PUBLIC_KEY]);
4357 guint32 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
4359 if ((cols [MONO_ASSEMBLYREF_FLAGS] & ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG)) {
4360 /* public key token isn't copied - the class library will
4361 automatically generate it from the public key if required */
4362 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4363 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
4365 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4366 memcpy (mono_array_addr (aname->keyToken, guint8, 0), pkey_ptr, pkey_len);
4369 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, 0));
4372 /* note: this function doesn't return the codebase on purpose (i.e. it can
4373 be used under partial trust as path information isn't present). */
4375 mono_array_setref (result, i, aname);
4386 foreach_namespace (const char* key, gconstpointer val, NameSpaceInfo *info)
4388 MonoString *name = mono_string_new (mono_object_domain (info->res), key);
4390 mono_array_setref (info->res, info->idx, name);
4395 ves_icall_System_Reflection_Assembly_GetNamespaces (MonoReflectionAssembly *assembly)
4397 MonoImage *img = assembly->assembly->image;
4401 MONO_ARCH_SAVE_REGS;
4403 if (!img->name_cache)
4404 mono_image_init_name_cache (img);
4406 res = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, g_hash_table_size (img->name_cache));
4409 g_hash_table_foreach (img->name_cache, (GHFunc)foreach_namespace, &info);
4414 /* move this in some file in mono/util/ */
4416 g_concat_dir_and_file (const char *dir, const char *file)
4418 g_return_val_if_fail (dir != NULL, NULL);
4419 g_return_val_if_fail (file != NULL, NULL);
4422 * If the directory name doesn't have a / on the end, we need
4423 * to add one so we get a proper path to the file
4425 if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
4426 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
4428 return g_strconcat (dir, file, NULL);
4432 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssembly *assembly, MonoString *name, gint32 *size, MonoReflectionModule **ref_module)
4434 char *n = mono_string_to_utf8 (name);
4435 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4437 guint32 cols [MONO_MANIFEST_SIZE];
4438 guint32 impl, file_idx;
4442 MONO_ARCH_SAVE_REGS;
4444 for (i = 0; i < table->rows; ++i) {
4445 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4446 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4447 if (strcmp (val, n) == 0)
4451 if (i == table->rows)
4454 impl = cols [MONO_MANIFEST_IMPLEMENTATION];
4457 * this code should only be called after obtaining the
4458 * ResourceInfo and handling the other cases.
4460 g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
4461 file_idx = impl >> MONO_IMPLEMENTATION_BITS;
4463 module = mono_image_load_file_for_image (assembly->assembly->image, file_idx);
4468 module = assembly->assembly->image;
4470 *ref_module = mono_module_get_object (mono_domain_get (), module);
4472 return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
4476 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoManifestResourceInfo *info)
4478 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4480 guint32 cols [MONO_MANIFEST_SIZE];
4481 guint32 file_cols [MONO_FILE_SIZE];
4485 MONO_ARCH_SAVE_REGS;
4487 n = mono_string_to_utf8 (name);
4488 for (i = 0; i < table->rows; ++i) {
4489 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4490 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4491 if (strcmp (val, n) == 0)
4495 if (i == table->rows)
4498 if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
4499 info->location = RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST;
4502 switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
4503 case MONO_IMPLEMENTATION_FILE:
4504 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4505 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4506 mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
4507 val = mono_metadata_string_heap (assembly->assembly->image, file_cols [MONO_FILE_NAME]);
4508 MONO_OBJECT_SETREF (info, filename, mono_string_new (mono_object_domain (assembly), val));
4509 if (file_cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA)
4512 info->location = RESOURCE_LOCATION_EMBEDDED;
4515 case MONO_IMPLEMENTATION_ASSEMBLYREF:
4516 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4517 mono_assembly_load_reference (assembly->assembly->image, i - 1);
4518 if (assembly->assembly->image->references [i - 1] == (gpointer)-1) {
4519 char *msg = g_strdup_printf ("Assembly %d referenced from assembly %s not found ", i - 1, assembly->assembly->image->name);
4520 MonoException *ex = mono_get_exception_file_not_found2 (msg, NULL);
4522 mono_raise_exception (ex);
4524 MONO_OBJECT_SETREF (info, assembly, mono_assembly_get_object (mono_domain_get (), assembly->assembly->image->references [i - 1]));
4526 /* Obtain info recursively */
4527 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (info->assembly, name, info);
4528 info->location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
4531 case MONO_IMPLEMENTATION_EXP_TYPE:
4532 g_assert_not_reached ();
4541 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoBoolean resource_modules)
4543 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4544 MonoArray *result = NULL;
4549 MONO_ARCH_SAVE_REGS;
4551 /* check hash if needed */
4553 n = mono_string_to_utf8 (name);
4554 for (i = 0; i < table->rows; ++i) {
4555 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4556 if (strcmp (val, n) == 0) {
4559 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4560 fn = mono_string_new (mono_object_domain (assembly), n);
4562 return (MonoObject*)fn;
4570 for (i = 0; i < table->rows; ++i) {
4571 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA))
4575 result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, count);
4578 for (i = 0; i < table->rows; ++i) {
4579 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4580 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4581 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4582 mono_array_setref (result, count, mono_string_new (mono_object_domain (assembly), n));
4587 return (MonoObject*)result;
4591 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly *assembly)
4593 MonoDomain *domain = mono_domain_get();
4596 int i, j, file_count = 0;
4597 MonoImage **modules;
4598 guint32 module_count, real_module_count;
4599 MonoTableInfo *table;
4600 guint32 cols [MONO_FILE_SIZE];
4601 MonoImage *image = assembly->assembly->image;
4603 g_assert (image != NULL);
4604 g_assert (!assembly->assembly->dynamic);
4606 table = &image->tables [MONO_TABLE_FILE];
4607 file_count = table->rows;
4609 modules = image->modules;
4610 module_count = image->module_count;
4612 real_module_count = 0;
4613 for (i = 0; i < module_count; ++i)
4615 real_module_count ++;
4617 klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "Module");
4618 res = mono_array_new (domain, klass, 1 + real_module_count + file_count);
4620 mono_array_setref (res, 0, mono_module_get_object (domain, image));
4622 for (i = 0; i < module_count; ++i)
4624 mono_array_setref (res, j, mono_module_get_object (domain, modules[i]));
4628 for (i = 0; i < file_count; ++i, ++j) {
4629 mono_metadata_decode_row (table, i, cols, MONO_FILE_SIZE);
4630 if (cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA)
4631 mono_array_setref (res, j, mono_module_file_get_object (domain, image, i));
4633 MonoImage *m = mono_image_load_file_for_image (image, i + 1);
4635 MonoString *fname = mono_string_new (mono_domain_get (), mono_metadata_string_heap (image, cols [MONO_FILE_NAME]));
4636 mono_raise_exception (mono_get_exception_file_not_found2 (NULL, fname));
4638 mono_array_setref (res, j, mono_module_get_object (domain, m));
4645 static MonoReflectionMethod*
4646 ves_icall_GetCurrentMethod (void)
4648 MonoMethod *m = mono_method_get_last_managed ();
4650 MONO_ARCH_SAVE_REGS;
4652 return mono_method_get_object (mono_domain_get (), m, NULL);
4655 static MonoReflectionMethod*
4656 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType (MonoMethod *method, MonoType *type)
4658 /* FIXME check that method belongs to klass or a parent */
4661 klass = mono_class_from_mono_type (type);
4663 klass = method->klass;
4664 return mono_method_get_object (mono_domain_get (), method, klass);
4667 static MonoReflectionMethod*
4668 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternal (MonoMethod *method)
4670 return mono_method_get_object (mono_domain_get (), method, NULL);
4673 static MonoReflectionMethodBody*
4674 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod *method)
4676 return mono_method_body_get_object (mono_domain_get (), method);
4679 static MonoReflectionAssembly*
4680 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (void)
4682 MonoMethod *m = mono_method_get_last_managed ();
4684 MONO_ARCH_SAVE_REGS;
4686 return mono_assembly_get_object (mono_domain_get (), m->klass->image->assembly);
4690 static MonoReflectionAssembly*
4691 ves_icall_System_Reflection_Assembly_GetEntryAssembly (void)
4693 MonoDomain* domain = mono_domain_get ();
4695 MONO_ARCH_SAVE_REGS;
4697 if (!domain->entry_assembly)
4700 return mono_assembly_get_object (domain, domain->entry_assembly);
4703 static MonoReflectionAssembly*
4704 ves_icall_System_Reflection_Assembly_GetCallingAssembly (void)
4706 MonoMethod *m = mono_method_get_last_managed ();
4707 MonoMethod *dest = m;
4709 MONO_ARCH_SAVE_REGS;
4711 mono_stack_walk_no_il (get_caller, &dest);
4714 return mono_assembly_get_object (mono_domain_get (), dest->klass->image->assembly);
4718 ves_icall_System_MonoType_getFullName (MonoReflectionType *object, gboolean full_name,
4719 gboolean assembly_qualified)
4721 MonoDomain *domain = mono_object_domain (object);
4722 MonoTypeNameFormat format;
4726 MONO_ARCH_SAVE_REGS;
4728 format = assembly_qualified ?
4729 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
4730 MONO_TYPE_NAME_FORMAT_FULL_NAME;
4732 format = MONO_TYPE_NAME_FORMAT_REFLECTION;
4734 name = mono_type_get_name_full (object->type, format);
4738 if (full_name && (object->type->type == MONO_TYPE_VAR || object->type->type == MONO_TYPE_MVAR)) {
4743 res = mono_string_new (domain, name);
4750 fill_reflection_assembly_name (MonoDomain *domain, MonoReflectionAssemblyName *aname, MonoAssemblyName *name, const char *absolute, gboolean by_default_version, gboolean default_publickey, gboolean default_token)
4752 static MonoMethod *create_culture = NULL;
4755 const char *pkey_ptr;
4757 gboolean assembly_ref = FALSE;
4759 MONO_ARCH_SAVE_REGS;
4761 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, name->name));
4762 aname->major = name->major;
4763 aname->minor = name->minor;
4764 aname->build = name->build;
4765 aname->flags = name->flags;
4766 aname->revision = name->revision;
4767 aname->hashalg = name->hash_alg;
4768 aname->versioncompat = 1; /* SameMachine (default) */
4770 if (by_default_version)
4771 MONO_OBJECT_SETREF (aname, version, create_version (domain, name->major, name->minor, name->build, name->revision));
4773 codebase = g_filename_to_uri (absolute, NULL, NULL);
4775 MONO_OBJECT_SETREF (aname, codebase, mono_string_new (domain, codebase));
4779 if (!create_culture) {
4780 MonoMethodDesc *desc = mono_method_desc_new ("System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE);
4781 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4782 g_assert (create_culture);
4783 mono_method_desc_free (desc);
4786 if (name->culture) {
4787 args [0] = mono_string_new (domain, name->culture);
4788 args [1] = &assembly_ref;
4789 MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
4792 if (name->public_key) {
4793 pkey_ptr = (char*)name->public_key;
4794 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
4796 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4797 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
4798 aname->flags |= ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG;
4799 } else if (default_publickey) {
4800 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, 0));
4801 aname->flags |= ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG;
4804 /* MonoAssemblyName keeps the public key token as an hexadecimal string */
4805 if (name->public_key_token [0]) {
4809 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, 8));
4810 p = mono_array_addr (aname->keyToken, char, 0);
4812 for (i = 0, j = 0; i < 8; i++) {
4813 *p = g_ascii_xdigit_value (name->public_key_token [j++]) << 4;
4814 *p |= g_ascii_xdigit_value (name->public_key_token [j++]);
4817 } else if (default_token) {
4818 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, 0));
4823 ves_icall_System_Reflection_Assembly_get_fullName (MonoReflectionAssembly *assembly)
4825 MonoDomain *domain = mono_object_domain (assembly);
4826 MonoAssembly *mass = assembly->assembly;
4830 name = g_strdup_printf (
4831 "%s, Version=%d.%d.%d.%d, Culture=%s, PublicKeyToken=%s%s",
4833 mass->aname.major, mass->aname.minor, mass->aname.build, mass->aname.revision,
4834 mass->aname.culture && *mass->aname.culture? mass->aname.culture: "neutral",
4835 mass->aname.public_key_token [0] ? (char *)mass->aname.public_key_token : "null",
4836 (mass->aname.flags & ASSEMBLYREF_RETARGETABLE_FLAG) ? ", Retargetable=Yes" : "");
4838 res = mono_string_new (domain, name);
4845 ves_icall_System_Reflection_Assembly_FillName (MonoReflectionAssembly *assembly, MonoReflectionAssemblyName *aname)
4848 MonoAssembly *mass = assembly->assembly;
4850 MONO_ARCH_SAVE_REGS;
4852 if (g_path_is_absolute (mass->image->name)) {
4853 fill_reflection_assembly_name (mono_object_domain (assembly),
4854 aname, &mass->aname, mass->image->name, TRUE,
4855 TRUE, mono_get_runtime_info ()->framework_version [0] >= '2');
4858 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4860 fill_reflection_assembly_name (mono_object_domain (assembly),
4861 aname, &mass->aname, absolute, TRUE, TRUE,
4862 mono_get_runtime_info ()->framework_version [0] >= '2');
4868 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoString *fname, MonoReflectionAssemblyName *aname)
4871 MonoImageOpenStatus status = MONO_IMAGE_OK;
4874 MonoAssemblyName name;
4876 MONO_ARCH_SAVE_REGS;
4878 filename = mono_string_to_utf8 (fname);
4880 image = mono_image_open (filename, &status);
4886 if (status == MONO_IMAGE_IMAGE_INVALID)
4887 exc = mono_get_exception_bad_image_format2 (NULL, fname);
4889 exc = mono_get_exception_file_not_found2 (NULL, fname);
4890 mono_raise_exception (exc);
4893 res = mono_assembly_fill_assembly_name (image, &name);
4895 mono_image_close (image);
4897 mono_raise_exception (mono_get_exception_argument ("assemblyFile", "The file does not contain a manifest"));
4900 fill_reflection_assembly_name (mono_domain_get (), aname, &name, filename,
4901 TRUE, mono_get_runtime_info ()->framework_version [0] == '1',
4902 mono_get_runtime_info ()->framework_version [0] >= '2');
4905 mono_image_close (image);
4909 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssembly *assembly,
4910 char **minimum, guint32 *minLength, char **optional, guint32 *optLength, char **refused, guint32 *refLength)
4912 MonoBoolean result = FALSE;
4913 MonoDeclSecurityEntry entry;
4915 /* SecurityAction.RequestMinimum */
4916 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQMIN, &entry)) {
4917 *minimum = entry.blob;
4918 *minLength = entry.size;
4921 /* SecurityAction.RequestOptional */
4922 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQOPT, &entry)) {
4923 *optional = entry.blob;
4924 *optLength = entry.size;
4927 /* SecurityAction.RequestRefuse */
4928 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQREFUSE, &entry)) {
4929 *refused = entry.blob;
4930 *refLength = entry.size;
4938 mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoBoolean exportedOnly)
4942 MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
4944 guint32 attrs, visibility;
4946 /* we start the count from 1 because we skip the special type <Module> */
4949 for (i = 1; i < tdef->rows; ++i) {
4950 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
4951 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
4952 if (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)
4956 count = tdef->rows - 1;
4958 res = mono_array_new (domain, mono_defaults.monotype_class, count);
4960 for (i = 1; i < tdef->rows; ++i) {
4961 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
4962 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
4963 if (!exportedOnly || (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)) {
4964 klass = mono_class_get_throw (image, (i + 1) | MONO_TOKEN_TYPE_DEF);
4965 if (mono_loader_get_last_error ())
4966 mono_loader_clear_error ();
4967 mono_array_setref (res, count, mono_type_get_object (domain, &klass->byval_arg));
4976 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly, MonoBoolean exportedOnly)
4978 MonoArray *res = NULL;
4979 MonoImage *image = NULL;
4980 MonoTableInfo *table = NULL;
4985 MONO_ARCH_SAVE_REGS;
4987 domain = mono_object_domain (assembly);
4989 g_assert (!assembly->assembly->dynamic);
4990 image = assembly->assembly->image;
4991 table = &image->tables [MONO_TABLE_FILE];
4992 res = mono_module_get_types (domain, image, exportedOnly);
4994 /* Append data from all modules in the assembly */
4995 for (i = 0; i < table->rows; ++i) {
4996 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4997 MonoImage *loaded_image = mono_assembly_load_module (image->assembly, i + 1);
4999 MonoArray *res2 = mono_module_get_types (domain, loaded_image, exportedOnly);
5000 /* Append the new types to the end of the array */
5001 if (mono_array_length (res2) > 0) {
5005 len1 = mono_array_length (res);
5006 len2 = mono_array_length (res2);
5007 res3 = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
5008 mono_array_memcpy_refs (res3, 0, res, 0, len1);
5009 mono_array_memcpy_refs (res3, len1, res2, 0, len2);
5016 /* the ReflectionTypeLoadException must have all the types (Types property),
5017 * NULL replacing types which throws an exception. The LoaderException must
5018 * contain all exceptions for NULL items.
5021 len = mono_array_length (res);
5023 for (i = 0; i < len; i++) {
5024 MonoReflectionType *t = mono_array_get (res, gpointer, i);
5025 MonoClass *klass = mono_type_get_class (t->type);
5026 if ((klass != NULL) && klass->exception_type) {
5027 /* keep the class in the list */
5028 list = g_list_append (list, klass);
5029 /* and replace Type with NULL */
5030 mono_array_setref (res, i, NULL);
5036 MonoException *exc = NULL;
5037 MonoArray *exl = NULL;
5038 int length = g_list_length (list);
5040 mono_loader_clear_error ();
5042 exl = mono_array_new (domain, mono_defaults.exception_class, length);
5043 for (i = 0, tmp = list; i < length; i++, tmp = tmp->next) {
5044 MonoException *exc = mono_class_get_exception_for_failure (tmp->data);
5045 mono_array_setref (exl, i, exc);
5050 exc = mono_get_exception_reflection_type_load (res, exl);
5051 mono_loader_clear_error ();
5052 mono_raise_exception (exc);
5059 ves_icall_System_Reflection_AssemblyName_ParseName (MonoReflectionAssemblyName *name, MonoString *assname)
5061 MonoAssemblyName aname;
5062 MonoDomain *domain = mono_object_domain (name);
5064 gboolean is_version_defined;
5065 gboolean is_token_defined;
5067 val = mono_string_to_utf8 (assname);
5068 if (!mono_assembly_name_parse_full (val, &aname, TRUE, &is_version_defined, &is_token_defined))
5071 fill_reflection_assembly_name (domain, name, &aname, "", is_version_defined,
5072 FALSE, is_token_defined);
5074 mono_assembly_name_free (&aname);
5075 g_free ((guint8*) aname.public_key);
5081 static MonoReflectionType*
5082 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModule *module)
5084 MonoDomain *domain = mono_object_domain (module);
5087 MONO_ARCH_SAVE_REGS;
5089 g_assert (module->image);
5091 if (module->image->dynamic && ((MonoDynamicImage*)(module->image))->initial_image)
5092 /* These images do not have a global type */
5095 klass = mono_class_get (module->image, 1 | MONO_TOKEN_TYPE_DEF);
5096 return mono_type_get_object (domain, &klass->byval_arg);
5100 ves_icall_System_Reflection_Module_Close (MonoReflectionModule *module)
5102 /*if (module->image)
5103 mono_image_close (module->image);*/
5107 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModule *module)
5109 MonoDomain *domain = mono_object_domain (module);
5111 MONO_ARCH_SAVE_REGS;
5113 g_assert (module->image);
5114 return mono_string_new (domain, module->image->guid);
5118 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine)
5120 if (image->dynamic) {
5121 MonoDynamicImage *dyn = (MonoDynamicImage*)image;
5122 *pe_kind = dyn->pe_kind;
5123 *machine = dyn->machine;
5126 *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
5127 *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
5132 ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage *image)
5134 return (image->md_version_major << 16) | (image->md_version_minor);
5138 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModule *module)
5140 MONO_ARCH_SAVE_REGS;
5143 return mono_array_new (mono_object_domain (module), mono_defaults.monotype_class, 0);
5145 return mono_module_get_types (mono_object_domain (module), module->image, FALSE);
5149 mono_metadata_memberref_is_method (MonoImage *image, guint32 token)
5151 guint32 cols [MONO_MEMBERREF_SIZE];
5153 mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
5154 sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
5155 mono_metadata_decode_blob_size (sig, &sig);
5156 return (*sig != 0x6);
5160 init_generic_context_from_args (MonoGenericContext *context, MonoArray *type_args, MonoArray *method_args)
5163 context->class_inst = mono_metadata_get_generic_inst (mono_array_length (type_args),
5164 mono_array_addr (type_args, MonoType*, 0));
5166 context->class_inst = NULL;
5168 context->method_inst = mono_metadata_get_generic_inst (mono_array_length (method_args),
5169 mono_array_addr (method_args, MonoType*, 0));
5171 context->method_inst = NULL;
5175 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5178 int table = mono_metadata_token_table (token);
5179 int index = mono_metadata_token_index (token);
5180 MonoGenericContext context;
5182 *error = ResolveTokenError_Other;
5184 /* Validate token */
5185 if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) &&
5186 (table != MONO_TABLE_TYPESPEC)) {
5187 *error = ResolveTokenError_BadTable;
5191 if (image->dynamic) {
5192 if (type_args || method_args)
5193 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5194 return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5197 if ((index <= 0) || (index > image->tables [table].rows)) {
5198 *error = ResolveTokenError_OutOfRange;
5202 init_generic_context_from_args (&context, type_args, method_args);
5203 klass = mono_class_get_full (image, token, &context);
5205 if (mono_loader_get_last_error ())
5206 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
5209 return &klass->byval_arg;
5215 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5217 int table = mono_metadata_token_table (token);
5218 int index = mono_metadata_token_index (token);
5219 MonoGenericContext context;
5222 *error = ResolveTokenError_Other;
5224 /* Validate token */
5225 if ((table != MONO_TABLE_METHOD) && (table != MONO_TABLE_METHODSPEC) &&
5226 (table != MONO_TABLE_MEMBERREF)) {
5227 *error = ResolveTokenError_BadTable;
5231 if (image->dynamic) {
5232 if (type_args || method_args)
5233 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5234 /* FIXME: validate memberref token type */
5235 return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5238 if ((index <= 0) || (index > image->tables [table].rows)) {
5239 *error = ResolveTokenError_OutOfRange;
5242 if ((table == MONO_TABLE_MEMBERREF) && (!mono_metadata_memberref_is_method (image, token))) {
5243 *error = ResolveTokenError_BadTable;
5247 init_generic_context_from_args (&context, type_args, method_args);
5248 method = mono_get_method_full (image, token, NULL, &context);
5250 if (mono_loader_get_last_error ())
5251 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
5257 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
5259 int index = mono_metadata_token_index (token);
5261 *error = ResolveTokenError_Other;
5263 /* Validate token */
5264 if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
5265 *error = ResolveTokenError_BadTable;
5270 return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5272 if ((index <= 0) || (index >= image->heap_us.size)) {
5273 *error = ResolveTokenError_OutOfRange;
5277 /* FIXME: What to do if the index points into the middle of a string ? */
5279 return mono_ldstr (mono_domain_get (), image, index);
5282 static MonoClassField*
5283 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5286 int table = mono_metadata_token_table (token);
5287 int index = mono_metadata_token_index (token);
5288 MonoGenericContext context;
5289 MonoClassField *field;
5291 *error = ResolveTokenError_Other;
5293 /* Validate token */
5294 if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
5295 *error = ResolveTokenError_BadTable;
5299 if (image->dynamic) {
5300 if (type_args || method_args)
5301 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5302 /* FIXME: validate memberref token type */
5303 return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5306 if ((index <= 0) || (index > image->tables [table].rows)) {
5307 *error = ResolveTokenError_OutOfRange;
5310 if ((table == MONO_TABLE_MEMBERREF) && (mono_metadata_memberref_is_method (image, token))) {
5311 *error = ResolveTokenError_BadTable;
5315 init_generic_context_from_args (&context, type_args, method_args);
5316 field = mono_field_from_token (image, token, &klass, &context);
5318 if (mono_loader_get_last_error ())
5319 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
5326 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5328 int table = mono_metadata_token_table (token);
5330 *error = ResolveTokenError_Other;
5333 case MONO_TABLE_TYPEDEF:
5334 case MONO_TABLE_TYPEREF:
5335 case MONO_TABLE_TYPESPEC: {
5336 MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, type_args, method_args, error);
5338 return (MonoObject*)mono_type_get_object (mono_domain_get (), t);
5342 case MONO_TABLE_METHOD:
5343 case MONO_TABLE_METHODSPEC: {
5344 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5346 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
5350 case MONO_TABLE_FIELD: {
5351 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5353 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
5357 case MONO_TABLE_MEMBERREF:
5358 if (mono_metadata_memberref_is_method (image, token)) {
5359 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5361 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
5366 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5368 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
5375 *error = ResolveTokenError_BadTable;
5382 ves_icall_System_Reflection_Module_ResolveSignature (MonoImage *image, guint32 token, MonoResolveTokenError *error)
5384 int table = mono_metadata_token_table (token);
5385 int idx = mono_metadata_token_index (token);
5386 MonoTableInfo *tables = image->tables;
5391 *error = ResolveTokenError_OutOfRange;
5393 /* FIXME: Support other tables ? */
5394 if (table != MONO_TABLE_STANDALONESIG)
5400 if ((idx == 0) || (idx > tables [MONO_TABLE_STANDALONESIG].rows))
5403 sig = mono_metadata_decode_row_col (&tables [MONO_TABLE_STANDALONESIG], idx - 1, 0);
5405 ptr = mono_metadata_blob_heap (image, sig);
5406 len = mono_metadata_decode_blob_size (ptr, &ptr);
5408 res = mono_array_new (mono_domain_get (), mono_defaults.byte_class, len);
5409 memcpy (mono_array_addr (res, guint8, 0), ptr, len);
5413 static MonoReflectionType*
5414 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
5417 int isbyref = 0, rank;
5418 char *str = mono_string_to_utf8 (smodifiers);
5421 MONO_ARCH_SAVE_REGS;
5423 klass = mono_class_from_mono_type (tb->type.type);
5425 /* logic taken from mono_reflection_parse_type(): keep in sync */
5429 if (isbyref) { /* only one level allowed by the spec */
5436 return mono_type_get_object (mono_object_domain (tb), &klass->this_arg);
5439 klass = mono_ptr_class_get (&klass->byval_arg);
5440 mono_class_init (klass);
5451 else if (*p != '*') { /* '*' means unknown lower bound */
5462 klass = mono_array_class_get (klass, rank);
5463 mono_class_init (klass);
5470 return mono_type_get_object (mono_object_domain (tb), &klass->byval_arg);
5474 ves_icall_Type_IsArrayImpl (MonoReflectionType *t)
5479 MONO_ARCH_SAVE_REGS;
5482 res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
5487 static MonoReflectionType *
5488 ves_icall_Type_make_array_type (MonoReflectionType *type, int rank)
5490 MonoClass *klass, *aklass;
5492 MONO_ARCH_SAVE_REGS;
5494 klass = mono_class_from_mono_type (type->type);
5495 aklass = mono_array_class_get (klass, rank);
5497 return mono_type_get_object (mono_object_domain (type), &aklass->byval_arg);
5500 static MonoReflectionType *
5501 ves_icall_Type_make_byref_type (MonoReflectionType *type)
5505 MONO_ARCH_SAVE_REGS;
5507 klass = mono_class_from_mono_type (type->type);
5509 return mono_type_get_object (mono_object_domain (type), &klass->this_arg);
5512 static MonoReflectionType *
5513 ves_icall_Type_MakePointerType (MonoReflectionType *type)
5517 MONO_ARCH_SAVE_REGS;
5519 pklass = mono_ptr_class_get (type->type);
5521 return mono_type_get_object (mono_object_domain (type), &pklass->byval_arg);
5525 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
5526 MonoReflectionMethod *info)
5528 MonoClass *delegate_class = mono_class_from_mono_type (type->type);
5529 MonoObject *delegate;
5532 MONO_ARCH_SAVE_REGS;
5534 mono_assert (delegate_class->parent == mono_defaults.multicastdelegate_class);
5536 delegate = mono_object_new (mono_object_domain (type), delegate_class);
5538 if (info->method->dynamic)
5539 /* Creating a trampoline would leak memory */
5540 func = mono_compile_method (info->method);
5542 func = mono_create_ftnptr (mono_domain_get (), mono_runtime_create_jump_trampoline (mono_domain_get (), info->method, TRUE));
5544 mono_delegate_ctor (delegate, target, func);
5550 ves_icall_System_Delegate_SetMulticastInvoke (MonoDelegate *this)
5552 /* Reset the invoke impl to the default one */
5553 this->invoke_impl = mono_runtime_create_delegate_trampoline (this->object.vtable->klass);
5557 * Magic number to convert a time which is relative to
5558 * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
5560 #define EPOCH_ADJUST ((guint64)62135596800LL)
5563 * Magic number to convert FILETIME base Jan 1, 1601 to DateTime - base Jan, 1, 0001
5565 #define FILETIME_ADJUST ((guint64)504911232000000000LL)
5567 #ifdef PLATFORM_WIN32
5568 /* convert a SYSTEMTIME which is of the form "last thursday in october" to a real date */
5570 convert_to_absolute_date(SYSTEMTIME *date)
5572 #define IS_LEAP(y) ((y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0))
5573 static int days_in_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5574 static int leap_days_in_month[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5575 /* from the calendar FAQ */
5576 int a = (14 - date->wMonth) / 12;
5577 int y = date->wYear - a;
5578 int m = date->wMonth + 12 * a - 2;
5579 int d = (1 + y + y/4 - y/100 + y/400 + (31*m)/12) % 7;
5581 /* d is now the day of the week for the first of the month (0 == Sunday) */
5583 int day_of_week = date->wDayOfWeek;
5585 /* set day_in_month to the first day in the month which falls on day_of_week */
5586 int day_in_month = 1 + (day_of_week - d);
5587 if (day_in_month <= 0)
5590 /* wDay is 1 for first weekday in month, 2 for 2nd ... 5 means last - so work that out allowing for days in the month */
5591 date->wDay = day_in_month + (date->wDay - 1) * 7;
5592 if (date->wDay > (IS_LEAP(date->wYear) ? leap_days_in_month[date->wMonth - 1] : days_in_month[date->wMonth - 1]))
5597 #ifndef PLATFORM_WIN32
5599 * Return's the offset from GMT of a local time.
5601 * tm is a local time
5602 * t is the same local time as seconds.
5605 gmt_offset(struct tm *tm, time_t t)
5607 #if defined (HAVE_TM_GMTOFF)
5608 return tm->tm_gmtoff;
5613 g.tm_isdst = tm->tm_isdst;
5615 return (int)difftime(t, t2);
5620 * This is heavily based on zdump.c from glibc 2.2.
5622 * * data[0]: start of daylight saving time (in DateTime ticks).
5623 * * data[1]: end of daylight saving time (in DateTime ticks).
5624 * * data[2]: utcoffset (in TimeSpan ticks).
5625 * * data[3]: additional offset when daylight saving (in TimeSpan ticks).
5626 * * name[0]: name of this timezone when not daylight saving.
5627 * * name[1]: name of this timezone when daylight saving.
5629 * FIXME: This only works with "standard" Unix dates (years between 1900 and 2100) while
5630 * the class library allows years between 1 and 9999.
5632 * Returns true on success and zero on failure.
5635 ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year, MonoArray **data, MonoArray **names)
5637 #ifndef PLATFORM_WIN32
5638 MonoDomain *domain = mono_domain_get ();
5639 struct tm start, tt;
5643 int is_daylight = 0, day;
5646 MONO_ARCH_SAVE_REGS;
5648 MONO_CHECK_ARG_NULL (data);
5649 MONO_CHECK_ARG_NULL (names);
5651 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5652 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5655 * no info is better than crashing: we'll need our own tz data
5656 * to make this work properly, anyway. The range is probably
5657 * reduced to 1970 .. 2037 because that is what mktime is
5658 * guaranteed to support (we get into an infinite loop
5662 memset (&start, 0, sizeof (start));
5665 start.tm_year = year-1900;
5667 t = mktime (&start);
5669 if ((year < 1970) || (year > 2037) || (t == -1)) {
5671 tt = *localtime (&t);
5672 strftime (tzone, sizeof (tzone), "%Z", &tt);
5673 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5674 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5678 gmtoff = gmt_offset (&start, t);
5680 /* For each day of the year, calculate the tm_gmtoff. */
5681 for (day = 0; day < 365; day++) {
5684 tt = *localtime (&t);
5686 /* Daylight saving starts or ends here. */
5687 if (gmt_offset (&tt, t) != gmtoff) {
5691 /* Try to find the exact hour when daylight saving starts/ends. */
5695 tt1 = *localtime (&t1);
5696 } while (gmt_offset (&tt1, t1) != gmtoff);
5698 /* Try to find the exact minute when daylight saving starts/ends. */
5701 tt1 = *localtime (&t1);
5702 } while (gmt_offset (&tt1, t1) == gmtoff);
5704 strftime (tzone, sizeof (tzone), "%Z", &tt);
5706 /* Write data, if we're already in daylight saving, we're done. */
5708 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5709 mono_array_set ((*data), gint64, 1, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
5712 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5713 mono_array_set ((*data), gint64, 0, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
5717 /* This is only set once when we enter daylight saving. */
5718 mono_array_set ((*data), gint64, 2, (gint64)gmtoff * 10000000L);
5719 mono_array_set ((*data), gint64, 3, (gint64)(gmt_offset (&tt, t) - gmtoff) * 10000000L);
5721 gmtoff = gmt_offset (&tt, t);
5726 strftime (tzone, sizeof (tzone), "%Z", &tt);
5727 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5728 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5729 mono_array_set ((*data), gint64, 0, 0);
5730 mono_array_set ((*data), gint64, 1, 0);
5731 mono_array_set ((*data), gint64, 2, (gint64) gmtoff * 10000000L);
5732 mono_array_set ((*data), gint64, 3, 0);
5737 MonoDomain *domain = mono_domain_get ();
5738 TIME_ZONE_INFORMATION tz_info;
5743 tz_id = GetTimeZoneInformation (&tz_info);
5744 if (tz_id == TIME_ZONE_ID_INVALID)
5747 MONO_CHECK_ARG_NULL (data);
5748 MONO_CHECK_ARG_NULL (names);
5750 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5751 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5753 for (i = 0; i < 32; ++i)
5754 if (!tz_info.DaylightName [i])
5756 mono_array_setref ((*names), 1, mono_string_new_utf16 (domain, tz_info.DaylightName, i));
5757 for (i = 0; i < 32; ++i)
5758 if (!tz_info.StandardName [i])
5760 mono_array_setref ((*names), 0, mono_string_new_utf16 (domain, tz_info.StandardName, i));
5762 if ((year <= 1601) || (year > 30827)) {
5764 * According to MSDN, the MS time functions can't handle dates outside
5770 /* even if the timezone has no daylight savings it may have Bias (e.g. GMT+13 it seems) */
5771 if (tz_id != TIME_ZONE_ID_UNKNOWN) {
5772 tz_info.StandardDate.wYear = year;
5773 convert_to_absolute_date(&tz_info.StandardDate);
5774 err = SystemTimeToFileTime (&tz_info.StandardDate, &ft);
5779 mono_array_set ((*data), gint64, 1, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
5780 tz_info.DaylightDate.wYear = year;
5781 convert_to_absolute_date(&tz_info.DaylightDate);
5782 err = SystemTimeToFileTime (&tz_info.DaylightDate, &ft);
5787 mono_array_set ((*data), gint64, 0, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
5789 mono_array_set ((*data), gint64, 2, (tz_info.Bias + tz_info.StandardBias) * -600000000LL);
5790 mono_array_set ((*data), gint64, 3, (tz_info.DaylightBias - tz_info.StandardBias) * -600000000LL);
5797 ves_icall_System_Object_obj_address (MonoObject *this)
5799 MONO_ARCH_SAVE_REGS;
5806 static inline gint32
5807 mono_array_get_byte_length (MonoArray *array)
5813 klass = array->obj.vtable->klass;
5815 if (array->bounds == NULL)
5816 length = array->max_length;
5819 for (i = 0; i < klass->rank; ++ i)
5820 length *= array->bounds [i].length;
5823 switch (klass->element_class->byval_arg.type) {
5826 case MONO_TYPE_BOOLEAN:
5830 case MONO_TYPE_CHAR:
5838 return length * sizeof (gpointer);
5849 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array)
5851 MONO_ARCH_SAVE_REGS;
5853 return mono_array_get_byte_length (array);
5857 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx)
5859 MONO_ARCH_SAVE_REGS;
5861 return mono_array_get (array, gint8, idx);
5865 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value)
5867 MONO_ARCH_SAVE_REGS;
5869 mono_array_set (array, gint8, idx, value);
5873 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count)
5875 guint8 *src_buf, *dest_buf;
5877 MONO_ARCH_SAVE_REGS;
5879 /* watch out for integer overflow */
5880 if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count))
5883 src_buf = (guint8 *)src->vector + src_offset;
5884 dest_buf = (guint8 *)dest->vector + dest_offset;
5887 memcpy (dest_buf, src_buf, count);
5889 memmove (dest_buf, src_buf, count); /* Source and dest are the same array */
5895 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this, MonoString *class_name)
5897 MonoDomain *domain = mono_object_domain (this);
5899 MonoRealProxy *rp = ((MonoRealProxy *)this);
5900 MonoTransparentProxy *tp;
5904 MONO_ARCH_SAVE_REGS;
5906 res = mono_object_new (domain, mono_defaults.transparent_proxy_class);
5907 tp = (MonoTransparentProxy*) res;
5909 MONO_OBJECT_SETREF (tp, rp, rp);
5910 type = ((MonoReflectionType *)rp->class_to_proxy)->type;
5911 klass = mono_class_from_mono_type (type);
5913 tp->custom_type_info = (mono_object_isinst (this, mono_defaults.iremotingtypeinfo_class) != NULL);
5914 tp->remote_class = mono_remote_class (domain, class_name, klass);
5916 res->vtable = mono_remote_class_vtable (domain, tp->remote_class, rp);
5920 static MonoReflectionType *
5921 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
5923 return mono_type_get_object (mono_object_domain (tp), &tp->remote_class->proxy_class->byval_arg);
5926 /* System.Environment */
5929 ves_icall_System_Environment_get_MachineName (void)
5931 #if defined (PLATFORM_WIN32)
5936 len = MAX_COMPUTERNAME_LENGTH + 1;
5937 buf = g_new (gunichar2, len);
5940 if (GetComputerName (buf, (PDWORD) &len))
5941 result = mono_string_new_utf16 (mono_domain_get (), buf, len);
5949 if (gethostname (buf, sizeof (buf)) == 0)
5950 result = mono_string_new (mono_domain_get (), buf);
5959 ves_icall_System_Environment_get_Platform (void)
5961 MONO_ARCH_SAVE_REGS;
5963 #if defined (PLATFORM_WIN32)
5973 ves_icall_System_Environment_get_NewLine (void)
5975 MONO_ARCH_SAVE_REGS;
5977 #if defined (PLATFORM_WIN32)
5978 return mono_string_new (mono_domain_get (), "\r\n");
5980 return mono_string_new (mono_domain_get (), "\n");
5985 ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name)
5990 MONO_ARCH_SAVE_REGS;
5995 utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
5996 value = g_getenv (utf8_name);
6003 return mono_string_new (mono_domain_get (), value);
6007 * There is no standard way to get at environ.
6010 #ifndef __MINGW32_VERSION
6017 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
6019 #ifdef PLATFORM_WIN32
6028 env_strings = GetEnvironmentStrings();
6031 env_string = env_strings;
6032 while (*env_string != '\0') {
6033 /* weird case that MS seems to skip */
6034 if (*env_string != '=')
6036 while (*env_string != '\0')
6042 domain = mono_domain_get ();
6043 names = mono_array_new (domain, mono_defaults.string_class, n);
6047 env_string = env_strings;
6048 while (*env_string != '\0') {
6049 /* weird case that MS seems to skip */
6050 if (*env_string != '=') {
6051 equal_str = wcschr(env_string, '=');
6052 g_assert(equal_str);
6053 str = mono_string_new_utf16 (domain, env_string, equal_str-env_string);
6054 mono_array_setref (names, n, str);
6057 while (*env_string != '\0')
6062 FreeEnvironmentStrings (env_strings);
6074 MONO_ARCH_SAVE_REGS;
6077 for (e = environ; *e != 0; ++ e)
6080 domain = mono_domain_get ();
6081 names = mono_array_new (domain, mono_defaults.string_class, n);
6084 for (e = environ; *e != 0; ++ e) {
6085 parts = g_strsplit (*e, "=", 2);
6087 str = mono_string_new (domain, *parts);
6088 mono_array_setref (names, n, str);
6101 * If your platform lacks setenv/unsetenv, you must upgrade your glib.
6103 #if !GLIB_CHECK_VERSION(2,4,0)
6104 #define g_setenv(a,b,c) setenv(a,b,c)
6105 #define g_unsetenv(a) unsetenv(a)
6109 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
6111 #ifdef PLATFORM_WIN32
6112 gunichar2 *utf16_name, *utf16_value;
6114 gchar *utf8_name, *utf8_value;
6117 MONO_ARCH_SAVE_REGS;
6119 #ifdef PLATFORM_WIN32
6120 utf16_name = mono_string_to_utf16 (name);
6121 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
6122 SetEnvironmentVariable (utf16_name, NULL);
6123 g_free (utf16_name);
6127 utf16_value = mono_string_to_utf16 (value);
6129 SetEnvironmentVariable (utf16_name, utf16_value);
6131 g_free (utf16_name);
6132 g_free (utf16_value);
6134 utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
6136 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
6137 g_unsetenv (utf8_name);
6142 utf8_value = mono_string_to_utf8 (value);
6143 g_setenv (utf8_name, utf8_value, TRUE);
6146 g_free (utf8_value);
6151 ves_icall_System_Environment_Exit (int result)
6153 MONO_ARCH_SAVE_REGS;
6155 if (!mono_threads_set_shutting_down ())
6158 mono_runtime_set_shutting_down ();
6160 /* Suspend all managed threads since the runtime is going away */
6161 mono_thread_suspend_all_other_threads ();
6163 mono_runtime_quit ();
6165 /* we may need to do some cleanup here... */
6170 ves_icall_System_Environment_GetGacPath (void)
6172 return mono_string_new (mono_domain_get (), mono_assembly_getrootdir ());
6176 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
6178 #if defined (PLATFORM_WIN32)
6179 #ifndef CSIDL_FLAG_CREATE
6180 #define CSIDL_FLAG_CREATE 0x8000
6183 WCHAR path [MAX_PATH];
6184 /* Create directory if no existing */
6185 if (SUCCEEDED (SHGetFolderPathW (NULL, folder | CSIDL_FLAG_CREATE, NULL, 0, path))) {
6189 return mono_string_new_utf16 (mono_domain_get (), path, len);
6192 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
6194 return mono_string_new (mono_domain_get (), "");
6198 ves_icall_System_Environment_GetLogicalDrives (void)
6200 gunichar2 buf [128], *ptr, *dname;
6202 gint initial_size = 127, size = 128;
6205 MonoString *drivestr;
6206 MonoDomain *domain = mono_domain_get ();
6209 MONO_ARCH_SAVE_REGS;
6214 while (size > initial_size) {
6215 size = GetLogicalDriveStrings (initial_size, ptr);
6216 if (size > initial_size) {
6219 ptr = g_malloc0 ((size + 1) * sizeof (gunichar2));
6220 initial_size = size;
6234 result = mono_array_new (domain, mono_defaults.string_class, ndrives);
6239 while (*u16) { u16++; len ++; }
6240 drivestr = mono_string_new_utf16 (domain, dname, len);
6241 mono_array_setref (result, ndrives++, drivestr);
6252 ves_icall_System_Environment_InternalGetHome (void)
6254 MONO_ARCH_SAVE_REGS;
6256 return mono_string_new (mono_domain_get (), g_get_home_dir ());
6259 static const char *encodings [] = {
6261 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
6262 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
6263 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
6265 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
6266 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
6267 "x_unicode_2_0_utf_7",
6269 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
6270 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
6272 "utf_16", "UTF_16LE", "ucs_2", "unicode",
6275 "unicodefffe", "utf_16be",
6282 * Returns the internal codepage, if the value of "int_code_page" is
6283 * 1 at entry, and we can not compute a suitable code page number,
6284 * returns the code page as a string
6287 ves_icall_System_Text_Encoding_InternalCodePage (gint32 *int_code_page)
6292 char *codepage = NULL;
6294 int want_name = *int_code_page;
6297 *int_code_page = -1;
6298 MONO_ARCH_SAVE_REGS;
6300 g_get_charset (&cset);
6301 c = codepage = strdup (cset);
6302 for (c = codepage; *c; c++){
6303 if (isascii (*c) && isalpha (*c))
6308 /* g_print ("charset: %s\n", cset); */
6310 /* handle some common aliases */
6313 for (i = 0; p != 0; ){
6314 if ((gssize) p < 7){
6316 p = encodings [++i];
6319 if (strcmp (p, codepage) == 0){
6320 *int_code_page = code;
6323 p = encodings [++i];
6326 if (strstr (codepage, "utf_8") != NULL)
6327 *int_code_page |= 0x10000000;
6330 if (want_name && *int_code_page == -1)
6331 return mono_string_new (mono_domain_get (), cset);
6337 ves_icall_System_Environment_get_HasShutdownStarted (void)
6339 if (mono_runtime_is_shutting_down ())
6342 if (mono_domain_is_unloading (mono_domain_get ()))
6349 ves_icall_MonoMethodMessage_InitMessage (MonoMethodMessage *this,
6350 MonoReflectionMethod *method,
6351 MonoArray *out_args)
6353 MONO_ARCH_SAVE_REGS;
6355 mono_message_init (mono_object_domain (this), this, method, out_args);
6359 ves_icall_IsTransparentProxy (MonoObject *proxy)
6361 MONO_ARCH_SAVE_REGS;
6366 if (proxy->vtable->klass == mono_defaults.transparent_proxy_class)
6372 static MonoReflectionMethod *
6373 ves_icall_Remoting_RemotingServices_GetVirtualMethod (
6374 MonoReflectionType *rtype, MonoReflectionMethod *rmethod)
6378 MonoMethod **vtable;
6379 MonoMethod *res = NULL;
6381 MONO_CHECK_ARG_NULL (rtype);
6382 MONO_CHECK_ARG_NULL (rmethod);
6384 method = rmethod->method;
6385 klass = mono_class_from_mono_type (rtype->type);
6387 if (MONO_CLASS_IS_INTERFACE (klass))
6390 if (method->flags & METHOD_ATTRIBUTE_STATIC)
6393 if ((method->flags & METHOD_ATTRIBUTE_FINAL) || !(method->flags & METHOD_ATTRIBUTE_VIRTUAL)) {
6394 if (klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE))
6400 mono_class_setup_vtable (klass);
6401 vtable = klass->vtable;
6403 if (method->klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
6404 int offs = mono_class_interface_offset (klass, method->klass);
6406 res = vtable [offs + method->slot];
6408 if (!(klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE)))
6411 if (method->slot != -1)
6412 res = vtable [method->slot];
6418 return mono_method_get_object (mono_domain_get (), res, NULL);
6422 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6427 MONO_ARCH_SAVE_REGS;
6429 klass = mono_class_from_mono_type (type->type);
6430 vtable = mono_class_vtable (mono_domain_get (), klass);
6432 if (enable) vtable->remote = 1;
6433 else vtable->remote = 0;
6437 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type)
6442 MONO_ARCH_SAVE_REGS;
6444 domain = mono_object_domain (type);
6445 klass = mono_class_from_mono_type (type->type);
6447 if (klass->rank >= 1) {
6448 g_assert (klass->rank == 1);
6449 return (MonoObject *) mono_array_new (domain, klass->element_class, 0);
6451 /* Bypass remoting object creation check */
6452 return mono_object_new_alloc_specific (mono_class_vtable (domain, klass));
6457 ves_icall_System_IO_get_temp_path (void)
6459 MONO_ARCH_SAVE_REGS;
6461 return mono_string_new (mono_domain_get (), g_get_tmp_dir ());
6465 ves_icall_RuntimeMethod_GetFunctionPointer (MonoMethod *method)
6467 MONO_ARCH_SAVE_REGS;
6469 return mono_compile_method (method);
6473 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
6478 MONO_ARCH_SAVE_REGS;
6480 path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
6482 #if defined (PLATFORM_WIN32)
6483 /* Avoid mixing '/' and '\\' */
6486 for (i = strlen (path) - 1; i >= 0; i--)
6487 if (path [i] == '/')
6491 mcpath = mono_string_new (mono_domain_get (), path);
6498 get_bundled_machine_config (void)
6500 const gchar *machine_config;
6502 MONO_ARCH_SAVE_REGS;
6504 machine_config = mono_get_machine_config ();
6506 if (!machine_config)
6509 return mono_string_new (mono_domain_get (), machine_config);
6513 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
6518 MONO_ARCH_SAVE_REGS;
6520 path = g_path_get_dirname (mono_get_config_dir ());
6522 #if defined (PLATFORM_WIN32)
6523 /* Avoid mixing '/' and '\\' */
6526 for (i = strlen (path) - 1; i >= 0; i--)
6527 if (path [i] == '/')
6531 ipath = mono_string_new (mono_domain_get (), path);
6538 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
6540 #if defined (PLATFORM_WIN32)
6541 OutputDebugString (mono_string_chars (message));
6543 g_warning ("WriteWindowsDebugString called and PLATFORM_WIN32 not defined!\n");
6547 /* Only used for value types */
6549 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
6554 MONO_ARCH_SAVE_REGS;
6556 domain = mono_object_domain (type);
6557 klass = mono_class_from_mono_type (type->type);
6559 if (mono_class_is_nullable (klass))
6560 /* No arguments -> null */
6563 return mono_object_new (domain, klass);
6566 static MonoReflectionMethod *
6567 ves_icall_MonoMethod_get_base_definition (MonoReflectionMethod *m)
6569 MonoClass *klass, *parent;
6570 MonoMethod *method = m->method;
6571 MonoMethod *result = NULL;
6573 MONO_ARCH_SAVE_REGS;
6575 if (method->klass == NULL)
6578 if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
6579 MONO_CLASS_IS_INTERFACE (method->klass) ||
6580 method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
6583 klass = method->klass;
6584 if (klass->generic_class)
6585 klass = klass->generic_class->container_class;
6587 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
6588 for (parent = klass->parent; parent != NULL; parent = parent->parent) {
6589 mono_class_setup_vtable (parent);
6590 if (parent->vtable_size <= method->slot)
6595 if (klass == method->klass)
6598 result = klass->vtable [method->slot];
6599 if (result == NULL) {
6600 /* It is an abstract method */
6601 gpointer iter = NULL;
6602 while ((result = mono_class_get_methods (klass, &iter)))
6603 if (result->slot == method->slot)
6610 return mono_method_get_object (mono_domain_get (), result, NULL);
6614 ves_icall_MonoMethod_get_name (MonoReflectionMethod *m)
6616 MonoMethod *method = m->method;
6618 MONO_OBJECT_SETREF (m, name, mono_string_new (mono_object_domain (m), method->name));
6623 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
6625 MONO_ARCH_SAVE_REGS;
6627 iter->sig = *(MonoMethodSignature**)argsp;
6629 g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
6630 g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
6633 /* FIXME: it's not documented what start is exactly... */
6637 guint32 i, arg_size;
6639 iter->args = argsp + sizeof (gpointer);
6640 #ifndef MONO_ARCH_REGPARMS
6641 for (i = 0; i < iter->sig->sentinelpos; ++i) {
6642 arg_size = mono_type_stack_size (iter->sig->params [i], &align);
6643 iter->args = (char*)iter->args + arg_size;
6647 iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
6649 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
6653 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
6655 guint32 i, arg_size;
6658 MONO_ARCH_SAVE_REGS;
6660 i = iter->sig->sentinelpos + iter->next_arg;
6662 g_assert (i < iter->sig->param_count);
6664 res.type = iter->sig->params [i];
6665 res.klass = mono_class_from_mono_type (res.type);
6666 /* FIXME: endianess issue... */
6667 res.value = iter->args;
6668 arg_size = mono_type_stack_size (res.type, &align);
6669 iter->args = (char*)iter->args + arg_size;
6672 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6678 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
6680 guint32 i, arg_size;
6683 MONO_ARCH_SAVE_REGS;
6685 i = iter->sig->sentinelpos + iter->next_arg;
6687 g_assert (i < iter->sig->param_count);
6689 while (i < iter->sig->param_count) {
6690 if (!mono_metadata_type_equal (type, iter->sig->params [i]))
6692 res.type = iter->sig->params [i];
6693 res.klass = mono_class_from_mono_type (res.type);
6694 /* FIXME: endianess issue... */
6695 res.value = iter->args;
6696 arg_size = mono_type_stack_size (res.type, &align);
6697 iter->args = (char*)iter->args + arg_size;
6699 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6702 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
6711 mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
6714 MONO_ARCH_SAVE_REGS;
6716 i = iter->sig->sentinelpos + iter->next_arg;
6718 g_assert (i < iter->sig->param_count);
6720 return iter->sig->params [i];
6724 mono_TypedReference_ToObject (MonoTypedRef tref)
6726 MONO_ARCH_SAVE_REGS;
6728 if (MONO_TYPE_IS_REFERENCE (tref.type)) {
6729 MonoObject** objp = tref.value;
6733 return mono_value_box (mono_domain_get (), tref.klass, tref.value);
6737 mono_TypedReference_ToObjectInternal (MonoType *type, gpointer value, MonoClass *klass)
6739 MONO_ARCH_SAVE_REGS;
6741 if (MONO_TYPE_IS_REFERENCE (type)) {
6742 MonoObject** objp = value;
6746 return mono_value_box (mono_domain_get (), klass, value);
6750 prelink_method (MonoMethod *method)
6752 const char *exc_class, *exc_arg;
6753 if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
6755 mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
6757 mono_raise_exception(
6758 mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg ) );
6760 /* create the wrapper, too? */
6764 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
6766 MONO_ARCH_SAVE_REGS;
6767 prelink_method (method->method);
6771 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
6773 MonoClass *klass = mono_class_from_mono_type (type->type);
6775 gpointer iter = NULL;
6776 MONO_ARCH_SAVE_REGS;
6778 while ((m = mono_class_get_methods (klass, &iter)))
6782 /* These parameters are "readonly" in corlib/System/NumberFormatter.cs */
6784 ves_icall_System_NumberFormatter_GetFormatterTables (guint64 const **mantissas,
6785 gint32 const **exponents,
6786 gunichar2 const **digitLowerTable,
6787 gunichar2 const **digitUpperTable,
6788 gint64 const **tenPowersList,
6789 gint32 const **decHexDigits)
6791 *mantissas = Formatter_MantissaBitsTable;
6792 *exponents = Formatter_TensExponentTable;
6793 *digitLowerTable = Formatter_DigitLowerTable;
6794 *digitUpperTable = Formatter_DigitUpperTable;
6795 *tenPowersList = Formatter_TenPowersList;
6796 *decHexDigits = Formatter_DecHexDigits;
6799 /* These parameters are "readonly" in corlib/System/Char.cs */
6801 ves_icall_System_Char_GetDataTablePointers (guint8 const **category_data,
6802 guint8 const **numeric_data,
6803 gdouble const **numeric_data_values,
6804 guint16 const **to_lower_data_low,
6805 guint16 const **to_lower_data_high,
6806 guint16 const **to_upper_data_low,
6807 guint16 const **to_upper_data_high)
6809 *category_data = CategoryData;
6810 *numeric_data = NumericData;
6811 *numeric_data_values = NumericDataValues;
6812 *to_lower_data_low = ToLowerDataLow;
6813 *to_lower_data_high = ToLowerDataHigh;
6814 *to_upper_data_low = ToUpperDataLow;
6815 *to_upper_data_high = ToUpperDataHigh;
6819 ves_icall_MonoDebugger_GetMethodToken (MonoReflectionMethod *method)
6821 return method->method->token;
6825 * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
6826 * and avoid useless allocations.
6829 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional)
6833 for (i = 0; i < type->num_mods; ++i) {
6834 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
6839 res = mono_array_new (mono_domain_get (), mono_defaults.systemtype_class, count);
6841 for (i = 0; i < type->num_mods; ++i) {
6842 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
6843 MonoClass *klass = mono_class_get (image, type->modifiers [i].token);
6844 mono_array_setref (res, count, mono_type_get_object (mono_domain_get (), &klass->byval_arg));
6852 param_info_get_type_modifiers (MonoReflectionParameter *param, MonoBoolean optional)
6854 MonoType *type = param->ClassImpl->type;
6855 MonoReflectionMethod *method = (MonoReflectionMethod*)param->MemberImpl;
6856 MonoImage *image = method->method->klass->image;
6857 int pos = param->PositionImpl;
6858 MonoMethodSignature *sig = mono_method_signature (method->method);
6862 type = sig->params [pos];
6864 return type_array_from_modifiers (image, type, optional);
6868 get_property_type (MonoProperty *prop)
6870 MonoMethodSignature *sig;
6872 sig = mono_method_signature (prop->get);
6874 } else if (prop->set) {
6875 sig = mono_method_signature (prop->set);
6876 return sig->params [sig->param_count - 1];
6882 property_info_get_type_modifiers (MonoReflectionProperty *property, MonoBoolean optional)
6884 MonoType *type = get_property_type (property->property);
6885 MonoImage *image = property->klass->image;
6889 return type_array_from_modifiers (image, type, optional);
6893 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
6895 MonoCustomAttrInfo *cinfo;
6898 cinfo = mono_reflection_get_custom_attrs_info (obj);
6901 found = mono_custom_attrs_has_attr (cinfo, mono_class_from_mono_type (attr_type->type));
6903 mono_custom_attrs_free (cinfo);
6908 custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
6910 MonoArray *res = mono_reflection_get_custom_attrs_by_type (obj, attr_type ? mono_class_from_mono_type (attr_type->type) : NULL);
6912 if (mono_loader_get_last_error ()) {
6913 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
6914 g_assert_not_reached ();
6921 GCHandle_CheckCurrentDomain (guint32 gchandle)
6923 return mono_gchandle_is_in_domain (gchandle, mono_domain_get ());
6927 ves_icall_Mono_Runtime_GetDisplayName (void)
6929 static const char display_name_str [] = "Mono " VERSION;
6930 MonoString *display_name = mono_string_new (mono_domain_get (), display_name_str);
6931 return display_name;
6936 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
6937 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
6938 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 62, 128, 128, 128, 63,
6939 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 0, 128, 128,
6940 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
6941 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 128, 128, 128, 128, 128,
6942 128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
6943 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
6947 base64_to_byte_array (gunichar2 *start, gint ilength, MonoBoolean allowWhitespaceOnly)
6952 gunichar2 last, prev_last;
6960 last = prev_last = 0;
6961 for (i = 0; i < ilength; i++) {
6963 if (c >= sizeof (dbase64)) {
6964 exc = mono_exception_from_name_msg (mono_get_corlib (),
6965 "System", "FormatException",
6966 "Invalid character found.");
6967 mono_raise_exception (exc);
6968 } else if (isspace (c)) {
6976 olength = ilength - ignored;
6978 if (allowWhitespaceOnly && olength == 0) {
6979 return mono_array_new (mono_domain_get (), mono_defaults.byte_class, 0);
6982 if ((olength & 3) != 0 || olength <= 0) {
6983 exc = mono_exception_from_name_msg (mono_get_corlib (), "System",
6984 "FormatException", "Invalid length.");
6985 mono_raise_exception (exc);
6988 olength = (olength * 3) / 4;
6992 if (prev_last == '=')
6995 result = mono_array_new (mono_domain_get (), mono_defaults.byte_class, olength);
6996 res_ptr = mono_array_addr (result, guchar, 0);
6997 for (i = 0; i < ilength; ) {
7000 for (k = 0; k < 4 && i < ilength;) {
7006 if (((b [k] = dbase64 [c]) & 0x80) != 0) {
7007 exc = mono_exception_from_name_msg (mono_get_corlib (),
7008 "System", "FormatException",
7009 "Invalid character found.");
7010 mono_raise_exception (exc);
7015 *res_ptr++ = (b [0] << 2) | (b [1] >> 4);
7017 *res_ptr++ = (b [1] << 4) | (b [2] >> 2);
7019 *res_ptr++ = (b [2] << 6) | b [3];
7021 while (i < ilength && isspace (start [i]))
7029 InternalFromBase64String (MonoString *str, MonoBoolean allowWhitespaceOnly)
7031 MONO_ARCH_SAVE_REGS;
7033 return base64_to_byte_array (mono_string_chars (str),
7034 mono_string_length (str), allowWhitespaceOnly);
7038 InternalFromBase64CharArray (MonoArray *input, gint offset, gint length)
7040 MONO_ARCH_SAVE_REGS;
7042 return base64_to_byte_array (mono_array_addr (input, gunichar2, offset),
7046 #define ICALL_TYPE(id,name,first)
7047 #define ICALL(id,name,func) Icall_ ## id,
7050 #include "metadata/icall-def.h"
7056 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
7057 #define ICALL(id,name,func)
7059 #include "metadata/icall-def.h"
7065 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
7066 #define ICALL(id,name,func)
7068 guint16 first_icall;
7071 static const IcallTypeDesc
7072 icall_type_descs [] = {
7073 #include "metadata/icall-def.h"
7077 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
7080 #define ICALL_TYPE(id,name,first)
7083 #ifdef HAVE_ARRAY_ELEM_INIT
7084 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
7085 #define MSGSTRFIELD1(line) str##line
7087 static const struct msgstrtn_t {
7088 #define ICALL(id,name,func)
7090 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7091 #include "metadata/icall-def.h"
7093 } icall_type_names_str = {
7094 #define ICALL_TYPE(id,name,first) (name),
7095 #include "metadata/icall-def.h"
7098 static const guint16 icall_type_names_idx [] = {
7099 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
7100 #include "metadata/icall-def.h"
7103 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
7105 static const struct msgstr_t {
7107 #define ICALL_TYPE(id,name,first)
7108 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7109 #include "metadata/icall-def.h"
7111 } icall_names_str = {
7112 #define ICALL(id,name,func) (name),
7113 #include "metadata/icall-def.h"
7116 static const guint16 icall_names_idx [] = {
7117 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
7118 #include "metadata/icall-def.h"
7121 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
7127 #define ICALL_TYPE(id,name,first) name,
7128 #define ICALL(id,name,func)
7129 static const char* const
7130 icall_type_names [] = {
7131 #include "metadata/icall-def.h"
7135 #define icall_type_name_get(id) (icall_type_names [(id)])
7139 #define ICALL_TYPE(id,name,first)
7140 #define ICALL(id,name,func) name,
7141 static const char* const
7143 #include "metadata/icall-def.h"
7146 #define icall_name_get(id) icall_names [(id)]
7148 #endif /* !HAVE_ARRAY_ELEM_INIT */
7152 #define ICALL_TYPE(id,name,first)
7153 #define ICALL(id,name,func) func,
7154 static const gconstpointer
7155 icall_functions [] = {
7156 #include "metadata/icall-def.h"
7160 static GHashTable *icall_hash = NULL;
7161 static GHashTable *jit_icall_hash_name = NULL;
7162 static GHashTable *jit_icall_hash_addr = NULL;
7165 mono_icall_init (void)
7169 /* check that tables are sorted: disable in release */
7172 const char *prev_class = NULL;
7173 const char *prev_method;
7175 for (i = 0; i < Icall_type_num; ++i) {
7176 const IcallTypeDesc *desc;
7179 if (prev_class && strcmp (prev_class, icall_type_name_get (i)) >= 0)
7180 g_print ("class %s should come before class %s\n", icall_type_name_get (i), prev_class);
7181 prev_class = icall_type_name_get (i);
7182 desc = &icall_type_descs [i];
7183 num_icalls = icall_desc_num_icalls (desc);
7184 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
7185 for (j = 0; j < num_icalls; ++j) {
7186 const char *methodn = icall_name_get (desc->first_icall + j);
7187 if (prev_method && strcmp (prev_method, methodn) >= 0)
7188 g_print ("method %s should come before method %s\n", methodn, prev_method);
7189 prev_method = methodn;
7194 icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
7198 mono_icall_cleanup (void)
7200 g_hash_table_destroy (icall_hash);
7201 g_hash_table_destroy (jit_icall_hash_name);
7202 g_hash_table_destroy (jit_icall_hash_addr);
7206 mono_add_internal_call (const char *name, gconstpointer method)
7208 mono_loader_lock ();
7210 g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
7212 mono_loader_unlock ();
7215 #ifdef HAVE_ARRAY_ELEM_INIT
7217 compare_method_imap (const void *key, const void *elem)
7219 const char* method_name = (const char*)&icall_names_str + (*(guint16*)elem);
7220 return strcmp (key, method_name);
7224 find_method_icall (const IcallTypeDesc *imap, const char *name)
7226 const guint16 *nameslot = bsearch (name, icall_names_idx + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names_idx [0]), compare_method_imap);
7229 return (gpointer)icall_functions [(nameslot - &icall_names_idx [0])];
7233 compare_class_imap (const void *key, const void *elem)
7235 const char* class_name = (const char*)&icall_type_names_str + (*(guint16*)elem);
7236 return strcmp (key, class_name);
7239 static const IcallTypeDesc*
7240 find_class_icalls (const char *name)
7242 const guint16 *nameslot = bsearch (name, icall_type_names_idx, Icall_type_num, sizeof (icall_type_names_idx [0]), compare_class_imap);
7245 return &icall_type_descs [nameslot - &icall_type_names_idx [0]];
7250 compare_method_imap (const void *key, const void *elem)
7252 const char** method_name = (const char**)elem;
7253 return strcmp (key, *method_name);
7257 find_method_icall (const IcallTypeDesc *imap, const char *name)
7259 const char **nameslot = bsearch (name, icall_names + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names [0]), compare_method_imap);
7262 return (gpointer)icall_functions [(nameslot - icall_names)];
7266 compare_class_imap (const void *key, const void *elem)
7268 const char** class_name = (const char**)elem;
7269 return strcmp (key, *class_name);
7272 static const IcallTypeDesc*
7273 find_class_icalls (const char *name)
7275 const char **nameslot = bsearch (name, icall_type_names, Icall_type_num, sizeof (icall_type_names [0]), compare_class_imap);
7278 return &icall_type_descs [nameslot - icall_type_names];
7284 * we should probably export this as an helper (handle nested types).
7285 * Returns the number of chars written in buf.
7288 concat_class_name (char *buf, int bufsize, MonoClass *klass)
7290 int nspacelen, cnamelen;
7291 nspacelen = strlen (klass->name_space);
7292 cnamelen = strlen (klass->name);
7293 if (nspacelen + cnamelen + 2 > bufsize)
7296 memcpy (buf, klass->name_space, nspacelen);
7297 buf [nspacelen ++] = '.';
7299 memcpy (buf + nspacelen, klass->name, cnamelen);
7300 buf [nspacelen + cnamelen] = 0;
7301 return nspacelen + cnamelen;
7305 mono_lookup_internal_call (MonoMethod *method)
7310 int typelen = 0, mlen, siglen;
7312 const IcallTypeDesc *imap;
7314 g_assert (method != NULL);
7316 if (method->is_inflated)
7317 method = ((MonoMethodInflated *) method)->declaring;
7319 if (method->klass->nested_in) {
7320 int pos = concat_class_name (mname, sizeof (mname)-2, method->klass->nested_in);
7324 mname [pos++] = '/';
7327 typelen = concat_class_name (mname+pos, sizeof (mname)-pos-1, method->klass);
7333 typelen = concat_class_name (mname, sizeof (mname), method->klass);
7338 imap = find_class_icalls (mname);
7340 mname [typelen] = ':';
7341 mname [typelen + 1] = ':';
7343 mlen = strlen (method->name);
7344 memcpy (mname + typelen + 2, method->name, mlen);
7345 sigstart = mname + typelen + 2 + mlen;
7348 tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
7349 siglen = strlen (tmpsig);
7350 if (typelen + mlen + siglen + 6 > sizeof (mname))
7353 memcpy (sigstart + 1, tmpsig, siglen);
7354 sigstart [siglen + 1] = ')';
7355 sigstart [siglen + 2] = 0;
7358 mono_loader_lock ();
7360 res = g_hash_table_lookup (icall_hash, mname);
7362 mono_loader_unlock ();
7365 /* try without signature */
7367 res = g_hash_table_lookup (icall_hash, mname);
7369 mono_loader_unlock ();
7373 /* it wasn't found in the static call tables */
7375 mono_loader_unlock ();
7378 res = find_method_icall (imap, sigstart - mlen);
7380 mono_loader_unlock ();
7383 /* try _with_ signature */
7385 res = find_method_icall (imap, sigstart - mlen);
7387 mono_loader_unlock ();
7391 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname);
7392 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
7393 g_print ("The out of sync library is: %s\n", method->klass->image->name);
7394 g_print ("\nWhen you update one from svn you need to update, compile and install\nthe other too.\n");
7395 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");
7396 g_print ("If you see other errors or faults after this message they are probably related\n");
7397 g_print ("and you need to fix your mono install first.\n");
7399 mono_loader_unlock ();
7405 type_from_typename (char *typename)
7407 MonoClass *klass = NULL; /* assignment to shut GCC warning up */
7409 if (!strcmp (typename, "int"))
7410 klass = mono_defaults.int_class;
7411 else if (!strcmp (typename, "ptr"))
7412 klass = mono_defaults.int_class;
7413 else if (!strcmp (typename, "void"))
7414 klass = mono_defaults.void_class;
7415 else if (!strcmp (typename, "int32"))
7416 klass = mono_defaults.int32_class;
7417 else if (!strcmp (typename, "uint32"))
7418 klass = mono_defaults.uint32_class;
7419 else if (!strcmp (typename, "int8"))
7420 klass = mono_defaults.sbyte_class;
7421 else if (!strcmp (typename, "uint8"))
7422 klass = mono_defaults.byte_class;
7423 else if (!strcmp (typename, "int16"))
7424 klass = mono_defaults.int16_class;
7425 else if (!strcmp (typename, "uint16"))
7426 klass = mono_defaults.uint16_class;
7427 else if (!strcmp (typename, "long"))
7428 klass = mono_defaults.int64_class;
7429 else if (!strcmp (typename, "ulong"))
7430 klass = mono_defaults.uint64_class;
7431 else if (!strcmp (typename, "float"))
7432 klass = mono_defaults.single_class;
7433 else if (!strcmp (typename, "double"))
7434 klass = mono_defaults.double_class;
7435 else if (!strcmp (typename, "object"))
7436 klass = mono_defaults.object_class;
7437 else if (!strcmp (typename, "obj"))
7438 klass = mono_defaults.object_class;
7441 g_assert_not_reached ();
7443 return &klass->byval_arg;
7446 MonoMethodSignature*
7447 mono_create_icall_signature (const char *sigstr)
7452 MonoMethodSignature *res;
7454 mono_loader_lock ();
7455 res = g_hash_table_lookup (mono_defaults.corlib->helper_signatures, sigstr);
7457 mono_loader_unlock ();
7461 parts = g_strsplit (sigstr, " ", 256);
7470 res = mono_metadata_signature_alloc (mono_defaults.corlib, len - 1);
7473 #ifdef PLATFORM_WIN32
7475 * Under windows, the default pinvoke calling convention is STDCALL but
7478 res->call_convention = MONO_CALL_C;
7481 res->ret = type_from_typename (parts [0]);
7482 for (i = 1; i < len; ++i) {
7483 res->params [i - 1] = type_from_typename (parts [i]);
7488 g_hash_table_insert (mono_defaults.corlib->helper_signatures, (gpointer)sigstr, res);
7490 mono_loader_unlock ();
7496 mono_find_jit_icall_by_name (const char *name)
7498 MonoJitICallInfo *info;
7499 g_assert (jit_icall_hash_name);
7501 mono_loader_lock ();
7502 info = g_hash_table_lookup (jit_icall_hash_name, name);
7503 mono_loader_unlock ();
7508 mono_find_jit_icall_by_addr (gconstpointer addr)
7510 MonoJitICallInfo *info;
7511 g_assert (jit_icall_hash_addr);
7513 mono_loader_lock ();
7514 info = g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
7515 mono_loader_unlock ();
7521 mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
7523 mono_loader_lock ();
7524 g_hash_table_insert (jit_icall_hash_addr, (gpointer)wrapper, info);
7525 mono_loader_unlock ();
7529 mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
7531 MonoJitICallInfo *info;
7536 mono_loader_lock ();
7538 if (!jit_icall_hash_name) {
7539 jit_icall_hash_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
7540 jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
7543 if (g_hash_table_lookup (jit_icall_hash_name, name)) {
7544 g_warning ("jit icall already defined \"%s\"\n", name);
7545 g_assert_not_reached ();
7548 info = g_new0 (MonoJitICallInfo, 1);
7555 info->wrapper = func;
7557 info->wrapper = NULL;
7560 g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
7561 g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
7563 mono_loader_unlock ();