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 get_caller (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1057 MonoMethod **dest = data;
1059 /* skip unmanaged frames */
1074 static MonoReflectionType *
1075 type_from_name (const char *str, MonoBoolean ignoreCase)
1077 MonoType *type = NULL;
1078 MonoAssembly *assembly = NULL;
1079 MonoTypeNameParse info;
1080 char *temp_str = g_strdup (str);
1081 gboolean type_resolve = FALSE;
1083 MONO_ARCH_SAVE_REGS;
1085 /* mono_reflection_parse_type() mangles the string */
1086 if (!mono_reflection_parse_type (temp_str, &info)) {
1087 mono_reflection_free_type_info (&info);
1092 if (info.assembly.name) {
1093 assembly = mono_assembly_load (&info.assembly, NULL, NULL);
1095 MonoMethod *m = mono_method_get_last_managed ();
1096 MonoMethod *dest = m;
1098 mono_stack_walk_no_il (get_caller, &dest);
1103 * FIXME: mono_method_get_last_managed() sometimes returns NULL, thus
1104 * causing ves_icall_System_Reflection_Assembly_GetCallingAssembly()
1105 * to crash. This only seems to happen in some strange remoting
1106 * scenarios and I was unable to figure out what's happening there.
1107 * Dec 10, 2005 - Martin.
1111 assembly = dest->klass->image->assembly;
1113 g_warning (G_STRLOC);
1118 type = mono_reflection_get_type (assembly->image, &info, ignoreCase, &type_resolve);
1120 if (!info.assembly.name && !type) /* try mscorlib */
1121 type = mono_reflection_get_type (NULL, &info, ignoreCase, &type_resolve);
1123 mono_reflection_free_type_info (&info);
1129 return mono_type_get_object (mono_domain_get (), type);
1133 MonoReflectionType *
1134 mono_type_get (const char *str)
1136 char *copy = g_strdup (str);
1137 MonoReflectionType *type = type_from_name (copy, FALSE);
1144 static MonoReflectionType*
1145 ves_icall_type_from_name (MonoString *name,
1146 MonoBoolean throwOnError,
1147 MonoBoolean ignoreCase)
1149 char *str = mono_string_to_utf8 (name);
1150 MonoReflectionType *type;
1152 type = type_from_name (str, ignoreCase);
1155 MonoException *e = NULL;
1158 e = mono_get_exception_type_load (name, NULL);
1160 mono_loader_clear_error ();
1162 mono_raise_exception (e);
1169 static MonoReflectionType*
1170 ves_icall_type_from_handle (MonoType *handle)
1172 MonoDomain *domain = mono_domain_get ();
1173 MonoClass *klass = mono_class_from_mono_type (handle);
1175 MONO_ARCH_SAVE_REGS;
1177 mono_class_init (klass);
1178 return mono_type_get_object (domain, handle);
1182 ves_icall_System_Type_EqualsInternal (MonoReflectionType *type, MonoReflectionType *c)
1184 MONO_ARCH_SAVE_REGS;
1186 if (c && type->type && c->type)
1187 return mono_metadata_type_equal (type->type, c->type);
1192 /* System.TypeCode */
1211 TYPECODE_STRING = 18
1215 ves_icall_type_GetTypeCodeInternal (MonoReflectionType *type)
1217 int t = type->type->type;
1219 MONO_ARCH_SAVE_REGS;
1221 if (type->type->byref)
1222 return TYPECODE_OBJECT;
1226 case MONO_TYPE_VOID:
1227 return TYPECODE_OBJECT;
1228 case MONO_TYPE_BOOLEAN:
1229 return TYPECODE_BOOLEAN;
1231 return TYPECODE_BYTE;
1233 return TYPECODE_SBYTE;
1235 return TYPECODE_UINT16;
1237 return TYPECODE_INT16;
1238 case MONO_TYPE_CHAR:
1239 return TYPECODE_CHAR;
1243 return TYPECODE_OBJECT;
1245 return TYPECODE_UINT32;
1247 return TYPECODE_INT32;
1249 return TYPECODE_UINT64;
1251 return TYPECODE_INT64;
1253 return TYPECODE_SINGLE;
1255 return TYPECODE_DOUBLE;
1256 case MONO_TYPE_VALUETYPE:
1257 if (type->type->data.klass->enumtype) {
1258 t = type->type->data.klass->enum_basetype->type;
1261 MonoClass *k = type->type->data.klass;
1262 if (strcmp (k->name_space, "System") == 0) {
1263 if (strcmp (k->name, "Decimal") == 0)
1264 return TYPECODE_DECIMAL;
1265 else if (strcmp (k->name, "DateTime") == 0)
1266 return TYPECODE_DATETIME;
1269 return TYPECODE_OBJECT;
1270 case MONO_TYPE_STRING:
1271 return TYPECODE_STRING;
1272 case MONO_TYPE_SZARRAY:
1273 case MONO_TYPE_ARRAY:
1274 case MONO_TYPE_OBJECT:
1276 case MONO_TYPE_MVAR:
1277 case MONO_TYPE_TYPEDBYREF:
1278 return TYPECODE_OBJECT;
1279 case MONO_TYPE_CLASS:
1281 MonoClass *k = type->type->data.klass;
1282 if (strcmp (k->name_space, "System") == 0) {
1283 if (strcmp (k->name, "DBNull") == 0)
1284 return TYPECODE_DBNULL;
1287 return TYPECODE_OBJECT;
1288 case MONO_TYPE_GENERICINST:
1289 return TYPECODE_OBJECT;
1291 g_error ("type 0x%02x not handled in GetTypeCode()", t);
1297 ves_icall_type_is_subtype_of (MonoReflectionType *type, MonoReflectionType *c, MonoBoolean check_interfaces)
1303 MONO_ARCH_SAVE_REGS;
1305 g_assert (type != NULL);
1307 domain = ((MonoObject *)type)->vtable->domain;
1309 if (!c) /* FIXME: dont know what do do here */
1312 klass = mono_class_from_mono_type (type->type);
1313 klassc = mono_class_from_mono_type (c->type);
1315 if (type->type->byref)
1316 return klassc == mono_defaults.object_class;
1318 return mono_class_is_subclass_of (klass, klassc, check_interfaces);
1322 ves_icall_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType *c)
1328 MONO_ARCH_SAVE_REGS;
1330 g_assert (type != NULL);
1332 domain = ((MonoObject *)type)->vtable->domain;
1334 klass = mono_class_from_mono_type (type->type);
1335 klassc = mono_class_from_mono_type (c->type);
1337 if (type->type->byref && !c->type->byref)
1340 return mono_class_is_assignable_from (klass, klassc);
1344 ves_icall_type_IsInstanceOfType (MonoReflectionType *type, MonoObject *obj)
1346 MonoClass *klass = mono_class_from_mono_type (type->type);
1347 return mono_object_isinst (obj, klass) != NULL;
1351 ves_icall_get_attributes (MonoReflectionType *type)
1353 MonoClass *klass = mono_class_from_mono_type (type->type);
1355 MONO_ARCH_SAVE_REGS;
1357 return klass->flags;
1360 static MonoReflectionMarshal*
1361 ves_icall_System_Reflection_FieldInfo_GetUnmanagedMarshal (MonoReflectionField *field)
1363 MonoClass *klass = field->field->parent;
1364 MonoMarshalType *info;
1367 if (klass->generic_container ||
1368 (klass->generic_class && klass->generic_class->context.class_inst->is_open))
1371 info = mono_marshal_load_type_info (klass);
1373 for (i = 0; i < info->num_fields; ++i) {
1374 if (info->fields [i].field == field->field) {
1375 if (!info->fields [i].mspec)
1378 return mono_reflection_marshal_from_marshal_spec (field->object.vtable->domain, klass, info->fields [i].mspec);
1385 static MonoReflectionField*
1386 ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoClass *klass)
1391 klass = handle->parent;
1393 /* FIXME: check that handle is a field of klass or of a parent: return null
1394 * and throw the exception in managed code.
1396 return mono_field_get_object (mono_domain_get (), klass, handle);
1399 static MonoReflectionField*
1400 ves_icall_System_Reflection_FieldInfo_internal_from_handle (MonoClassField *handle)
1402 MONO_ARCH_SAVE_REGS;
1406 return mono_field_get_object (mono_domain_get (), handle->parent, handle);
1410 ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionField *field, MonoBoolean optional)
1412 MonoType *type = field->field->type;
1414 return type_array_from_modifiers (field->field->parent->image, type, optional);
1418 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
1420 MonoDomain *domain = mono_domain_get ();
1421 MonoMethodSignature* sig;
1422 MONO_ARCH_SAVE_REGS;
1424 sig = mono_method_signature (method);
1426 g_assert (mono_loader_get_last_error ());
1427 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
1430 info->parent = mono_type_get_object (domain, &method->klass->byval_arg);
1431 info->ret = mono_type_get_object (domain, sig->ret);
1432 info->attrs = method->flags;
1433 info->implattrs = method->iflags;
1434 if (sig->call_convention == MONO_CALL_DEFAULT)
1437 if (sig->call_convention == MONO_CALL_VARARG)
1442 info->callconv |= (sig->hasthis << 5) | (sig->explicit_this << 6);
1446 ves_icall_get_parameter_info (MonoMethod *method)
1448 MonoDomain *domain = mono_domain_get ();
1450 return mono_param_get_objects (domain, method);
1453 static MonoReflectionMarshal*
1454 ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod *method)
1456 MonoDomain *domain = mono_domain_get ();
1457 MonoReflectionMarshal* res = NULL;
1458 MonoMarshalSpec **mspecs;
1461 mspecs = g_new (MonoMarshalSpec*, mono_method_signature (method)->param_count + 1);
1462 mono_method_get_marshal_info (method, mspecs);
1465 res = mono_reflection_marshal_from_marshal_spec (domain, method->klass, mspecs [0]);
1467 for (i = mono_method_signature (method)->param_count; i >= 0; i--)
1469 mono_metadata_free_marshal_spec (mspecs [i]);
1476 ves_icall_MonoField_GetFieldOffset (MonoReflectionField *field)
1478 return field->field->offset - sizeof (MonoObject);
1481 static MonoReflectionType*
1482 ves_icall_MonoField_GetParentType (MonoReflectionField *field, MonoBoolean declaring)
1485 MONO_ARCH_SAVE_REGS;
1487 parent = declaring? field->field->parent: field->klass;
1489 return mono_type_get_object (mono_object_domain (field), &parent->byval_arg);
1493 ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj)
1496 MonoClassField *cf = field->field;
1500 MonoDomain *domain = mono_object_domain (field);
1502 gboolean is_static = FALSE;
1503 gboolean is_ref = FALSE;
1505 MONO_ARCH_SAVE_REGS;
1507 if (field->klass->image->assembly->ref_only)
1508 mono_raise_exception (mono_get_exception_invalid_operation (
1509 "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
1511 mono_class_init (field->klass);
1513 if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC)
1516 if (obj && !is_static) {
1517 /* Check that the field belongs to the object */
1518 gboolean found = FALSE;
1521 for (k = obj->vtable->klass; k; k = k->parent) {
1522 if (k == cf->parent) {
1529 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);
1530 MonoException *ex = mono_get_exception_argument (NULL, msg);
1532 mono_raise_exception (ex);
1536 t = mono_type_get_underlying_type (cf->type);
1538 case MONO_TYPE_STRING:
1539 case MONO_TYPE_OBJECT:
1540 case MONO_TYPE_CLASS:
1541 case MONO_TYPE_ARRAY:
1542 case MONO_TYPE_SZARRAY:
1547 case MONO_TYPE_BOOLEAN:
1550 case MONO_TYPE_CHAR:
1559 case MONO_TYPE_VALUETYPE:
1562 case MONO_TYPE_GENERICINST:
1563 if (mono_type_generic_inst_is_valuetype (t)) {
1570 g_error ("type 0x%x not handled in "
1571 "ves_icall_Monofield_GetValue", t->type);
1577 vtable = mono_class_vtable (domain, cf->parent);
1578 if (!vtable->initialized && !(cf->type->attrs & FIELD_ATTRIBUTE_LITERAL))
1579 mono_runtime_class_init (vtable);
1584 mono_field_static_get_value (vtable, cf, &o);
1586 mono_field_get_value (obj, cf, &o);
1591 if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) {
1592 MonoClass *nklass = mono_class_from_mono_type (cf->type);
1595 /* Convert the Nullable structure into a boxed vtype */
1597 buf = (guint8*)vtable->data + cf->offset;
1599 buf = (guint8*)obj + cf->offset;
1601 return mono_nullable_box (buf, nklass);
1604 /* boxed value type */
1605 klass = mono_class_from_mono_type (cf->type);
1606 o = mono_object_new (domain, klass);
1607 v = ((gchar *) o) + sizeof (MonoObject);
1609 mono_field_static_get_value (vtable, cf, v);
1611 mono_field_get_value (obj, cf, v);
1618 ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value)
1620 MonoClassField *cf = field->field;
1623 MONO_ARCH_SAVE_REGS;
1625 if (field->klass->image->assembly->ref_only)
1626 mono_raise_exception (mono_get_exception_invalid_operation (
1627 "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
1629 v = (gchar *) value;
1630 if (!cf->type->byref) {
1631 switch (cf->type->type) {
1634 case MONO_TYPE_BOOLEAN:
1637 case MONO_TYPE_CHAR:
1646 case MONO_TYPE_VALUETYPE:
1648 v += sizeof (MonoObject);
1650 case MONO_TYPE_STRING:
1651 case MONO_TYPE_OBJECT:
1652 case MONO_TYPE_CLASS:
1653 case MONO_TYPE_ARRAY:
1654 case MONO_TYPE_SZARRAY:
1657 case MONO_TYPE_GENERICINST: {
1658 MonoGenericClass *gclass = cf->type->data.generic_class;
1659 g_assert (!gclass->context.class_inst->is_open);
1661 if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) {
1662 MonoClass *nklass = mono_class_from_mono_type (cf->type);
1663 MonoObject *nullable;
1666 * Convert the boxed vtype into a Nullable structure.
1667 * This is complicated by the fact that Nullables have
1668 * a variable structure.
1670 nullable = mono_object_new (mono_domain_get (), nklass);
1672 mono_nullable_init (mono_object_unbox (nullable), value, nklass);
1674 v = mono_object_unbox (nullable);
1677 if (gclass->container_class->valuetype && (v != NULL))
1678 v += sizeof (MonoObject);
1682 g_error ("type 0x%x not handled in "
1683 "ves_icall_FieldInfo_SetValueInternal", cf->type->type);
1688 if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) {
1689 MonoVTable *vtable = mono_class_vtable (mono_object_domain (field), cf->parent);
1690 if (!vtable->initialized)
1691 mono_runtime_class_init (vtable);
1692 mono_field_static_set_value (vtable, cf, v);
1694 mono_field_set_value (obj, cf, v);
1699 ves_icall_MonoField_GetRawConstantValue (MonoReflectionField *this)
1701 MonoObject *o = NULL;
1702 MonoClassField *field = this->field;
1704 MonoDomain *domain = mono_object_domain (this);
1706 MonoTypeEnum def_type;
1707 const char *def_value;
1709 MONO_ARCH_SAVE_REGS;
1711 mono_class_init (field->parent);
1713 if (!(field->type->attrs & FIELD_ATTRIBUTE_HAS_DEFAULT))
1714 mono_raise_exception (mono_get_exception_invalid_operation (NULL));
1716 if (field->parent->image->dynamic) {
1718 g_assert_not_reached ();
1721 def_value = mono_class_get_field_default_value (field, &def_type);
1726 case MONO_TYPE_BOOLEAN:
1729 case MONO_TYPE_CHAR:
1737 case MONO_TYPE_R8: {
1740 /* boxed value type */
1741 t = g_new0 (MonoType, 1);
1743 klass = mono_class_from_mono_type (t);
1745 o = mono_object_new (domain, klass);
1746 v = ((gchar *) o) + sizeof (MonoObject);
1747 mono_get_constant_value_from_blob (domain, def_type, def_value, v);
1750 case MONO_TYPE_STRING:
1751 case MONO_TYPE_CLASS:
1752 mono_get_constant_value_from_blob (domain, def_type, def_value, &o);
1755 g_assert_not_reached ();
1761 static MonoReflectionType*
1762 ves_icall_MonoGenericMethod_get_ReflectedType (MonoReflectionGenericMethod *rmethod)
1764 MonoMethod *method = rmethod->method.method;
1766 return mono_type_get_object (mono_object_domain (rmethod), &method->klass->byval_arg);
1769 /* From MonoProperty.cs */
1771 PInfo_Attributes = 1,
1772 PInfo_GetMethod = 1 << 1,
1773 PInfo_SetMethod = 1 << 2,
1774 PInfo_ReflectedType = 1 << 3,
1775 PInfo_DeclaringType = 1 << 4,
1780 ves_icall_get_property_info (MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
1782 MonoDomain *domain = mono_object_domain (property);
1784 MONO_ARCH_SAVE_REGS;
1786 if ((req_info & PInfo_ReflectedType) != 0)
1787 MONO_STRUCT_SETREF (info, parent, mono_type_get_object (domain, &property->klass->byval_arg));
1788 else if ((req_info & PInfo_DeclaringType) != 0)
1789 MONO_STRUCT_SETREF (info, parent, mono_type_get_object (domain, &property->property->parent->byval_arg));
1791 if ((req_info & PInfo_Name) != 0)
1792 MONO_STRUCT_SETREF (info, name, mono_string_new (domain, property->property->name));
1794 if ((req_info & PInfo_Attributes) != 0)
1795 info->attrs = property->property->attrs;
1797 if ((req_info & PInfo_GetMethod) != 0)
1798 MONO_STRUCT_SETREF (info, get, property->property->get ?
1799 mono_method_get_object (domain, property->property->get, property->klass): NULL);
1801 if ((req_info & PInfo_SetMethod) != 0)
1802 MONO_STRUCT_SETREF (info, set, property->property->set ?
1803 mono_method_get_object (domain, property->property->set, property->klass): NULL);
1805 * There may be other methods defined for properties, though, it seems they are not exposed
1806 * in the reflection API
1811 ves_icall_get_event_info (MonoReflectionEvent *event, MonoEventInfo *info)
1813 MonoDomain *domain = mono_object_domain (event);
1815 MONO_ARCH_SAVE_REGS;
1817 info->reflected_type = mono_type_get_object (domain, &event->klass->byval_arg);
1818 info->declaring_type = mono_type_get_object (domain, &event->event->parent->byval_arg);
1820 info->name = mono_string_new (domain, event->event->name);
1821 info->attrs = event->event->attrs;
1822 info->add_method = event->event->add ? mono_method_get_object (domain, event->event->add, NULL): NULL;
1823 info->remove_method = event->event->remove ? mono_method_get_object (domain, event->event->remove, NULL): NULL;
1824 info->raise_method = event->event->raise ? mono_method_get_object (domain, event->event->raise, NULL): NULL;
1826 if (event->event->other) {
1828 while (event->event->other [n])
1830 info->other_methods = mono_array_new (domain, mono_defaults.method_info_class, n);
1832 for (i = 0; i < n; i++)
1833 mono_array_setref (info->other_methods, i, mono_method_get_object (domain, event->event->other [i], NULL));
1838 ves_icall_Type_GetInterfaces (MonoReflectionType* type)
1840 MonoDomain *domain = mono_object_domain (type);
1842 GPtrArray *ifaces = NULL;
1844 MonoClass *class = mono_class_from_mono_type (type->type);
1847 MonoGenericContext *context = NULL;
1849 MONO_ARCH_SAVE_REGS;
1851 if (class->generic_class && class->generic_class->context.class_inst->is_open) {
1852 context = mono_class_get_context (class);
1853 class = class->generic_class->container_class;
1856 mono_class_setup_vtable (class);
1858 slots = mono_bitset_new (class->max_interface_id + 1, 0);
1860 for (parent = class; parent; parent = parent->parent) {
1861 GPtrArray *tmp_ifaces = mono_class_get_implemented_interfaces (parent);
1863 for (i = 0; i < tmp_ifaces->len; ++i) {
1864 MonoClass *ic = g_ptr_array_index (tmp_ifaces, i);
1866 if (mono_bitset_test (slots, ic->interface_id))
1869 mono_bitset_set (slots, ic->interface_id);
1871 ifaces = g_ptr_array_new ();
1872 g_ptr_array_add (ifaces, ic);
1874 g_ptr_array_free (tmp_ifaces, TRUE);
1877 mono_bitset_free (slots);
1880 return mono_array_new (domain, mono_defaults.monotype_class, 0);
1882 intf = mono_array_new (domain, mono_defaults.monotype_class, ifaces->len);
1883 for (i = 0; i < ifaces->len; ++i) {
1884 MonoClass *ic = g_ptr_array_index (ifaces, i);
1885 MonoType *ret = &ic->byval_arg;
1886 if (context && ic->generic_class && ic->generic_class->context.class_inst->is_open)
1887 ret = mono_class_inflate_generic_type (ret, context);
1889 mono_array_setref (intf, i, mono_type_get_object (domain, ret));
1891 g_ptr_array_free (ifaces, TRUE);
1897 ves_icall_Type_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType *iface, MonoArray **targets, MonoArray **methods)
1899 MonoClass *class = mono_class_from_mono_type (type->type);
1900 MonoClass *iclass = mono_class_from_mono_type (iface->type);
1901 MonoReflectionMethod *member;
1904 int i = 0, len, ioffset;
1907 MONO_ARCH_SAVE_REGS;
1909 mono_class_setup_vtable (class);
1911 /* type doesn't implement iface: the exception is thrown in managed code */
1912 if (! MONO_CLASS_IMPLEMENTS_INTERFACE (class, iclass->interface_id))
1915 len = mono_class_num_methods (iclass);
1916 ioffset = mono_class_interface_offset (class, iclass);
1917 domain = mono_object_domain (type);
1918 *targets = mono_array_new (domain, mono_defaults.method_info_class, len);
1919 *methods = mono_array_new (domain, mono_defaults.method_info_class, len);
1922 while ((method = mono_class_get_methods (iclass, &iter))) {
1923 member = mono_method_get_object (domain, method, iclass);
1924 mono_array_setref (*methods, i, member);
1925 member = mono_method_get_object (domain, class->vtable [i + ioffset], class);
1926 mono_array_setref (*targets, i, member);
1933 ves_icall_Type_GetPacking (MonoReflectionType *type, guint32 *packing, guint32 *size)
1935 MonoClass *klass = mono_class_from_mono_type (type->type);
1937 if (klass->image->dynamic) {
1938 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)type;
1939 *packing = tb->packing_size;
1940 *size = tb->class_size;
1942 mono_metadata_packing_from_typedef (klass->image, klass->type_token, packing, size);
1946 static MonoReflectionType*
1947 ves_icall_MonoType_GetElementType (MonoReflectionType *type)
1949 MonoClass *class = mono_class_from_mono_type (type->type);
1951 MONO_ARCH_SAVE_REGS;
1953 // GetElementType should only return a type for:
1954 // Array Pointer PassedByRef
1955 if (type->type->byref)
1956 return mono_type_get_object (mono_object_domain (type), &class->byval_arg);
1957 else if (class->element_class && MONO_CLASS_IS_ARRAY (class))
1958 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
1959 else if (class->element_class && type->type->type == MONO_TYPE_PTR)
1960 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
1965 static MonoReflectionType*
1966 ves_icall_get_type_parent (MonoReflectionType *type)
1968 MonoClass *class = mono_class_from_mono_type (type->type);
1970 MONO_ARCH_SAVE_REGS;
1972 return class->parent ? mono_type_get_object (mono_object_domain (type), &class->parent->byval_arg): NULL;
1976 ves_icall_type_ispointer (MonoReflectionType *type)
1978 MONO_ARCH_SAVE_REGS;
1980 return type->type->type == MONO_TYPE_PTR;
1984 ves_icall_type_isprimitive (MonoReflectionType *type)
1986 MONO_ARCH_SAVE_REGS;
1988 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)));
1992 ves_icall_type_isbyref (MonoReflectionType *type)
1994 MONO_ARCH_SAVE_REGS;
1996 return type->type->byref;
2000 ves_icall_type_iscomobject (MonoReflectionType *type)
2002 MonoClass *klass = mono_class_from_mono_type (type->type);
2003 MONO_ARCH_SAVE_REGS;
2005 return (klass && klass->is_com_object);
2008 static MonoReflectionModule*
2009 ves_icall_MonoType_get_Module (MonoReflectionType *type)
2011 MonoClass *class = mono_class_from_mono_type (type->type);
2013 MONO_ARCH_SAVE_REGS;
2015 return mono_module_get_object (mono_object_domain (type), class->image);
2018 static MonoReflectionAssembly*
2019 ves_icall_MonoType_get_Assembly (MonoReflectionType *type)
2021 MonoDomain *domain = mono_domain_get ();
2022 MonoClass *class = mono_class_from_mono_type (type->type);
2024 MONO_ARCH_SAVE_REGS;
2026 return mono_assembly_get_object (domain, class->image->assembly);
2029 static MonoReflectionType*
2030 ves_icall_MonoType_get_DeclaringType (MonoReflectionType *type)
2032 MonoDomain *domain = mono_domain_get ();
2035 MONO_ARCH_SAVE_REGS;
2037 if (type->type->byref)
2039 if (type->type->type == MONO_TYPE_VAR)
2040 class = type->type->data.generic_param->owner->owner.klass;
2041 else if (type->type->type == MONO_TYPE_MVAR)
2042 class = type->type->data.generic_param->owner->owner.method->klass;
2044 class = mono_class_from_mono_type (type->type)->nested_in;
2046 return class ? mono_type_get_object (domain, &class->byval_arg) : NULL;
2049 static MonoReflectionType*
2050 ves_icall_MonoType_get_UnderlyingSystemType (MonoReflectionType *type)
2052 MonoDomain *domain = mono_domain_get ();
2053 MonoClass *class = mono_class_from_mono_type (type->type);
2055 MONO_ARCH_SAVE_REGS;
2057 if (class->enumtype && class->enum_basetype) /* types that are modified typebuilders may not have enum_basetype set */
2058 return mono_type_get_object (domain, class->enum_basetype);
2059 else if (class->element_class)
2060 return mono_type_get_object (domain, &class->element_class->byval_arg);
2066 ves_icall_MonoType_get_Name (MonoReflectionType *type)
2068 MonoDomain *domain = mono_domain_get ();
2069 MonoClass *class = mono_class_from_mono_type (type->type);
2071 MONO_ARCH_SAVE_REGS;
2073 if (type->type->byref) {
2074 char *n = g_strdup_printf ("%s&", class->name);
2075 MonoString *res = mono_string_new (domain, n);
2081 return mono_string_new (domain, class->name);
2086 ves_icall_MonoType_get_Namespace (MonoReflectionType *type)
2088 MonoDomain *domain = mono_domain_get ();
2089 MonoClass *class = mono_class_from_mono_type (type->type);
2091 MONO_ARCH_SAVE_REGS;
2093 while (class->nested_in)
2094 class = class->nested_in;
2096 if (class->name_space [0] == '\0')
2099 return mono_string_new (domain, class->name_space);
2103 ves_icall_MonoType_GetArrayRank (MonoReflectionType *type)
2105 MonoClass *class = mono_class_from_mono_type (type->type);
2107 MONO_ARCH_SAVE_REGS;
2113 ves_icall_MonoType_GetGenericArguments (MonoReflectionType *type)
2116 MonoClass *klass, *pklass;
2118 MONO_ARCH_SAVE_REGS;
2120 klass = mono_class_from_mono_type (type->type);
2122 if (klass->generic_container) {
2123 MonoGenericContainer *container = klass->generic_container;
2124 res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, container->type_argc);
2125 for (i = 0; i < container->type_argc; ++i) {
2126 pklass = mono_class_from_generic_parameter (&container->type_params [i], klass->image, FALSE);
2127 mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), &pklass->byval_arg));
2129 } else if (klass->generic_class) {
2130 MonoGenericInst *inst = klass->generic_class->context.class_inst;
2131 res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, inst->type_argc);
2132 for (i = 0; i < inst->type_argc; ++i)
2133 mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), inst->type_argv [i]));
2135 res = mono_array_new (mono_object_domain (type), mono_defaults.systemtype_class, 0);
2141 ves_icall_Type_get_IsGenericTypeDefinition (MonoReflectionType *type)
2144 MONO_ARCH_SAVE_REGS;
2146 if (type->type->byref)
2149 klass = mono_class_from_mono_type (type->type);
2151 return klass->generic_container != NULL;
2154 static MonoReflectionType*
2155 ves_icall_Type_GetGenericTypeDefinition_impl (MonoReflectionType *type)
2158 MONO_ARCH_SAVE_REGS;
2160 if (type->type->byref)
2163 klass = mono_class_from_mono_type (type->type);
2164 if (klass->generic_container) {
2165 return type; /* check this one */
2167 if (klass->generic_class) {
2168 MonoClass *generic_class = klass->generic_class->container_class;
2170 if (generic_class->wastypebuilder && generic_class->reflection_info)
2171 return generic_class->reflection_info;
2173 return mono_type_get_object (mono_object_domain (type), &generic_class->byval_arg);
2178 static MonoReflectionType*
2179 ves_icall_Type_MakeGenericType (MonoReflectionType *type, MonoArray *type_array)
2181 MonoType *geninst, **types;
2184 MONO_ARCH_SAVE_REGS;
2186 count = mono_array_length (type_array);
2187 types = g_new0 (MonoType *, count);
2189 for (i = 0; i < count; i++) {
2190 MonoReflectionType *t = mono_array_get (type_array, gpointer, i);
2191 types [i] = t->type;
2194 geninst = mono_reflection_bind_generic_parameters (type, count, types);
2199 return mono_type_get_object (mono_object_domain (type), geninst);
2203 ves_icall_Type_get_IsGenericInstance (MonoReflectionType *type)
2206 MONO_ARCH_SAVE_REGS;
2208 if (type->type->byref)
2211 klass = mono_class_from_mono_type (type->type);
2212 return klass->generic_class != NULL;
2216 ves_icall_Type_get_IsGenericType (MonoReflectionType *type)
2219 MONO_ARCH_SAVE_REGS;
2221 if (type->type->byref)
2224 klass = mono_class_from_mono_type (type->type);
2225 return klass->generic_class != NULL || klass->generic_container != NULL;
2229 ves_icall_Type_GetGenericParameterPosition (MonoReflectionType *type)
2231 MONO_ARCH_SAVE_REGS;
2233 if (is_generic_parameter (type->type))
2234 return type->type->data.generic_param->num;
2238 static GenericParameterAttributes
2239 ves_icall_Type_GetGenericParameterAttributes (MonoReflectionType *type)
2241 MONO_ARCH_SAVE_REGS;
2242 g_assert (is_generic_parameter (type->type));
2243 return type->type->data.generic_param->flags;
2247 ves_icall_Type_GetGenericParameterConstraints (MonoReflectionType *type)
2249 MonoGenericParam *param;
2255 MONO_ARCH_SAVE_REGS;
2257 domain = mono_object_domain (type);
2258 param = type->type->data.generic_param;
2259 for (count = 0, ptr = param->constraints; ptr && *ptr; ptr++, count++)
2262 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2263 for (i = 0; i < count; i++)
2264 mono_array_setref (res, i, mono_type_get_object (domain, ¶m->constraints [i]->byval_arg));
2271 ves_icall_MonoType_get_IsGenericParameter (MonoReflectionType *type)
2273 MONO_ARCH_SAVE_REGS;
2274 return is_generic_parameter (type->type);
2278 ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder *tb)
2280 MONO_ARCH_SAVE_REGS;
2281 return is_generic_parameter (tb->type.type);
2285 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
2286 MonoReflectionType *t)
2288 enumtype->type = t->type;
2291 static MonoReflectionType*
2292 ves_icall_MonoGenericClass_GetParentType (MonoReflectionGenericClass *type)
2294 MonoDynamicGenericClass *gclass;
2295 MonoReflectionType *parent = NULL;
2300 MONO_ARCH_SAVE_REGS;
2302 g_assert (type->type.type->data.generic_class->is_dynamic);
2303 gclass = (MonoDynamicGenericClass *) type->type.type->data.generic_class;
2305 domain = mono_object_domain (type);
2306 klass = mono_class_from_mono_type (type->generic_type->type.type);
2308 if (!klass->generic_class && !klass->generic_container)
2311 parent = type->generic_type->parent;
2313 if (!parent || (parent->type->type != MONO_TYPE_GENERICINST))
2316 inflated = mono_class_inflate_generic_type (
2317 parent->type, mono_generic_class_get_context ((MonoGenericClass *) gclass));
2319 return mono_type_get_object (domain, inflated);
2323 ves_icall_MonoGenericClass_GetInterfaces (MonoReflectionGenericClass *type)
2325 static MonoClass *System_Reflection_MonoGenericClass;
2326 MonoGenericClass *gclass;
2327 MonoReflectionTypeBuilder *tb = NULL;
2328 MonoClass *klass = NULL;
2333 MONO_ARCH_SAVE_REGS;
2335 if (!System_Reflection_MonoGenericClass) {
2336 System_Reflection_MonoGenericClass = mono_class_from_name (
2337 mono_defaults.corlib, "System.Reflection", "MonoGenericClass");
2338 g_assert (System_Reflection_MonoGenericClass);
2341 domain = mono_object_domain (type);
2343 gclass = type->type.type->data.generic_class;
2344 g_assert (gclass->is_dynamic);
2346 tb = type->generic_type;
2347 icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
2349 res = mono_array_new (domain, System_Reflection_MonoGenericClass, icount);
2351 for (i = 0; i < icount; i++) {
2352 MonoReflectionType *iface;
2356 iface = mono_array_get (tb->interfaces, MonoReflectionType *, i);
2359 it = &klass->interfaces [i]->byval_arg;
2361 it = mono_class_inflate_generic_type (it, mono_generic_class_get_context (gclass));
2363 iface = mono_type_get_object (domain, it);
2364 mono_array_setref (res, i, iface);
2370 static MonoReflectionMethod*
2371 ves_icall_MonoGenericClass_GetCorrespondingInflatedMethod (MonoReflectionGenericClass *type,
2372 MonoReflectionMethod* generic)
2374 MonoGenericClass *gclass;
2375 MonoDynamicGenericClass *dgclass;
2379 MONO_ARCH_SAVE_REGS;
2381 gclass = type->type.type->data.generic_class;
2382 g_assert (gclass->is_dynamic);
2384 dgclass = (MonoDynamicGenericClass *) gclass;
2386 domain = mono_object_domain (type);
2388 for (i = 0; i < dgclass->count_methods; i++)
2389 if (generic->method->token == dgclass->methods [i]->token)
2390 return mono_method_get_object (domain, dgclass->methods [i], NULL);
2395 static MonoReflectionMethod*
2396 ves_icall_MonoGenericClass_GetCorrespondingInflatedConstructor (MonoReflectionGenericClass *type,
2397 MonoReflectionMethod* generic)
2399 MonoGenericClass *gclass;
2400 MonoDynamicGenericClass *dgclass;
2404 MONO_ARCH_SAVE_REGS;
2406 gclass = type->type.type->data.generic_class;
2407 g_assert (gclass->is_dynamic);
2409 dgclass = (MonoDynamicGenericClass *) gclass;
2411 domain = mono_object_domain (type);
2413 for (i = 0; i < dgclass->count_ctors; i++)
2414 if (generic->method->token == dgclass->ctors [i]->token)
2415 return mono_method_get_object (domain, dgclass->ctors [i], NULL);
2421 static MonoReflectionField*
2422 ves_icall_MonoGenericClass_GetCorrespondingInflatedField (MonoReflectionGenericClass *type,
2423 MonoString* generic_name)
2425 MonoGenericClass *gclass;
2426 MonoDynamicGenericClass *dgclass;
2428 MonoClass *refclass;
2429 char *utf8_name = mono_string_to_utf8 (generic_name);
2432 MONO_ARCH_SAVE_REGS;
2434 gclass = type->type.type->data.generic_class;
2435 g_assert (gclass->is_dynamic);
2437 dgclass = (MonoDynamicGenericClass *) gclass;
2439 refclass = mono_class_from_mono_type (type->type.type);
2441 domain = mono_object_domain (type);
2443 for (i = 0; i < dgclass->count_fields; i++)
2444 if (strcmp (utf8_name, dgclass->fields [i].name) == 0) {
2446 return mono_field_get_object (domain, refclass, &dgclass->fields [i]);
2455 static MonoReflectionMethod*
2456 ves_icall_MonoType_GetCorrespondingInflatedMethod (MonoReflectionType *type,
2457 MonoReflectionMethod* generic)
2464 MONO_ARCH_SAVE_REGS;
2466 domain = ((MonoObject *)type)->vtable->domain;
2468 klass = mono_class_from_mono_type (type->type);
2471 while ((method = mono_class_get_methods (klass, &iter))) {
2472 if (method->token == generic->method->token)
2473 return mono_method_get_object (domain, method, klass);
2480 ves_icall_MonoGenericClass_GetMethods (MonoReflectionGenericClass *type,
2481 MonoReflectionType *reflected_type)
2483 MonoGenericClass *gclass;
2484 MonoDynamicGenericClass *dgclass;
2486 MonoClass *refclass;
2490 MONO_ARCH_SAVE_REGS;
2492 gclass = type->type.type->data.generic_class;
2493 g_assert (gclass->is_dynamic);
2494 dgclass = (MonoDynamicGenericClass *) gclass;
2496 refclass = mono_class_from_mono_type (reflected_type->type);
2498 domain = mono_object_domain (type);
2499 res = mono_array_new (domain, mono_defaults.method_info_class, dgclass->count_methods);
2501 for (i = 0; i < dgclass->count_methods; i++)
2502 mono_array_setref (res, i, mono_method_get_object (domain, dgclass->methods [i], refclass));
2508 ves_icall_MonoGenericClass_GetConstructors (MonoReflectionGenericClass *type,
2509 MonoReflectionType *reflected_type)
2511 static MonoClass *System_Reflection_ConstructorInfo;
2512 MonoGenericClass *gclass;
2513 MonoDynamicGenericClass *dgclass;
2515 MonoClass *refclass;
2519 MONO_ARCH_SAVE_REGS;
2521 if (!System_Reflection_ConstructorInfo)
2522 System_Reflection_ConstructorInfo = mono_class_from_name (
2523 mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
2525 gclass = type->type.type->data.generic_class;
2526 g_assert (gclass->is_dynamic);
2527 dgclass = (MonoDynamicGenericClass *) gclass;
2529 refclass = mono_class_from_mono_type (reflected_type->type);
2531 domain = mono_object_domain (type);
2532 res = mono_array_new (domain, System_Reflection_ConstructorInfo, dgclass->count_ctors);
2534 for (i = 0; i < dgclass->count_ctors; i++)
2535 mono_array_setref (res, i, mono_method_get_object (domain, dgclass->ctors [i], refclass));
2541 ves_icall_MonoGenericClass_GetFields (MonoReflectionGenericClass *type,
2542 MonoReflectionType *reflected_type)
2544 MonoGenericClass *gclass;
2545 MonoDynamicGenericClass *dgclass;
2547 MonoClass *refclass;
2551 MONO_ARCH_SAVE_REGS;
2553 gclass = type->type.type->data.generic_class;
2554 g_assert (gclass->is_dynamic);
2555 dgclass = (MonoDynamicGenericClass *) gclass;
2557 refclass = mono_class_from_mono_type (reflected_type->type);
2559 domain = mono_object_domain (type);
2560 res = mono_array_new (domain, mono_defaults.field_info_class, dgclass->count_fields);
2562 for (i = 0; i < dgclass->count_fields; i++)
2563 mono_array_setref (res, i, mono_field_get_object (domain, refclass, &dgclass->fields [i]));
2569 ves_icall_MonoGenericClass_GetProperties (MonoReflectionGenericClass *type,
2570 MonoReflectionType *reflected_type)
2572 static MonoClass *System_Reflection_PropertyInfo;
2573 MonoGenericClass *gclass;
2574 MonoDynamicGenericClass *dgclass;
2576 MonoClass *refclass;
2580 MONO_ARCH_SAVE_REGS;
2582 if (!System_Reflection_PropertyInfo)
2583 System_Reflection_PropertyInfo = mono_class_from_name (
2584 mono_defaults.corlib, "System.Reflection", "PropertyInfo");
2586 gclass = type->type.type->data.generic_class;
2587 g_assert (gclass->is_dynamic);
2588 dgclass = (MonoDynamicGenericClass *) gclass;
2590 refclass = mono_class_from_mono_type (reflected_type->type);
2592 domain = mono_object_domain (type);
2593 res = mono_array_new (domain, System_Reflection_PropertyInfo, dgclass->count_properties);
2595 for (i = 0; i < dgclass->count_properties; i++)
2596 mono_array_setref (res, i, mono_property_get_object (domain, refclass, &dgclass->properties [i]));
2602 ves_icall_MonoGenericClass_GetEvents (MonoReflectionGenericClass *type,
2603 MonoReflectionType *reflected_type)
2605 static MonoClass *System_Reflection_EventInfo;
2606 MonoGenericClass *gclass;
2607 MonoDynamicGenericClass *dgclass;
2609 MonoClass *refclass;
2613 MONO_ARCH_SAVE_REGS;
2615 if (!System_Reflection_EventInfo)
2616 System_Reflection_EventInfo = mono_class_from_name (
2617 mono_defaults.corlib, "System.Reflection", "EventInfo");
2619 gclass = type->type.type->data.generic_class;
2620 g_assert (gclass->is_dynamic);
2621 dgclass = (MonoDynamicGenericClass *) gclass;
2623 refclass = mono_class_from_mono_type (reflected_type->type);
2625 domain = mono_object_domain (type);
2626 res = mono_array_new (domain, System_Reflection_EventInfo, dgclass->count_events);
2628 for (i = 0; i < dgclass->count_events; i++)
2629 mono_array_setref (res, i, mono_event_get_object (domain, refclass, &dgclass->events [i]));
2634 static MonoReflectionMethod *
2635 ves_icall_MonoType_get_DeclaringMethod (MonoReflectionType *type)
2640 MONO_ARCH_SAVE_REGS;
2642 if (type->type->byref || type->type->type != MONO_TYPE_MVAR)
2645 method = type->type->data.generic_param->owner->owner.method;
2647 klass = mono_class_from_mono_type (type->type);
2648 return mono_method_get_object (mono_object_domain (type), method, klass);
2651 static MonoReflectionDllImportAttribute*
2652 ves_icall_MonoMethod_GetDllImportAttribute (MonoMethod *method)
2654 static MonoClass *DllImportAttributeClass = NULL;
2655 MonoDomain *domain = mono_domain_get ();
2656 MonoReflectionDllImportAttribute *attr;
2657 MonoImage *image = method->klass->image;
2658 MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method;
2659 MonoTableInfo *tables = image->tables;
2660 MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
2661 MonoTableInfo *mr = &tables [MONO_TABLE_MODULEREF];
2662 guint32 im_cols [MONO_IMPLMAP_SIZE];
2663 guint32 scope_token;
2664 const char *import = NULL;
2665 const char *scope = NULL;
2668 if (!method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)
2671 if (!DllImportAttributeClass) {
2672 DllImportAttributeClass =
2673 mono_class_from_name (mono_defaults.corlib,
2674 "System.Runtime.InteropServices", "DllImportAttribute");
2675 g_assert (DllImportAttributeClass);
2678 if (method->klass->image->dynamic) {
2679 MonoReflectionMethodAux *method_aux =
2680 g_hash_table_lookup (
2681 ((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
2683 import = method_aux->dllentry;
2684 scope = method_aux->dll;
2688 if (piinfo->implmap_idx) {
2689 mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
2691 piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
2692 import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
2693 scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
2694 scope = mono_metadata_string_heap (image, scope_token);
2697 flags = piinfo->piflags;
2699 attr = (MonoReflectionDllImportAttribute*)mono_object_new (domain, DllImportAttributeClass);
2701 MONO_OBJECT_SETREF (attr, dll, mono_string_new (domain, scope));
2702 MONO_OBJECT_SETREF (attr, entry_point, mono_string_new (domain, import));
2703 attr->call_conv = (flags & 0x700) >> 8;
2704 attr->charset = ((flags & 0x6) >> 1) + 1;
2705 if (attr->charset == 1)
2707 attr->exact_spelling = (flags & 0x1) != 0;
2708 attr->set_last_error = (flags & 0x40) != 0;
2709 attr->best_fit_mapping = (flags & 0x30) == 0x10;
2710 attr->throw_on_unmappable = (flags & 0x3000) == 0x1000;
2711 attr->preserve_sig = FALSE;
2716 static MonoReflectionMethod *
2717 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
2719 MonoMethodInflated *imethod;
2722 MONO_ARCH_SAVE_REGS;
2724 if (method->method->generic_container)
2727 if (!method->method->is_inflated)
2730 imethod = (MonoMethodInflated *) method->method;
2731 if (imethod->reflection_info)
2732 return imethod->reflection_info;
2734 result = imethod->declaring;
2735 /* Not a generic method. */
2736 if (!result->generic_container)
2738 if (imethod->context.class_inst) {
2739 MonoClass *klass = ((MonoMethod *) imethod)->klass;
2740 result = mono_class_inflate_generic_method_full (result, klass, mono_class_get_context (klass));
2743 return mono_method_get_object (mono_object_domain (method), result, NULL);
2747 ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethod *method)
2749 MONO_ARCH_SAVE_REGS;
2751 return mono_method_signature (method->method)->generic_param_count != 0;
2755 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method)
2757 MONO_ARCH_SAVE_REGS;
2759 return method->method->generic_container != NULL;
2763 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
2768 MONO_ARCH_SAVE_REGS;
2770 domain = mono_object_domain (method);
2772 if (method->method->is_inflated) {
2773 MonoGenericInst *inst = mono_method_get_context (method->method)->method_inst;
2776 count = inst->type_argc;
2777 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2779 for (i = 0; i < count; i++)
2780 mono_array_setref (res, i, mono_type_get_object (domain, inst->type_argv [i]));
2786 count = mono_method_signature (method->method)->generic_param_count;
2787 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2789 for (i = 0; i < count; i++) {
2790 MonoGenericParam *param = &method->method->generic_container->type_params [i];
2791 MonoClass *pklass = mono_class_from_generic_parameter (
2792 param, method->method->klass->image, TRUE);
2793 mono_array_setref (res, i,
2794 mono_type_get_object (domain, &pklass->byval_arg));
2801 ensure_reflection_security (void)
2803 MonoMethod *m = mono_method_get_last_managed ();
2807 g_print ("method %s.%s.%s in image %s\n",
2808 m->klass->name_space, m->klass->name, m->name, m->klass->image->name);
2811 /* We stop at the first method which is not in
2812 System.Reflection or which is not in a platform
2814 if (strcmp (m->klass->name_space, "System.Reflection") != 0 ||
2815 !mono_security_core_clr_is_platform_image (m->klass->image)) {
2816 /* If the method is transparent we throw an exception. */
2817 if (mono_security_core_clr_method_level (m, TRUE) == MONO_SECURITY_CORE_CLR_TRANSPARENT ) {
2818 MonoException *ex = mono_exception_from_name_msg (mono_defaults.corlib, "System", "MethodAccessException", "Reflection called from transparent code");
2820 mono_raise_exception (ex);
2825 mono_stack_walk_no_il (get_caller, &m);
2830 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoArray *params)
2833 * Invoke from reflection is supposed to always be a virtual call (the API
2834 * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
2835 * greater flexibility.
2837 MonoMethod *m = method->method;
2841 MONO_ARCH_SAVE_REGS;
2843 if (mono_security_get_mode () == MONO_SECURITY_MODE_CORE_CLR &&
2844 mono_security_core_clr_method_level (m, TRUE) == MONO_SECURITY_CORE_CLR_CRITICAL)
2845 ensure_reflection_security ();
2847 if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
2849 if (!mono_object_isinst (this, m->klass))
2850 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
2851 m = mono_object_get_virtual_method (this, m);
2852 /* must pass the pointer to the value for valuetype methods */
2853 if (m->klass->valuetype)
2854 obj = mono_object_unbox (this);
2855 } else if (strcmp (m->name, ".ctor") && !m->wrapper_type)
2856 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
2859 pcount = params? mono_array_length (params): 0;
2860 if (pcount != mono_method_signature (m)->param_count)
2861 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
2863 if ((m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) && !strcmp (m->name, ".ctor") && !this)
2864 mono_raise_exception (mono_exception_from_name_msg (mono_defaults.corlib, "System", "MethodAccessException", "Cannot invoke constructor of an abstract class."));
2866 if (m->klass->image->assembly->ref_only)
2867 mono_raise_exception (mono_get_exception_invalid_operation ("It is illegal to invoke a method on a type loaded using the ReflectionOnly api."));
2869 if (m->klass->rank && !strcmp (m->name, ".ctor")) {
2872 guint32 *lower_bounds;
2873 pcount = mono_array_length (params);
2874 lengths = alloca (sizeof (guint32) * pcount);
2875 for (i = 0; i < pcount; ++i)
2876 lengths [i] = *(gint32*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
2878 if (m->klass->rank == pcount) {
2879 /* Only lengths provided. */
2880 lower_bounds = NULL;
2882 g_assert (pcount == (m->klass->rank * 2));
2883 /* lower bounds are first. */
2884 lower_bounds = lengths;
2885 lengths += m->klass->rank;
2888 return (MonoObject*)mono_array_new_full (mono_object_domain (params), m->klass, lengths, lower_bounds);
2890 return mono_runtime_invoke_array (m, obj, params, NULL);
2894 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this, MonoArray *params, MonoArray **outArgs)
2896 MonoDomain *domain = mono_object_domain (method);
2897 MonoMethod *m = method->method;
2898 MonoMethodSignature *sig = mono_method_signature (m);
2899 MonoArray *out_args;
2901 int i, j, outarg_count = 0;
2903 MONO_ARCH_SAVE_REGS;
2905 if (m->klass == mono_defaults.object_class) {
2907 if (!strcmp (m->name, "FieldGetter")) {
2908 MonoClass *k = this->vtable->klass;
2912 /* If this is a proxy, then it must be a CBO */
2913 if (k == mono_defaults.transparent_proxy_class) {
2914 MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
2915 this = tp->rp->unwrapped_server;
2917 k = this->vtable->klass;
2920 name = mono_array_get (params, MonoString *, 1);
2921 str = mono_string_to_utf8 (name);
2924 MonoClassField* field = mono_class_get_field_from_name (k, str);
2926 MonoClass *field_klass = mono_class_from_mono_type (field->type);
2927 if (field_klass->valuetype)
2928 result = mono_value_box (domain, field_klass, (char *)this + field->offset);
2930 result = *((gpointer *)((char *)this + field->offset));
2932 out_args = mono_array_new (domain, mono_defaults.object_class, 1);
2933 *outArgs = out_args;
2934 mono_array_setref (out_args, 0, result);
2942 g_assert_not_reached ();
2944 } else if (!strcmp (m->name, "FieldSetter")) {
2945 MonoClass *k = this->vtable->klass;
2951 /* If this is a proxy, then it must be a CBO */
2952 if (k == mono_defaults.transparent_proxy_class) {
2953 MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
2954 this = tp->rp->unwrapped_server;
2956 k = this->vtable->klass;
2959 name = mono_array_get (params, MonoString *, 1);
2960 str = mono_string_to_utf8 (name);
2963 MonoClassField* field = mono_class_get_field_from_name (k, str);
2965 MonoClass *field_klass = mono_class_from_mono_type (field->type);
2966 MonoObject *val = mono_array_get (params, gpointer, 2);
2968 if (field_klass->valuetype) {
2969 size = mono_type_size (field->type, &align);
2970 memcpy ((char *)this + field->offset,
2971 ((char *)val) + sizeof (MonoObject), size);
2973 *(MonoObject**)((char *)this + field->offset) = val;
2975 out_args = mono_array_new (domain, mono_defaults.object_class, 0);
2976 *outArgs = out_args;
2986 g_assert_not_reached ();
2991 for (i = 0; i < mono_array_length (params); i++) {
2992 if (sig->params [i]->byref)
2996 out_args = mono_array_new (domain, mono_defaults.object_class, outarg_count);
2998 /* handle constructors only for objects already allocated */
2999 if (!strcmp (method->method->name, ".ctor"))
3002 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
3003 g_assert (!method->method->klass->valuetype);
3004 result = mono_runtime_invoke_array (method->method, this, params, NULL);
3006 for (i = 0, j = 0; i < mono_array_length (params); i++) {
3007 if (sig->params [i]->byref) {
3009 arg = mono_array_get (params, gpointer, i);
3010 mono_array_setref (out_args, j, arg);
3015 *outArgs = out_args;
3021 read_enum_value (char *mem, int type)
3025 return *(guint8*)mem;
3027 return *(gint8*)mem;
3029 return *(guint16*)mem;
3031 return *(gint16*)mem;
3033 return *(guint32*)mem;
3035 return *(gint32*)mem;
3037 return *(guint64*)mem;
3039 return *(gint64*)mem;
3041 g_assert_not_reached ();
3047 write_enum_value (char *mem, int type, guint64 value)
3051 case MONO_TYPE_I1: {
3052 guint8 *p = (guint8*)mem;
3057 case MONO_TYPE_I2: {
3058 guint16 *p = (void*)mem;
3063 case MONO_TYPE_I4: {
3064 guint32 *p = (void*)mem;
3069 case MONO_TYPE_I8: {
3070 guint64 *p = (void*)mem;
3075 g_assert_not_reached ();
3081 ves_icall_System_Enum_ToObject (MonoReflectionType *enumType, MonoObject *value)
3084 MonoClass *enumc, *objc;
3088 MONO_ARCH_SAVE_REGS;
3090 MONO_CHECK_ARG_NULL (enumType);
3091 MONO_CHECK_ARG_NULL (value);
3093 domain = mono_object_domain (enumType);
3094 enumc = mono_class_from_mono_type (enumType->type);
3095 objc = value->vtable->klass;
3097 if (!enumc->enumtype)
3098 mono_raise_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
3099 if (!((objc->enumtype) || (objc->byval_arg.type >= MONO_TYPE_I1 && objc->byval_arg.type <= MONO_TYPE_U8)))
3100 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."));
3102 res = mono_object_new (domain, enumc);
3103 val = read_enum_value ((char *)value + sizeof (MonoObject), objc->enumtype? objc->enum_basetype->type: objc->byval_arg.type);
3104 write_enum_value ((char *)res + sizeof (MonoObject), enumc->enum_basetype->type, val);
3110 ves_icall_System_Enum_get_value (MonoObject *this)
3118 MONO_ARCH_SAVE_REGS;
3123 g_assert (this->vtable->klass->enumtype);
3125 enumc = mono_class_from_mono_type (this->vtable->klass->enum_basetype);
3126 res = mono_object_new (mono_object_domain (this), enumc);
3127 dst = (char *)res + sizeof (MonoObject);
3128 src = (char *)this + sizeof (MonoObject);
3129 size = mono_class_value_size (enumc, NULL);
3131 memcpy (dst, src, size);
3137 ves_icall_get_enum_info (MonoReflectionType *type, MonoEnumInfo *info)
3139 MonoDomain *domain = mono_object_domain (type);
3140 MonoClass *enumc = mono_class_from_mono_type (type->type);
3141 guint j = 0, nvalues, crow;
3143 MonoClassField *field;
3145 MONO_ARCH_SAVE_REGS;
3147 info->utype = mono_type_get_object (domain, enumc->enum_basetype);
3148 nvalues = mono_class_num_fields (enumc) ? mono_class_num_fields (enumc) - 1 : 0;
3149 info->names = mono_array_new (domain, mono_defaults.string_class, nvalues);
3150 info->values = mono_array_new (domain, enumc, nvalues);
3154 while ((field = mono_class_get_fields (enumc, &iter))) {
3158 if (strcmp ("value__", field->name) == 0)
3160 if (mono_field_is_deleted (field))
3162 mono_array_setref (info->names, j, mono_string_new (domain, field->name));
3165 crow = mono_metadata_get_constant_index (enumc->image, mono_class_get_field_token (field), crow + 1);
3166 field->def_type = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_TYPE);
3167 crow = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_VALUE);
3168 field->data = (gpointer)mono_metadata_blob_heap (enumc->image, crow);
3172 len = mono_metadata_decode_blob_size (p, &p);
3173 switch (enumc->enum_basetype->type) {
3176 mono_array_set (info->values, gchar, j, *p);
3178 case MONO_TYPE_CHAR:
3181 mono_array_set (info->values, gint16, j, read16 (p));
3185 mono_array_set (info->values, gint32, j, read32 (p));
3189 mono_array_set (info->values, gint64, j, read64 (p));
3192 g_error ("Implement type 0x%02x in get_enum_info", enumc->enum_basetype->type);
3199 BFLAGS_IgnoreCase = 1,
3200 BFLAGS_DeclaredOnly = 2,
3201 BFLAGS_Instance = 4,
3203 BFLAGS_Public = 0x10,
3204 BFLAGS_NonPublic = 0x20,
3205 BFLAGS_FlattenHierarchy = 0x40,
3206 BFLAGS_InvokeMethod = 0x100,
3207 BFLAGS_CreateInstance = 0x200,
3208 BFLAGS_GetField = 0x400,
3209 BFLAGS_SetField = 0x800,
3210 BFLAGS_GetProperty = 0x1000,
3211 BFLAGS_SetProperty = 0x2000,
3212 BFLAGS_ExactBinding = 0x10000,
3213 BFLAGS_SuppressChangeType = 0x20000,
3214 BFLAGS_OptionalParamBinding = 0x40000
3217 static MonoReflectionField *
3218 ves_icall_Type_GetField (MonoReflectionType *type, MonoString *name, guint32 bflags)
3221 MonoClass *startklass, *klass;
3223 MonoClassField *field;
3226 int (*compare_func) (const char *s1, const char *s2) = NULL;
3227 domain = ((MonoObject *)type)->vtable->domain;
3228 klass = startklass = mono_class_from_mono_type (type->type);
3230 MONO_ARCH_SAVE_REGS;
3233 mono_raise_exception (mono_get_exception_argument_null ("name"));
3234 if (type->type->byref)
3237 compare_func = (bflags & BFLAGS_IgnoreCase) ? g_strcasecmp : strcmp;
3240 if (klass->exception_type != MONO_EXCEPTION_NONE)
3241 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3244 while ((field = mono_class_get_fields (klass, &iter))) {
3247 if (field->type == NULL)
3249 if (mono_field_is_deleted (field))
3251 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3252 if (bflags & BFLAGS_Public)
3254 } else if ((klass == startklass) || (field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
3255 if (bflags & BFLAGS_NonPublic) {
3262 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
3263 if (bflags & BFLAGS_Static)
3264 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3267 if (bflags & BFLAGS_Instance)
3274 utf8_name = mono_string_to_utf8 (name);
3276 if (compare_func (field->name, utf8_name)) {
3282 return mono_field_get_object (domain, klass, field);
3284 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3291 ves_icall_Type_GetFields_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3294 MonoClass *startklass, *klass, *refklass;
3299 MonoClassField *field;
3301 MONO_ARCH_SAVE_REGS;
3303 domain = ((MonoObject *)type)->vtable->domain;
3304 if (type->type->byref)
3305 return mono_array_new (domain, mono_defaults.field_info_class, 0);
3306 klass = startklass = mono_class_from_mono_type (type->type);
3307 refklass = mono_class_from_mono_type (reftype->type);
3311 res = mono_array_new (domain, mono_defaults.field_info_class, len);
3313 if (klass->exception_type != MONO_EXCEPTION_NONE)
3314 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3317 while ((field = mono_class_get_fields (klass, &iter))) {
3319 if (mono_field_is_deleted (field))
3321 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3322 if (bflags & BFLAGS_Public)
3324 } else if ((klass == startklass) || (field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
3325 if (bflags & BFLAGS_NonPublic) {
3332 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
3333 if (bflags & BFLAGS_Static)
3334 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3337 if (bflags & BFLAGS_Instance)
3343 member = (MonoObject*)mono_field_get_object (domain, refklass, field);
3345 MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, len * 2);
3346 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3350 mono_array_setref (res, i, member);
3353 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3356 MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, i);
3357 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3360 * Better solution for the new GC.
3361 * res->max_length = i;
3368 method_nonpublic (MonoMethod* method, gboolean start_klass)
3370 switch (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) {
3371 case METHOD_ATTRIBUTE_ASSEM:
3372 return (start_klass || mono_defaults.generic_ilist_class);
3373 case METHOD_ATTRIBUTE_PRIVATE:
3375 case METHOD_ATTRIBUTE_PUBLIC:
3383 ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
3386 MonoClass *startklass, *klass, *refklass;
3391 int i, len, match, nslots;
3392 guint32 method_slots_default [8];
3393 guint32 *method_slots;
3394 gchar *mname = NULL;
3395 int (*compare_func) (const char *s1, const char *s2) = NULL;
3397 MONO_ARCH_SAVE_REGS;
3399 domain = ((MonoObject *)type)->vtable->domain;
3400 if (type->type->byref)
3401 return mono_array_new (domain, mono_defaults.method_info_class, 0);
3402 klass = startklass = mono_class_from_mono_type (type->type);
3403 refklass = mono_class_from_mono_type (reftype->type);
3406 mname = mono_string_to_utf8 (name);
3407 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
3410 mono_class_setup_vtable (klass);
3412 if (is_generic_parameter (type->type))
3413 nslots = klass->parent->vtable_size;
3415 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : klass->vtable_size;
3416 if (nslots >= sizeof (method_slots_default) * 8) {
3417 method_slots = g_new0 (guint32, nslots / 32 + 1);
3419 method_slots = method_slots_default;
3420 memset (method_slots, 0, sizeof (method_slots_default));
3424 res = mono_array_new (domain, mono_defaults.method_info_class, len);
3426 mono_class_setup_vtable (klass);
3427 if (klass->exception_type != MONO_EXCEPTION_NONE)
3428 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3431 while ((method = mono_class_get_methods (klass, &iter))) {
3433 if (method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
3435 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3436 if (bflags & BFLAGS_Public)
3438 } else if ((bflags & BFLAGS_NonPublic) && method_nonpublic (method, (klass == startklass))) {
3444 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3445 if (bflags & BFLAGS_Static)
3446 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3449 if (bflags & BFLAGS_Instance)
3457 if (compare_func (mname, method->name))
3462 if (method->slot != -1) {
3463 g_assert (method->slot < nslots);
3464 if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
3466 method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
3469 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
3472 MonoArray *new_res = mono_array_new (domain, mono_defaults.method_info_class, len * 2);
3473 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3477 mono_array_setref (res, i, member);
3480 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3484 if (method_slots != method_slots_default)
3485 g_free (method_slots);
3487 MonoArray *new_res = mono_array_new (domain, mono_defaults.method_info_class, i);
3488 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3491 * Better solution for the new GC.
3492 * res->max_length = i;
3499 ves_icall_Type_GetConstructors_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3502 static MonoClass *System_Reflection_ConstructorInfo;
3503 MonoClass *startklass, *klass, *refklass;
3508 gpointer iter = NULL;
3510 MONO_ARCH_SAVE_REGS;
3512 domain = ((MonoObject *)type)->vtable->domain;
3513 if (type->type->byref)
3514 return mono_array_new (domain, mono_defaults.method_info_class, 0);
3515 klass = startklass = mono_class_from_mono_type (type->type);
3516 refklass = mono_class_from_mono_type (reftype->type);
3518 if (klass->exception_type != MONO_EXCEPTION_NONE)
3519 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3521 if (!System_Reflection_ConstructorInfo)
3522 System_Reflection_ConstructorInfo = mono_class_from_name (
3523 mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
3527 res = mono_array_new (domain, System_Reflection_ConstructorInfo, len);
3529 while ((method = mono_class_get_methods (klass, &iter))) {
3531 if (strcmp (method->name, ".ctor") && strcmp (method->name, ".cctor"))
3533 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3534 if (bflags & BFLAGS_Public)
3537 if (bflags & BFLAGS_NonPublic)
3543 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3544 if (bflags & BFLAGS_Static)
3545 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3548 if (bflags & BFLAGS_Instance)
3554 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
3557 MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, len * 2);
3558 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3562 mono_array_setref (res, i, member);
3566 MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, i);
3567 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3570 * Better solution for the new GC.
3571 * res->max_length = i;
3578 property_hash (gconstpointer data)
3580 MonoProperty *prop = (MonoProperty*)data;
3582 return g_str_hash (prop->name);
3586 property_equal (MonoProperty *prop1, MonoProperty *prop2)
3588 // Properties are hide-by-name-and-signature
3589 if (!g_str_equal (prop1->name, prop2->name))
3592 if (prop1->get && prop2->get && !mono_metadata_signature_equal (mono_method_signature (prop1->get), mono_method_signature (prop2->get)))
3594 if (prop1->set && prop2->set && !mono_metadata_signature_equal (mono_method_signature (prop1->set), mono_method_signature (prop2->set)))
3600 property_accessor_nonpublic (MonoMethod* accessor, gboolean start_klass)
3605 return method_nonpublic (accessor, start_klass);
3609 ves_icall_Type_GetPropertiesByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
3612 static MonoClass *System_Reflection_PropertyInfo;
3613 MonoClass *startklass, *klass;
3620 gchar *propname = NULL;
3621 int (*compare_func) (const char *s1, const char *s2) = NULL;
3623 GHashTable *properties;
3625 MONO_ARCH_SAVE_REGS;
3627 if (!System_Reflection_PropertyInfo)
3628 System_Reflection_PropertyInfo = mono_class_from_name (
3629 mono_defaults.corlib, "System.Reflection", "PropertyInfo");
3631 domain = ((MonoObject *)type)->vtable->domain;
3632 if (type->type->byref)
3633 return mono_array_new (domain, System_Reflection_PropertyInfo, 0);
3634 klass = startklass = mono_class_from_mono_type (type->type);
3636 propname = mono_string_to_utf8 (name);
3637 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
3640 mono_class_setup_vtable (klass);
3642 properties = g_hash_table_new (property_hash, (GEqualFunc)property_equal);
3645 res = mono_array_new (domain, System_Reflection_PropertyInfo, len);
3647 mono_class_setup_vtable (klass);
3648 if (klass->exception_type != MONO_EXCEPTION_NONE) {
3649 g_hash_table_destroy (properties);
3652 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3656 while ((prop = mono_class_get_properties (klass, &iter))) {
3662 flags = method->flags;
3665 if ((prop->get && ((prop->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC)) ||
3666 (prop->set && ((prop->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC))) {
3667 if (bflags & BFLAGS_Public)
3669 } else if (bflags & BFLAGS_NonPublic) {
3670 if (property_accessor_nonpublic(prop->get, startklass == klass) ||
3671 property_accessor_nonpublic(prop->set, startklass == klass)) {
3678 if (flags & METHOD_ATTRIBUTE_STATIC) {
3679 if (bflags & BFLAGS_Static)
3680 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3683 if (bflags & BFLAGS_Instance)
3692 if (compare_func (propname, prop->name))
3696 if (g_hash_table_lookup (properties, prop))
3700 MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, len * 2);
3701 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3705 mono_array_setref (res, i, mono_property_get_object (domain, startklass, prop));
3708 g_hash_table_insert (properties, prop, prop);
3710 if ((!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent)))
3713 g_hash_table_destroy (properties);
3716 MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, i);
3717 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3720 * Better solution for the new GC.
3721 * res->max_length = i;
3727 static MonoReflectionEvent *
3728 ves_icall_MonoType_GetEvent (MonoReflectionType *type, MonoString *name, guint32 bflags)
3731 MonoClass *klass, *startklass;
3737 MONO_ARCH_SAVE_REGS;
3739 event_name = mono_string_to_utf8 (name);
3740 if (type->type->byref)
3742 klass = startklass = mono_class_from_mono_type (type->type);
3743 domain = mono_object_domain (type);
3746 if (klass->exception_type != MONO_EXCEPTION_NONE)
3747 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3750 while ((event = mono_class_get_events (klass, &iter))) {
3751 if (strcmp (event->name, event_name))
3754 method = event->add;
3756 method = event->remove;
3758 method = event->raise;
3760 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3761 if (!(bflags & BFLAGS_Public))
3764 if (!(bflags & BFLAGS_NonPublic))
3766 if ((klass != startklass) && (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PRIVATE)
3771 if (!(bflags & BFLAGS_NonPublic))
3774 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3775 if (!(bflags & BFLAGS_Static))
3777 if (!(bflags & BFLAGS_FlattenHierarchy) && (klass != startklass))
3780 if (!(bflags & BFLAGS_Instance))
3784 g_free (event_name);
3785 return mono_event_get_object (domain, startklass, event);
3788 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3791 g_free (event_name);
3796 ves_icall_Type_GetEvents_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3799 static MonoClass *System_Reflection_EventInfo;
3800 MonoClass *startklass, *klass;
3807 MONO_ARCH_SAVE_REGS;
3809 if (!System_Reflection_EventInfo)
3810 System_Reflection_EventInfo = mono_class_from_name (
3811 mono_defaults.corlib, "System.Reflection", "EventInfo");
3813 domain = mono_object_domain (type);
3814 if (type->type->byref)
3815 return mono_array_new (domain, System_Reflection_EventInfo, 0);
3816 klass = startklass = mono_class_from_mono_type (type->type);
3820 res = mono_array_new (domain, System_Reflection_EventInfo, len);
3822 if (klass->exception_type != MONO_EXCEPTION_NONE)
3823 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3826 while ((event = mono_class_get_events (klass, &iter))) {
3828 method = event->add;
3830 method = event->remove;
3832 method = event->raise;
3834 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3835 if (bflags & BFLAGS_Public)
3837 } else if ((klass == startklass) || (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) {
3838 if (bflags & BFLAGS_NonPublic)
3843 if (bflags & BFLAGS_NonPublic)
3849 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3850 if (bflags & BFLAGS_Static)
3851 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3854 if (bflags & BFLAGS_Instance)
3859 if (bflags & BFLAGS_Instance)
3865 MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, len * 2);
3866 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3870 mono_array_setref (res, i, mono_event_get_object (domain, startklass, event));
3873 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3876 MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, i);
3877 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3880 * Better solution for the new GC.
3881 * res->max_length = i;
3887 static MonoReflectionType *
3888 ves_icall_Type_GetNestedType (MonoReflectionType *type, MonoString *name, guint32 bflags)
3896 MONO_ARCH_SAVE_REGS;
3898 domain = ((MonoObject *)type)->vtable->domain;
3899 if (type->type->byref)
3901 klass = mono_class_from_mono_type (type->type);
3902 str = mono_string_to_utf8 (name);
3905 if (klass->exception_type != MONO_EXCEPTION_NONE)
3906 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3909 * If a nested type is generic, return its generic type definition.
3910 * Note that this means that the return value is essentially a
3911 * nested type of the generic type definition of @klass.
3913 * A note in MSDN claims that a generic type definition can have
3914 * nested types that aren't generic. In any case, the container of that
3915 * nested type would be the generic type definition.
3917 if (klass->generic_class)
3918 klass = klass->generic_class->container_class;
3920 for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
3922 nested = tmpn->data;
3923 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
3924 if (bflags & BFLAGS_Public)
3927 if (bflags & BFLAGS_NonPublic)
3932 if (strcmp (nested->name, str) == 0){
3934 return mono_type_get_object (domain, &nested->byval_arg);
3937 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3944 ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags)
3954 MONO_ARCH_SAVE_REGS;
3956 domain = ((MonoObject *)type)->vtable->domain;
3957 if (type->type->byref)
3958 return mono_array_new (domain, mono_defaults.monotype_class, 0);
3959 klass = mono_class_from_mono_type (type->type);
3960 if (klass->exception_type != MONO_EXCEPTION_NONE)
3961 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3964 * If a nested type is generic, return its generic type definition.
3965 * Note that this means that the return value is essentially the set
3966 * of nested types of the generic type definition of @klass.
3968 * A note in MSDN claims that a generic type definition can have
3969 * nested types that aren't generic. In any case, the container of that
3970 * nested type would be the generic type definition.
3972 if (klass->generic_class)
3973 klass = klass->generic_class->container_class;
3977 res = mono_array_new (domain, mono_defaults.monotype_class, len);
3978 for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
3980 nested = tmpn->data;
3981 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
3982 if (bflags & BFLAGS_Public)
3985 if (bflags & BFLAGS_NonPublic)
3990 member = (MonoObject*)mono_type_get_object (domain, &nested->byval_arg);
3992 MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, len * 2);
3993 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3997 mono_array_setref (res, i, member);
4001 MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, i);
4002 mono_array_memcpy_refs (new_res, 0, res, 0, i);
4005 * Better solution for the new GC.
4006 * res->max_length = i;
4012 static MonoReflectionType*
4013 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *assembly, MonoReflectionModule *module, MonoString *name, MonoBoolean throwOnError, MonoBoolean ignoreCase)
4016 MonoType *type = NULL;
4017 MonoTypeNameParse info;
4018 gboolean type_resolve;
4020 MONO_ARCH_SAVE_REGS;
4022 /* On MS.NET, this does not fire a TypeResolve event */
4023 type_resolve = TRUE;
4024 str = mono_string_to_utf8 (name);
4025 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
4026 if (!mono_reflection_parse_type (str, &info)) {
4028 mono_reflection_free_type_info (&info);
4029 if (throwOnError) /* uhm: this is a parse error, though... */
4030 mono_raise_exception (mono_get_exception_type_load (name, NULL));
4031 /*g_print ("failed parse\n");*/
4035 if (info.assembly.name) {
4037 /* 1.0 and 2.0 throw different exceptions */
4038 if (mono_defaults.generic_ilist_class)
4039 mono_raise_exception (mono_get_exception_argument (NULL, "Type names passed to Assembly.GetType() must not specify an assembly."));
4041 mono_raise_exception (mono_get_exception_type_load (name, NULL));
4046 if (module != NULL) {
4048 type = mono_reflection_get_type (module->image, &info, ignoreCase, &type_resolve);
4053 if (assembly->assembly->dynamic) {
4054 /* Enumerate all modules */
4055 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
4059 if (abuilder->modules) {
4060 for (i = 0; i < mono_array_length (abuilder->modules); ++i) {
4061 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
4062 type = mono_reflection_get_type (&mb->dynamic_image->image, &info, ignoreCase, &type_resolve);
4068 if (!type && abuilder->loaded_modules) {
4069 for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) {
4070 MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
4071 type = mono_reflection_get_type (mod->image, &info, ignoreCase, &type_resolve);
4078 type = mono_reflection_get_type (assembly->assembly->image, &info, ignoreCase, &type_resolve);
4080 mono_reflection_free_type_info (&info);
4082 MonoException *e = NULL;
4085 e = mono_get_exception_type_load (name, NULL);
4087 mono_loader_clear_error ();
4090 mono_raise_exception (e);
4095 if (type->type == MONO_TYPE_CLASS) {
4096 MonoClass *klass = mono_type_get_class (type);
4097 /* need to report exceptions ? */
4098 if (throwOnError && klass->exception_type) {
4099 /* report SecurityException (or others) that occured when loading the assembly */
4100 MonoException *exc = mono_class_get_exception_for_failure (klass);
4101 mono_loader_clear_error ();
4102 mono_raise_exception (exc);
4103 } else if (klass->exception_type == MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND) {
4108 /* g_print ("got it\n"); */
4109 return mono_type_get_object (mono_object_domain (assembly), type);
4113 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *assembly, MonoBoolean escaped)
4115 MonoDomain *domain = mono_object_domain (assembly);
4116 MonoAssembly *mass = assembly->assembly;
4117 MonoString *res = NULL;
4121 MONO_ARCH_SAVE_REGS;
4123 if (g_path_is_absolute (mass->image->name))
4124 absolute = g_strdup (mass->image->name);
4126 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4130 for (i = strlen (absolute) - 1; i >= 0; i--)
4131 if (absolute [i] == '\\')
4136 uri = g_filename_to_uri (absolute, NULL, NULL);
4138 uri = g_strconcat ("file://", absolute, NULL);
4142 res = mono_string_new (domain, uri);
4150 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssembly *assembly)
4152 MonoAssembly *mass = assembly->assembly;
4154 MONO_ARCH_SAVE_REGS;
4156 return mass->in_gac;
4159 static MonoReflectionAssembly*
4160 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoString *mname, MonoObject *evidence)
4164 MonoImageOpenStatus status;
4166 MONO_ARCH_SAVE_REGS;
4168 name = mono_string_to_utf8 (mname);
4169 res = mono_assembly_load_with_partial_name (name, &status);
4175 return mono_assembly_get_object (mono_domain_get (), res);
4179 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssembly *assembly)
4181 MonoDomain *domain = mono_object_domain (assembly);
4184 MONO_ARCH_SAVE_REGS;
4186 res = mono_string_new (domain, mono_image_get_filename (assembly->assembly->image));
4192 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssembly *assembly)
4194 MONO_ARCH_SAVE_REGS;
4196 return assembly->assembly->ref_only;
4200 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssembly *assembly)
4202 MonoDomain *domain = mono_object_domain (assembly);
4204 MONO_ARCH_SAVE_REGS;
4206 return mono_string_new (domain, assembly->assembly->image->version);
4209 static MonoReflectionMethod*
4210 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssembly *assembly)
4212 guint32 token = mono_image_get_entry_point (assembly->assembly->image);
4214 MONO_ARCH_SAVE_REGS;
4218 return mono_method_get_object (mono_object_domain (assembly), mono_get_method (assembly->assembly->image, token, NULL), NULL);
4221 static MonoReflectionModule*
4222 ves_icall_System_Reflection_Assembly_GetManifestModuleInternal (MonoReflectionAssembly *assembly)
4224 return mono_module_get_object (mono_object_domain (assembly), assembly->assembly->image);
4228 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssembly *assembly)
4230 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4231 MonoArray *result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, table->rows);
4235 MONO_ARCH_SAVE_REGS;
4237 for (i = 0; i < table->rows; ++i) {
4238 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_MANIFEST_NAME));
4239 mono_array_setref (result, i, mono_string_new (mono_object_domain (assembly), val));
4245 create_version (MonoDomain *domain, guint32 major, guint32 minor, guint32 build, guint32 revision)
4247 static MonoClass *System_Version = NULL;
4248 static MonoMethod *create_version = NULL;
4252 if (!System_Version) {
4253 System_Version = mono_class_from_name (mono_defaults.corlib, "System", "Version");
4254 g_assert (System_Version);
4257 if (!create_version) {
4258 MonoMethodDesc *desc = mono_method_desc_new (":.ctor(int,int,int,int)", FALSE);
4259 create_version = mono_method_desc_search_in_class (desc, System_Version);
4260 g_assert (create_version);
4261 mono_method_desc_free (desc);
4267 args [3] = &revision;
4268 result = mono_object_new (domain, System_Version);
4269 mono_runtime_invoke (create_version, result, args, NULL);
4275 ves_icall_System_Reflection_Assembly_GetReferencedAssemblies (MonoReflectionAssembly *assembly)
4277 static MonoClass *System_Reflection_AssemblyName;
4279 MonoDomain *domain = mono_object_domain (assembly);
4281 static MonoMethod *create_culture = NULL;
4282 MonoImage *image = assembly->assembly->image;
4285 MONO_ARCH_SAVE_REGS;
4287 if (!System_Reflection_AssemblyName)
4288 System_Reflection_AssemblyName = mono_class_from_name (
4289 mono_defaults.corlib, "System.Reflection", "AssemblyName");
4291 t = &assembly->assembly->image->tables [MONO_TABLE_ASSEMBLYREF];
4294 result = mono_array_new (domain, System_Reflection_AssemblyName, count);
4297 MonoMethodDesc *desc = mono_method_desc_new (
4298 "System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE);
4299 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4300 g_assert (create_culture);
4301 mono_method_desc_free (desc);
4304 for (i = 0; i < count; i++) {
4305 MonoReflectionAssemblyName *aname;
4306 guint32 cols [MONO_ASSEMBLYREF_SIZE];
4308 mono_metadata_decode_row (t, i, cols, MONO_ASSEMBLYREF_SIZE);
4310 aname = (MonoReflectionAssemblyName *) mono_object_new (
4311 domain, System_Reflection_AssemblyName);
4313 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_NAME])));
4315 aname->major = cols [MONO_ASSEMBLYREF_MAJOR_VERSION];
4316 aname->minor = cols [MONO_ASSEMBLYREF_MINOR_VERSION];
4317 aname->build = cols [MONO_ASSEMBLYREF_BUILD_NUMBER];
4318 aname->revision = cols [MONO_ASSEMBLYREF_REV_NUMBER];
4319 aname->flags = cols [MONO_ASSEMBLYREF_FLAGS];
4320 aname->versioncompat = 1; /* SameMachine (default) */
4321 aname->hashalg = ASSEMBLY_HASH_SHA1; /* SHA1 (default) */
4322 MONO_OBJECT_SETREF (aname, version, create_version (domain, aname->major, aname->minor, aname->build, aname->revision));
4324 if (create_culture) {
4326 gboolean assembly_ref = TRUE;
4327 args [0] = mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_CULTURE]));
4328 args [1] = &assembly_ref;
4329 MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
4332 if (cols [MONO_ASSEMBLYREF_PUBLIC_KEY]) {
4333 const gchar *pkey_ptr = mono_metadata_blob_heap (image, cols [MONO_ASSEMBLYREF_PUBLIC_KEY]);
4334 guint32 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
4336 if ((cols [MONO_ASSEMBLYREF_FLAGS] & ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG)) {
4337 /* public key token isn't copied - the class library will
4338 automatically generate it from the public key if required */
4339 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4340 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
4342 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4343 memcpy (mono_array_addr (aname->keyToken, guint8, 0), pkey_ptr, pkey_len);
4346 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, 0));
4349 /* note: this function doesn't return the codebase on purpose (i.e. it can
4350 be used under partial trust as path information isn't present). */
4352 mono_array_setref (result, i, aname);
4363 foreach_namespace (const char* key, gconstpointer val, NameSpaceInfo *info)
4365 MonoString *name = mono_string_new (mono_object_domain (info->res), key);
4367 mono_array_setref (info->res, info->idx, name);
4372 ves_icall_System_Reflection_Assembly_GetNamespaces (MonoReflectionAssembly *assembly)
4374 MonoImage *img = assembly->assembly->image;
4378 MONO_ARCH_SAVE_REGS;
4380 if (!img->name_cache)
4381 mono_image_init_name_cache (img);
4383 res = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, g_hash_table_size (img->name_cache));
4386 g_hash_table_foreach (img->name_cache, (GHFunc)foreach_namespace, &info);
4391 /* move this in some file in mono/util/ */
4393 g_concat_dir_and_file (const char *dir, const char *file)
4395 g_return_val_if_fail (dir != NULL, NULL);
4396 g_return_val_if_fail (file != NULL, NULL);
4399 * If the directory name doesn't have a / on the end, we need
4400 * to add one so we get a proper path to the file
4402 if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
4403 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
4405 return g_strconcat (dir, file, NULL);
4409 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssembly *assembly, MonoString *name, gint32 *size, MonoReflectionModule **ref_module)
4411 char *n = mono_string_to_utf8 (name);
4412 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4414 guint32 cols [MONO_MANIFEST_SIZE];
4415 guint32 impl, file_idx;
4419 MONO_ARCH_SAVE_REGS;
4421 for (i = 0; i < table->rows; ++i) {
4422 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4423 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4424 if (strcmp (val, n) == 0)
4428 if (i == table->rows)
4431 impl = cols [MONO_MANIFEST_IMPLEMENTATION];
4434 * this code should only be called after obtaining the
4435 * ResourceInfo and handling the other cases.
4437 g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
4438 file_idx = impl >> MONO_IMPLEMENTATION_BITS;
4440 module = mono_image_load_file_for_image (assembly->assembly->image, file_idx);
4445 module = assembly->assembly->image;
4447 *ref_module = mono_module_get_object (mono_domain_get (), module);
4449 return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
4453 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoManifestResourceInfo *info)
4455 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4457 guint32 cols [MONO_MANIFEST_SIZE];
4458 guint32 file_cols [MONO_FILE_SIZE];
4462 MONO_ARCH_SAVE_REGS;
4464 n = mono_string_to_utf8 (name);
4465 for (i = 0; i < table->rows; ++i) {
4466 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4467 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4468 if (strcmp (val, n) == 0)
4472 if (i == table->rows)
4475 if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
4476 info->location = RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST;
4479 switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
4480 case MONO_IMPLEMENTATION_FILE:
4481 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4482 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4483 mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
4484 val = mono_metadata_string_heap (assembly->assembly->image, file_cols [MONO_FILE_NAME]);
4485 MONO_OBJECT_SETREF (info, filename, mono_string_new (mono_object_domain (assembly), val));
4486 if (file_cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA)
4489 info->location = RESOURCE_LOCATION_EMBEDDED;
4492 case MONO_IMPLEMENTATION_ASSEMBLYREF:
4493 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4494 mono_assembly_load_reference (assembly->assembly->image, i - 1);
4495 if (assembly->assembly->image->references [i - 1] == (gpointer)-1) {
4496 char *msg = g_strdup_printf ("Assembly %d referenced from assembly %s not found ", i - 1, assembly->assembly->image->name);
4497 MonoException *ex = mono_get_exception_file_not_found2 (msg, NULL);
4499 mono_raise_exception (ex);
4501 MONO_OBJECT_SETREF (info, assembly, mono_assembly_get_object (mono_domain_get (), assembly->assembly->image->references [i - 1]));
4503 /* Obtain info recursively */
4504 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (info->assembly, name, info);
4505 info->location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
4508 case MONO_IMPLEMENTATION_EXP_TYPE:
4509 g_assert_not_reached ();
4518 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoBoolean resource_modules)
4520 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4521 MonoArray *result = NULL;
4526 MONO_ARCH_SAVE_REGS;
4528 /* check hash if needed */
4530 n = mono_string_to_utf8 (name);
4531 for (i = 0; i < table->rows; ++i) {
4532 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4533 if (strcmp (val, n) == 0) {
4536 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4537 fn = mono_string_new (mono_object_domain (assembly), n);
4539 return (MonoObject*)fn;
4547 for (i = 0; i < table->rows; ++i) {
4548 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA))
4552 result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, count);
4555 for (i = 0; i < table->rows; ++i) {
4556 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4557 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4558 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4559 mono_array_setref (result, count, mono_string_new (mono_object_domain (assembly), n));
4564 return (MonoObject*)result;
4568 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly *assembly)
4570 MonoDomain *domain = mono_domain_get();
4573 int i, j, file_count = 0;
4574 MonoImage **modules;
4575 guint32 module_count, real_module_count;
4576 MonoTableInfo *table;
4577 guint32 cols [MONO_FILE_SIZE];
4578 MonoImage *image = assembly->assembly->image;
4580 g_assert (image != NULL);
4581 g_assert (!assembly->assembly->dynamic);
4583 table = &image->tables [MONO_TABLE_FILE];
4584 file_count = table->rows;
4586 modules = image->modules;
4587 module_count = image->module_count;
4589 real_module_count = 0;
4590 for (i = 0; i < module_count; ++i)
4592 real_module_count ++;
4594 klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "Module");
4595 res = mono_array_new (domain, klass, 1 + real_module_count + file_count);
4597 mono_array_setref (res, 0, mono_module_get_object (domain, image));
4599 for (i = 0; i < module_count; ++i)
4601 mono_array_setref (res, j, mono_module_get_object (domain, modules[i]));
4605 for (i = 0; i < file_count; ++i, ++j) {
4606 mono_metadata_decode_row (table, i, cols, MONO_FILE_SIZE);
4607 if (cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA)
4608 mono_array_setref (res, j, mono_module_file_get_object (domain, image, i));
4610 MonoImage *m = mono_image_load_file_for_image (image, i + 1);
4612 MonoString *fname = mono_string_new (mono_domain_get (), mono_metadata_string_heap (image, cols [MONO_FILE_NAME]));
4613 mono_raise_exception (mono_get_exception_file_not_found2 (NULL, fname));
4615 mono_array_setref (res, j, mono_module_get_object (domain, m));
4622 static MonoReflectionMethod*
4623 ves_icall_GetCurrentMethod (void)
4625 MonoMethod *m = mono_method_get_last_managed ();
4627 MONO_ARCH_SAVE_REGS;
4629 return mono_method_get_object (mono_domain_get (), m, NULL);
4632 static MonoReflectionMethod*
4633 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType (MonoMethod *method, MonoType *type)
4635 /* FIXME check that method belongs to klass or a parent */
4638 klass = mono_class_from_mono_type (type);
4640 klass = method->klass;
4641 return mono_method_get_object (mono_domain_get (), method, klass);
4644 static MonoReflectionMethod*
4645 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternal (MonoMethod *method)
4647 return mono_method_get_object (mono_domain_get (), method, NULL);
4650 static MonoReflectionMethodBody*
4651 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod *method)
4653 return mono_method_body_get_object (mono_domain_get (), method);
4656 static MonoReflectionAssembly*
4657 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (void)
4659 MonoMethod *m = mono_method_get_last_managed ();
4661 MONO_ARCH_SAVE_REGS;
4663 return mono_assembly_get_object (mono_domain_get (), m->klass->image->assembly);
4667 static MonoReflectionAssembly*
4668 ves_icall_System_Reflection_Assembly_GetEntryAssembly (void)
4670 MonoDomain* domain = mono_domain_get ();
4672 MONO_ARCH_SAVE_REGS;
4674 if (!domain->entry_assembly)
4677 return mono_assembly_get_object (domain, domain->entry_assembly);
4680 static MonoReflectionAssembly*
4681 ves_icall_System_Reflection_Assembly_GetCallingAssembly (void)
4683 MonoMethod *m = mono_method_get_last_managed ();
4684 MonoMethod *dest = m;
4686 MONO_ARCH_SAVE_REGS;
4688 mono_stack_walk_no_il (get_caller, &dest);
4691 return mono_assembly_get_object (mono_domain_get (), dest->klass->image->assembly);
4695 ves_icall_System_MonoType_getFullName (MonoReflectionType *object, gboolean full_name,
4696 gboolean assembly_qualified)
4698 MonoDomain *domain = mono_object_domain (object);
4699 MonoTypeNameFormat format;
4703 MONO_ARCH_SAVE_REGS;
4705 format = assembly_qualified ?
4706 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
4707 MONO_TYPE_NAME_FORMAT_FULL_NAME;
4709 format = MONO_TYPE_NAME_FORMAT_REFLECTION;
4711 name = mono_type_get_name_full (object->type, format);
4715 if (full_name && (object->type->type == MONO_TYPE_VAR || object->type->type == MONO_TYPE_MVAR)) {
4720 res = mono_string_new (domain, name);
4727 fill_reflection_assembly_name (MonoDomain *domain, MonoReflectionAssemblyName *aname, MonoAssemblyName *name, const char *absolute, gboolean by_default_version, gboolean default_publickey, gboolean default_token)
4729 static MonoMethod *create_culture = NULL;
4732 const char *pkey_ptr;
4734 gboolean assembly_ref = FALSE;
4736 MONO_ARCH_SAVE_REGS;
4738 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, name->name));
4739 aname->major = name->major;
4740 aname->minor = name->minor;
4741 aname->build = name->build;
4742 aname->flags = name->flags;
4743 aname->revision = name->revision;
4744 aname->hashalg = name->hash_alg;
4745 aname->versioncompat = 1; /* SameMachine (default) */
4747 if (by_default_version)
4748 MONO_OBJECT_SETREF (aname, version, create_version (domain, name->major, name->minor, name->build, name->revision));
4750 codebase = g_filename_to_uri (absolute, NULL, NULL);
4752 MONO_OBJECT_SETREF (aname, codebase, mono_string_new (domain, codebase));
4756 if (!create_culture) {
4757 MonoMethodDesc *desc = mono_method_desc_new ("System.Globalization.CultureInfo:CreateCulture(string,bool)", TRUE);
4758 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4759 g_assert (create_culture);
4760 mono_method_desc_free (desc);
4763 if (name->culture) {
4764 args [0] = mono_string_new (domain, name->culture);
4765 args [1] = &assembly_ref;
4766 MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
4769 if (name->public_key) {
4770 pkey_ptr = (char*)name->public_key;
4771 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
4773 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4774 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
4775 aname->flags |= ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG;
4776 } else if (default_publickey) {
4777 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, 0));
4778 aname->flags |= ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG;
4781 /* MonoAssemblyName keeps the public key token as an hexadecimal string */
4782 if (name->public_key_token [0]) {
4786 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, 8));
4787 p = mono_array_addr (aname->keyToken, char, 0);
4789 for (i = 0, j = 0; i < 8; i++) {
4790 *p = g_ascii_xdigit_value (name->public_key_token [j++]) << 4;
4791 *p |= g_ascii_xdigit_value (name->public_key_token [j++]);
4794 } else if (default_token) {
4795 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, 0));
4800 ves_icall_System_Reflection_Assembly_get_fullName (MonoReflectionAssembly *assembly)
4802 MonoDomain *domain = mono_object_domain (assembly);
4803 MonoAssembly *mass = assembly->assembly;
4807 name = g_strdup_printf (
4808 "%s, Version=%d.%d.%d.%d, Culture=%s, PublicKeyToken=%s%s",
4810 mass->aname.major, mass->aname.minor, mass->aname.build, mass->aname.revision,
4811 mass->aname.culture && *mass->aname.culture? mass->aname.culture: "neutral",
4812 mass->aname.public_key_token [0] ? (char *)mass->aname.public_key_token : "null",
4813 (mass->aname.flags & ASSEMBLYREF_RETARGETABLE_FLAG) ? ", Retargetable=Yes" : "");
4815 res = mono_string_new (domain, name);
4822 ves_icall_System_Reflection_Assembly_FillName (MonoReflectionAssembly *assembly, MonoReflectionAssemblyName *aname)
4825 MonoAssembly *mass = assembly->assembly;
4827 MONO_ARCH_SAVE_REGS;
4829 if (g_path_is_absolute (mass->image->name)) {
4830 fill_reflection_assembly_name (mono_object_domain (assembly),
4831 aname, &mass->aname, mass->image->name, TRUE,
4832 TRUE, mono_get_runtime_info ()->framework_version [0] >= '2');
4835 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4837 fill_reflection_assembly_name (mono_object_domain (assembly),
4838 aname, &mass->aname, absolute, TRUE, TRUE,
4839 mono_get_runtime_info ()->framework_version [0] >= '2');
4845 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoString *fname, MonoReflectionAssemblyName *aname)
4848 MonoImageOpenStatus status = MONO_IMAGE_OK;
4851 MonoAssemblyName name;
4853 MONO_ARCH_SAVE_REGS;
4855 filename = mono_string_to_utf8 (fname);
4857 image = mono_image_open (filename, &status);
4863 if (status == MONO_IMAGE_IMAGE_INVALID)
4864 exc = mono_get_exception_bad_image_format2 (NULL, fname);
4866 exc = mono_get_exception_file_not_found2 (NULL, fname);
4867 mono_raise_exception (exc);
4870 res = mono_assembly_fill_assembly_name (image, &name);
4872 mono_image_close (image);
4874 mono_raise_exception (mono_get_exception_argument ("assemblyFile", "The file does not contain a manifest"));
4877 fill_reflection_assembly_name (mono_domain_get (), aname, &name, filename,
4878 TRUE, mono_get_runtime_info ()->framework_version [0] == '1',
4879 mono_get_runtime_info ()->framework_version [0] >= '2');
4882 mono_image_close (image);
4886 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssembly *assembly,
4887 char **minimum, guint32 *minLength, char **optional, guint32 *optLength, char **refused, guint32 *refLength)
4889 MonoBoolean result = FALSE;
4890 MonoDeclSecurityEntry entry;
4892 /* SecurityAction.RequestMinimum */
4893 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQMIN, &entry)) {
4894 *minimum = entry.blob;
4895 *minLength = entry.size;
4898 /* SecurityAction.RequestOptional */
4899 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQOPT, &entry)) {
4900 *optional = entry.blob;
4901 *optLength = entry.size;
4904 /* SecurityAction.RequestRefuse */
4905 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQREFUSE, &entry)) {
4906 *refused = entry.blob;
4907 *refLength = entry.size;
4915 mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoBoolean exportedOnly)
4919 MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
4921 guint32 attrs, visibility;
4923 /* we start the count from 1 because we skip the special type <Module> */
4926 for (i = 1; i < tdef->rows; ++i) {
4927 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
4928 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
4929 if (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)
4933 count = tdef->rows - 1;
4935 res = mono_array_new (domain, mono_defaults.monotype_class, count);
4937 for (i = 1; i < tdef->rows; ++i) {
4938 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
4939 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
4940 if (!exportedOnly || (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)) {
4941 klass = mono_class_get_throw (image, (i + 1) | MONO_TOKEN_TYPE_DEF);
4942 if (mono_loader_get_last_error ())
4943 mono_loader_clear_error ();
4944 mono_array_setref (res, count, mono_type_get_object (domain, &klass->byval_arg));
4953 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly, MonoBoolean exportedOnly)
4955 MonoArray *res = NULL;
4956 MonoImage *image = NULL;
4957 MonoTableInfo *table = NULL;
4962 MONO_ARCH_SAVE_REGS;
4964 domain = mono_object_domain (assembly);
4966 g_assert (!assembly->assembly->dynamic);
4967 image = assembly->assembly->image;
4968 table = &image->tables [MONO_TABLE_FILE];
4969 res = mono_module_get_types (domain, image, exportedOnly);
4971 /* Append data from all modules in the assembly */
4972 for (i = 0; i < table->rows; ++i) {
4973 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4974 MonoImage *loaded_image = mono_assembly_load_module (image->assembly, i + 1);
4976 MonoArray *res2 = mono_module_get_types (domain, loaded_image, exportedOnly);
4977 /* Append the new types to the end of the array */
4978 if (mono_array_length (res2) > 0) {
4982 len1 = mono_array_length (res);
4983 len2 = mono_array_length (res2);
4984 res3 = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4985 mono_array_memcpy_refs (res3, 0, res, 0, len1);
4986 mono_array_memcpy_refs (res3, len1, res2, 0, len2);
4993 /* the ReflectionTypeLoadException must have all the types (Types property),
4994 * NULL replacing types which throws an exception. The LoaderException must
4995 * contain all exceptions for NULL items.
4998 len = mono_array_length (res);
5000 for (i = 0; i < len; i++) {
5001 MonoReflectionType *t = mono_array_get (res, gpointer, i);
5002 MonoClass *klass = mono_type_get_class (t->type);
5003 if ((klass != NULL) && klass->exception_type) {
5004 /* keep the class in the list */
5005 list = g_list_append (list, klass);
5006 /* and replace Type with NULL */
5007 mono_array_setref (res, i, NULL);
5013 MonoException *exc = NULL;
5014 MonoArray *exl = NULL;
5015 int length = g_list_length (list);
5017 mono_loader_clear_error ();
5019 exl = mono_array_new (domain, mono_defaults.exception_class, length);
5020 for (i = 0, tmp = list; i < length; i++, tmp = tmp->next) {
5021 MonoException *exc = mono_class_get_exception_for_failure (tmp->data);
5022 mono_array_setref (exl, i, exc);
5027 exc = mono_get_exception_reflection_type_load (res, exl);
5028 mono_loader_clear_error ();
5029 mono_raise_exception (exc);
5036 ves_icall_System_Reflection_AssemblyName_ParseName (MonoReflectionAssemblyName *name, MonoString *assname)
5038 MonoAssemblyName aname;
5039 MonoDomain *domain = mono_object_domain (name);
5041 gboolean is_version_defined;
5042 gboolean is_token_defined;
5044 val = mono_string_to_utf8 (assname);
5045 if (!mono_assembly_name_parse_full (val, &aname, TRUE, &is_version_defined, &is_token_defined))
5048 fill_reflection_assembly_name (domain, name, &aname, "", is_version_defined,
5049 FALSE, is_token_defined);
5051 mono_assembly_name_free (&aname);
5052 g_free ((guint8*) aname.public_key);
5058 static MonoReflectionType*
5059 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModule *module)
5061 MonoDomain *domain = mono_object_domain (module);
5064 MONO_ARCH_SAVE_REGS;
5066 g_assert (module->image);
5068 if (module->image->dynamic && ((MonoDynamicImage*)(module->image))->initial_image)
5069 /* These images do not have a global type */
5072 klass = mono_class_get (module->image, 1 | MONO_TOKEN_TYPE_DEF);
5073 return mono_type_get_object (domain, &klass->byval_arg);
5077 ves_icall_System_Reflection_Module_Close (MonoReflectionModule *module)
5079 /*if (module->image)
5080 mono_image_close (module->image);*/
5084 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModule *module)
5086 MonoDomain *domain = mono_object_domain (module);
5088 MONO_ARCH_SAVE_REGS;
5090 g_assert (module->image);
5091 return mono_string_new (domain, module->image->guid);
5095 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine)
5097 if (image->dynamic) {
5098 MonoDynamicImage *dyn = (MonoDynamicImage*)image;
5099 *pe_kind = dyn->pe_kind;
5100 *machine = dyn->machine;
5103 *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
5104 *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
5109 ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage *image)
5111 return (image->md_version_major << 16) | (image->md_version_minor);
5115 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModule *module)
5117 MONO_ARCH_SAVE_REGS;
5120 return mono_array_new (mono_object_domain (module), mono_defaults.monotype_class, 0);
5122 return mono_module_get_types (mono_object_domain (module), module->image, FALSE);
5126 mono_metadata_memberref_is_method (MonoImage *image, guint32 token)
5128 guint32 cols [MONO_MEMBERREF_SIZE];
5130 mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
5131 sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
5132 mono_metadata_decode_blob_size (sig, &sig);
5133 return (*sig != 0x6);
5137 init_generic_context_from_args (MonoGenericContext *context, MonoArray *type_args, MonoArray *method_args)
5140 context->class_inst = mono_metadata_get_generic_inst (mono_array_length (type_args),
5141 mono_array_addr (type_args, MonoType*, 0));
5143 context->class_inst = NULL;
5145 context->method_inst = mono_metadata_get_generic_inst (mono_array_length (method_args),
5146 mono_array_addr (method_args, MonoType*, 0));
5148 context->method_inst = NULL;
5152 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5155 int table = mono_metadata_token_table (token);
5156 int index = mono_metadata_token_index (token);
5157 MonoGenericContext context;
5159 *error = ResolveTokenError_Other;
5161 /* Validate token */
5162 if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) &&
5163 (table != MONO_TABLE_TYPESPEC)) {
5164 *error = ResolveTokenError_BadTable;
5168 if (image->dynamic) {
5169 if (type_args || method_args)
5170 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5171 return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5174 if ((index <= 0) || (index > image->tables [table].rows)) {
5175 *error = ResolveTokenError_OutOfRange;
5179 init_generic_context_from_args (&context, type_args, method_args);
5180 klass = mono_class_get_full (image, token, &context);
5182 if (mono_loader_get_last_error ())
5183 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
5186 return &klass->byval_arg;
5192 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5194 int table = mono_metadata_token_table (token);
5195 int index = mono_metadata_token_index (token);
5196 MonoGenericContext context;
5199 *error = ResolveTokenError_Other;
5201 /* Validate token */
5202 if ((table != MONO_TABLE_METHOD) && (table != MONO_TABLE_METHODSPEC) &&
5203 (table != MONO_TABLE_MEMBERREF)) {
5204 *error = ResolveTokenError_BadTable;
5208 if (image->dynamic) {
5209 if (type_args || method_args)
5210 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5211 /* FIXME: validate memberref token type */
5212 return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5215 if ((index <= 0) || (index > image->tables [table].rows)) {
5216 *error = ResolveTokenError_OutOfRange;
5219 if ((table == MONO_TABLE_MEMBERREF) && (!mono_metadata_memberref_is_method (image, token))) {
5220 *error = ResolveTokenError_BadTable;
5224 init_generic_context_from_args (&context, type_args, method_args);
5225 method = mono_get_method_full (image, token, NULL, &context);
5227 if (mono_loader_get_last_error ())
5228 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
5234 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
5236 int index = mono_metadata_token_index (token);
5238 *error = ResolveTokenError_Other;
5240 /* Validate token */
5241 if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
5242 *error = ResolveTokenError_BadTable;
5247 return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5249 if ((index <= 0) || (index >= image->heap_us.size)) {
5250 *error = ResolveTokenError_OutOfRange;
5254 /* FIXME: What to do if the index points into the middle of a string ? */
5256 return mono_ldstr (mono_domain_get (), image, index);
5259 static MonoClassField*
5260 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5263 int table = mono_metadata_token_table (token);
5264 int index = mono_metadata_token_index (token);
5265 MonoGenericContext context;
5266 MonoClassField *field;
5268 *error = ResolveTokenError_Other;
5270 /* Validate token */
5271 if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
5272 *error = ResolveTokenError_BadTable;
5276 if (image->dynamic) {
5277 if (type_args || method_args)
5278 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5279 /* FIXME: validate memberref token type */
5280 return mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
5283 if ((index <= 0) || (index > image->tables [table].rows)) {
5284 *error = ResolveTokenError_OutOfRange;
5287 if ((table == MONO_TABLE_MEMBERREF) && (mono_metadata_memberref_is_method (image, token))) {
5288 *error = ResolveTokenError_BadTable;
5292 init_generic_context_from_args (&context, type_args, method_args);
5293 field = mono_field_from_token (image, token, &klass, &context);
5295 if (mono_loader_get_last_error ())
5296 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
5303 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5305 int table = mono_metadata_token_table (token);
5307 *error = ResolveTokenError_Other;
5310 case MONO_TABLE_TYPEDEF:
5311 case MONO_TABLE_TYPEREF:
5312 case MONO_TABLE_TYPESPEC: {
5313 MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, type_args, method_args, error);
5315 return (MonoObject*)mono_type_get_object (mono_domain_get (), t);
5319 case MONO_TABLE_METHOD:
5320 case MONO_TABLE_METHODSPEC: {
5321 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5323 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
5327 case MONO_TABLE_FIELD: {
5328 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5330 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
5334 case MONO_TABLE_MEMBERREF:
5335 if (mono_metadata_memberref_is_method (image, token)) {
5336 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5338 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
5343 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5345 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
5352 *error = ResolveTokenError_BadTable;
5359 ves_icall_System_Reflection_Module_ResolveSignature (MonoImage *image, guint32 token, MonoResolveTokenError *error)
5361 int table = mono_metadata_token_table (token);
5362 int idx = mono_metadata_token_index (token);
5363 MonoTableInfo *tables = image->tables;
5368 *error = ResolveTokenError_OutOfRange;
5370 /* FIXME: Support other tables ? */
5371 if (table != MONO_TABLE_STANDALONESIG)
5377 if ((idx == 0) || (idx > tables [MONO_TABLE_STANDALONESIG].rows))
5380 sig = mono_metadata_decode_row_col (&tables [MONO_TABLE_STANDALONESIG], idx - 1, 0);
5382 ptr = mono_metadata_blob_heap (image, sig);
5383 len = mono_metadata_decode_blob_size (ptr, &ptr);
5385 res = mono_array_new (mono_domain_get (), mono_defaults.byte_class, len);
5386 memcpy (mono_array_addr (res, guint8, 0), ptr, len);
5390 static MonoReflectionType*
5391 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
5394 int isbyref = 0, rank;
5395 char *str = mono_string_to_utf8 (smodifiers);
5398 MONO_ARCH_SAVE_REGS;
5400 klass = mono_class_from_mono_type (tb->type.type);
5402 /* logic taken from mono_reflection_parse_type(): keep in sync */
5406 if (isbyref) { /* only one level allowed by the spec */
5413 return mono_type_get_object (mono_object_domain (tb), &klass->this_arg);
5416 klass = mono_ptr_class_get (&klass->byval_arg);
5417 mono_class_init (klass);
5428 else if (*p != '*') { /* '*' means unknown lower bound */
5439 klass = mono_array_class_get (klass, rank);
5440 mono_class_init (klass);
5447 return mono_type_get_object (mono_object_domain (tb), &klass->byval_arg);
5451 ves_icall_Type_IsArrayImpl (MonoReflectionType *t)
5456 MONO_ARCH_SAVE_REGS;
5459 res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
5464 static MonoReflectionType *
5465 ves_icall_Type_make_array_type (MonoReflectionType *type, int rank)
5467 MonoClass *klass, *aklass;
5469 MONO_ARCH_SAVE_REGS;
5471 klass = mono_class_from_mono_type (type->type);
5472 aklass = mono_array_class_get (klass, rank);
5474 return mono_type_get_object (mono_object_domain (type), &aklass->byval_arg);
5477 static MonoReflectionType *
5478 ves_icall_Type_make_byref_type (MonoReflectionType *type)
5482 MONO_ARCH_SAVE_REGS;
5484 klass = mono_class_from_mono_type (type->type);
5486 return mono_type_get_object (mono_object_domain (type), &klass->this_arg);
5489 static MonoReflectionType *
5490 ves_icall_Type_MakePointerType (MonoReflectionType *type)
5494 MONO_ARCH_SAVE_REGS;
5496 pklass = mono_ptr_class_get (type->type);
5498 return mono_type_get_object (mono_object_domain (type), &pklass->byval_arg);
5502 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
5503 MonoReflectionMethod *info)
5505 MonoClass *delegate_class = mono_class_from_mono_type (type->type);
5506 MonoObject *delegate;
5509 MONO_ARCH_SAVE_REGS;
5511 mono_assert (delegate_class->parent == mono_defaults.multicastdelegate_class);
5513 delegate = mono_object_new (mono_object_domain (type), delegate_class);
5515 if (info->method->dynamic)
5516 /* Creating a trampoline would leak memory */
5517 func = mono_compile_method (info->method);
5519 func = mono_create_ftnptr (mono_domain_get (), mono_runtime_create_jump_trampoline (mono_domain_get (), info->method, TRUE));
5521 mono_delegate_ctor (delegate, target, func);
5527 ves_icall_System_Delegate_SetMulticastInvoke (MonoDelegate *this)
5529 /* Reset the invoke impl to the default one */
5530 this->invoke_impl = mono_runtime_create_delegate_trampoline (this->object.vtable->klass);
5534 * Magic number to convert a time which is relative to
5535 * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
5537 #define EPOCH_ADJUST ((guint64)62135596800LL)
5540 * Magic number to convert FILETIME base Jan 1, 1601 to DateTime - base Jan, 1, 0001
5542 #define FILETIME_ADJUST ((guint64)504911232000000000LL)
5544 #ifdef PLATFORM_WIN32
5545 /* convert a SYSTEMTIME which is of the form "last thursday in october" to a real date */
5547 convert_to_absolute_date(SYSTEMTIME *date)
5549 #define IS_LEAP(y) ((y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0))
5550 static int days_in_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5551 static int leap_days_in_month[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5552 /* from the calendar FAQ */
5553 int a = (14 - date->wMonth) / 12;
5554 int y = date->wYear - a;
5555 int m = date->wMonth + 12 * a - 2;
5556 int d = (1 + y + y/4 - y/100 + y/400 + (31*m)/12) % 7;
5558 /* d is now the day of the week for the first of the month (0 == Sunday) */
5560 int day_of_week = date->wDayOfWeek;
5562 /* set day_in_month to the first day in the month which falls on day_of_week */
5563 int day_in_month = 1 + (day_of_week - d);
5564 if (day_in_month <= 0)
5567 /* wDay is 1 for first weekday in month, 2 for 2nd ... 5 means last - so work that out allowing for days in the month */
5568 date->wDay = day_in_month + (date->wDay - 1) * 7;
5569 if (date->wDay > (IS_LEAP(date->wYear) ? leap_days_in_month[date->wMonth - 1] : days_in_month[date->wMonth - 1]))
5574 #ifndef PLATFORM_WIN32
5576 * Return's the offset from GMT of a local time.
5578 * tm is a local time
5579 * t is the same local time as seconds.
5582 gmt_offset(struct tm *tm, time_t t)
5584 #if defined (HAVE_TM_GMTOFF)
5585 return tm->tm_gmtoff;
5590 g.tm_isdst = tm->tm_isdst;
5592 return (int)difftime(t, t2);
5597 * This is heavily based on zdump.c from glibc 2.2.
5599 * * data[0]: start of daylight saving time (in DateTime ticks).
5600 * * data[1]: end of daylight saving time (in DateTime ticks).
5601 * * data[2]: utcoffset (in TimeSpan ticks).
5602 * * data[3]: additional offset when daylight saving (in TimeSpan ticks).
5603 * * name[0]: name of this timezone when not daylight saving.
5604 * * name[1]: name of this timezone when daylight saving.
5606 * FIXME: This only works with "standard" Unix dates (years between 1900 and 2100) while
5607 * the class library allows years between 1 and 9999.
5609 * Returns true on success and zero on failure.
5612 ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year, MonoArray **data, MonoArray **names)
5614 #ifndef PLATFORM_WIN32
5615 MonoDomain *domain = mono_domain_get ();
5616 struct tm start, tt;
5620 int is_daylight = 0, day;
5623 MONO_ARCH_SAVE_REGS;
5625 MONO_CHECK_ARG_NULL (data);
5626 MONO_CHECK_ARG_NULL (names);
5628 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5629 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5632 * no info is better than crashing: we'll need our own tz data
5633 * to make this work properly, anyway. The range is probably
5634 * reduced to 1970 .. 2037 because that is what mktime is
5635 * guaranteed to support (we get into an infinite loop
5639 memset (&start, 0, sizeof (start));
5642 start.tm_year = year-1900;
5644 t = mktime (&start);
5646 if ((year < 1970) || (year > 2037) || (t == -1)) {
5648 tt = *localtime (&t);
5649 strftime (tzone, sizeof (tzone), "%Z", &tt);
5650 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5651 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5655 gmtoff = gmt_offset (&start, t);
5657 /* For each day of the year, calculate the tm_gmtoff. */
5658 for (day = 0; day < 365; day++) {
5661 tt = *localtime (&t);
5663 /* Daylight saving starts or ends here. */
5664 if (gmt_offset (&tt, t) != gmtoff) {
5668 /* Try to find the exact hour when daylight saving starts/ends. */
5672 tt1 = *localtime (&t1);
5673 } while (gmt_offset (&tt1, t1) != gmtoff);
5675 /* Try to find the exact minute when daylight saving starts/ends. */
5678 tt1 = *localtime (&t1);
5679 } while (gmt_offset (&tt1, t1) == gmtoff);
5681 strftime (tzone, sizeof (tzone), "%Z", &tt);
5683 /* Write data, if we're already in daylight saving, we're done. */
5685 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5686 mono_array_set ((*data), gint64, 1, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
5689 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5690 mono_array_set ((*data), gint64, 0, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
5694 /* This is only set once when we enter daylight saving. */
5695 mono_array_set ((*data), gint64, 2, (gint64)gmtoff * 10000000L);
5696 mono_array_set ((*data), gint64, 3, (gint64)(gmt_offset (&tt, t) - gmtoff) * 10000000L);
5698 gmtoff = gmt_offset (&tt, t);
5703 strftime (tzone, sizeof (tzone), "%Z", &tt);
5704 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5705 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5706 mono_array_set ((*data), gint64, 0, 0);
5707 mono_array_set ((*data), gint64, 1, 0);
5708 mono_array_set ((*data), gint64, 2, (gint64) gmtoff * 10000000L);
5709 mono_array_set ((*data), gint64, 3, 0);
5714 MonoDomain *domain = mono_domain_get ();
5715 TIME_ZONE_INFORMATION tz_info;
5720 tz_id = GetTimeZoneInformation (&tz_info);
5721 if (tz_id == TIME_ZONE_ID_INVALID)
5724 MONO_CHECK_ARG_NULL (data);
5725 MONO_CHECK_ARG_NULL (names);
5727 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5728 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5730 for (i = 0; i < 32; ++i)
5731 if (!tz_info.DaylightName [i])
5733 mono_array_setref ((*names), 1, mono_string_new_utf16 (domain, tz_info.DaylightName, i));
5734 for (i = 0; i < 32; ++i)
5735 if (!tz_info.StandardName [i])
5737 mono_array_setref ((*names), 0, mono_string_new_utf16 (domain, tz_info.StandardName, i));
5739 if ((year <= 1601) || (year > 30827)) {
5741 * According to MSDN, the MS time functions can't handle dates outside
5747 /* even if the timezone has no daylight savings it may have Bias (e.g. GMT+13 it seems) */
5748 if (tz_id != TIME_ZONE_ID_UNKNOWN) {
5749 tz_info.StandardDate.wYear = year;
5750 convert_to_absolute_date(&tz_info.StandardDate);
5751 err = SystemTimeToFileTime (&tz_info.StandardDate, &ft);
5756 mono_array_set ((*data), gint64, 1, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
5757 tz_info.DaylightDate.wYear = year;
5758 convert_to_absolute_date(&tz_info.DaylightDate);
5759 err = SystemTimeToFileTime (&tz_info.DaylightDate, &ft);
5764 mono_array_set ((*data), gint64, 0, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
5766 mono_array_set ((*data), gint64, 2, (tz_info.Bias + tz_info.StandardBias) * -600000000LL);
5767 mono_array_set ((*data), gint64, 3, (tz_info.DaylightBias - tz_info.StandardBias) * -600000000LL);
5774 ves_icall_System_Object_obj_address (MonoObject *this)
5776 MONO_ARCH_SAVE_REGS;
5783 static inline gint32
5784 mono_array_get_byte_length (MonoArray *array)
5790 klass = array->obj.vtable->klass;
5792 if (array->bounds == NULL)
5793 length = array->max_length;
5796 for (i = 0; i < klass->rank; ++ i)
5797 length *= array->bounds [i].length;
5800 switch (klass->element_class->byval_arg.type) {
5803 case MONO_TYPE_BOOLEAN:
5807 case MONO_TYPE_CHAR:
5815 return length * sizeof (gpointer);
5826 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array)
5828 MONO_ARCH_SAVE_REGS;
5830 return mono_array_get_byte_length (array);
5834 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx)
5836 MONO_ARCH_SAVE_REGS;
5838 return mono_array_get (array, gint8, idx);
5842 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value)
5844 MONO_ARCH_SAVE_REGS;
5846 mono_array_set (array, gint8, idx, value);
5850 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count)
5852 guint8 *src_buf, *dest_buf;
5854 MONO_ARCH_SAVE_REGS;
5856 /* watch out for integer overflow */
5857 if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count))
5860 src_buf = (guint8 *)src->vector + src_offset;
5861 dest_buf = (guint8 *)dest->vector + dest_offset;
5864 memcpy (dest_buf, src_buf, count);
5866 memmove (dest_buf, src_buf, count); /* Source and dest are the same array */
5872 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this, MonoString *class_name)
5874 MonoDomain *domain = mono_object_domain (this);
5876 MonoRealProxy *rp = ((MonoRealProxy *)this);
5877 MonoTransparentProxy *tp;
5881 MONO_ARCH_SAVE_REGS;
5883 res = mono_object_new (domain, mono_defaults.transparent_proxy_class);
5884 tp = (MonoTransparentProxy*) res;
5886 MONO_OBJECT_SETREF (tp, rp, rp);
5887 type = ((MonoReflectionType *)rp->class_to_proxy)->type;
5888 klass = mono_class_from_mono_type (type);
5890 tp->custom_type_info = (mono_object_isinst (this, mono_defaults.iremotingtypeinfo_class) != NULL);
5891 tp->remote_class = mono_remote_class (domain, class_name, klass);
5893 res->vtable = mono_remote_class_vtable (domain, tp->remote_class, rp);
5897 static MonoReflectionType *
5898 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
5900 return mono_type_get_object (mono_object_domain (tp), &tp->remote_class->proxy_class->byval_arg);
5903 /* System.Environment */
5906 ves_icall_System_Environment_get_MachineName (void)
5908 #if defined (PLATFORM_WIN32)
5913 len = MAX_COMPUTERNAME_LENGTH + 1;
5914 buf = g_new (gunichar2, len);
5917 if (GetComputerName (buf, (PDWORD) &len))
5918 result = mono_string_new_utf16 (mono_domain_get (), buf, len);
5926 if (gethostname (buf, sizeof (buf)) == 0)
5927 result = mono_string_new (mono_domain_get (), buf);
5936 ves_icall_System_Environment_get_Platform (void)
5938 MONO_ARCH_SAVE_REGS;
5940 #if defined (PLATFORM_WIN32)
5950 ves_icall_System_Environment_get_NewLine (void)
5952 MONO_ARCH_SAVE_REGS;
5954 #if defined (PLATFORM_WIN32)
5955 return mono_string_new (mono_domain_get (), "\r\n");
5957 return mono_string_new (mono_domain_get (), "\n");
5962 ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name)
5967 MONO_ARCH_SAVE_REGS;
5972 utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
5973 value = g_getenv (utf8_name);
5980 return mono_string_new (mono_domain_get (), value);
5984 * There is no standard way to get at environ.
5987 #ifndef __MINGW32_VERSION
5994 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
5996 #ifdef PLATFORM_WIN32
6005 env_strings = GetEnvironmentStrings();
6008 env_string = env_strings;
6009 while (*env_string != '\0') {
6010 /* weird case that MS seems to skip */
6011 if (*env_string != '=')
6013 while (*env_string != '\0')
6019 domain = mono_domain_get ();
6020 names = mono_array_new (domain, mono_defaults.string_class, n);
6024 env_string = env_strings;
6025 while (*env_string != '\0') {
6026 /* weird case that MS seems to skip */
6027 if (*env_string != '=') {
6028 equal_str = wcschr(env_string, '=');
6029 g_assert(equal_str);
6030 str = mono_string_new_utf16 (domain, env_string, equal_str-env_string);
6031 mono_array_setref (names, n, str);
6034 while (*env_string != '\0')
6039 FreeEnvironmentStrings (env_strings);
6051 MONO_ARCH_SAVE_REGS;
6054 for (e = environ; *e != 0; ++ e)
6057 domain = mono_domain_get ();
6058 names = mono_array_new (domain, mono_defaults.string_class, n);
6061 for (e = environ; *e != 0; ++ e) {
6062 parts = g_strsplit (*e, "=", 2);
6064 str = mono_string_new (domain, *parts);
6065 mono_array_setref (names, n, str);
6078 * If your platform lacks setenv/unsetenv, you must upgrade your glib.
6080 #if !GLIB_CHECK_VERSION(2,4,0)
6081 #define g_setenv(a,b,c) setenv(a,b,c)
6082 #define g_unsetenv(a) unsetenv(a)
6086 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
6088 #ifdef PLATFORM_WIN32
6089 gunichar2 *utf16_name, *utf16_value;
6091 gchar *utf8_name, *utf8_value;
6094 MONO_ARCH_SAVE_REGS;
6096 #ifdef PLATFORM_WIN32
6097 utf16_name = mono_string_to_utf16 (name);
6098 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
6099 SetEnvironmentVariable (utf16_name, NULL);
6100 g_free (utf16_name);
6104 utf16_value = mono_string_to_utf16 (value);
6106 SetEnvironmentVariable (utf16_name, utf16_value);
6108 g_free (utf16_name);
6109 g_free (utf16_value);
6111 utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
6113 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
6114 g_unsetenv (utf8_name);
6119 utf8_value = mono_string_to_utf8 (value);
6120 g_setenv (utf8_name, utf8_value, TRUE);
6123 g_free (utf8_value);
6128 ves_icall_System_Environment_Exit (int result)
6130 MONO_ARCH_SAVE_REGS;
6132 if (!mono_threads_set_shutting_down ())
6135 mono_runtime_set_shutting_down ();
6137 /* Suspend all managed threads since the runtime is going away */
6138 mono_thread_suspend_all_other_threads ();
6140 mono_runtime_quit ();
6142 /* we may need to do some cleanup here... */
6147 ves_icall_System_Environment_GetGacPath (void)
6149 return mono_string_new (mono_domain_get (), mono_assembly_getrootdir ());
6153 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
6155 #if defined (PLATFORM_WIN32)
6156 #ifndef CSIDL_FLAG_CREATE
6157 #define CSIDL_FLAG_CREATE 0x8000
6160 WCHAR path [MAX_PATH];
6161 /* Create directory if no existing */
6162 if (SUCCEEDED (SHGetFolderPathW (NULL, folder | CSIDL_FLAG_CREATE, NULL, 0, path))) {
6166 return mono_string_new_utf16 (mono_domain_get (), path, len);
6169 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
6171 return mono_string_new (mono_domain_get (), "");
6175 ves_icall_System_Environment_GetLogicalDrives (void)
6177 gunichar2 buf [128], *ptr, *dname;
6179 gint initial_size = 127, size = 128;
6182 MonoString *drivestr;
6183 MonoDomain *domain = mono_domain_get ();
6186 MONO_ARCH_SAVE_REGS;
6191 while (size > initial_size) {
6192 size = GetLogicalDriveStrings (initial_size, ptr);
6193 if (size > initial_size) {
6196 ptr = g_malloc0 ((size + 1) * sizeof (gunichar2));
6197 initial_size = size;
6211 result = mono_array_new (domain, mono_defaults.string_class, ndrives);
6216 while (*u16) { u16++; len ++; }
6217 drivestr = mono_string_new_utf16 (domain, dname, len);
6218 mono_array_setref (result, ndrives++, drivestr);
6229 ves_icall_System_Environment_InternalGetHome (void)
6231 MONO_ARCH_SAVE_REGS;
6233 return mono_string_new (mono_domain_get (), g_get_home_dir ());
6236 static const char *encodings [] = {
6238 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
6239 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
6240 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
6242 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
6243 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
6244 "x_unicode_2_0_utf_7",
6246 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
6247 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
6249 "utf_16", "UTF_16LE", "ucs_2", "unicode",
6252 "unicodefffe", "utf_16be",
6259 * Returns the internal codepage, if the value of "int_code_page" is
6260 * 1 at entry, and we can not compute a suitable code page number,
6261 * returns the code page as a string
6264 ves_icall_System_Text_Encoding_InternalCodePage (gint32 *int_code_page)
6269 char *codepage = NULL;
6271 int want_name = *int_code_page;
6274 *int_code_page = -1;
6275 MONO_ARCH_SAVE_REGS;
6277 g_get_charset (&cset);
6278 c = codepage = strdup (cset);
6279 for (c = codepage; *c; c++){
6280 if (isascii (*c) && isalpha (*c))
6285 /* g_print ("charset: %s\n", cset); */
6287 /* handle some common aliases */
6290 for (i = 0; p != 0; ){
6291 if ((gssize) p < 7){
6293 p = encodings [++i];
6296 if (strcmp (p, codepage) == 0){
6297 *int_code_page = code;
6300 p = encodings [++i];
6303 if (strstr (codepage, "utf_8") != NULL)
6304 *int_code_page |= 0x10000000;
6307 if (want_name && *int_code_page == -1)
6308 return mono_string_new (mono_domain_get (), cset);
6314 ves_icall_System_Environment_get_HasShutdownStarted (void)
6316 if (mono_runtime_is_shutting_down ())
6319 if (mono_domain_is_unloading (mono_domain_get ()))
6326 ves_icall_MonoMethodMessage_InitMessage (MonoMethodMessage *this,
6327 MonoReflectionMethod *method,
6328 MonoArray *out_args)
6330 MONO_ARCH_SAVE_REGS;
6332 mono_message_init (mono_object_domain (this), this, method, out_args);
6336 ves_icall_IsTransparentProxy (MonoObject *proxy)
6338 MONO_ARCH_SAVE_REGS;
6343 if (proxy->vtable->klass == mono_defaults.transparent_proxy_class)
6349 static MonoReflectionMethod *
6350 ves_icall_Remoting_RemotingServices_GetVirtualMethod (
6351 MonoReflectionType *rtype, MonoReflectionMethod *rmethod)
6355 MonoMethod **vtable;
6356 MonoMethod *res = NULL;
6358 MONO_CHECK_ARG_NULL (rtype);
6359 MONO_CHECK_ARG_NULL (rmethod);
6361 method = rmethod->method;
6362 klass = mono_class_from_mono_type (rtype->type);
6364 if (MONO_CLASS_IS_INTERFACE (klass))
6367 if (method->flags & METHOD_ATTRIBUTE_STATIC)
6370 if ((method->flags & METHOD_ATTRIBUTE_FINAL) || !(method->flags & METHOD_ATTRIBUTE_VIRTUAL)) {
6371 if (klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE))
6377 mono_class_setup_vtable (klass);
6378 vtable = klass->vtable;
6380 if (method->klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
6381 int offs = mono_class_interface_offset (klass, method->klass);
6383 res = vtable [offs + method->slot];
6385 if (!(klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE)))
6388 if (method->slot != -1)
6389 res = vtable [method->slot];
6395 return mono_method_get_object (mono_domain_get (), res, NULL);
6399 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6404 MONO_ARCH_SAVE_REGS;
6406 klass = mono_class_from_mono_type (type->type);
6407 vtable = mono_class_vtable (mono_domain_get (), klass);
6409 if (enable) vtable->remote = 1;
6410 else vtable->remote = 0;
6414 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type)
6419 MONO_ARCH_SAVE_REGS;
6421 domain = mono_object_domain (type);
6422 klass = mono_class_from_mono_type (type->type);
6424 if (klass->rank >= 1) {
6425 g_assert (klass->rank == 1);
6426 return (MonoObject *) mono_array_new (domain, klass->element_class, 0);
6428 /* Bypass remoting object creation check */
6429 return mono_object_new_alloc_specific (mono_class_vtable (domain, klass));
6434 ves_icall_System_IO_get_temp_path (void)
6436 MONO_ARCH_SAVE_REGS;
6438 return mono_string_new (mono_domain_get (), g_get_tmp_dir ());
6442 ves_icall_RuntimeMethod_GetFunctionPointer (MonoMethod *method)
6444 MONO_ARCH_SAVE_REGS;
6446 return mono_compile_method (method);
6450 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
6455 MONO_ARCH_SAVE_REGS;
6457 path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
6459 #if defined (PLATFORM_WIN32)
6460 /* Avoid mixing '/' and '\\' */
6463 for (i = strlen (path) - 1; i >= 0; i--)
6464 if (path [i] == '/')
6468 mcpath = mono_string_new (mono_domain_get (), path);
6475 get_bundled_machine_config (void)
6477 const gchar *machine_config;
6479 MONO_ARCH_SAVE_REGS;
6481 machine_config = mono_get_machine_config ();
6483 if (!machine_config)
6486 return mono_string_new (mono_domain_get (), machine_config);
6490 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
6495 MONO_ARCH_SAVE_REGS;
6497 path = g_path_get_dirname (mono_get_config_dir ());
6499 #if defined (PLATFORM_WIN32)
6500 /* Avoid mixing '/' and '\\' */
6503 for (i = strlen (path) - 1; i >= 0; i--)
6504 if (path [i] == '/')
6508 ipath = mono_string_new (mono_domain_get (), path);
6515 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
6517 #if defined (PLATFORM_WIN32)
6518 OutputDebugString (mono_string_chars (message));
6520 g_warning ("WriteWindowsDebugString called and PLATFORM_WIN32 not defined!\n");
6524 /* Only used for value types */
6526 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
6531 MONO_ARCH_SAVE_REGS;
6533 domain = mono_object_domain (type);
6534 klass = mono_class_from_mono_type (type->type);
6536 if (mono_class_is_nullable (klass))
6537 /* No arguments -> null */
6540 return mono_object_new (domain, klass);
6543 static MonoReflectionMethod *
6544 ves_icall_MonoMethod_get_base_definition (MonoReflectionMethod *m)
6546 MonoClass *klass, *parent;
6547 MonoMethod *method = m->method;
6548 MonoMethod *result = NULL;
6550 MONO_ARCH_SAVE_REGS;
6552 if (method->klass == NULL)
6555 if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
6556 MONO_CLASS_IS_INTERFACE (method->klass) ||
6557 method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
6560 klass = method->klass;
6561 if (klass->generic_class)
6562 klass = klass->generic_class->container_class;
6564 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
6565 for (parent = klass->parent; parent != NULL; parent = parent->parent) {
6566 mono_class_setup_vtable (parent);
6567 if (parent->vtable_size <= method->slot)
6572 if (klass == method->klass)
6575 result = klass->vtable [method->slot];
6576 if (result == NULL) {
6577 /* It is an abstract method */
6578 gpointer iter = NULL;
6579 while ((result = mono_class_get_methods (klass, &iter)))
6580 if (result->slot == method->slot)
6587 return mono_method_get_object (mono_domain_get (), result, NULL);
6591 ves_icall_MonoMethod_get_name (MonoReflectionMethod *m)
6593 MonoMethod *method = m->method;
6595 MONO_OBJECT_SETREF (m, name, mono_string_new (mono_object_domain (m), method->name));
6600 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
6602 MONO_ARCH_SAVE_REGS;
6604 iter->sig = *(MonoMethodSignature**)argsp;
6606 g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
6607 g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
6610 /* FIXME: it's not documented what start is exactly... */
6614 guint32 i, arg_size;
6616 iter->args = argsp + sizeof (gpointer);
6617 #ifndef MONO_ARCH_REGPARMS
6618 for (i = 0; i < iter->sig->sentinelpos; ++i) {
6619 arg_size = mono_type_stack_size (iter->sig->params [i], &align);
6620 iter->args = (char*)iter->args + arg_size;
6624 iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
6626 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
6630 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
6632 guint32 i, arg_size;
6635 MONO_ARCH_SAVE_REGS;
6637 i = iter->sig->sentinelpos + iter->next_arg;
6639 g_assert (i < iter->sig->param_count);
6641 res.type = iter->sig->params [i];
6642 res.klass = mono_class_from_mono_type (res.type);
6643 /* FIXME: endianess issue... */
6644 res.value = iter->args;
6645 arg_size = mono_type_stack_size (res.type, &align);
6646 iter->args = (char*)iter->args + arg_size;
6649 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6655 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
6657 guint32 i, arg_size;
6660 MONO_ARCH_SAVE_REGS;
6662 i = iter->sig->sentinelpos + iter->next_arg;
6664 g_assert (i < iter->sig->param_count);
6666 while (i < iter->sig->param_count) {
6667 if (!mono_metadata_type_equal (type, iter->sig->params [i]))
6669 res.type = iter->sig->params [i];
6670 res.klass = mono_class_from_mono_type (res.type);
6671 /* FIXME: endianess issue... */
6672 res.value = iter->args;
6673 arg_size = mono_type_stack_size (res.type, &align);
6674 iter->args = (char*)iter->args + arg_size;
6676 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6679 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
6688 mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
6691 MONO_ARCH_SAVE_REGS;
6693 i = iter->sig->sentinelpos + iter->next_arg;
6695 g_assert (i < iter->sig->param_count);
6697 return iter->sig->params [i];
6701 mono_TypedReference_ToObject (MonoTypedRef tref)
6703 MONO_ARCH_SAVE_REGS;
6705 if (MONO_TYPE_IS_REFERENCE (tref.type)) {
6706 MonoObject** objp = tref.value;
6710 return mono_value_box (mono_domain_get (), tref.klass, tref.value);
6714 mono_TypedReference_ToObjectInternal (MonoType *type, gpointer value, MonoClass *klass)
6716 MONO_ARCH_SAVE_REGS;
6718 if (MONO_TYPE_IS_REFERENCE (type)) {
6719 MonoObject** objp = value;
6723 return mono_value_box (mono_domain_get (), klass, value);
6727 prelink_method (MonoMethod *method)
6729 const char *exc_class, *exc_arg;
6730 if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
6732 mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
6734 mono_raise_exception(
6735 mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg ) );
6737 /* create the wrapper, too? */
6741 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
6743 MONO_ARCH_SAVE_REGS;
6744 prelink_method (method->method);
6748 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
6750 MonoClass *klass = mono_class_from_mono_type (type->type);
6752 gpointer iter = NULL;
6753 MONO_ARCH_SAVE_REGS;
6755 while ((m = mono_class_get_methods (klass, &iter)))
6759 /* These parameters are "readonly" in corlib/System/NumberFormatter.cs */
6761 ves_icall_System_NumberFormatter_GetFormatterTables (guint64 const **mantissas,
6762 gint32 const **exponents,
6763 gunichar2 const **digitLowerTable,
6764 gunichar2 const **digitUpperTable,
6765 gint64 const **tenPowersList,
6766 gint32 const **decHexDigits)
6768 *mantissas = Formatter_MantissaBitsTable;
6769 *exponents = Formatter_TensExponentTable;
6770 *digitLowerTable = Formatter_DigitLowerTable;
6771 *digitUpperTable = Formatter_DigitUpperTable;
6772 *tenPowersList = Formatter_TenPowersList;
6773 *decHexDigits = Formatter_DecHexDigits;
6776 /* These parameters are "readonly" in corlib/System/Char.cs */
6778 ves_icall_System_Char_GetDataTablePointers (guint8 const **category_data,
6779 guint8 const **numeric_data,
6780 gdouble const **numeric_data_values,
6781 guint16 const **to_lower_data_low,
6782 guint16 const **to_lower_data_high,
6783 guint16 const **to_upper_data_low,
6784 guint16 const **to_upper_data_high)
6786 *category_data = CategoryData;
6787 *numeric_data = NumericData;
6788 *numeric_data_values = NumericDataValues;
6789 *to_lower_data_low = ToLowerDataLow;
6790 *to_lower_data_high = ToLowerDataHigh;
6791 *to_upper_data_low = ToUpperDataLow;
6792 *to_upper_data_high = ToUpperDataHigh;
6796 ves_icall_MonoDebugger_GetMethodToken (MonoReflectionMethod *method)
6798 return method->method->token;
6802 * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
6803 * and avoid useless allocations.
6806 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional)
6810 for (i = 0; i < type->num_mods; ++i) {
6811 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
6816 res = mono_array_new (mono_domain_get (), mono_defaults.systemtype_class, count);
6818 for (i = 0; i < type->num_mods; ++i) {
6819 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
6820 MonoClass *klass = mono_class_get (image, type->modifiers [i].token);
6821 mono_array_setref (res, count, mono_type_get_object (mono_domain_get (), &klass->byval_arg));
6829 param_info_get_type_modifiers (MonoReflectionParameter *param, MonoBoolean optional)
6831 MonoType *type = param->ClassImpl->type;
6832 MonoReflectionMethod *method = (MonoReflectionMethod*)param->MemberImpl;
6833 MonoImage *image = method->method->klass->image;
6834 int pos = param->PositionImpl;
6835 MonoMethodSignature *sig = mono_method_signature (method->method);
6839 type = sig->params [pos];
6841 return type_array_from_modifiers (image, type, optional);
6845 get_property_type (MonoProperty *prop)
6847 MonoMethodSignature *sig;
6849 sig = mono_method_signature (prop->get);
6851 } else if (prop->set) {
6852 sig = mono_method_signature (prop->set);
6853 return sig->params [sig->param_count - 1];
6859 property_info_get_type_modifiers (MonoReflectionProperty *property, MonoBoolean optional)
6861 MonoType *type = get_property_type (property->property);
6862 MonoImage *image = property->klass->image;
6866 return type_array_from_modifiers (image, type, optional);
6870 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
6872 MonoCustomAttrInfo *cinfo;
6875 cinfo = mono_reflection_get_custom_attrs_info (obj);
6878 found = mono_custom_attrs_has_attr (cinfo, mono_class_from_mono_type (attr_type->type));
6880 mono_custom_attrs_free (cinfo);
6885 custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
6887 MonoArray *res = mono_reflection_get_custom_attrs_by_type (obj, attr_type ? mono_class_from_mono_type (attr_type->type) : NULL);
6889 if (mono_loader_get_last_error ()) {
6890 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
6891 g_assert_not_reached ();
6898 GCHandle_CheckCurrentDomain (guint32 gchandle)
6900 return mono_gchandle_is_in_domain (gchandle, mono_domain_get ());
6904 ves_icall_Mono_Runtime_GetDisplayName (void)
6906 static const char display_name_str [] = "Mono " VERSION;
6907 MonoString *display_name = mono_string_new (mono_domain_get (), display_name_str);
6908 return display_name;
6913 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
6914 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
6915 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 62, 128, 128, 128, 63,
6916 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 0, 128, 128,
6917 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
6918 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 128, 128, 128, 128, 128,
6919 128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
6920 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
6924 base64_to_byte_array (gunichar2 *start, gint ilength, MonoBoolean allowWhitespaceOnly)
6929 gunichar2 last, prev_last;
6937 last = prev_last = 0;
6938 for (i = 0; i < ilength; i++) {
6940 if (c >= sizeof (dbase64)) {
6941 exc = mono_exception_from_name_msg (mono_get_corlib (),
6942 "System", "FormatException",
6943 "Invalid character found.");
6944 mono_raise_exception (exc);
6945 } else if (isspace (c)) {
6953 olength = ilength - ignored;
6955 if (allowWhitespaceOnly && olength == 0) {
6956 return mono_array_new (mono_domain_get (), mono_defaults.byte_class, 0);
6959 if ((olength & 3) != 0 || olength <= 0) {
6960 exc = mono_exception_from_name_msg (mono_get_corlib (), "System",
6961 "FormatException", "Invalid length.");
6962 mono_raise_exception (exc);
6965 olength = (olength * 3) / 4;
6969 if (prev_last == '=')
6972 result = mono_array_new (mono_domain_get (), mono_defaults.byte_class, olength);
6973 res_ptr = mono_array_addr (result, guchar, 0);
6974 for (i = 0; i < ilength; ) {
6977 for (k = 0; k < 4 && i < ilength;) {
6983 if (((b [k] = dbase64 [c]) & 0x80) != 0) {
6984 exc = mono_exception_from_name_msg (mono_get_corlib (),
6985 "System", "FormatException",
6986 "Invalid character found.");
6987 mono_raise_exception (exc);
6992 *res_ptr++ = (b [0] << 2) | (b [1] >> 4);
6994 *res_ptr++ = (b [1] << 4) | (b [2] >> 2);
6996 *res_ptr++ = (b [2] << 6) | b [3];
6998 while (i < ilength && isspace (start [i]))
7006 InternalFromBase64String (MonoString *str, MonoBoolean allowWhitespaceOnly)
7008 MONO_ARCH_SAVE_REGS;
7010 return base64_to_byte_array (mono_string_chars (str),
7011 mono_string_length (str), allowWhitespaceOnly);
7015 InternalFromBase64CharArray (MonoArray *input, gint offset, gint length)
7017 MONO_ARCH_SAVE_REGS;
7019 return base64_to_byte_array (mono_array_addr (input, gunichar2, offset),
7023 #define ICALL_TYPE(id,name,first)
7024 #define ICALL(id,name,func) Icall_ ## id,
7027 #include "metadata/icall-def.h"
7033 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
7034 #define ICALL(id,name,func)
7036 #include "metadata/icall-def.h"
7042 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
7043 #define ICALL(id,name,func)
7045 guint16 first_icall;
7048 static const IcallTypeDesc
7049 icall_type_descs [] = {
7050 #include "metadata/icall-def.h"
7054 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
7057 #define ICALL_TYPE(id,name,first)
7060 #ifdef HAVE_ARRAY_ELEM_INIT
7061 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
7062 #define MSGSTRFIELD1(line) str##line
7064 static const struct msgstrtn_t {
7065 #define ICALL(id,name,func)
7067 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7068 #include "metadata/icall-def.h"
7070 } icall_type_names_str = {
7071 #define ICALL_TYPE(id,name,first) (name),
7072 #include "metadata/icall-def.h"
7075 static const guint16 icall_type_names_idx [] = {
7076 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
7077 #include "metadata/icall-def.h"
7080 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
7082 static const struct msgstr_t {
7084 #define ICALL_TYPE(id,name,first)
7085 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7086 #include "metadata/icall-def.h"
7088 } icall_names_str = {
7089 #define ICALL(id,name,func) (name),
7090 #include "metadata/icall-def.h"
7093 static const guint16 icall_names_idx [] = {
7094 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
7095 #include "metadata/icall-def.h"
7098 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
7104 #define ICALL_TYPE(id,name,first) name,
7105 #define ICALL(id,name,func)
7106 static const char* const
7107 icall_type_names [] = {
7108 #include "metadata/icall-def.h"
7112 #define icall_type_name_get(id) (icall_type_names [(id)])
7116 #define ICALL_TYPE(id,name,first)
7117 #define ICALL(id,name,func) name,
7118 static const char* const
7120 #include "metadata/icall-def.h"
7123 #define icall_name_get(id) icall_names [(id)]
7125 #endif /* !HAVE_ARRAY_ELEM_INIT */
7129 #define ICALL_TYPE(id,name,first)
7130 #define ICALL(id,name,func) func,
7131 static const gconstpointer
7132 icall_functions [] = {
7133 #include "metadata/icall-def.h"
7137 static GHashTable *icall_hash = NULL;
7138 static GHashTable *jit_icall_hash_name = NULL;
7139 static GHashTable *jit_icall_hash_addr = NULL;
7142 mono_icall_init (void)
7146 /* check that tables are sorted: disable in release */
7149 const char *prev_class = NULL;
7150 const char *prev_method;
7152 for (i = 0; i < Icall_type_num; ++i) {
7153 const IcallTypeDesc *desc;
7156 if (prev_class && strcmp (prev_class, icall_type_name_get (i)) >= 0)
7157 g_print ("class %s should come before class %s\n", icall_type_name_get (i), prev_class);
7158 prev_class = icall_type_name_get (i);
7159 desc = &icall_type_descs [i];
7160 num_icalls = icall_desc_num_icalls (desc);
7161 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
7162 for (j = 0; j < num_icalls; ++j) {
7163 const char *methodn = icall_name_get (desc->first_icall + j);
7164 if (prev_method && strcmp (prev_method, methodn) >= 0)
7165 g_print ("method %s should come before method %s\n", methodn, prev_method);
7166 prev_method = methodn;
7171 icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
7175 mono_icall_cleanup (void)
7177 g_hash_table_destroy (icall_hash);
7178 g_hash_table_destroy (jit_icall_hash_name);
7179 g_hash_table_destroy (jit_icall_hash_addr);
7183 mono_add_internal_call (const char *name, gconstpointer method)
7185 mono_loader_lock ();
7187 g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
7189 mono_loader_unlock ();
7192 #ifdef HAVE_ARRAY_ELEM_INIT
7194 compare_method_imap (const void *key, const void *elem)
7196 const char* method_name = (const char*)&icall_names_str + (*(guint16*)elem);
7197 return strcmp (key, method_name);
7201 find_method_icall (const IcallTypeDesc *imap, const char *name)
7203 const guint16 *nameslot = bsearch (name, icall_names_idx + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names_idx [0]), compare_method_imap);
7206 return (gpointer)icall_functions [(nameslot - &icall_names_idx [0])];
7210 compare_class_imap (const void *key, const void *elem)
7212 const char* class_name = (const char*)&icall_type_names_str + (*(guint16*)elem);
7213 return strcmp (key, class_name);
7216 static const IcallTypeDesc*
7217 find_class_icalls (const char *name)
7219 const guint16 *nameslot = bsearch (name, icall_type_names_idx, Icall_type_num, sizeof (icall_type_names_idx [0]), compare_class_imap);
7222 return &icall_type_descs [nameslot - &icall_type_names_idx [0]];
7227 compare_method_imap (const void *key, const void *elem)
7229 const char** method_name = (const char**)elem;
7230 return strcmp (key, *method_name);
7234 find_method_icall (const IcallTypeDesc *imap, const char *name)
7236 const char **nameslot = bsearch (name, icall_names + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names [0]), compare_method_imap);
7239 return (gpointer)icall_functions [(nameslot - icall_names)];
7243 compare_class_imap (const void *key, const void *elem)
7245 const char** class_name = (const char**)elem;
7246 return strcmp (key, *class_name);
7249 static const IcallTypeDesc*
7250 find_class_icalls (const char *name)
7252 const char **nameslot = bsearch (name, icall_type_names, Icall_type_num, sizeof (icall_type_names [0]), compare_class_imap);
7255 return &icall_type_descs [nameslot - icall_type_names];
7261 * we should probably export this as an helper (handle nested types).
7262 * Returns the number of chars written in buf.
7265 concat_class_name (char *buf, int bufsize, MonoClass *klass)
7267 int nspacelen, cnamelen;
7268 nspacelen = strlen (klass->name_space);
7269 cnamelen = strlen (klass->name);
7270 if (nspacelen + cnamelen + 2 > bufsize)
7273 memcpy (buf, klass->name_space, nspacelen);
7274 buf [nspacelen ++] = '.';
7276 memcpy (buf + nspacelen, klass->name, cnamelen);
7277 buf [nspacelen + cnamelen] = 0;
7278 return nspacelen + cnamelen;
7282 mono_lookup_internal_call (MonoMethod *method)
7287 int typelen = 0, mlen, siglen;
7289 const IcallTypeDesc *imap;
7291 g_assert (method != NULL);
7293 if (method->is_inflated)
7294 method = ((MonoMethodInflated *) method)->declaring;
7296 if (method->klass->nested_in) {
7297 int pos = concat_class_name (mname, sizeof (mname)-2, method->klass->nested_in);
7301 mname [pos++] = '/';
7304 typelen = concat_class_name (mname+pos, sizeof (mname)-pos-1, method->klass);
7310 typelen = concat_class_name (mname, sizeof (mname), method->klass);
7315 imap = find_class_icalls (mname);
7317 mname [typelen] = ':';
7318 mname [typelen + 1] = ':';
7320 mlen = strlen (method->name);
7321 memcpy (mname + typelen + 2, method->name, mlen);
7322 sigstart = mname + typelen + 2 + mlen;
7325 tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
7326 siglen = strlen (tmpsig);
7327 if (typelen + mlen + siglen + 6 > sizeof (mname))
7330 memcpy (sigstart + 1, tmpsig, siglen);
7331 sigstart [siglen + 1] = ')';
7332 sigstart [siglen + 2] = 0;
7335 mono_loader_lock ();
7337 res = g_hash_table_lookup (icall_hash, mname);
7339 mono_loader_unlock ();
7342 /* try without signature */
7344 res = g_hash_table_lookup (icall_hash, mname);
7346 mono_loader_unlock ();
7350 /* it wasn't found in the static call tables */
7352 mono_loader_unlock ();
7355 res = find_method_icall (imap, sigstart - mlen);
7357 mono_loader_unlock ();
7360 /* try _with_ signature */
7362 res = find_method_icall (imap, sigstart - mlen);
7364 mono_loader_unlock ();
7368 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname);
7369 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
7370 g_print ("The out of sync library is: %s\n", method->klass->image->name);
7371 g_print ("\nWhen you update one from cvs you need to update, compile and install\nthe other too.\n");
7372 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");
7373 g_print ("If you see other errors or faults after this message they are probably related\n");
7374 g_print ("and you need to fix your mono install first.\n");
7376 mono_loader_unlock ();
7382 type_from_typename (char *typename)
7384 MonoClass *klass = NULL; /* assignment to shut GCC warning up */
7386 if (!strcmp (typename, "int"))
7387 klass = mono_defaults.int_class;
7388 else if (!strcmp (typename, "ptr"))
7389 klass = mono_defaults.int_class;
7390 else if (!strcmp (typename, "void"))
7391 klass = mono_defaults.void_class;
7392 else if (!strcmp (typename, "int32"))
7393 klass = mono_defaults.int32_class;
7394 else if (!strcmp (typename, "uint32"))
7395 klass = mono_defaults.uint32_class;
7396 else if (!strcmp (typename, "int8"))
7397 klass = mono_defaults.sbyte_class;
7398 else if (!strcmp (typename, "uint8"))
7399 klass = mono_defaults.byte_class;
7400 else if (!strcmp (typename, "int16"))
7401 klass = mono_defaults.int16_class;
7402 else if (!strcmp (typename, "uint16"))
7403 klass = mono_defaults.uint16_class;
7404 else if (!strcmp (typename, "long"))
7405 klass = mono_defaults.int64_class;
7406 else if (!strcmp (typename, "ulong"))
7407 klass = mono_defaults.uint64_class;
7408 else if (!strcmp (typename, "float"))
7409 klass = mono_defaults.single_class;
7410 else if (!strcmp (typename, "double"))
7411 klass = mono_defaults.double_class;
7412 else if (!strcmp (typename, "object"))
7413 klass = mono_defaults.object_class;
7414 else if (!strcmp (typename, "obj"))
7415 klass = mono_defaults.object_class;
7418 g_assert_not_reached ();
7420 return &klass->byval_arg;
7423 MonoMethodSignature*
7424 mono_create_icall_signature (const char *sigstr)
7429 MonoMethodSignature *res;
7431 mono_loader_lock ();
7432 res = g_hash_table_lookup (mono_defaults.corlib->helper_signatures, sigstr);
7434 mono_loader_unlock ();
7438 parts = g_strsplit (sigstr, " ", 256);
7447 res = mono_metadata_signature_alloc (mono_defaults.corlib, len - 1);
7450 #ifdef PLATFORM_WIN32
7452 * Under windows, the default pinvoke calling convention is STDCALL but
7455 res->call_convention = MONO_CALL_C;
7458 res->ret = type_from_typename (parts [0]);
7459 for (i = 1; i < len; ++i) {
7460 res->params [i - 1] = type_from_typename (parts [i]);
7465 g_hash_table_insert (mono_defaults.corlib->helper_signatures, (gpointer)sigstr, res);
7467 mono_loader_unlock ();
7473 mono_find_jit_icall_by_name (const char *name)
7475 MonoJitICallInfo *info;
7476 g_assert (jit_icall_hash_name);
7478 mono_loader_lock ();
7479 info = g_hash_table_lookup (jit_icall_hash_name, name);
7480 mono_loader_unlock ();
7485 mono_find_jit_icall_by_addr (gconstpointer addr)
7487 MonoJitICallInfo *info;
7488 g_assert (jit_icall_hash_addr);
7490 mono_loader_lock ();
7491 info = g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
7492 mono_loader_unlock ();
7498 mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
7500 mono_loader_lock ();
7501 g_hash_table_insert (jit_icall_hash_addr, (gpointer)wrapper, info);
7502 mono_loader_unlock ();
7506 mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
7508 MonoJitICallInfo *info;
7513 mono_loader_lock ();
7515 if (!jit_icall_hash_name) {
7516 jit_icall_hash_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
7517 jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
7520 if (g_hash_table_lookup (jit_icall_hash_name, name)) {
7521 g_warning ("jit icall already defined \"%s\"\n", name);
7522 g_assert_not_reached ();
7525 info = g_new0 (MonoJitICallInfo, 1);
7532 info->wrapper = func;
7534 info->wrapper = NULL;
7537 g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
7538 g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
7540 mono_loader_unlock ();