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, MonoException **exc)
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;
2868 if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR &&
2869 mono_security_core_clr_method_level (m, TRUE) == MONO_SECURITY_CORE_CLR_CRITICAL)
2870 ensure_reflection_security ();
2872 if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
2874 if (!mono_object_isinst (this, m->klass)) {
2875 *exc = mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException");
2878 m = mono_object_get_virtual_method (this, m);
2879 /* must pass the pointer to the value for valuetype methods */
2880 if (m->klass->valuetype)
2881 obj = mono_object_unbox (this);
2882 } else if (strcmp (m->name, ".ctor") && !m->wrapper_type) {
2883 *exc = mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException");
2888 pcount = params? mono_array_length (params): 0;
2889 if (pcount != mono_method_signature (m)->param_count) {
2890 *exc = mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException");
2894 if ((m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) && !strcmp (m->name, ".ctor") && !this) {
2895 *exc = mono_exception_from_name_msg (mono_defaults.corlib, "System", "MethodAccessException", "Cannot invoke constructor of an abstract class.");
2899 if (m->klass->image->assembly->ref_only) {
2900 *exc = mono_get_exception_invalid_operation ("It is illegal to invoke a method on a type loaded using the ReflectionOnly api.");
2904 if (m->klass->rank && !strcmp (m->name, ".ctor")) {
2907 guint32 *lower_bounds;
2908 pcount = mono_array_length (params);
2909 lengths = alloca (sizeof (guint32) * pcount);
2910 for (i = 0; i < pcount; ++i)
2911 lengths [i] = *(gint32*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
2913 if (m->klass->rank == pcount) {
2914 /* Only lengths provided. */
2915 lower_bounds = NULL;
2917 g_assert (pcount == (m->klass->rank * 2));
2918 /* lower bounds are first. */
2919 lower_bounds = lengths;
2920 lengths += m->klass->rank;
2923 return (MonoObject*)mono_array_new_full (mono_object_domain (params), m->klass, lengths, lower_bounds);
2925 return mono_runtime_invoke_array (m, obj, params, NULL);
2929 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this, MonoArray *params, MonoArray **outArgs)
2931 MonoDomain *domain = mono_object_domain (method);
2932 MonoMethod *m = method->method;
2933 MonoMethodSignature *sig = mono_method_signature (m);
2934 MonoArray *out_args;
2936 int i, j, outarg_count = 0;
2938 MONO_ARCH_SAVE_REGS;
2940 if (m->klass == mono_defaults.object_class) {
2942 if (!strcmp (m->name, "FieldGetter")) {
2943 MonoClass *k = this->vtable->klass;
2947 /* If this is a proxy, then it must be a CBO */
2948 if (k == mono_defaults.transparent_proxy_class) {
2949 MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
2950 this = tp->rp->unwrapped_server;
2952 k = this->vtable->klass;
2955 name = mono_array_get (params, MonoString *, 1);
2956 str = mono_string_to_utf8 (name);
2959 MonoClassField* field = mono_class_get_field_from_name (k, str);
2961 MonoClass *field_klass = mono_class_from_mono_type (field->type);
2962 if (field_klass->valuetype)
2963 result = mono_value_box (domain, field_klass, (char *)this + field->offset);
2965 result = *((gpointer *)((char *)this + field->offset));
2967 out_args = mono_array_new (domain, mono_defaults.object_class, 1);
2968 *outArgs = out_args;
2969 mono_array_setref (out_args, 0, result);
2977 g_assert_not_reached ();
2979 } else if (!strcmp (m->name, "FieldSetter")) {
2980 MonoClass *k = this->vtable->klass;
2986 /* If this is a proxy, then it must be a CBO */
2987 if (k == mono_defaults.transparent_proxy_class) {
2988 MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
2989 this = tp->rp->unwrapped_server;
2991 k = this->vtable->klass;
2994 name = mono_array_get (params, MonoString *, 1);
2995 str = mono_string_to_utf8 (name);
2998 MonoClassField* field = mono_class_get_field_from_name (k, str);
3000 MonoClass *field_klass = mono_class_from_mono_type (field->type);
3001 MonoObject *val = mono_array_get (params, gpointer, 2);
3003 if (field_klass->valuetype) {
3004 size = mono_type_size (field->type, &align);
3005 memcpy ((char *)this + field->offset,
3006 ((char *)val) + sizeof (MonoObject), size);
3008 *(MonoObject**)((char *)this + field->offset) = val;
3010 out_args = mono_array_new (domain, mono_defaults.object_class, 0);
3011 *outArgs = out_args;
3021 g_assert_not_reached ();
3026 for (i = 0; i < mono_array_length (params); i++) {
3027 if (sig->params [i]->byref)
3031 out_args = mono_array_new (domain, mono_defaults.object_class, outarg_count);
3033 /* handle constructors only for objects already allocated */
3034 if (!strcmp (method->method->name, ".ctor"))
3037 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
3038 g_assert (!method->method->klass->valuetype);
3039 result = mono_runtime_invoke_array (method->method, this, params, NULL);
3041 for (i = 0, j = 0; i < mono_array_length (params); i++) {
3042 if (sig->params [i]->byref) {
3044 arg = mono_array_get (params, gpointer, i);
3045 mono_array_setref (out_args, j, arg);
3050 *outArgs = out_args;
3056 read_enum_value (char *mem, int type)
3060 return *(guint8*)mem;
3062 return *(gint8*)mem;
3064 return *(guint16*)mem;
3066 return *(gint16*)mem;
3068 return *(guint32*)mem;
3070 return *(gint32*)mem;
3072 return *(guint64*)mem;
3074 return *(gint64*)mem;
3076 g_assert_not_reached ();
3082 write_enum_value (char *mem, int type, guint64 value)
3086 case MONO_TYPE_I1: {
3087 guint8 *p = (guint8*)mem;
3092 case MONO_TYPE_I2: {
3093 guint16 *p = (void*)mem;
3098 case MONO_TYPE_I4: {
3099 guint32 *p = (void*)mem;
3104 case MONO_TYPE_I8: {
3105 guint64 *p = (void*)mem;
3110 g_assert_not_reached ();
3116 ves_icall_System_Enum_ToObject (MonoReflectionType *enumType, MonoObject *value)
3119 MonoClass *enumc, *objc;
3123 MONO_ARCH_SAVE_REGS;
3125 MONO_CHECK_ARG_NULL (enumType);
3126 MONO_CHECK_ARG_NULL (value);
3128 domain = mono_object_domain (enumType);
3129 enumc = mono_class_from_mono_type (enumType->type);
3130 objc = value->vtable->klass;
3132 if (!enumc->enumtype)
3133 mono_raise_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
3134 if (!((objc->enumtype) || (objc->byval_arg.type >= MONO_TYPE_I1 && objc->byval_arg.type <= MONO_TYPE_U8)))
3135 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."));
3137 res = mono_object_new (domain, enumc);
3138 val = read_enum_value ((char *)value + sizeof (MonoObject), objc->enumtype? objc->enum_basetype->type: objc->byval_arg.type);
3139 write_enum_value ((char *)res + sizeof (MonoObject), enumc->enum_basetype->type, val);
3145 ves_icall_System_Enum_get_value (MonoObject *this)
3153 MONO_ARCH_SAVE_REGS;
3158 g_assert (this->vtable->klass->enumtype);
3160 enumc = mono_class_from_mono_type (this->vtable->klass->enum_basetype);
3161 res = mono_object_new (mono_object_domain (this), enumc);
3162 dst = (char *)res + sizeof (MonoObject);
3163 src = (char *)this + sizeof (MonoObject);
3164 size = mono_class_value_size (enumc, NULL);
3166 memcpy (dst, src, size);
3172 ves_icall_get_enum_info (MonoReflectionType *type, MonoEnumInfo *info)
3174 MonoDomain *domain = mono_object_domain (type);
3175 MonoClass *enumc = mono_class_from_mono_type (type->type);
3176 guint j = 0, nvalues, crow;
3178 MonoClassField *field;
3180 MONO_ARCH_SAVE_REGS;
3182 info->utype = mono_type_get_object (domain, enumc->enum_basetype);
3183 nvalues = mono_class_num_fields (enumc) ? mono_class_num_fields (enumc) - 1 : 0;
3184 info->names = mono_array_new (domain, mono_defaults.string_class, nvalues);
3185 info->values = mono_array_new (domain, enumc, nvalues);
3189 while ((field = mono_class_get_fields (enumc, &iter))) {
3193 if (strcmp ("value__", field->name) == 0)
3195 if (mono_field_is_deleted (field))
3197 mono_array_setref (info->names, j, mono_string_new (domain, field->name));
3200 crow = mono_metadata_get_constant_index (enumc->image, mono_class_get_field_token (field), crow + 1);
3201 field->def_type = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_TYPE);
3202 crow = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_VALUE);
3203 field->data = (gpointer)mono_metadata_blob_heap (enumc->image, crow);
3207 len = mono_metadata_decode_blob_size (p, &p);
3208 switch (enumc->enum_basetype->type) {
3211 mono_array_set (info->values, gchar, j, *p);
3213 case MONO_TYPE_CHAR:
3216 mono_array_set (info->values, gint16, j, read16 (p));
3220 mono_array_set (info->values, gint32, j, read32 (p));
3224 mono_array_set (info->values, gint64, j, read64 (p));
3227 g_error ("Implement type 0x%02x in get_enum_info", enumc->enum_basetype->type);
3234 BFLAGS_IgnoreCase = 1,
3235 BFLAGS_DeclaredOnly = 2,
3236 BFLAGS_Instance = 4,
3238 BFLAGS_Public = 0x10,
3239 BFLAGS_NonPublic = 0x20,
3240 BFLAGS_FlattenHierarchy = 0x40,
3241 BFLAGS_InvokeMethod = 0x100,
3242 BFLAGS_CreateInstance = 0x200,
3243 BFLAGS_GetField = 0x400,
3244 BFLAGS_SetField = 0x800,
3245 BFLAGS_GetProperty = 0x1000,
3246 BFLAGS_SetProperty = 0x2000,
3247 BFLAGS_ExactBinding = 0x10000,
3248 BFLAGS_SuppressChangeType = 0x20000,
3249 BFLAGS_OptionalParamBinding = 0x40000
3252 static MonoReflectionField *
3253 ves_icall_Type_GetField (MonoReflectionType *type, MonoString *name, guint32 bflags)
3256 MonoClass *startklass, *klass;
3258 MonoClassField *field;
3261 int (*compare_func) (const char *s1, const char *s2) = NULL;
3262 domain = ((MonoObject *)type)->vtable->domain;
3263 klass = startklass = mono_class_from_mono_type (type->type);
3265 MONO_ARCH_SAVE_REGS;
3268 mono_raise_exception (mono_get_exception_argument_null ("name"));
3269 if (type->type->byref)
3272 compare_func = (bflags & BFLAGS_IgnoreCase) ? g_strcasecmp : strcmp;
3275 if (klass->exception_type != MONO_EXCEPTION_NONE)
3276 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3279 while ((field = mono_class_get_fields (klass, &iter))) {
3282 if (field->type == NULL)
3284 if (mono_field_is_deleted (field))
3286 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3287 if (bflags & BFLAGS_Public)
3289 } else if ((klass == startklass) || (field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
3290 if (bflags & BFLAGS_NonPublic) {
3297 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
3298 if (bflags & BFLAGS_Static)
3299 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3302 if (bflags & BFLAGS_Instance)
3309 utf8_name = mono_string_to_utf8 (name);
3311 if (compare_func (field->name, utf8_name)) {
3317 return mono_field_get_object (domain, klass, field);
3319 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3326 ves_icall_Type_GetFields_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3329 MonoClass *startklass, *klass, *refklass;
3334 MonoClassField *field;
3336 MONO_ARCH_SAVE_REGS;
3338 domain = ((MonoObject *)type)->vtable->domain;
3339 if (type->type->byref)
3340 return mono_array_new (domain, mono_defaults.field_info_class, 0);
3341 klass = startklass = mono_class_from_mono_type (type->type);
3342 refklass = mono_class_from_mono_type (reftype->type);
3346 res = mono_array_new (domain, mono_defaults.field_info_class, len);
3348 if (klass->exception_type != MONO_EXCEPTION_NONE)
3349 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3352 while ((field = mono_class_get_fields (klass, &iter))) {
3354 if (mono_field_is_deleted (field))
3356 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3357 if (bflags & BFLAGS_Public)
3359 } else if ((klass == startklass) || (field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
3360 if (bflags & BFLAGS_NonPublic) {
3367 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
3368 if (bflags & BFLAGS_Static)
3369 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3372 if (bflags & BFLAGS_Instance)
3378 member = (MonoObject*)mono_field_get_object (domain, refklass, field);
3380 MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, len * 2);
3381 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3385 mono_array_setref (res, i, member);
3388 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3391 MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, i);
3392 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3395 * Better solution for the new GC.
3396 * res->max_length = i;
3403 method_nonpublic (MonoMethod* method, gboolean start_klass)
3405 switch (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) {
3406 case METHOD_ATTRIBUTE_ASSEM:
3407 return (start_klass || mono_defaults.generic_ilist_class);
3408 case METHOD_ATTRIBUTE_PRIVATE:
3410 case METHOD_ATTRIBUTE_PUBLIC:
3418 ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
3421 MonoClass *startklass, *klass, *refklass;
3426 int i, len, match, nslots;
3427 guint32 method_slots_default [8];
3428 guint32 *method_slots;
3429 gchar *mname = NULL;
3430 int (*compare_func) (const char *s1, const char *s2) = NULL;
3432 MONO_ARCH_SAVE_REGS;
3434 domain = ((MonoObject *)type)->vtable->domain;
3435 if (type->type->byref)
3436 return mono_array_new (domain, mono_defaults.method_info_class, 0);
3437 klass = startklass = mono_class_from_mono_type (type->type);
3438 refklass = mono_class_from_mono_type (reftype->type);
3441 mname = mono_string_to_utf8 (name);
3442 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
3445 mono_class_setup_vtable (klass);
3447 if (is_generic_parameter (type->type))
3448 nslots = klass->parent->vtable_size;
3450 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : klass->vtable_size;
3451 if (nslots >= sizeof (method_slots_default) * 8) {
3452 method_slots = g_new0 (guint32, nslots / 32 + 1);
3454 method_slots = method_slots_default;
3455 memset (method_slots, 0, sizeof (method_slots_default));
3459 res = mono_array_new (domain, mono_defaults.method_info_class, len);
3461 mono_class_setup_vtable (klass);
3462 if (klass->exception_type != MONO_EXCEPTION_NONE)
3463 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3466 while ((method = mono_class_get_methods (klass, &iter))) {
3468 if (method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
3470 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3471 if (bflags & BFLAGS_Public)
3473 } else if ((bflags & BFLAGS_NonPublic) && method_nonpublic (method, (klass == startklass))) {
3479 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3480 if (bflags & BFLAGS_Static)
3481 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3484 if (bflags & BFLAGS_Instance)
3492 if (compare_func (mname, method->name))
3497 if (method->slot != -1) {
3498 g_assert (method->slot < nslots);
3499 if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
3501 method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
3504 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
3507 MonoArray *new_res = mono_array_new (domain, mono_defaults.method_info_class, len * 2);
3508 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3512 mono_array_setref (res, i, member);
3515 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3519 if (method_slots != method_slots_default)
3520 g_free (method_slots);
3522 MonoArray *new_res = mono_array_new (domain, mono_defaults.method_info_class, i);
3523 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3526 * Better solution for the new GC.
3527 * res->max_length = i;
3534 ves_icall_Type_GetConstructors_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3537 static MonoClass *System_Reflection_ConstructorInfo;
3538 MonoClass *startklass, *klass, *refklass;
3543 gpointer iter = NULL;
3545 MONO_ARCH_SAVE_REGS;
3547 domain = ((MonoObject *)type)->vtable->domain;
3548 if (type->type->byref)
3549 return mono_array_new (domain, mono_defaults.method_info_class, 0);
3550 klass = startklass = mono_class_from_mono_type (type->type);
3551 refklass = mono_class_from_mono_type (reftype->type);
3553 if (klass->exception_type != MONO_EXCEPTION_NONE)
3554 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3556 if (!System_Reflection_ConstructorInfo)
3557 System_Reflection_ConstructorInfo = mono_class_from_name (
3558 mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
3562 res = mono_array_new (domain, System_Reflection_ConstructorInfo, len);
3564 while ((method = mono_class_get_methods (klass, &iter))) {
3566 if (strcmp (method->name, ".ctor") && strcmp (method->name, ".cctor"))
3568 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3569 if (bflags & BFLAGS_Public)
3572 if (bflags & BFLAGS_NonPublic)
3578 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3579 if (bflags & BFLAGS_Static)
3580 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3583 if (bflags & BFLAGS_Instance)
3589 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
3592 MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, len * 2);
3593 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3597 mono_array_setref (res, i, member);
3601 MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, i);
3602 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3605 * Better solution for the new GC.
3606 * res->max_length = i;
3613 property_hash (gconstpointer data)
3615 MonoProperty *prop = (MonoProperty*)data;
3617 return g_str_hash (prop->name);
3621 property_equal (MonoProperty *prop1, MonoProperty *prop2)
3623 // Properties are hide-by-name-and-signature
3624 if (!g_str_equal (prop1->name, prop2->name))
3627 if (prop1->get && prop2->get && !mono_metadata_signature_equal (mono_method_signature (prop1->get), mono_method_signature (prop2->get)))
3629 if (prop1->set && prop2->set && !mono_metadata_signature_equal (mono_method_signature (prop1->set), mono_method_signature (prop2->set)))
3635 property_accessor_nonpublic (MonoMethod* accessor, gboolean start_klass)
3640 return method_nonpublic (accessor, start_klass);
3644 ves_icall_Type_GetPropertiesByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
3647 static MonoClass *System_Reflection_PropertyInfo;
3648 MonoClass *startklass, *klass;
3655 gchar *propname = NULL;
3656 int (*compare_func) (const char *s1, const char *s2) = NULL;
3658 GHashTable *properties;
3660 MONO_ARCH_SAVE_REGS;
3662 if (!System_Reflection_PropertyInfo)
3663 System_Reflection_PropertyInfo = mono_class_from_name (
3664 mono_defaults.corlib, "System.Reflection", "PropertyInfo");
3666 domain = ((MonoObject *)type)->vtable->domain;
3667 if (type->type->byref)
3668 return mono_array_new (domain, System_Reflection_PropertyInfo, 0);
3669 klass = startklass = mono_class_from_mono_type (type->type);
3671 propname = mono_string_to_utf8 (name);
3672 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
3675 mono_class_setup_vtable (klass);
3677 properties = g_hash_table_new (property_hash, (GEqualFunc)property_equal);
3680 res = mono_array_new (domain, System_Reflection_PropertyInfo, len);
3682 mono_class_setup_vtable (klass);
3683 if (klass->exception_type != MONO_EXCEPTION_NONE) {
3684 g_hash_table_destroy (properties);
3687 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3691 while ((prop = mono_class_get_properties (klass, &iter))) {
3697 flags = method->flags;
3700 if ((prop->get && ((prop->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC)) ||
3701 (prop->set && ((prop->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC))) {
3702 if (bflags & BFLAGS_Public)
3704 } else if (bflags & BFLAGS_NonPublic) {
3705 if (property_accessor_nonpublic(prop->get, startklass == klass) ||
3706 property_accessor_nonpublic(prop->set, startklass == klass)) {
3713 if (flags & METHOD_ATTRIBUTE_STATIC) {
3714 if (bflags & BFLAGS_Static)
3715 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3718 if (bflags & BFLAGS_Instance)
3727 if (compare_func (propname, prop->name))
3731 if (g_hash_table_lookup (properties, prop))
3735 MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, len * 2);
3736 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3740 mono_array_setref (res, i, mono_property_get_object (domain, startklass, prop));
3743 g_hash_table_insert (properties, prop, prop);
3745 if ((!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent)))
3748 g_hash_table_destroy (properties);
3751 MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, i);
3752 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3755 * Better solution for the new GC.
3756 * res->max_length = i;
3762 static MonoReflectionEvent *
3763 ves_icall_MonoType_GetEvent (MonoReflectionType *type, MonoString *name, guint32 bflags)
3766 MonoClass *klass, *startklass;
3772 MONO_ARCH_SAVE_REGS;
3774 event_name = mono_string_to_utf8 (name);
3775 if (type->type->byref)
3777 klass = startklass = mono_class_from_mono_type (type->type);
3778 domain = mono_object_domain (type);
3781 if (klass->exception_type != MONO_EXCEPTION_NONE)
3782 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3785 while ((event = mono_class_get_events (klass, &iter))) {
3786 if (strcmp (event->name, event_name))
3789 method = event->add;
3791 method = event->remove;
3793 method = event->raise;
3795 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3796 if (!(bflags & BFLAGS_Public))
3799 if (!(bflags & BFLAGS_NonPublic))
3801 if ((klass != startklass) && (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PRIVATE)
3806 if (!(bflags & BFLAGS_NonPublic))
3809 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3810 if (!(bflags & BFLAGS_Static))
3812 if (!(bflags & BFLAGS_FlattenHierarchy) && (klass != startklass))
3815 if (!(bflags & BFLAGS_Instance))
3819 g_free (event_name);
3820 return mono_event_get_object (domain, startklass, event);
3823 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3826 g_free (event_name);
3831 ves_icall_Type_GetEvents_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3834 static MonoClass *System_Reflection_EventInfo;
3835 MonoClass *startklass, *klass;
3842 MONO_ARCH_SAVE_REGS;
3844 if (!System_Reflection_EventInfo)
3845 System_Reflection_EventInfo = mono_class_from_name (
3846 mono_defaults.corlib, "System.Reflection", "EventInfo");
3848 domain = mono_object_domain (type);
3849 if (type->type->byref)
3850 return mono_array_new (domain, System_Reflection_EventInfo, 0);
3851 klass = startklass = mono_class_from_mono_type (type->type);
3855 res = mono_array_new (domain, System_Reflection_EventInfo, len);
3857 if (klass->exception_type != MONO_EXCEPTION_NONE)
3858 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3861 while ((event = mono_class_get_events (klass, &iter))) {
3863 method = event->add;
3865 method = event->remove;
3867 method = event->raise;
3869 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3870 if (bflags & BFLAGS_Public)
3872 } else if ((klass == startklass) || (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) {
3873 if (bflags & BFLAGS_NonPublic)
3878 if (bflags & BFLAGS_NonPublic)
3884 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3885 if (bflags & BFLAGS_Static)
3886 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3889 if (bflags & BFLAGS_Instance)
3894 if (bflags & BFLAGS_Instance)
3900 MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, len * 2);
3901 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3905 mono_array_setref (res, i, mono_event_get_object (domain, startklass, event));
3908 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3911 MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, i);
3912 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3915 * Better solution for the new GC.
3916 * res->max_length = i;
3922 static MonoReflectionType *
3923 ves_icall_Type_GetNestedType (MonoReflectionType *type, MonoString *name, guint32 bflags)
3931 MONO_ARCH_SAVE_REGS;
3933 domain = ((MonoObject *)type)->vtable->domain;
3934 if (type->type->byref)
3936 klass = mono_class_from_mono_type (type->type);
3937 str = mono_string_to_utf8 (name);
3940 if (klass->exception_type != MONO_EXCEPTION_NONE)
3941 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3944 * If a nested type is generic, return its generic type definition.
3945 * Note that this means that the return value is essentially a
3946 * nested type of the generic type definition of @klass.
3948 * A note in MSDN claims that a generic type definition can have
3949 * nested types that aren't generic. In any case, the container of that
3950 * nested type would be the generic type definition.
3952 if (klass->generic_class)
3953 klass = klass->generic_class->container_class;
3955 for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
3957 nested = tmpn->data;
3958 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
3959 if (bflags & BFLAGS_Public)
3962 if (bflags & BFLAGS_NonPublic)
3967 if (strcmp (nested->name, str) == 0){
3969 return mono_type_get_object (domain, &nested->byval_arg);
3972 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3979 ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags)
3989 MONO_ARCH_SAVE_REGS;
3991 domain = ((MonoObject *)type)->vtable->domain;
3992 if (type->type->byref)
3993 return mono_array_new (domain, mono_defaults.monotype_class, 0);
3994 klass = mono_class_from_mono_type (type->type);
3995 if (klass->exception_type != MONO_EXCEPTION_NONE)
3996 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3999 * If a nested type is generic, return its generic type definition.
4000 * Note that this means that the return value is essentially the set
4001 * of nested types of the generic type definition of @klass.
4003 * A note in MSDN claims that a generic type definition can have
4004 * nested types that aren't generic. In any case, the container of that
4005 * nested type would be the generic type definition.
4007 if (klass->generic_class)
4008 klass = klass->generic_class->container_class;
4012 res = mono_array_new (domain, mono_defaults.monotype_class, len);
4013 for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
4015 nested = tmpn->data;
4016 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
4017 if (bflags & BFLAGS_Public)
4020 if (bflags & BFLAGS_NonPublic)
4025 member = (MonoObject*)mono_type_get_object (domain, &nested->byval_arg);
4027 MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, len * 2);
4028 mono_array_memcpy_refs (new_res, 0, res, 0, len);
4032 mono_array_setref (res, i, member);
4036 MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, i);
4037 mono_array_memcpy_refs (new_res, 0, res, 0, i);
4040 * Better solution for the new GC.
4041 * res->max_length = i;
4047 static MonoReflectionType*
4048 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *assembly, MonoReflectionModule *module, MonoString *name, MonoBoolean throwOnError, MonoBoolean ignoreCase)
4051 MonoType *type = NULL;
4052 MonoTypeNameParse info;
4053 gboolean type_resolve;
4055 MONO_ARCH_SAVE_REGS;
4057 /* On MS.NET, this does not fire a TypeResolve event */
4058 type_resolve = TRUE;
4059 str = mono_string_to_utf8 (name);
4060 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
4061 if (!mono_reflection_parse_type (str, &info)) {
4063 mono_reflection_free_type_info (&info);
4064 if (throwOnError) /* uhm: this is a parse error, though... */
4065 mono_raise_exception (mono_get_exception_type_load (name, NULL));
4066 /*g_print ("failed parse\n");*/
4070 if (info.assembly.name) {
4072 /* 1.0 and 2.0 throw different exceptions */
4073 if (mono_defaults.generic_ilist_class)
4074 mono_raise_exception (mono_get_exception_argument (NULL, "Type names passed to Assembly.GetType() must not specify an assembly."));
4076 mono_raise_exception (mono_get_exception_type_load (name, NULL));
4081 if (module != NULL) {
4083 type = mono_reflection_get_type (module->image, &info, ignoreCase, &type_resolve);
4088 if (assembly->assembly->dynamic) {
4089 /* Enumerate all modules */
4090 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
4094 if (abuilder->modules) {
4095 for (i = 0; i < mono_array_length (abuilder->modules); ++i) {
4096 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
4097 type = mono_reflection_get_type (&mb->dynamic_image->image, &info, ignoreCase, &type_resolve);
4103 if (!type && abuilder->loaded_modules) {
4104 for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) {
4105 MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
4106 type = mono_reflection_get_type (mod->image, &info, ignoreCase, &type_resolve);
4113 type = mono_reflection_get_type (assembly->assembly->image, &info, ignoreCase, &type_resolve);
4115 mono_reflection_free_type_info (&info);
4117 MonoException *e = NULL;
4120 e = mono_get_exception_type_load (name, NULL);
4122 mono_loader_clear_error ();
4125 mono_raise_exception (e);
4130 if (type->type == MONO_TYPE_CLASS) {
4131 MonoClass *klass = mono_type_get_class (type);
4132 /* need to report exceptions ? */
4133 if (throwOnError && klass->exception_type) {
4134 /* report SecurityException (or others) that occured when loading the assembly */
4135 MonoException *exc = mono_class_get_exception_for_failure (klass);
4136 mono_loader_clear_error ();
4137 mono_raise_exception (exc);
4138 } else if (klass->exception_type == MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND) {
4143 /* g_print ("got it\n"); */
4144 return mono_type_get_object (mono_object_domain (assembly), type);
4148 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *assembly, MonoBoolean escaped)
4150 MonoDomain *domain = mono_object_domain (assembly);
4151 MonoAssembly *mass = assembly->assembly;
4152 MonoString *res = NULL;
4156 MONO_ARCH_SAVE_REGS;
4158 if (g_path_is_absolute (mass->image->name))
4159 absolute = g_strdup (mass->image->name);
4161 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4165 for (i = strlen (absolute) - 1; i >= 0; i--)
4166 if (absolute [i] == '\\')
4171 uri = g_filename_to_uri (absolute, NULL, NULL);
4173 uri = g_strconcat ("file://", absolute, NULL);
4177 res = mono_string_new (domain, uri);
4185 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssembly *assembly)
4187 MonoAssembly *mass = assembly->assembly;
4189 MONO_ARCH_SAVE_REGS;
4191 return mass->in_gac;
4194 static MonoReflectionAssembly*
4195 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoString *mname, MonoObject *evidence)
4199 MonoImageOpenStatus status;
4201 MONO_ARCH_SAVE_REGS;
4203 name = mono_string_to_utf8 (mname);
4204 res = mono_assembly_load_with_partial_name (name, &status);
4210 return mono_assembly_get_object (mono_domain_get (), res);
4214 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssembly *assembly)
4216 MonoDomain *domain = mono_object_domain (assembly);
4219 MONO_ARCH_SAVE_REGS;
4221 res = mono_string_new (domain, mono_image_get_filename (assembly->assembly->image));
4227 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssembly *assembly)
4229 MONO_ARCH_SAVE_REGS;
4231 return assembly->assembly->ref_only;
4235 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssembly *assembly)
4237 MonoDomain *domain = mono_object_domain (assembly);
4239 MONO_ARCH_SAVE_REGS;
4241 return mono_string_new (domain, assembly->assembly->image->version);
4244 static MonoReflectionMethod*
4245 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssembly *assembly)
4247 guint32 token = mono_image_get_entry_point (assembly->assembly->image);
4249 MONO_ARCH_SAVE_REGS;
4253 return mono_method_get_object (mono_object_domain (assembly), mono_get_method (assembly->assembly->image, token, NULL), NULL);
4256 static MonoReflectionModule*
4257 ves_icall_System_Reflection_Assembly_GetManifestModuleInternal (MonoReflectionAssembly *assembly)
4259 return mono_module_get_object (mono_object_domain (assembly), assembly->assembly->image);
4263 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssembly *assembly)
4265 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4266 MonoArray *result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, table->rows);
4270 MONO_ARCH_SAVE_REGS;
4272 for (i = 0; i < table->rows; ++i) {
4273 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_MANIFEST_NAME));
4274 mono_array_setref (result, i, mono_string_new (mono_object_domain (assembly), val));
4280 create_version (MonoDomain *domain, guint32 major, guint32 minor, guint32 build, guint32 revision)
4282 static MonoClass *System_Version = NULL;
4283 static MonoMethod *create_version = NULL;
4287 if (!System_Version) {
4288 System_Version = mono_class_from_name (mono_defaults.corlib, "System", "Version");
4289 g_assert (System_Version);
4292 if (!create_version) {
4293 MonoMethodDesc *desc = mono_method_desc_new (":.ctor(int,int,int,int)", FALSE);
4294 create_version = mono_method_desc_search_in_class (desc, System_Version);
4295 g_assert (create_version);
4296 mono_method_desc_free (desc);
4302 args [3] = &revision;
4303 result = mono_object_new (domain, System_Version);
4304 mono_runtime_invoke (create_version, result, args, NULL);
4310 ves_icall_System_Reflection_Assembly_GetReferencedAssemblies (MonoReflectionAssembly *assembly)
4312 static MonoClass *System_Reflection_AssemblyName;
4314 MonoDomain *domain = mono_object_domain (assembly);
4316 static MonoMethod *create_culture = NULL;
4317 MonoImage *image = assembly->assembly->image;
4320 MONO_ARCH_SAVE_REGS;
4322 if (!System_Reflection_AssemblyName)
4323 System_Reflection_AssemblyName = mono_class_from_name (
4324 mono_defaults.corlib, "System.Reflection", "AssemblyName");
4326 t = &assembly->assembly->image->tables [MONO_TABLE_ASSEMBLYREF];
4329 result = mono_array_new (domain, System_Reflection_AssemblyName, count);
4332 MonoMethodDesc *desc = mono_method_desc_new (
4333 "System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE);
4334 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4335 g_assert (create_culture);
4336 mono_method_desc_free (desc);
4339 for (i = 0; i < count; i++) {
4340 MonoReflectionAssemblyName *aname;
4341 guint32 cols [MONO_ASSEMBLYREF_SIZE];
4343 mono_metadata_decode_row (t, i, cols, MONO_ASSEMBLYREF_SIZE);
4345 aname = (MonoReflectionAssemblyName *) mono_object_new (
4346 domain, System_Reflection_AssemblyName);
4348 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_NAME])));
4350 aname->major = cols [MONO_ASSEMBLYREF_MAJOR_VERSION];
4351 aname->minor = cols [MONO_ASSEMBLYREF_MINOR_VERSION];
4352 aname->build = cols [MONO_ASSEMBLYREF_BUILD_NUMBER];
4353 aname->revision = cols [MONO_ASSEMBLYREF_REV_NUMBER];
4354 aname->flags = cols [MONO_ASSEMBLYREF_FLAGS];
4355 aname->versioncompat = 1; /* SameMachine (default) */
4356 aname->hashalg = ASSEMBLY_HASH_SHA1; /* SHA1 (default) */
4357 MONO_OBJECT_SETREF (aname, version, create_version (domain, aname->major, aname->minor, aname->build, aname->revision));
4359 if (create_culture) {
4361 gboolean assembly_ref = TRUE;
4362 args [0] = mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_CULTURE]));
4363 args [1] = &assembly_ref;
4364 MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
4367 if (cols [MONO_ASSEMBLYREF_PUBLIC_KEY]) {
4368 const gchar *pkey_ptr = mono_metadata_blob_heap (image, cols [MONO_ASSEMBLYREF_PUBLIC_KEY]);
4369 guint32 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
4371 if ((cols [MONO_ASSEMBLYREF_FLAGS] & ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG)) {
4372 /* public key token isn't copied - the class library will
4373 automatically generate it from the public key if required */
4374 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4375 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
4377 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4378 memcpy (mono_array_addr (aname->keyToken, guint8, 0), pkey_ptr, pkey_len);
4381 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, 0));
4384 /* note: this function doesn't return the codebase on purpose (i.e. it can
4385 be used under partial trust as path information isn't present). */
4387 mono_array_setref (result, i, aname);
4398 foreach_namespace (const char* key, gconstpointer val, NameSpaceInfo *info)
4400 MonoString *name = mono_string_new (mono_object_domain (info->res), key);
4402 mono_array_setref (info->res, info->idx, name);
4407 ves_icall_System_Reflection_Assembly_GetNamespaces (MonoReflectionAssembly *assembly)
4409 MonoImage *img = assembly->assembly->image;
4413 MONO_ARCH_SAVE_REGS;
4415 if (!img->name_cache)
4416 mono_image_init_name_cache (img);
4418 res = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, g_hash_table_size (img->name_cache));
4421 g_hash_table_foreach (img->name_cache, (GHFunc)foreach_namespace, &info);
4426 /* move this in some file in mono/util/ */
4428 g_concat_dir_and_file (const char *dir, const char *file)
4430 g_return_val_if_fail (dir != NULL, NULL);
4431 g_return_val_if_fail (file != NULL, NULL);
4434 * If the directory name doesn't have a / on the end, we need
4435 * to add one so we get a proper path to the file
4437 if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
4438 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
4440 return g_strconcat (dir, file, NULL);
4444 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssembly *assembly, MonoString *name, gint32 *size, MonoReflectionModule **ref_module)
4446 char *n = mono_string_to_utf8 (name);
4447 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4449 guint32 cols [MONO_MANIFEST_SIZE];
4450 guint32 impl, file_idx;
4454 MONO_ARCH_SAVE_REGS;
4456 for (i = 0; i < table->rows; ++i) {
4457 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4458 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4459 if (strcmp (val, n) == 0)
4463 if (i == table->rows)
4466 impl = cols [MONO_MANIFEST_IMPLEMENTATION];
4469 * this code should only be called after obtaining the
4470 * ResourceInfo and handling the other cases.
4472 g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
4473 file_idx = impl >> MONO_IMPLEMENTATION_BITS;
4475 module = mono_image_load_file_for_image (assembly->assembly->image, file_idx);
4480 module = assembly->assembly->image;
4482 *ref_module = mono_module_get_object (mono_domain_get (), module);
4484 return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
4488 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoManifestResourceInfo *info)
4490 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4492 guint32 cols [MONO_MANIFEST_SIZE];
4493 guint32 file_cols [MONO_FILE_SIZE];
4497 MONO_ARCH_SAVE_REGS;
4499 n = mono_string_to_utf8 (name);
4500 for (i = 0; i < table->rows; ++i) {
4501 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4502 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4503 if (strcmp (val, n) == 0)
4507 if (i == table->rows)
4510 if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
4511 info->location = RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST;
4514 switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
4515 case MONO_IMPLEMENTATION_FILE:
4516 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4517 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4518 mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
4519 val = mono_metadata_string_heap (assembly->assembly->image, file_cols [MONO_FILE_NAME]);
4520 MONO_OBJECT_SETREF (info, filename, mono_string_new (mono_object_domain (assembly), val));
4521 if (file_cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA)
4524 info->location = RESOURCE_LOCATION_EMBEDDED;
4527 case MONO_IMPLEMENTATION_ASSEMBLYREF:
4528 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4529 mono_assembly_load_reference (assembly->assembly->image, i - 1);
4530 if (assembly->assembly->image->references [i - 1] == (gpointer)-1) {
4531 char *msg = g_strdup_printf ("Assembly %d referenced from assembly %s not found ", i - 1, assembly->assembly->image->name);
4532 MonoException *ex = mono_get_exception_file_not_found2 (msg, NULL);
4534 mono_raise_exception (ex);
4536 MONO_OBJECT_SETREF (info, assembly, mono_assembly_get_object (mono_domain_get (), assembly->assembly->image->references [i - 1]));
4538 /* Obtain info recursively */
4539 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (info->assembly, name, info);
4540 info->location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
4543 case MONO_IMPLEMENTATION_EXP_TYPE:
4544 g_assert_not_reached ();
4553 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoBoolean resource_modules)
4555 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4556 MonoArray *result = NULL;
4561 MONO_ARCH_SAVE_REGS;
4563 /* check hash if needed */
4565 n = mono_string_to_utf8 (name);
4566 for (i = 0; i < table->rows; ++i) {
4567 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4568 if (strcmp (val, n) == 0) {
4571 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4572 fn = mono_string_new (mono_object_domain (assembly), n);
4574 return (MonoObject*)fn;
4582 for (i = 0; i < table->rows; ++i) {
4583 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA))
4587 result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, count);
4590 for (i = 0; i < table->rows; ++i) {
4591 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4592 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4593 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4594 mono_array_setref (result, count, mono_string_new (mono_object_domain (assembly), n));
4599 return (MonoObject*)result;
4603 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly *assembly)
4605 MonoDomain *domain = mono_domain_get();
4608 int i, j, file_count = 0;
4609 MonoImage **modules;
4610 guint32 module_count, real_module_count;
4611 MonoTableInfo *table;
4612 guint32 cols [MONO_FILE_SIZE];
4613 MonoImage *image = assembly->assembly->image;
4615 g_assert (image != NULL);
4616 g_assert (!assembly->assembly->dynamic);
4618 table = &image->tables [MONO_TABLE_FILE];
4619 file_count = table->rows;
4621 modules = image->modules;
4622 module_count = image->module_count;
4624 real_module_count = 0;
4625 for (i = 0; i < module_count; ++i)
4627 real_module_count ++;
4629 klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "Module");
4630 res = mono_array_new (domain, klass, 1 + real_module_count + file_count);
4632 mono_array_setref (res, 0, mono_module_get_object (domain, image));
4634 for (i = 0; i < module_count; ++i)
4636 mono_array_setref (res, j, mono_module_get_object (domain, modules[i]));
4640 for (i = 0; i < file_count; ++i, ++j) {
4641 mono_metadata_decode_row (table, i, cols, MONO_FILE_SIZE);
4642 if (cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA)
4643 mono_array_setref (res, j, mono_module_file_get_object (domain, image, i));
4645 MonoImage *m = mono_image_load_file_for_image (image, i + 1);
4647 MonoString *fname = mono_string_new (mono_domain_get (), mono_metadata_string_heap (image, cols [MONO_FILE_NAME]));
4648 mono_raise_exception (mono_get_exception_file_not_found2 (NULL, fname));
4650 mono_array_setref (res, j, mono_module_get_object (domain, m));
4657 static MonoReflectionMethod*
4658 ves_icall_GetCurrentMethod (void)
4660 MonoMethod *m = mono_method_get_last_managed ();
4662 MONO_ARCH_SAVE_REGS;
4664 return mono_method_get_object (mono_domain_get (), m, NULL);
4667 static MonoReflectionMethod*
4668 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType (MonoMethod *method, MonoType *type)
4670 /* FIXME check that method belongs to klass or a parent */
4673 klass = mono_class_from_mono_type (type);
4675 klass = method->klass;
4676 return mono_method_get_object (mono_domain_get (), method, klass);
4679 static MonoReflectionMethod*
4680 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternal (MonoMethod *method)
4682 return mono_method_get_object (mono_domain_get (), method, NULL);
4685 static MonoReflectionMethodBody*
4686 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod *method)
4688 return mono_method_body_get_object (mono_domain_get (), method);
4691 static MonoReflectionAssembly*
4692 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (void)
4694 MonoMethod *m = mono_method_get_last_managed ();
4696 MONO_ARCH_SAVE_REGS;
4698 return mono_assembly_get_object (mono_domain_get (), m->klass->image->assembly);
4702 static MonoReflectionAssembly*
4703 ves_icall_System_Reflection_Assembly_GetEntryAssembly (void)
4705 MonoDomain* domain = mono_domain_get ();
4707 MONO_ARCH_SAVE_REGS;
4709 if (!domain->entry_assembly)
4712 return mono_assembly_get_object (domain, domain->entry_assembly);
4715 static MonoReflectionAssembly*
4716 ves_icall_System_Reflection_Assembly_GetCallingAssembly (void)
4718 MonoMethod *m = mono_method_get_last_managed ();
4719 MonoMethod *dest = m;
4721 MONO_ARCH_SAVE_REGS;
4723 mono_stack_walk_no_il (get_caller, &dest);
4726 return mono_assembly_get_object (mono_domain_get (), dest->klass->image->assembly);
4730 ves_icall_System_MonoType_getFullName (MonoReflectionType *object, gboolean full_name,
4731 gboolean assembly_qualified)
4733 MonoDomain *domain = mono_object_domain (object);
4734 MonoTypeNameFormat format;
4738 MONO_ARCH_SAVE_REGS;
4740 format = assembly_qualified ?
4741 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
4742 MONO_TYPE_NAME_FORMAT_FULL_NAME;
4744 format = MONO_TYPE_NAME_FORMAT_REFLECTION;
4746 name = mono_type_get_name_full (object->type, format);
4750 if (full_name && (object->type->type == MONO_TYPE_VAR || object->type->type == MONO_TYPE_MVAR)) {
4755 res = mono_string_new (domain, name);
4762 fill_reflection_assembly_name (MonoDomain *domain, MonoReflectionAssemblyName *aname, MonoAssemblyName *name, const char *absolute, gboolean by_default_version, gboolean default_publickey, gboolean default_token)
4764 static MonoMethod *create_culture = NULL;
4767 const char *pkey_ptr;
4769 gboolean assembly_ref = FALSE;
4771 MONO_ARCH_SAVE_REGS;
4773 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, name->name));
4774 aname->major = name->major;
4775 aname->minor = name->minor;
4776 aname->build = name->build;
4777 aname->flags = name->flags;
4778 aname->revision = name->revision;
4779 aname->hashalg = name->hash_alg;
4780 aname->versioncompat = 1; /* SameMachine (default) */
4782 if (by_default_version)
4783 MONO_OBJECT_SETREF (aname, version, create_version (domain, name->major, name->minor, name->build, name->revision));
4785 codebase = g_filename_to_uri (absolute, NULL, NULL);
4787 MONO_OBJECT_SETREF (aname, codebase, mono_string_new (domain, codebase));
4791 if (!create_culture) {
4792 MonoMethodDesc *desc = mono_method_desc_new ("System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE);
4793 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4794 g_assert (create_culture);
4795 mono_method_desc_free (desc);
4798 if (name->culture) {
4799 args [0] = mono_string_new (domain, name->culture);
4800 args [1] = &assembly_ref;
4801 MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
4804 if (name->public_key) {
4805 pkey_ptr = (char*)name->public_key;
4806 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
4808 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4809 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
4810 aname->flags |= ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG;
4811 } else if (default_publickey) {
4812 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, 0));
4813 aname->flags |= ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG;
4816 /* MonoAssemblyName keeps the public key token as an hexadecimal string */
4817 if (name->public_key_token [0]) {
4821 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, 8));
4822 p = mono_array_addr (aname->keyToken, char, 0);
4824 for (i = 0, j = 0; i < 8; i++) {
4825 *p = g_ascii_xdigit_value (name->public_key_token [j++]) << 4;
4826 *p |= g_ascii_xdigit_value (name->public_key_token [j++]);
4829 } else if (default_token) {
4830 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, 0));
4835 ves_icall_System_Reflection_Assembly_get_fullName (MonoReflectionAssembly *assembly)
4837 MonoDomain *domain = mono_object_domain (assembly);
4838 MonoAssembly *mass = assembly->assembly;
4842 name = g_strdup_printf (
4843 "%s, Version=%d.%d.%d.%d, Culture=%s, PublicKeyToken=%s%s",
4845 mass->aname.major, mass->aname.minor, mass->aname.build, mass->aname.revision,
4846 mass->aname.culture && *mass->aname.culture? mass->aname.culture: "neutral",
4847 mass->aname.public_key_token [0] ? (char *)mass->aname.public_key_token : "null",
4848 (mass->aname.flags & ASSEMBLYREF_RETARGETABLE_FLAG) ? ", Retargetable=Yes" : "");
4850 res = mono_string_new (domain, name);
4857 ves_icall_System_Reflection_Assembly_FillName (MonoReflectionAssembly *assembly, MonoReflectionAssemblyName *aname)
4860 MonoAssembly *mass = assembly->assembly;
4862 MONO_ARCH_SAVE_REGS;
4864 if (g_path_is_absolute (mass->image->name)) {
4865 fill_reflection_assembly_name (mono_object_domain (assembly),
4866 aname, &mass->aname, mass->image->name, TRUE,
4867 TRUE, mono_get_runtime_info ()->framework_version [0] >= '2');
4870 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4872 fill_reflection_assembly_name (mono_object_domain (assembly),
4873 aname, &mass->aname, absolute, TRUE, TRUE,
4874 mono_get_runtime_info ()->framework_version [0] >= '2');
4880 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoString *fname, MonoReflectionAssemblyName *aname)
4883 MonoImageOpenStatus status = MONO_IMAGE_OK;
4886 MonoAssemblyName name;
4888 MONO_ARCH_SAVE_REGS;
4890 filename = mono_string_to_utf8 (fname);
4892 image = mono_image_open (filename, &status);
4898 if (status == MONO_IMAGE_IMAGE_INVALID)
4899 exc = mono_get_exception_bad_image_format2 (NULL, fname);
4901 exc = mono_get_exception_file_not_found2 (NULL, fname);
4902 mono_raise_exception (exc);
4905 res = mono_assembly_fill_assembly_name (image, &name);
4907 mono_image_close (image);
4909 mono_raise_exception (mono_get_exception_argument ("assemblyFile", "The file does not contain a manifest"));
4912 fill_reflection_assembly_name (mono_domain_get (), aname, &name, filename,
4913 TRUE, mono_get_runtime_info ()->framework_version [0] == '1',
4914 mono_get_runtime_info ()->framework_version [0] >= '2');
4917 mono_image_close (image);
4921 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssembly *assembly,
4922 char **minimum, guint32 *minLength, char **optional, guint32 *optLength, char **refused, guint32 *refLength)
4924 MonoBoolean result = FALSE;
4925 MonoDeclSecurityEntry entry;
4927 /* SecurityAction.RequestMinimum */
4928 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQMIN, &entry)) {
4929 *minimum = entry.blob;
4930 *minLength = entry.size;
4933 /* SecurityAction.RequestOptional */
4934 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQOPT, &entry)) {
4935 *optional = entry.blob;
4936 *optLength = entry.size;
4939 /* SecurityAction.RequestRefuse */
4940 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQREFUSE, &entry)) {
4941 *refused = entry.blob;
4942 *refLength = entry.size;
4950 mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoBoolean exportedOnly)
4954 MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
4956 guint32 attrs, visibility;
4958 /* we start the count from 1 because we skip the special type <Module> */
4961 for (i = 1; i < tdef->rows; ++i) {
4962 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
4963 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
4964 if (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)
4968 count = tdef->rows - 1;
4970 res = mono_array_new (domain, mono_defaults.monotype_class, count);
4972 for (i = 1; i < tdef->rows; ++i) {
4973 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
4974 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
4975 if (!exportedOnly || (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)) {
4976 klass = mono_class_get_throw (image, (i + 1) | MONO_TOKEN_TYPE_DEF);
4977 if (mono_loader_get_last_error ())
4978 mono_loader_clear_error ();
4979 mono_array_setref (res, count, mono_type_get_object (domain, &klass->byval_arg));
4988 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly, MonoBoolean exportedOnly)
4990 MonoArray *res = NULL;
4991 MonoImage *image = NULL;
4992 MonoTableInfo *table = NULL;
4997 MONO_ARCH_SAVE_REGS;
4999 domain = mono_object_domain (assembly);
5001 g_assert (!assembly->assembly->dynamic);
5002 image = assembly->assembly->image;
5003 table = &image->tables [MONO_TABLE_FILE];
5004 res = mono_module_get_types (domain, image, exportedOnly);
5006 /* Append data from all modules in the assembly */
5007 for (i = 0; i < table->rows; ++i) {
5008 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
5009 MonoImage *loaded_image = mono_assembly_load_module (image->assembly, i + 1);
5011 MonoArray *res2 = mono_module_get_types (domain, loaded_image, exportedOnly);
5012 /* Append the new types to the end of the array */
5013 if (mono_array_length (res2) > 0) {
5017 len1 = mono_array_length (res);
5018 len2 = mono_array_length (res2);
5019 res3 = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
5020 mono_array_memcpy_refs (res3, 0, res, 0, len1);
5021 mono_array_memcpy_refs (res3, len1, res2, 0, len2);
5028 /* the ReflectionTypeLoadException must have all the types (Types property),
5029 * NULL replacing types which throws an exception. The LoaderException must
5030 * contain all exceptions for NULL items.
5033 len = mono_array_length (res);
5035 for (i = 0; i < len; i++) {
5036 MonoReflectionType *t = mono_array_get (res, gpointer, i);
5037 MonoClass *klass = mono_type_get_class (t->type);
5038 if ((klass != NULL) && klass->exception_type) {
5039 /* keep the class in the list */
5040 list = g_list_append (list, klass);
5041 /* and replace Type with NULL */
5042 mono_array_setref (res, i, NULL);
5048 MonoException *exc = NULL;
5049 MonoArray *exl = NULL;
5050 int length = g_list_length (list);
5052 mono_loader_clear_error ();
5054 exl = mono_array_new (domain, mono_defaults.exception_class, length);
5055 for (i = 0, tmp = list; i < length; i++, tmp = tmp->next) {
5056 MonoException *exc = mono_class_get_exception_for_failure (tmp->data);
5057 mono_array_setref (exl, i, exc);
5062 exc = mono_get_exception_reflection_type_load (res, exl);
5063 mono_loader_clear_error ();
5064 mono_raise_exception (exc);
5071 ves_icall_System_Reflection_AssemblyName_ParseName (MonoReflectionAssemblyName *name, MonoString *assname)
5073 MonoAssemblyName aname;
5074 MonoDomain *domain = mono_object_domain (name);
5076 gboolean is_version_defined;
5077 gboolean is_token_defined;
5079 val = mono_string_to_utf8 (assname);
5080 if (!mono_assembly_name_parse_full (val, &aname, TRUE, &is_version_defined, &is_token_defined))
5083 fill_reflection_assembly_name (domain, name, &aname, "", is_version_defined,
5084 FALSE, is_token_defined);
5086 mono_assembly_name_free (&aname);
5087 g_free ((guint8*) aname.public_key);
5093 static MonoReflectionType*
5094 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModule *module)
5096 MonoDomain *domain = mono_object_domain (module);
5099 MONO_ARCH_SAVE_REGS;
5101 g_assert (module->image);
5103 if (module->image->dynamic && ((MonoDynamicImage*)(module->image))->initial_image)
5104 /* These images do not have a global type */
5107 klass = mono_class_get (module->image, 1 | MONO_TOKEN_TYPE_DEF);
5108 return mono_type_get_object (domain, &klass->byval_arg);
5112 ves_icall_System_Reflection_Module_Close (MonoReflectionModule *module)
5114 /*if (module->image)
5115 mono_image_close (module->image);*/
5119 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModule *module)
5121 MonoDomain *domain = mono_object_domain (module);
5123 MONO_ARCH_SAVE_REGS;
5125 g_assert (module->image);
5126 return mono_string_new (domain, module->image->guid);
5130 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine)
5132 if (image->dynamic) {
5133 MonoDynamicImage *dyn = (MonoDynamicImage*)image;
5134 *pe_kind = dyn->pe_kind;
5135 *machine = dyn->machine;
5138 *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
5139 *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
5144 ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage *image)
5146 return (image->md_version_major << 16) | (image->md_version_minor);
5150 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModule *module)
5152 MONO_ARCH_SAVE_REGS;
5155 return mono_array_new (mono_object_domain (module), mono_defaults.monotype_class, 0);
5157 return mono_module_get_types (mono_object_domain (module), module->image, FALSE);
5161 mono_metadata_memberref_is_method (MonoImage *image, guint32 token)
5163 guint32 cols [MONO_MEMBERREF_SIZE];
5165 mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
5166 sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
5167 mono_metadata_decode_blob_size (sig, &sig);
5168 return (*sig != 0x6);
5172 init_generic_context_from_args (MonoGenericContext *context, MonoArray *type_args, MonoArray *method_args)
5175 context->class_inst = mono_metadata_get_generic_inst (mono_array_length (type_args),
5176 mono_array_addr (type_args, MonoType*, 0));
5178 context->class_inst = NULL;
5180 context->method_inst = mono_metadata_get_generic_inst (mono_array_length (method_args),
5181 mono_array_addr (method_args, MonoType*, 0));
5183 context->method_inst = NULL;
5187 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5190 int table = mono_metadata_token_table (token);
5191 int index = mono_metadata_token_index (token);
5192 MonoGenericContext context;
5194 *error = ResolveTokenError_Other;
5196 /* Validate token */
5197 if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) &&
5198 (table != MONO_TABLE_TYPESPEC)) {
5199 *error = ResolveTokenError_BadTable;
5203 if (image->dynamic) {
5204 if (type_args || method_args)
5205 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5206 return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5209 if ((index <= 0) || (index > image->tables [table].rows)) {
5210 *error = ResolveTokenError_OutOfRange;
5214 init_generic_context_from_args (&context, type_args, method_args);
5215 klass = mono_class_get_full (image, token, &context);
5217 if (mono_loader_get_last_error ())
5218 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
5221 return &klass->byval_arg;
5227 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5229 int table = mono_metadata_token_table (token);
5230 int index = mono_metadata_token_index (token);
5231 MonoGenericContext context;
5234 *error = ResolveTokenError_Other;
5236 /* Validate token */
5237 if ((table != MONO_TABLE_METHOD) && (table != MONO_TABLE_METHODSPEC) &&
5238 (table != MONO_TABLE_MEMBERREF)) {
5239 *error = ResolveTokenError_BadTable;
5243 if (image->dynamic) {
5244 if (type_args || method_args)
5245 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5246 /* FIXME: validate memberref token type */
5247 return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5250 if ((index <= 0) || (index > image->tables [table].rows)) {
5251 *error = ResolveTokenError_OutOfRange;
5254 if ((table == MONO_TABLE_MEMBERREF) && (!mono_metadata_memberref_is_method (image, token))) {
5255 *error = ResolveTokenError_BadTable;
5259 init_generic_context_from_args (&context, type_args, method_args);
5260 method = mono_get_method_full (image, token, NULL, &context);
5262 if (mono_loader_get_last_error ())
5263 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
5269 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
5271 int index = mono_metadata_token_index (token);
5273 *error = ResolveTokenError_Other;
5275 /* Validate token */
5276 if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
5277 *error = ResolveTokenError_BadTable;
5282 return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5284 if ((index <= 0) || (index >= image->heap_us.size)) {
5285 *error = ResolveTokenError_OutOfRange;
5289 /* FIXME: What to do if the index points into the middle of a string ? */
5291 return mono_ldstr (mono_domain_get (), image, index);
5294 static MonoClassField*
5295 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5298 int table = mono_metadata_token_table (token);
5299 int index = mono_metadata_token_index (token);
5300 MonoGenericContext context;
5301 MonoClassField *field;
5303 *error = ResolveTokenError_Other;
5305 /* Validate token */
5306 if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
5307 *error = ResolveTokenError_BadTable;
5311 if (image->dynamic) {
5312 if (type_args || method_args)
5313 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5314 /* FIXME: validate memberref token type */
5315 return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5318 if ((index <= 0) || (index > image->tables [table].rows)) {
5319 *error = ResolveTokenError_OutOfRange;
5322 if ((table == MONO_TABLE_MEMBERREF) && (mono_metadata_memberref_is_method (image, token))) {
5323 *error = ResolveTokenError_BadTable;
5327 init_generic_context_from_args (&context, type_args, method_args);
5328 field = mono_field_from_token (image, token, &klass, &context);
5330 if (mono_loader_get_last_error ())
5331 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
5338 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5340 int table = mono_metadata_token_table (token);
5342 *error = ResolveTokenError_Other;
5345 case MONO_TABLE_TYPEDEF:
5346 case MONO_TABLE_TYPEREF:
5347 case MONO_TABLE_TYPESPEC: {
5348 MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, type_args, method_args, error);
5350 return (MonoObject*)mono_type_get_object (mono_domain_get (), t);
5354 case MONO_TABLE_METHOD:
5355 case MONO_TABLE_METHODSPEC: {
5356 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5358 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
5362 case MONO_TABLE_FIELD: {
5363 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5365 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
5369 case MONO_TABLE_MEMBERREF:
5370 if (mono_metadata_memberref_is_method (image, token)) {
5371 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5373 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
5378 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5380 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
5387 *error = ResolveTokenError_BadTable;
5394 ves_icall_System_Reflection_Module_ResolveSignature (MonoImage *image, guint32 token, MonoResolveTokenError *error)
5396 int table = mono_metadata_token_table (token);
5397 int idx = mono_metadata_token_index (token);
5398 MonoTableInfo *tables = image->tables;
5403 *error = ResolveTokenError_OutOfRange;
5405 /* FIXME: Support other tables ? */
5406 if (table != MONO_TABLE_STANDALONESIG)
5412 if ((idx == 0) || (idx > tables [MONO_TABLE_STANDALONESIG].rows))
5415 sig = mono_metadata_decode_row_col (&tables [MONO_TABLE_STANDALONESIG], idx - 1, 0);
5417 ptr = mono_metadata_blob_heap (image, sig);
5418 len = mono_metadata_decode_blob_size (ptr, &ptr);
5420 res = mono_array_new (mono_domain_get (), mono_defaults.byte_class, len);
5421 memcpy (mono_array_addr (res, guint8, 0), ptr, len);
5425 static MonoReflectionType*
5426 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
5429 int isbyref = 0, rank;
5430 char *str = mono_string_to_utf8 (smodifiers);
5433 MONO_ARCH_SAVE_REGS;
5435 klass = mono_class_from_mono_type (tb->type.type);
5437 /* logic taken from mono_reflection_parse_type(): keep in sync */
5441 if (isbyref) { /* only one level allowed by the spec */
5448 return mono_type_get_object (mono_object_domain (tb), &klass->this_arg);
5451 klass = mono_ptr_class_get (&klass->byval_arg);
5452 mono_class_init (klass);
5463 else if (*p != '*') { /* '*' means unknown lower bound */
5474 klass = mono_array_class_get (klass, rank);
5475 mono_class_init (klass);
5482 return mono_type_get_object (mono_object_domain (tb), &klass->byval_arg);
5486 ves_icall_Type_IsArrayImpl (MonoReflectionType *t)
5491 MONO_ARCH_SAVE_REGS;
5494 res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
5499 static MonoReflectionType *
5500 ves_icall_Type_make_array_type (MonoReflectionType *type, int rank)
5502 MonoClass *klass, *aklass;
5504 MONO_ARCH_SAVE_REGS;
5506 klass = mono_class_from_mono_type (type->type);
5507 aklass = mono_array_class_get (klass, rank);
5509 return mono_type_get_object (mono_object_domain (type), &aklass->byval_arg);
5512 static MonoReflectionType *
5513 ves_icall_Type_make_byref_type (MonoReflectionType *type)
5517 MONO_ARCH_SAVE_REGS;
5519 klass = mono_class_from_mono_type (type->type);
5521 return mono_type_get_object (mono_object_domain (type), &klass->this_arg);
5524 static MonoReflectionType *
5525 ves_icall_Type_MakePointerType (MonoReflectionType *type)
5529 MONO_ARCH_SAVE_REGS;
5531 pklass = mono_ptr_class_get (type->type);
5533 return mono_type_get_object (mono_object_domain (type), &pklass->byval_arg);
5537 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
5538 MonoReflectionMethod *info)
5540 MonoClass *delegate_class = mono_class_from_mono_type (type->type);
5541 MonoObject *delegate;
5544 MONO_ARCH_SAVE_REGS;
5546 mono_assert (delegate_class->parent == mono_defaults.multicastdelegate_class);
5548 delegate = mono_object_new (mono_object_domain (type), delegate_class);
5550 if (info->method->dynamic)
5551 /* Creating a trampoline would leak memory */
5552 func = mono_compile_method (info->method);
5554 func = mono_create_ftnptr (mono_domain_get (), mono_runtime_create_jump_trampoline (mono_domain_get (), info->method, TRUE));
5556 mono_delegate_ctor (delegate, target, func);
5562 ves_icall_System_Delegate_SetMulticastInvoke (MonoDelegate *this)
5564 /* Reset the invoke impl to the default one */
5565 this->invoke_impl = mono_runtime_create_delegate_trampoline (this->object.vtable->klass);
5569 * Magic number to convert a time which is relative to
5570 * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
5572 #define EPOCH_ADJUST ((guint64)62135596800LL)
5575 * Magic number to convert FILETIME base Jan 1, 1601 to DateTime - base Jan, 1, 0001
5577 #define FILETIME_ADJUST ((guint64)504911232000000000LL)
5579 #ifdef PLATFORM_WIN32
5580 /* convert a SYSTEMTIME which is of the form "last thursday in october" to a real date */
5582 convert_to_absolute_date(SYSTEMTIME *date)
5584 #define IS_LEAP(y) ((y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0))
5585 static int days_in_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5586 static int leap_days_in_month[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5587 /* from the calendar FAQ */
5588 int a = (14 - date->wMonth) / 12;
5589 int y = date->wYear - a;
5590 int m = date->wMonth + 12 * a - 2;
5591 int d = (1 + y + y/4 - y/100 + y/400 + (31*m)/12) % 7;
5593 /* d is now the day of the week for the first of the month (0 == Sunday) */
5595 int day_of_week = date->wDayOfWeek;
5597 /* set day_in_month to the first day in the month which falls on day_of_week */
5598 int day_in_month = 1 + (day_of_week - d);
5599 if (day_in_month <= 0)
5602 /* wDay is 1 for first weekday in month, 2 for 2nd ... 5 means last - so work that out allowing for days in the month */
5603 date->wDay = day_in_month + (date->wDay - 1) * 7;
5604 if (date->wDay > (IS_LEAP(date->wYear) ? leap_days_in_month[date->wMonth - 1] : days_in_month[date->wMonth - 1]))
5609 #ifndef PLATFORM_WIN32
5611 * Return's the offset from GMT of a local time.
5613 * tm is a local time
5614 * t is the same local time as seconds.
5617 gmt_offset(struct tm *tm, time_t t)
5619 #if defined (HAVE_TM_GMTOFF)
5620 return tm->tm_gmtoff;
5625 g.tm_isdst = tm->tm_isdst;
5627 return (int)difftime(t, t2);
5632 * This is heavily based on zdump.c from glibc 2.2.
5634 * * data[0]: start of daylight saving time (in DateTime ticks).
5635 * * data[1]: end of daylight saving time (in DateTime ticks).
5636 * * data[2]: utcoffset (in TimeSpan ticks).
5637 * * data[3]: additional offset when daylight saving (in TimeSpan ticks).
5638 * * name[0]: name of this timezone when not daylight saving.
5639 * * name[1]: name of this timezone when daylight saving.
5641 * FIXME: This only works with "standard" Unix dates (years between 1900 and 2100) while
5642 * the class library allows years between 1 and 9999.
5644 * Returns true on success and zero on failure.
5647 ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year, MonoArray **data, MonoArray **names)
5649 #ifndef PLATFORM_WIN32
5650 MonoDomain *domain = mono_domain_get ();
5651 struct tm start, tt;
5655 int is_daylight = 0, day;
5658 MONO_ARCH_SAVE_REGS;
5660 MONO_CHECK_ARG_NULL (data);
5661 MONO_CHECK_ARG_NULL (names);
5663 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5664 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5667 * no info is better than crashing: we'll need our own tz data
5668 * to make this work properly, anyway. The range is probably
5669 * reduced to 1970 .. 2037 because that is what mktime is
5670 * guaranteed to support (we get into an infinite loop
5674 memset (&start, 0, sizeof (start));
5677 start.tm_year = year-1900;
5679 t = mktime (&start);
5681 if ((year < 1970) || (year > 2037) || (t == -1)) {
5683 tt = *localtime (&t);
5684 strftime (tzone, sizeof (tzone), "%Z", &tt);
5685 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5686 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5690 gmtoff = gmt_offset (&start, t);
5692 /* For each day of the year, calculate the tm_gmtoff. */
5693 for (day = 0; day < 365; day++) {
5696 tt = *localtime (&t);
5698 /* Daylight saving starts or ends here. */
5699 if (gmt_offset (&tt, t) != gmtoff) {
5703 /* Try to find the exact hour when daylight saving starts/ends. */
5707 tt1 = *localtime (&t1);
5708 } while (gmt_offset (&tt1, t1) != gmtoff);
5710 /* Try to find the exact minute when daylight saving starts/ends. */
5713 tt1 = *localtime (&t1);
5714 } while (gmt_offset (&tt1, t1) == gmtoff);
5716 strftime (tzone, sizeof (tzone), "%Z", &tt);
5718 /* Write data, if we're already in daylight saving, we're done. */
5720 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5721 mono_array_set ((*data), gint64, 1, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
5724 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5725 mono_array_set ((*data), gint64, 0, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
5729 /* This is only set once when we enter daylight saving. */
5730 mono_array_set ((*data), gint64, 2, (gint64)gmtoff * 10000000L);
5731 mono_array_set ((*data), gint64, 3, (gint64)(gmt_offset (&tt, t) - gmtoff) * 10000000L);
5733 gmtoff = gmt_offset (&tt, t);
5738 strftime (tzone, sizeof (tzone), "%Z", &tt);
5739 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5740 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5741 mono_array_set ((*data), gint64, 0, 0);
5742 mono_array_set ((*data), gint64, 1, 0);
5743 mono_array_set ((*data), gint64, 2, (gint64) gmtoff * 10000000L);
5744 mono_array_set ((*data), gint64, 3, 0);
5749 MonoDomain *domain = mono_domain_get ();
5750 TIME_ZONE_INFORMATION tz_info;
5755 tz_id = GetTimeZoneInformation (&tz_info);
5756 if (tz_id == TIME_ZONE_ID_INVALID)
5759 MONO_CHECK_ARG_NULL (data);
5760 MONO_CHECK_ARG_NULL (names);
5762 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5763 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5765 for (i = 0; i < 32; ++i)
5766 if (!tz_info.DaylightName [i])
5768 mono_array_setref ((*names), 1, mono_string_new_utf16 (domain, tz_info.DaylightName, i));
5769 for (i = 0; i < 32; ++i)
5770 if (!tz_info.StandardName [i])
5772 mono_array_setref ((*names), 0, mono_string_new_utf16 (domain, tz_info.StandardName, i));
5774 if ((year <= 1601) || (year > 30827)) {
5776 * According to MSDN, the MS time functions can't handle dates outside
5782 /* even if the timezone has no daylight savings it may have Bias (e.g. GMT+13 it seems) */
5783 if (tz_id != TIME_ZONE_ID_UNKNOWN) {
5784 tz_info.StandardDate.wYear = year;
5785 convert_to_absolute_date(&tz_info.StandardDate);
5786 err = SystemTimeToFileTime (&tz_info.StandardDate, &ft);
5791 mono_array_set ((*data), gint64, 1, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
5792 tz_info.DaylightDate.wYear = year;
5793 convert_to_absolute_date(&tz_info.DaylightDate);
5794 err = SystemTimeToFileTime (&tz_info.DaylightDate, &ft);
5799 mono_array_set ((*data), gint64, 0, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
5801 mono_array_set ((*data), gint64, 2, (tz_info.Bias + tz_info.StandardBias) * -600000000LL);
5802 mono_array_set ((*data), gint64, 3, (tz_info.DaylightBias - tz_info.StandardBias) * -600000000LL);
5809 ves_icall_System_Object_obj_address (MonoObject *this)
5811 MONO_ARCH_SAVE_REGS;
5818 static inline gint32
5819 mono_array_get_byte_length (MonoArray *array)
5825 klass = array->obj.vtable->klass;
5827 if (array->bounds == NULL)
5828 length = array->max_length;
5831 for (i = 0; i < klass->rank; ++ i)
5832 length *= array->bounds [i].length;
5835 switch (klass->element_class->byval_arg.type) {
5838 case MONO_TYPE_BOOLEAN:
5842 case MONO_TYPE_CHAR:
5850 return length * sizeof (gpointer);
5861 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array)
5863 MONO_ARCH_SAVE_REGS;
5865 return mono_array_get_byte_length (array);
5869 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx)
5871 MONO_ARCH_SAVE_REGS;
5873 return mono_array_get (array, gint8, idx);
5877 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value)
5879 MONO_ARCH_SAVE_REGS;
5881 mono_array_set (array, gint8, idx, value);
5885 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count)
5887 guint8 *src_buf, *dest_buf;
5889 MONO_ARCH_SAVE_REGS;
5891 /* watch out for integer overflow */
5892 if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count))
5895 src_buf = (guint8 *)src->vector + src_offset;
5896 dest_buf = (guint8 *)dest->vector + dest_offset;
5899 memcpy (dest_buf, src_buf, count);
5901 memmove (dest_buf, src_buf, count); /* Source and dest are the same array */
5907 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this, MonoString *class_name)
5909 MonoDomain *domain = mono_object_domain (this);
5911 MonoRealProxy *rp = ((MonoRealProxy *)this);
5912 MonoTransparentProxy *tp;
5916 MONO_ARCH_SAVE_REGS;
5918 res = mono_object_new (domain, mono_defaults.transparent_proxy_class);
5919 tp = (MonoTransparentProxy*) res;
5921 MONO_OBJECT_SETREF (tp, rp, rp);
5922 type = ((MonoReflectionType *)rp->class_to_proxy)->type;
5923 klass = mono_class_from_mono_type (type);
5925 tp->custom_type_info = (mono_object_isinst (this, mono_defaults.iremotingtypeinfo_class) != NULL);
5926 tp->remote_class = mono_remote_class (domain, class_name, klass);
5928 res->vtable = mono_remote_class_vtable (domain, tp->remote_class, rp);
5932 static MonoReflectionType *
5933 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
5935 return mono_type_get_object (mono_object_domain (tp), &tp->remote_class->proxy_class->byval_arg);
5938 /* System.Environment */
5941 ves_icall_System_Environment_get_MachineName (void)
5943 #if defined (PLATFORM_WIN32)
5948 len = MAX_COMPUTERNAME_LENGTH + 1;
5949 buf = g_new (gunichar2, len);
5952 if (GetComputerName (buf, (PDWORD) &len))
5953 result = mono_string_new_utf16 (mono_domain_get (), buf, len);
5961 if (gethostname (buf, sizeof (buf)) == 0)
5962 result = mono_string_new (mono_domain_get (), buf);
5971 ves_icall_System_Environment_get_Platform (void)
5973 MONO_ARCH_SAVE_REGS;
5975 #if defined (PLATFORM_WIN32)
5985 ves_icall_System_Environment_get_NewLine (void)
5987 MONO_ARCH_SAVE_REGS;
5989 #if defined (PLATFORM_WIN32)
5990 return mono_string_new (mono_domain_get (), "\r\n");
5992 return mono_string_new (mono_domain_get (), "\n");
5997 ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name)
6002 MONO_ARCH_SAVE_REGS;
6007 utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
6008 value = g_getenv (utf8_name);
6015 return mono_string_new (mono_domain_get (), value);
6019 * There is no standard way to get at environ.
6022 #ifndef __MINGW32_VERSION
6029 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
6031 #ifdef PLATFORM_WIN32
6040 env_strings = GetEnvironmentStrings();
6043 env_string = env_strings;
6044 while (*env_string != '\0') {
6045 /* weird case that MS seems to skip */
6046 if (*env_string != '=')
6048 while (*env_string != '\0')
6054 domain = mono_domain_get ();
6055 names = mono_array_new (domain, mono_defaults.string_class, n);
6059 env_string = env_strings;
6060 while (*env_string != '\0') {
6061 /* weird case that MS seems to skip */
6062 if (*env_string != '=') {
6063 equal_str = wcschr(env_string, '=');
6064 g_assert(equal_str);
6065 str = mono_string_new_utf16 (domain, env_string, equal_str-env_string);
6066 mono_array_setref (names, n, str);
6069 while (*env_string != '\0')
6074 FreeEnvironmentStrings (env_strings);
6086 MONO_ARCH_SAVE_REGS;
6089 for (e = environ; *e != 0; ++ e)
6092 domain = mono_domain_get ();
6093 names = mono_array_new (domain, mono_defaults.string_class, n);
6096 for (e = environ; *e != 0; ++ e) {
6097 parts = g_strsplit (*e, "=", 2);
6099 str = mono_string_new (domain, *parts);
6100 mono_array_setref (names, n, str);
6113 * If your platform lacks setenv/unsetenv, you must upgrade your glib.
6115 #if !GLIB_CHECK_VERSION(2,4,0)
6116 #define g_setenv(a,b,c) setenv(a,b,c)
6117 #define g_unsetenv(a) unsetenv(a)
6121 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
6123 #ifdef PLATFORM_WIN32
6124 gunichar2 *utf16_name, *utf16_value;
6126 gchar *utf8_name, *utf8_value;
6129 MONO_ARCH_SAVE_REGS;
6131 #ifdef PLATFORM_WIN32
6132 utf16_name = mono_string_to_utf16 (name);
6133 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
6134 SetEnvironmentVariable (utf16_name, NULL);
6135 g_free (utf16_name);
6139 utf16_value = mono_string_to_utf16 (value);
6141 SetEnvironmentVariable (utf16_name, utf16_value);
6143 g_free (utf16_name);
6144 g_free (utf16_value);
6146 utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
6148 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
6149 g_unsetenv (utf8_name);
6154 utf8_value = mono_string_to_utf8 (value);
6155 g_setenv (utf8_name, utf8_value, TRUE);
6158 g_free (utf8_value);
6163 ves_icall_System_Environment_Exit (int result)
6165 MONO_ARCH_SAVE_REGS;
6167 if (!mono_threads_set_shutting_down ())
6170 mono_runtime_set_shutting_down ();
6172 /* Suspend all managed threads since the runtime is going away */
6173 mono_thread_suspend_all_other_threads ();
6175 mono_runtime_quit ();
6177 /* we may need to do some cleanup here... */
6182 ves_icall_System_Environment_GetGacPath (void)
6184 return mono_string_new (mono_domain_get (), mono_assembly_getrootdir ());
6188 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
6190 #if defined (PLATFORM_WIN32)
6191 #ifndef CSIDL_FLAG_CREATE
6192 #define CSIDL_FLAG_CREATE 0x8000
6195 WCHAR path [MAX_PATH];
6196 /* Create directory if no existing */
6197 if (SUCCEEDED (SHGetFolderPathW (NULL, folder | CSIDL_FLAG_CREATE, NULL, 0, path))) {
6201 return mono_string_new_utf16 (mono_domain_get (), path, len);
6204 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
6206 return mono_string_new (mono_domain_get (), "");
6210 ves_icall_System_Environment_GetLogicalDrives (void)
6212 gunichar2 buf [128], *ptr, *dname;
6214 gint initial_size = 127, size = 128;
6217 MonoString *drivestr;
6218 MonoDomain *domain = mono_domain_get ();
6221 MONO_ARCH_SAVE_REGS;
6226 while (size > initial_size) {
6227 size = GetLogicalDriveStrings (initial_size, ptr);
6228 if (size > initial_size) {
6231 ptr = g_malloc0 ((size + 1) * sizeof (gunichar2));
6232 initial_size = size;
6246 result = mono_array_new (domain, mono_defaults.string_class, ndrives);
6251 while (*u16) { u16++; len ++; }
6252 drivestr = mono_string_new_utf16 (domain, dname, len);
6253 mono_array_setref (result, ndrives++, drivestr);
6264 ves_icall_System_Environment_InternalGetHome (void)
6266 MONO_ARCH_SAVE_REGS;
6268 return mono_string_new (mono_domain_get (), g_get_home_dir ());
6271 static const char *encodings [] = {
6273 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
6274 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
6275 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
6277 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
6278 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
6279 "x_unicode_2_0_utf_7",
6281 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
6282 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
6284 "utf_16", "UTF_16LE", "ucs_2", "unicode",
6287 "unicodefffe", "utf_16be",
6294 * Returns the internal codepage, if the value of "int_code_page" is
6295 * 1 at entry, and we can not compute a suitable code page number,
6296 * returns the code page as a string
6299 ves_icall_System_Text_Encoding_InternalCodePage (gint32 *int_code_page)
6304 char *codepage = NULL;
6306 int want_name = *int_code_page;
6309 *int_code_page = -1;
6310 MONO_ARCH_SAVE_REGS;
6312 g_get_charset (&cset);
6313 c = codepage = strdup (cset);
6314 for (c = codepage; *c; c++){
6315 if (isascii (*c) && isalpha (*c))
6320 /* g_print ("charset: %s\n", cset); */
6322 /* handle some common aliases */
6325 for (i = 0; p != 0; ){
6326 if ((gssize) p < 7){
6328 p = encodings [++i];
6331 if (strcmp (p, codepage) == 0){
6332 *int_code_page = code;
6335 p = encodings [++i];
6338 if (strstr (codepage, "utf_8") != NULL)
6339 *int_code_page |= 0x10000000;
6342 if (want_name && *int_code_page == -1)
6343 return mono_string_new (mono_domain_get (), cset);
6349 ves_icall_System_Environment_get_HasShutdownStarted (void)
6351 if (mono_runtime_is_shutting_down ())
6354 if (mono_domain_is_unloading (mono_domain_get ()))
6361 ves_icall_MonoMethodMessage_InitMessage (MonoMethodMessage *this,
6362 MonoReflectionMethod *method,
6363 MonoArray *out_args)
6365 MONO_ARCH_SAVE_REGS;
6367 mono_message_init (mono_object_domain (this), this, method, out_args);
6371 ves_icall_IsTransparentProxy (MonoObject *proxy)
6373 MONO_ARCH_SAVE_REGS;
6378 if (proxy->vtable->klass == mono_defaults.transparent_proxy_class)
6384 static MonoReflectionMethod *
6385 ves_icall_Remoting_RemotingServices_GetVirtualMethod (
6386 MonoReflectionType *rtype, MonoReflectionMethod *rmethod)
6390 MonoMethod **vtable;
6391 MonoMethod *res = NULL;
6393 MONO_CHECK_ARG_NULL (rtype);
6394 MONO_CHECK_ARG_NULL (rmethod);
6396 method = rmethod->method;
6397 klass = mono_class_from_mono_type (rtype->type);
6399 if (MONO_CLASS_IS_INTERFACE (klass))
6402 if (method->flags & METHOD_ATTRIBUTE_STATIC)
6405 if ((method->flags & METHOD_ATTRIBUTE_FINAL) || !(method->flags & METHOD_ATTRIBUTE_VIRTUAL)) {
6406 if (klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE))
6412 mono_class_setup_vtable (klass);
6413 vtable = klass->vtable;
6415 if (method->klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
6416 int offs = mono_class_interface_offset (klass, method->klass);
6418 res = vtable [offs + method->slot];
6420 if (!(klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE)))
6423 if (method->slot != -1)
6424 res = vtable [method->slot];
6430 return mono_method_get_object (mono_domain_get (), res, NULL);
6434 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6439 MONO_ARCH_SAVE_REGS;
6441 klass = mono_class_from_mono_type (type->type);
6442 vtable = mono_class_vtable (mono_domain_get (), klass);
6444 if (enable) vtable->remote = 1;
6445 else vtable->remote = 0;
6449 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type)
6454 MONO_ARCH_SAVE_REGS;
6456 domain = mono_object_domain (type);
6457 klass = mono_class_from_mono_type (type->type);
6459 if (klass->rank >= 1) {
6460 g_assert (klass->rank == 1);
6461 return (MonoObject *) mono_array_new (domain, klass->element_class, 0);
6463 /* Bypass remoting object creation check */
6464 return mono_object_new_alloc_specific (mono_class_vtable (domain, klass));
6469 ves_icall_System_IO_get_temp_path (void)
6471 MONO_ARCH_SAVE_REGS;
6473 return mono_string_new (mono_domain_get (), g_get_tmp_dir ());
6477 ves_icall_RuntimeMethod_GetFunctionPointer (MonoMethod *method)
6479 MONO_ARCH_SAVE_REGS;
6481 return mono_compile_method (method);
6485 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
6490 MONO_ARCH_SAVE_REGS;
6492 path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
6494 #if defined (PLATFORM_WIN32)
6495 /* Avoid mixing '/' and '\\' */
6498 for (i = strlen (path) - 1; i >= 0; i--)
6499 if (path [i] == '/')
6503 mcpath = mono_string_new (mono_domain_get (), path);
6510 get_bundled_machine_config (void)
6512 const gchar *machine_config;
6514 MONO_ARCH_SAVE_REGS;
6516 machine_config = mono_get_machine_config ();
6518 if (!machine_config)
6521 return mono_string_new (mono_domain_get (), machine_config);
6525 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
6530 MONO_ARCH_SAVE_REGS;
6532 path = g_path_get_dirname (mono_get_config_dir ());
6534 #if defined (PLATFORM_WIN32)
6535 /* Avoid mixing '/' and '\\' */
6538 for (i = strlen (path) - 1; i >= 0; i--)
6539 if (path [i] == '/')
6543 ipath = mono_string_new (mono_domain_get (), path);
6550 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
6552 #if defined (PLATFORM_WIN32)
6553 OutputDebugString (mono_string_chars (message));
6555 g_warning ("WriteWindowsDebugString called and PLATFORM_WIN32 not defined!\n");
6559 /* Only used for value types */
6561 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
6566 MONO_ARCH_SAVE_REGS;
6568 domain = mono_object_domain (type);
6569 klass = mono_class_from_mono_type (type->type);
6571 if (mono_class_is_nullable (klass))
6572 /* No arguments -> null */
6575 return mono_object_new (domain, klass);
6578 static MonoReflectionMethod *
6579 ves_icall_MonoMethod_get_base_definition (MonoReflectionMethod *m)
6581 MonoClass *klass, *parent;
6582 MonoMethod *method = m->method;
6583 MonoMethod *result = NULL;
6585 MONO_ARCH_SAVE_REGS;
6587 if (method->klass == NULL)
6590 if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
6591 MONO_CLASS_IS_INTERFACE (method->klass) ||
6592 method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
6595 klass = method->klass;
6596 if (klass->generic_class)
6597 klass = klass->generic_class->container_class;
6599 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
6600 for (parent = klass->parent; parent != NULL; parent = parent->parent) {
6601 mono_class_setup_vtable (parent);
6602 if (parent->vtable_size <= method->slot)
6607 if (klass == method->klass)
6610 result = klass->vtable [method->slot];
6611 if (result == NULL) {
6612 /* It is an abstract method */
6613 gpointer iter = NULL;
6614 while ((result = mono_class_get_methods (klass, &iter)))
6615 if (result->slot == method->slot)
6622 return mono_method_get_object (mono_domain_get (), result, NULL);
6626 ves_icall_MonoMethod_get_name (MonoReflectionMethod *m)
6628 MonoMethod *method = m->method;
6630 MONO_OBJECT_SETREF (m, name, mono_string_new (mono_object_domain (m), method->name));
6635 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
6637 MONO_ARCH_SAVE_REGS;
6639 iter->sig = *(MonoMethodSignature**)argsp;
6641 g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
6642 g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
6645 /* FIXME: it's not documented what start is exactly... */
6649 guint32 i, arg_size;
6651 iter->args = argsp + sizeof (gpointer);
6652 #ifndef MONO_ARCH_REGPARMS
6653 for (i = 0; i < iter->sig->sentinelpos; ++i) {
6654 arg_size = mono_type_stack_size (iter->sig->params [i], &align);
6655 iter->args = (char*)iter->args + arg_size;
6659 iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
6661 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
6665 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
6667 guint32 i, arg_size;
6670 MONO_ARCH_SAVE_REGS;
6672 i = iter->sig->sentinelpos + iter->next_arg;
6674 g_assert (i < iter->sig->param_count);
6676 res.type = iter->sig->params [i];
6677 res.klass = mono_class_from_mono_type (res.type);
6678 /* FIXME: endianess issue... */
6679 res.value = iter->args;
6680 arg_size = mono_type_stack_size (res.type, &align);
6681 iter->args = (char*)iter->args + arg_size;
6684 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6690 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
6692 guint32 i, arg_size;
6695 MONO_ARCH_SAVE_REGS;
6697 i = iter->sig->sentinelpos + iter->next_arg;
6699 g_assert (i < iter->sig->param_count);
6701 while (i < iter->sig->param_count) {
6702 if (!mono_metadata_type_equal (type, iter->sig->params [i]))
6704 res.type = iter->sig->params [i];
6705 res.klass = mono_class_from_mono_type (res.type);
6706 /* FIXME: endianess issue... */
6707 res.value = iter->args;
6708 arg_size = mono_type_stack_size (res.type, &align);
6709 iter->args = (char*)iter->args + arg_size;
6711 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6714 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
6723 mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
6726 MONO_ARCH_SAVE_REGS;
6728 i = iter->sig->sentinelpos + iter->next_arg;
6730 g_assert (i < iter->sig->param_count);
6732 return iter->sig->params [i];
6736 mono_TypedReference_ToObject (MonoTypedRef tref)
6738 MONO_ARCH_SAVE_REGS;
6740 if (MONO_TYPE_IS_REFERENCE (tref.type)) {
6741 MonoObject** objp = tref.value;
6745 return mono_value_box (mono_domain_get (), tref.klass, tref.value);
6749 mono_TypedReference_ToObjectInternal (MonoType *type, gpointer value, MonoClass *klass)
6751 MONO_ARCH_SAVE_REGS;
6753 if (MONO_TYPE_IS_REFERENCE (type)) {
6754 MonoObject** objp = value;
6758 return mono_value_box (mono_domain_get (), klass, value);
6762 prelink_method (MonoMethod *method)
6764 const char *exc_class, *exc_arg;
6765 if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
6767 mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
6769 mono_raise_exception(
6770 mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg ) );
6772 /* create the wrapper, too? */
6776 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
6778 MONO_ARCH_SAVE_REGS;
6779 prelink_method (method->method);
6783 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
6785 MonoClass *klass = mono_class_from_mono_type (type->type);
6787 gpointer iter = NULL;
6788 MONO_ARCH_SAVE_REGS;
6790 while ((m = mono_class_get_methods (klass, &iter)))
6794 /* These parameters are "readonly" in corlib/System/NumberFormatter.cs */
6796 ves_icall_System_NumberFormatter_GetFormatterTables (guint64 const **mantissas,
6797 gint32 const **exponents,
6798 gunichar2 const **digitLowerTable,
6799 gunichar2 const **digitUpperTable,
6800 gint64 const **tenPowersList,
6801 gint32 const **decHexDigits)
6803 *mantissas = Formatter_MantissaBitsTable;
6804 *exponents = Formatter_TensExponentTable;
6805 *digitLowerTable = Formatter_DigitLowerTable;
6806 *digitUpperTable = Formatter_DigitUpperTable;
6807 *tenPowersList = Formatter_TenPowersList;
6808 *decHexDigits = Formatter_DecHexDigits;
6811 /* These parameters are "readonly" in corlib/System/Char.cs */
6813 ves_icall_System_Char_GetDataTablePointers (guint8 const **category_data,
6814 guint8 const **numeric_data,
6815 gdouble const **numeric_data_values,
6816 guint16 const **to_lower_data_low,
6817 guint16 const **to_lower_data_high,
6818 guint16 const **to_upper_data_low,
6819 guint16 const **to_upper_data_high)
6821 *category_data = CategoryData;
6822 *numeric_data = NumericData;
6823 *numeric_data_values = NumericDataValues;
6824 *to_lower_data_low = ToLowerDataLow;
6825 *to_lower_data_high = ToLowerDataHigh;
6826 *to_upper_data_low = ToUpperDataLow;
6827 *to_upper_data_high = ToUpperDataHigh;
6831 ves_icall_MonoDebugger_GetMethodToken (MonoReflectionMethod *method)
6833 return method->method->token;
6837 * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
6838 * and avoid useless allocations.
6841 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional)
6845 for (i = 0; i < type->num_mods; ++i) {
6846 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
6851 res = mono_array_new (mono_domain_get (), mono_defaults.systemtype_class, count);
6853 for (i = 0; i < type->num_mods; ++i) {
6854 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
6855 MonoClass *klass = mono_class_get (image, type->modifiers [i].token);
6856 mono_array_setref (res, count, mono_type_get_object (mono_domain_get (), &klass->byval_arg));
6864 param_info_get_type_modifiers (MonoReflectionParameter *param, MonoBoolean optional)
6866 MonoType *type = param->ClassImpl->type;
6867 MonoReflectionMethod *method = (MonoReflectionMethod*)param->MemberImpl;
6868 MonoImage *image = method->method->klass->image;
6869 int pos = param->PositionImpl;
6870 MonoMethodSignature *sig = mono_method_signature (method->method);
6874 type = sig->params [pos];
6876 return type_array_from_modifiers (image, type, optional);
6880 get_property_type (MonoProperty *prop)
6882 MonoMethodSignature *sig;
6884 sig = mono_method_signature (prop->get);
6886 } else if (prop->set) {
6887 sig = mono_method_signature (prop->set);
6888 return sig->params [sig->param_count - 1];
6894 property_info_get_type_modifiers (MonoReflectionProperty *property, MonoBoolean optional)
6896 MonoType *type = get_property_type (property->property);
6897 MonoImage *image = property->klass->image;
6901 return type_array_from_modifiers (image, type, optional);
6905 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
6907 MonoCustomAttrInfo *cinfo;
6910 cinfo = mono_reflection_get_custom_attrs_info (obj);
6913 found = mono_custom_attrs_has_attr (cinfo, mono_class_from_mono_type (attr_type->type));
6915 mono_custom_attrs_free (cinfo);
6920 custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
6922 MonoArray *res = mono_reflection_get_custom_attrs_by_type (obj, attr_type ? mono_class_from_mono_type (attr_type->type) : NULL);
6924 if (mono_loader_get_last_error ()) {
6925 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
6926 g_assert_not_reached ();
6933 GCHandle_CheckCurrentDomain (guint32 gchandle)
6935 return mono_gchandle_is_in_domain (gchandle, mono_domain_get ());
6939 ves_icall_Mono_Runtime_GetDisplayName (void)
6941 static const char display_name_str [] = "Mono " VERSION;
6942 MonoString *display_name = mono_string_new (mono_domain_get (), display_name_str);
6943 return display_name;
6948 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
6949 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
6950 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 62, 128, 128, 128, 63,
6951 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 0, 128, 128,
6952 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
6953 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 128, 128, 128, 128, 128,
6954 128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
6955 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
6959 base64_to_byte_array (gunichar2 *start, gint ilength, MonoBoolean allowWhitespaceOnly)
6964 gunichar2 last, prev_last;
6972 last = prev_last = 0;
6973 for (i = 0; i < ilength; i++) {
6975 if (c >= sizeof (dbase64)) {
6976 exc = mono_exception_from_name_msg (mono_get_corlib (),
6977 "System", "FormatException",
6978 "Invalid character found.");
6979 mono_raise_exception (exc);
6980 } else if (isspace (c)) {
6988 olength = ilength - ignored;
6990 if (allowWhitespaceOnly && olength == 0) {
6991 return mono_array_new (mono_domain_get (), mono_defaults.byte_class, 0);
6994 if ((olength & 3) != 0 || olength <= 0) {
6995 exc = mono_exception_from_name_msg (mono_get_corlib (), "System",
6996 "FormatException", "Invalid length.");
6997 mono_raise_exception (exc);
7000 olength = (olength * 3) / 4;
7004 if (prev_last == '=')
7007 result = mono_array_new (mono_domain_get (), mono_defaults.byte_class, olength);
7008 res_ptr = mono_array_addr (result, guchar, 0);
7009 for (i = 0; i < ilength; ) {
7012 for (k = 0; k < 4 && i < ilength;) {
7018 if (((b [k] = dbase64 [c]) & 0x80) != 0) {
7019 exc = mono_exception_from_name_msg (mono_get_corlib (),
7020 "System", "FormatException",
7021 "Invalid character found.");
7022 mono_raise_exception (exc);
7027 *res_ptr++ = (b [0] << 2) | (b [1] >> 4);
7029 *res_ptr++ = (b [1] << 4) | (b [2] >> 2);
7031 *res_ptr++ = (b [2] << 6) | b [3];
7033 while (i < ilength && isspace (start [i]))
7041 InternalFromBase64String (MonoString *str, MonoBoolean allowWhitespaceOnly)
7043 MONO_ARCH_SAVE_REGS;
7045 return base64_to_byte_array (mono_string_chars (str),
7046 mono_string_length (str), allowWhitespaceOnly);
7050 InternalFromBase64CharArray (MonoArray *input, gint offset, gint length)
7052 MONO_ARCH_SAVE_REGS;
7054 return base64_to_byte_array (mono_array_addr (input, gunichar2, offset),
7058 #define ICALL_TYPE(id,name,first)
7059 #define ICALL(id,name,func) Icall_ ## id,
7062 #include "metadata/icall-def.h"
7068 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
7069 #define ICALL(id,name,func)
7071 #include "metadata/icall-def.h"
7077 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
7078 #define ICALL(id,name,func)
7080 guint16 first_icall;
7083 static const IcallTypeDesc
7084 icall_type_descs [] = {
7085 #include "metadata/icall-def.h"
7089 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
7092 #define ICALL_TYPE(id,name,first)
7095 #ifdef HAVE_ARRAY_ELEM_INIT
7096 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
7097 #define MSGSTRFIELD1(line) str##line
7099 static const struct msgstrtn_t {
7100 #define ICALL(id,name,func)
7102 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7103 #include "metadata/icall-def.h"
7105 } icall_type_names_str = {
7106 #define ICALL_TYPE(id,name,first) (name),
7107 #include "metadata/icall-def.h"
7110 static const guint16 icall_type_names_idx [] = {
7111 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
7112 #include "metadata/icall-def.h"
7115 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
7117 static const struct msgstr_t {
7119 #define ICALL_TYPE(id,name,first)
7120 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7121 #include "metadata/icall-def.h"
7123 } icall_names_str = {
7124 #define ICALL(id,name,func) (name),
7125 #include "metadata/icall-def.h"
7128 static const guint16 icall_names_idx [] = {
7129 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
7130 #include "metadata/icall-def.h"
7133 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
7139 #define ICALL_TYPE(id,name,first) name,
7140 #define ICALL(id,name,func)
7141 static const char* const
7142 icall_type_names [] = {
7143 #include "metadata/icall-def.h"
7147 #define icall_type_name_get(id) (icall_type_names [(id)])
7151 #define ICALL_TYPE(id,name,first)
7152 #define ICALL(id,name,func) name,
7153 static const char* const
7155 #include "metadata/icall-def.h"
7158 #define icall_name_get(id) icall_names [(id)]
7160 #endif /* !HAVE_ARRAY_ELEM_INIT */
7164 #define ICALL_TYPE(id,name,first)
7165 #define ICALL(id,name,func) func,
7166 static const gconstpointer
7167 icall_functions [] = {
7168 #include "metadata/icall-def.h"
7172 static GHashTable *icall_hash = NULL;
7173 static GHashTable *jit_icall_hash_name = NULL;
7174 static GHashTable *jit_icall_hash_addr = NULL;
7177 mono_icall_init (void)
7181 /* check that tables are sorted: disable in release */
7184 const char *prev_class = NULL;
7185 const char *prev_method;
7187 for (i = 0; i < Icall_type_num; ++i) {
7188 const IcallTypeDesc *desc;
7191 if (prev_class && strcmp (prev_class, icall_type_name_get (i)) >= 0)
7192 g_print ("class %s should come before class %s\n", icall_type_name_get (i), prev_class);
7193 prev_class = icall_type_name_get (i);
7194 desc = &icall_type_descs [i];
7195 num_icalls = icall_desc_num_icalls (desc);
7196 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
7197 for (j = 0; j < num_icalls; ++j) {
7198 const char *methodn = icall_name_get (desc->first_icall + j);
7199 if (prev_method && strcmp (prev_method, methodn) >= 0)
7200 g_print ("method %s should come before method %s\n", methodn, prev_method);
7201 prev_method = methodn;
7206 icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
7210 mono_icall_cleanup (void)
7212 g_hash_table_destroy (icall_hash);
7213 g_hash_table_destroy (jit_icall_hash_name);
7214 g_hash_table_destroy (jit_icall_hash_addr);
7218 mono_add_internal_call (const char *name, gconstpointer method)
7220 mono_loader_lock ();
7222 g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
7224 mono_loader_unlock ();
7227 #ifdef HAVE_ARRAY_ELEM_INIT
7229 compare_method_imap (const void *key, const void *elem)
7231 const char* method_name = (const char*)&icall_names_str + (*(guint16*)elem);
7232 return strcmp (key, method_name);
7236 find_method_icall (const IcallTypeDesc *imap, const char *name)
7238 const guint16 *nameslot = bsearch (name, icall_names_idx + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names_idx [0]), compare_method_imap);
7241 return (gpointer)icall_functions [(nameslot - &icall_names_idx [0])];
7245 compare_class_imap (const void *key, const void *elem)
7247 const char* class_name = (const char*)&icall_type_names_str + (*(guint16*)elem);
7248 return strcmp (key, class_name);
7251 static const IcallTypeDesc*
7252 find_class_icalls (const char *name)
7254 const guint16 *nameslot = bsearch (name, icall_type_names_idx, Icall_type_num, sizeof (icall_type_names_idx [0]), compare_class_imap);
7257 return &icall_type_descs [nameslot - &icall_type_names_idx [0]];
7262 compare_method_imap (const void *key, const void *elem)
7264 const char** method_name = (const char**)elem;
7265 return strcmp (key, *method_name);
7269 find_method_icall (const IcallTypeDesc *imap, const char *name)
7271 const char **nameslot = bsearch (name, icall_names + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names [0]), compare_method_imap);
7274 return (gpointer)icall_functions [(nameslot - icall_names)];
7278 compare_class_imap (const void *key, const void *elem)
7280 const char** class_name = (const char**)elem;
7281 return strcmp (key, *class_name);
7284 static const IcallTypeDesc*
7285 find_class_icalls (const char *name)
7287 const char **nameslot = bsearch (name, icall_type_names, Icall_type_num, sizeof (icall_type_names [0]), compare_class_imap);
7290 return &icall_type_descs [nameslot - icall_type_names];
7296 * we should probably export this as an helper (handle nested types).
7297 * Returns the number of chars written in buf.
7300 concat_class_name (char *buf, int bufsize, MonoClass *klass)
7302 int nspacelen, cnamelen;
7303 nspacelen = strlen (klass->name_space);
7304 cnamelen = strlen (klass->name);
7305 if (nspacelen + cnamelen + 2 > bufsize)
7308 memcpy (buf, klass->name_space, nspacelen);
7309 buf [nspacelen ++] = '.';
7311 memcpy (buf + nspacelen, klass->name, cnamelen);
7312 buf [nspacelen + cnamelen] = 0;
7313 return nspacelen + cnamelen;
7317 mono_lookup_internal_call (MonoMethod *method)
7322 int typelen = 0, mlen, siglen;
7324 const IcallTypeDesc *imap;
7326 g_assert (method != NULL);
7328 if (method->is_inflated)
7329 method = ((MonoMethodInflated *) method)->declaring;
7331 if (method->klass->nested_in) {
7332 int pos = concat_class_name (mname, sizeof (mname)-2, method->klass->nested_in);
7336 mname [pos++] = '/';
7339 typelen = concat_class_name (mname+pos, sizeof (mname)-pos-1, method->klass);
7345 typelen = concat_class_name (mname, sizeof (mname), method->klass);
7350 imap = find_class_icalls (mname);
7352 mname [typelen] = ':';
7353 mname [typelen + 1] = ':';
7355 mlen = strlen (method->name);
7356 memcpy (mname + typelen + 2, method->name, mlen);
7357 sigstart = mname + typelen + 2 + mlen;
7360 tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
7361 siglen = strlen (tmpsig);
7362 if (typelen + mlen + siglen + 6 > sizeof (mname))
7365 memcpy (sigstart + 1, tmpsig, siglen);
7366 sigstart [siglen + 1] = ')';
7367 sigstart [siglen + 2] = 0;
7370 mono_loader_lock ();
7372 res = g_hash_table_lookup (icall_hash, mname);
7374 mono_loader_unlock ();
7377 /* try without signature */
7379 res = g_hash_table_lookup (icall_hash, mname);
7381 mono_loader_unlock ();
7385 /* it wasn't found in the static call tables */
7387 mono_loader_unlock ();
7390 res = find_method_icall (imap, sigstart - mlen);
7392 mono_loader_unlock ();
7395 /* try _with_ signature */
7397 res = find_method_icall (imap, sigstart - mlen);
7399 mono_loader_unlock ();
7403 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname);
7404 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
7405 g_print ("The out of sync library is: %s\n", method->klass->image->name);
7406 g_print ("\nWhen you update one from svn you need to update, compile and install\nthe other too.\n");
7407 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");
7408 g_print ("If you see other errors or faults after this message they are probably related\n");
7409 g_print ("and you need to fix your mono install first.\n");
7411 mono_loader_unlock ();
7417 type_from_typename (char *typename)
7419 MonoClass *klass = NULL; /* assignment to shut GCC warning up */
7421 if (!strcmp (typename, "int"))
7422 klass = mono_defaults.int_class;
7423 else if (!strcmp (typename, "ptr"))
7424 klass = mono_defaults.int_class;
7425 else if (!strcmp (typename, "void"))
7426 klass = mono_defaults.void_class;
7427 else if (!strcmp (typename, "int32"))
7428 klass = mono_defaults.int32_class;
7429 else if (!strcmp (typename, "uint32"))
7430 klass = mono_defaults.uint32_class;
7431 else if (!strcmp (typename, "int8"))
7432 klass = mono_defaults.sbyte_class;
7433 else if (!strcmp (typename, "uint8"))
7434 klass = mono_defaults.byte_class;
7435 else if (!strcmp (typename, "int16"))
7436 klass = mono_defaults.int16_class;
7437 else if (!strcmp (typename, "uint16"))
7438 klass = mono_defaults.uint16_class;
7439 else if (!strcmp (typename, "long"))
7440 klass = mono_defaults.int64_class;
7441 else if (!strcmp (typename, "ulong"))
7442 klass = mono_defaults.uint64_class;
7443 else if (!strcmp (typename, "float"))
7444 klass = mono_defaults.single_class;
7445 else if (!strcmp (typename, "double"))
7446 klass = mono_defaults.double_class;
7447 else if (!strcmp (typename, "object"))
7448 klass = mono_defaults.object_class;
7449 else if (!strcmp (typename, "obj"))
7450 klass = mono_defaults.object_class;
7453 g_assert_not_reached ();
7455 return &klass->byval_arg;
7458 MonoMethodSignature*
7459 mono_create_icall_signature (const char *sigstr)
7464 MonoMethodSignature *res;
7466 mono_loader_lock ();
7467 res = g_hash_table_lookup (mono_defaults.corlib->helper_signatures, sigstr);
7469 mono_loader_unlock ();
7473 parts = g_strsplit (sigstr, " ", 256);
7482 res = mono_metadata_signature_alloc (mono_defaults.corlib, len - 1);
7485 #ifdef PLATFORM_WIN32
7487 * Under windows, the default pinvoke calling convention is STDCALL but
7490 res->call_convention = MONO_CALL_C;
7493 res->ret = type_from_typename (parts [0]);
7494 for (i = 1; i < len; ++i) {
7495 res->params [i - 1] = type_from_typename (parts [i]);
7500 g_hash_table_insert (mono_defaults.corlib->helper_signatures, (gpointer)sigstr, res);
7502 mono_loader_unlock ();
7508 mono_find_jit_icall_by_name (const char *name)
7510 MonoJitICallInfo *info;
7511 g_assert (jit_icall_hash_name);
7513 mono_loader_lock ();
7514 info = g_hash_table_lookup (jit_icall_hash_name, name);
7515 mono_loader_unlock ();
7520 mono_find_jit_icall_by_addr (gconstpointer addr)
7522 MonoJitICallInfo *info;
7523 g_assert (jit_icall_hash_addr);
7525 mono_loader_lock ();
7526 info = g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
7527 mono_loader_unlock ();
7533 mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
7535 mono_loader_lock ();
7536 g_hash_table_insert (jit_icall_hash_addr, (gpointer)wrapper, info);
7537 mono_loader_unlock ();
7541 mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
7543 MonoJitICallInfo *info;
7548 mono_loader_lock ();
7550 if (!jit_icall_hash_name) {
7551 jit_icall_hash_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
7552 jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
7555 if (g_hash_table_lookup (jit_icall_hash_name, name)) {
7556 g_warning ("jit icall already defined \"%s\"\n", name);
7557 g_assert_not_reached ();
7560 info = g_new0 (MonoJitICallInfo, 1);
7567 info->wrapper = func;
7569 info->wrapper = NULL;
7572 g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
7573 g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
7575 mono_loader_unlock ();