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/security-manager.h>
61 #include <mono/io-layer/io-layer.h>
62 #include <mono/utils/strtod.h>
63 #include <mono/utils/monobitset.h>
65 #if defined (PLATFORM_WIN32)
71 static MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void);
74 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional);
76 static inline MonoBoolean
77 is_generic_parameter (MonoType *type)
79 return !type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR);
83 * We expect a pointer to a char, not a string
86 mono_double_ParseImpl (char *ptr, double *result)
95 *result = strtod (ptr, &endptr);
98 *result = bsd_strtod (ptr, &endptr);
101 if (!*ptr || (endptr && *endptr))
108 mono_class_get_throw (MonoImage *image, guint32 type_token)
110 MonoClass *class = mono_class_get (image, type_token);
111 MonoLoaderError *error;
117 error = mono_loader_get_last_error ();
118 g_assert (error != NULL);
120 ex = mono_loader_error_prepare_exception (error);
121 mono_raise_exception (ex);
126 ves_icall_System_Array_GetValueImpl (MonoObject *this, guint32 pos)
135 ao = (MonoArray *)this;
136 ac = (MonoClass *)ao->obj.vtable->klass;
138 esize = mono_array_element_size (ac);
139 ea = (gpointer*)((char*)ao->vector + (pos * esize));
141 if (ac->element_class->valuetype)
142 return mono_value_box (this->vtable->domain, ac->element_class, ea);
148 ves_icall_System_Array_GetValue (MonoObject *this, MonoObject *idxs)
156 MONO_CHECK_ARG_NULL (idxs);
158 io = (MonoArray *)idxs;
159 ic = (MonoClass *)io->obj.vtable->klass;
161 ao = (MonoArray *)this;
162 ac = (MonoClass *)ao->obj.vtable->klass;
164 g_assert (ic->rank == 1);
165 if (io->bounds != NULL || io->max_length != ac->rank)
166 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
168 ind = (gint32 *)io->vector;
170 if (ao->bounds == NULL) {
171 if (*ind < 0 || *ind >= ao->max_length)
172 mono_raise_exception (mono_get_exception_index_out_of_range ());
174 return ves_icall_System_Array_GetValueImpl (this, *ind);
177 for (i = 0; i < ac->rank; i++)
178 if ((ind [i] < ao->bounds [i].lower_bound) ||
179 (ind [i] >= ao->bounds [i].length + ao->bounds [i].lower_bound))
180 mono_raise_exception (mono_get_exception_index_out_of_range ());
182 pos = ind [0] - ao->bounds [0].lower_bound;
183 for (i = 1; i < ac->rank; i++)
184 pos = pos*ao->bounds [i].length + ind [i] -
185 ao->bounds [i].lower_bound;
187 return ves_icall_System_Array_GetValueImpl (this, pos);
191 ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32 pos)
193 MonoClass *ac, *vc, *ec;
205 vc = value->vtable->klass;
209 ac = this->obj.vtable->klass;
210 ec = ac->element_class;
212 esize = mono_array_element_size (ac);
213 ea = (gpointer*)((char*)this->vector + (pos * esize));
214 va = (gpointer*)((char*)value + sizeof (MonoObject));
217 memset (ea, 0, esize);
221 #define NO_WIDENING_CONVERSION G_STMT_START{\
222 mono_raise_exception (mono_get_exception_argument ( \
223 "value", "not a widening conversion")); \
226 #define CHECK_WIDENING_CONVERSION(extra) G_STMT_START{\
227 if (esize < vsize + (extra)) \
228 mono_raise_exception (mono_get_exception_argument ( \
229 "value", "not a widening conversion")); \
232 #define INVALID_CAST G_STMT_START{\
233 mono_raise_exception (mono_get_exception_invalid_cast ()); \
236 /* Check element (destination) type. */
237 switch (ec->byval_arg.type) {
238 case MONO_TYPE_STRING:
239 switch (vc->byval_arg.type) {
240 case MONO_TYPE_STRING:
246 case MONO_TYPE_BOOLEAN:
247 switch (vc->byval_arg.type) {
248 case MONO_TYPE_BOOLEAN:
261 NO_WIDENING_CONVERSION;
268 if (!ec->valuetype) {
269 if (!mono_object_isinst (value, ec))
271 *ea = (gpointer)value;
275 if (mono_object_isinst (value, ec)) {
276 memcpy (ea, (char *)value + sizeof (MonoObject), esize);
283 vsize = mono_class_instance_size (vc) - sizeof (MonoObject);
285 et = ec->byval_arg.type;
286 if (et == MONO_TYPE_VALUETYPE && ec->byval_arg.data.klass->enumtype)
287 et = ec->byval_arg.data.klass->enum_basetype->type;
289 vt = vc->byval_arg.type;
290 if (vt == MONO_TYPE_VALUETYPE && vc->byval_arg.data.klass->enumtype)
291 vt = vc->byval_arg.data.klass->enum_basetype->type;
293 #define ASSIGN_UNSIGNED(etype) G_STMT_START{\
299 case MONO_TYPE_CHAR: \
300 CHECK_WIDENING_CONVERSION(0); \
301 *(etype *) ea = (etype) u64; \
303 /* You can't assign a signed value to an unsigned array. */ \
308 /* You can't assign a floating point number to an integer array. */ \
311 NO_WIDENING_CONVERSION; \
315 #define ASSIGN_SIGNED(etype) G_STMT_START{\
321 CHECK_WIDENING_CONVERSION(0); \
322 *(etype *) ea = (etype) i64; \
324 /* You can assign an unsigned value to a signed array if the array's */ \
325 /* element size is larger than the value size. */ \
330 case MONO_TYPE_CHAR: \
331 CHECK_WIDENING_CONVERSION(1); \
332 *(etype *) ea = (etype) u64; \
334 /* You can't assign a floating point number to an integer array. */ \
337 NO_WIDENING_CONVERSION; \
341 #define ASSIGN_REAL(etype) G_STMT_START{\
345 CHECK_WIDENING_CONVERSION(0); \
346 *(etype *) ea = (etype) r64; \
348 /* All integer values fit into a floating point array, so we don't */ \
349 /* need to CHECK_WIDENING_CONVERSION here. */ \
354 *(etype *) ea = (etype) i64; \
360 case MONO_TYPE_CHAR: \
361 *(etype *) ea = (etype) u64; \
368 u64 = *(guint8 *) va;
371 u64 = *(guint16 *) va;
374 u64 = *(guint32 *) va;
377 u64 = *(guint64 *) va;
383 i64 = *(gint16 *) va;
386 i64 = *(gint32 *) va;
389 i64 = *(gint64 *) va;
392 r64 = *(gfloat *) va;
395 r64 = *(gdouble *) va;
398 u64 = *(guint16 *) va;
400 case MONO_TYPE_BOOLEAN:
401 /* Boolean is only compatible with itself. */
414 NO_WIDENING_CONVERSION;
421 /* If we can't do a direct copy, let's try a widening conversion. */
424 ASSIGN_UNSIGNED (guint16);
426 ASSIGN_UNSIGNED (guint8);
428 ASSIGN_UNSIGNED (guint16);
430 ASSIGN_UNSIGNED (guint32);
432 ASSIGN_UNSIGNED (guint64);
434 ASSIGN_SIGNED (gint8);
436 ASSIGN_SIGNED (gint16);
438 ASSIGN_SIGNED (gint32);
440 ASSIGN_SIGNED (gint64);
442 ASSIGN_REAL (gfloat);
444 ASSIGN_REAL (gdouble);
448 /* Not reached, INVALID_CAST does not return. Just to avoid a compiler warning ... */
452 #undef NO_WIDENING_CONVERSION
453 #undef CHECK_WIDENING_CONVERSION
454 #undef ASSIGN_UNSIGNED
460 ves_icall_System_Array_SetValue (MonoArray *this, MonoObject *value,
468 MONO_CHECK_ARG_NULL (idxs);
470 ic = idxs->obj.vtable->klass;
471 ac = this->obj.vtable->klass;
473 g_assert (ic->rank == 1);
474 if (idxs->bounds != NULL || idxs->max_length != ac->rank)
475 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
477 ind = (gint32 *)idxs->vector;
479 if (this->bounds == NULL) {
480 if (*ind < 0 || *ind >= this->max_length)
481 mono_raise_exception (mono_get_exception_index_out_of_range ());
483 ves_icall_System_Array_SetValueImpl (this, value, *ind);
487 for (i = 0; i < ac->rank; i++)
488 if ((ind [i] < this->bounds [i].lower_bound) ||
489 (ind [i] >= this->bounds [i].length + this->bounds [i].lower_bound))
490 mono_raise_exception (mono_get_exception_index_out_of_range ());
492 pos = ind [0] - this->bounds [0].lower_bound;
493 for (i = 1; i < ac->rank; i++)
494 pos = pos * this->bounds [i].length + ind [i] -
495 this->bounds [i].lower_bound;
497 ves_icall_System_Array_SetValueImpl (this, value, pos);
501 ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
506 gboolean bounded = FALSE;
510 MONO_CHECK_ARG_NULL (type);
511 MONO_CHECK_ARG_NULL (lengths);
513 MONO_CHECK_ARG (lengths, mono_array_length (lengths) > 0);
515 MONO_CHECK_ARG (bounds, mono_array_length (lengths) == mono_array_length (bounds));
517 for (i = 0; i < mono_array_length (lengths); i++)
518 if (mono_array_get (lengths, gint32, i) < 0)
519 mono_raise_exception (mono_get_exception_argument_out_of_range (NULL));
521 if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint32, 0) != 0))
522 /* vectors are not the same as one dimensional arrays with no-zero bounds */
527 aklass = mono_bounded_array_class_get (mono_class_from_mono_type (type->type), mono_array_length (lengths), bounded);
529 sizes = alloca (aklass->rank * sizeof(guint32) * 2);
530 for (i = 0; i < aklass->rank; ++i) {
531 sizes [i] = mono_array_get (lengths, guint32, i);
533 sizes [i + aklass->rank] = mono_array_get (bounds, guint32, i);
535 sizes [i + aklass->rank] = 0;
538 array = mono_array_new_full (mono_object_domain (type), aklass, sizes, sizes + aklass->rank);
544 ves_icall_System_Array_GetRank (MonoObject *this)
548 return this->vtable->klass->rank;
552 ves_icall_System_Array_GetLength (MonoArray *this, gint32 dimension)
554 gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
558 if ((dimension < 0) || (dimension >= rank))
559 mono_raise_exception (mono_get_exception_index_out_of_range ());
561 if (this->bounds == NULL)
562 return this->max_length;
564 return this->bounds [dimension].length;
568 ves_icall_System_Array_GetLowerBound (MonoArray *this, gint32 dimension)
570 gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
574 if ((dimension < 0) || (dimension >= rank))
575 mono_raise_exception (mono_get_exception_index_out_of_range ());
577 if (this->bounds == NULL)
580 return this->bounds [dimension].lower_bound;
584 ves_icall_System_Array_ClearInternal (MonoArray *arr, int idx, int length)
586 int sz = mono_array_element_size (mono_object_class (arr));
587 memset (mono_array_addr_with_size (arr, sz, idx), 0, length * sz);
591 ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* dest, int dest_idx, int length)
596 MonoClass *src_class;
597 MonoClass *dest_class;
602 if (source->obj.vtable->klass->rank != dest->obj.vtable->klass->rank)
605 if (source->bounds || dest->bounds)
608 if ((dest_idx + length > mono_array_length (dest)) ||
609 (source_idx + length > mono_array_length (source)))
612 src_class = source->obj.vtable->klass->element_class;
613 dest_class = dest->obj.vtable->klass->element_class;
616 * Handle common cases.
619 /* Case1: object[] -> valuetype[] (ArrayList::ToArray) */
620 if (src_class == mono_defaults.object_class && dest_class->valuetype) {
621 int has_refs = dest_class->has_references;
622 for (i = source_idx; i < source_idx + length; ++i) {
623 MonoObject *elem = mono_array_get (source, MonoObject*, i);
624 if (elem && !mono_object_isinst (elem, dest_class))
628 element_size = mono_array_element_size (dest->obj.vtable->klass);
629 memset (mono_array_addr_with_size (dest, element_size, dest_idx), 0, element_size * length);
630 for (i = 0; i < length; ++i) {
631 MonoObject *elem = mono_array_get (source, MonoObject*, source_idx + i);
632 void *addr = mono_array_addr_with_size (dest, element_size, dest_idx + i);
636 mono_value_copy (addr, (char *)elem + sizeof (MonoObject), dest_class);
638 memcpy (addr, (char *)elem + sizeof (MonoObject), element_size);
643 /* Check if we're copying a char[] <==> (u)short[] */
644 if (src_class != dest_class) {
645 if (dest_class->valuetype || dest_class->enumtype || src_class->valuetype || src_class->enumtype)
648 if (mono_class_is_subclass_of (src_class, dest_class, FALSE))
650 /* Case2: object[] -> reftype[] (ArrayList::ToArray) */
651 else if (mono_class_is_subclass_of (dest_class, src_class, FALSE))
652 for (i = source_idx; i < source_idx + length; ++i) {
653 MonoObject *elem = mono_array_get (source, MonoObject*, i);
654 if (elem && !mono_object_isinst (elem, dest_class))
661 if (dest_class->valuetype) {
662 element_size = mono_array_element_size (source->obj.vtable->klass);
663 source_addr = mono_array_addr_with_size (source, element_size, source_idx);
664 if (dest_class->has_references) {
665 mono_value_copy_array (dest, dest_idx, source_addr, length);
667 dest_addr = mono_array_addr_with_size (dest, element_size, dest_idx);
668 memmove (dest_addr, source_addr, element_size * length);
671 mono_array_memcpy_refs (dest, dest_idx, source, source_idx, length);
678 ves_icall_System_Array_GetGenericValueImpl (MonoObject *this, guint32 pos, gpointer value)
687 ao = (MonoArray *)this;
688 ac = (MonoClass *)ao->obj.vtable->klass;
690 esize = mono_array_element_size (ac);
691 ea = (gpointer*)((char*)ao->vector + (pos * esize));
693 memcpy (value, ea, esize);
697 ves_icall_System_Array_SetGenericValueImpl (MonoObject *this, guint32 pos, gpointer value)
706 ao = (MonoArray *)this;
707 ac = (MonoClass *)ao->obj.vtable->klass;
709 esize = mono_array_element_size (ac);
710 ea = (gpointer*)((char*)ao->vector + (pos * esize));
712 memcpy (ea, value, esize);
716 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoArray *array, MonoClassField *field_handle)
718 MonoClass *klass = array->obj.vtable->klass;
719 guint32 size = mono_array_element_size (klass);
721 size *= array->max_length;
723 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
725 guint ## n *data = (guint ## n *) mono_array_addr (array, char, 0); \
726 guint ## n *src = (guint ## n *) field_handle->data; \
727 guint ## n *end = (guint ## n *)((char*)src + size); \
729 for (; src < end; data++, src++) { \
730 *data = read ## n (src); \
734 /* printf ("Initialize array with elements of %s type\n", klass->element_class->name); */
736 switch (mono_type_get_underlying_type (&klass->element_class->byval_arg)->type) {
753 memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
757 memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
759 if (klass->element_class->byval_arg.type == MONO_TYPE_R8) {
762 double *data = (double*)mono_array_addr (array, double, 0);
764 for (i = 0; i < size; i++, data++) {
774 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData (void)
778 return offsetof (MonoString, chars);
782 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue (MonoObject *obj)
786 if ((obj == NULL) || (! (obj->vtable->klass->valuetype)))
789 return mono_object_clone (obj);
793 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (MonoType *handle)
799 MONO_CHECK_ARG_NULL (handle);
801 klass = mono_class_from_mono_type (handle);
802 MONO_CHECK_ARG (handle, klass);
804 /* This will call the type constructor */
805 if (! (klass->flags & TYPE_ATTRIBUTE_INTERFACE))
806 mono_runtime_class_init (mono_class_vtable (mono_domain_get (), klass));
810 ves_icall_System_Object_MemberwiseClone (MonoObject *this)
814 return mono_object_clone (this);
818 ves_icall_System_ValueType_InternalGetHashCode (MonoObject *this, MonoArray **fields)
821 MonoObject **values = NULL;
825 MonoClassField* field;
830 klass = mono_object_class (this);
832 if (mono_class_num_fields (klass) == 0)
833 return mono_object_hash (this);
836 * Compute the starting value of the hashcode for fields of primitive
837 * types, and return the remaining fields in an array to the managed side.
838 * This way, we can avoid costly reflection operations in managed code.
841 while ((field = mono_class_get_fields (klass, &iter))) {
842 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
844 if (mono_field_is_deleted (field))
846 /* FIXME: Add more types */
847 switch (field->type->type) {
849 result ^= *(gint32*)((guint8*)this + field->offset);
851 case MONO_TYPE_STRING: {
853 s = *(MonoString**)((guint8*)this + field->offset);
855 result ^= mono_string_hash (s);
860 values = g_newa (MonoObject*, mono_class_num_fields (klass));
861 o = mono_field_get_value_object (mono_object_domain (this), field, this);
862 values [count++] = o;
868 *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
869 for (i = 0; i < count; ++i)
870 mono_array_setref (*fields, i, values [i]);
878 ves_icall_System_ValueType_Equals (MonoObject *this, MonoObject *that, MonoArray **fields)
881 MonoObject **values = NULL;
883 MonoClassField* field;
889 MONO_CHECK_ARG_NULL (that);
891 if (this->vtable != that->vtable)
894 klass = mono_object_class (this);
897 * Do the comparison for fields of primitive type and return a result if
898 * possible. Otherwise, return the remaining fields in an array to the
899 * managed side. This way, we can avoid costly reflection operations in
904 while ((field = mono_class_get_fields (klass, &iter))) {
905 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
907 if (mono_field_is_deleted (field))
909 /* FIXME: Add more types */
910 switch (field->type->type) {
912 if (*(gint32*)((guint8*)this + field->offset) != *(gint32*)((guint8*)that + field->offset))
915 case MONO_TYPE_STRING: {
917 guint32 s1len, s2len;
918 s1 = *(MonoString**)((guint8*)this + field->offset);
919 s2 = *(MonoString**)((guint8*)that + field->offset);
922 if ((s1 == NULL) || (s2 == NULL))
924 s1len = mono_string_length (s1);
925 s2len = mono_string_length (s2);
929 if (memcmp (mono_string_chars (s1), mono_string_chars (s2), s1len * sizeof (gunichar2)) != 0)
935 values = g_newa (MonoObject*, mono_class_num_fields (klass) * 2);
936 o = mono_field_get_value_object (mono_object_domain (this), field, this);
937 values [count++] = o;
938 o = mono_field_get_value_object (mono_object_domain (this), field, that);
939 values [count++] = o;
945 *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
946 for (i = 0; i < count; ++i)
947 mono_array_setref (*fields, i, values [i]);
954 static MonoReflectionType *
955 ves_icall_System_Object_GetType (MonoObject *obj)
959 if (obj->vtable->klass != mono_defaults.transparent_proxy_class)
960 return mono_type_get_object (mono_object_domain (obj), &obj->vtable->klass->byval_arg);
962 return mono_type_get_object (mono_object_domain (obj), &((MonoTransparentProxy*)obj)->remote_class->proxy_class->byval_arg);
966 mono_type_type_from_obj (MonoReflectionType *mtype, MonoObject *obj)
970 mtype->type = &obj->vtable->klass->byval_arg;
971 g_assert (mtype->type->type);
975 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj)
979 MONO_CHECK_ARG_NULL (obj);
981 return mono_image_create_token (mb->dynamic_image, obj, TRUE);
985 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder *mb,
986 MonoReflectionMethod *method,
987 MonoArray *opt_param_types)
991 MONO_CHECK_ARG_NULL (method);
993 return mono_image_create_method_token (
994 mb->dynamic_image, (MonoObject *) method, opt_param_types);
998 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder *mb, HANDLE file)
1000 MONO_ARCH_SAVE_REGS;
1002 mono_image_create_pefile (mb, file);
1006 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
1008 MONO_ARCH_SAVE_REGS;
1010 mono_image_build_metadata (mb);
1014 get_caller (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1016 MonoMethod **dest = data;
1018 /* skip unmanaged frames */
1033 static MonoReflectionType *
1034 type_from_name (const char *str, MonoBoolean ignoreCase)
1036 MonoType *type = NULL;
1037 MonoAssembly *assembly = NULL;
1038 MonoTypeNameParse info;
1039 char *temp_str = g_strdup (str);
1040 gboolean type_resolve = FALSE;
1042 MONO_ARCH_SAVE_REGS;
1044 /* mono_reflection_parse_type() mangles the string */
1045 if (!mono_reflection_parse_type (temp_str, &info)) {
1046 g_list_free (info.modifiers);
1047 g_list_free (info.nested);
1052 if (info.assembly.name) {
1053 assembly = mono_assembly_load (&info.assembly, NULL, NULL);
1055 MonoMethod *m = mono_method_get_last_managed ();
1056 MonoMethod *dest = m;
1058 mono_stack_walk_no_il (get_caller, &dest);
1063 * FIXME: mono_method_get_last_managed() sometimes returns NULL, thus
1064 * causing ves_icall_System_Reflection_Assembly_GetCallingAssembly()
1065 * to crash. This only seems to happen in some strange remoting
1066 * scenarios and I was unable to figure out what's happening there.
1067 * Dec 10, 2005 - Martin.
1071 assembly = dest->klass->image->assembly;
1073 g_warning (G_STRLOC);
1078 type = mono_reflection_get_type (assembly->image, &info, ignoreCase, &type_resolve);
1080 if (!info.assembly.name && !type) /* try mscorlib */
1081 type = mono_reflection_get_type (NULL, &info, ignoreCase, &type_resolve);
1083 g_list_free (info.modifiers);
1084 g_list_free (info.nested);
1090 return mono_type_get_object (mono_domain_get (), type);
1094 MonoReflectionType *
1095 mono_type_get (const char *str)
1097 char *copy = g_strdup (str);
1098 MonoReflectionType *type = type_from_name (copy, FALSE);
1105 static MonoReflectionType*
1106 ves_icall_type_from_name (MonoString *name,
1107 MonoBoolean throwOnError,
1108 MonoBoolean ignoreCase)
1110 char *str = mono_string_to_utf8 (name);
1111 MonoReflectionType *type;
1113 type = type_from_name (str, ignoreCase);
1116 MonoException *e = NULL;
1119 e = mono_get_exception_type_load (name, NULL);
1121 mono_loader_clear_error ();
1123 mono_raise_exception (e);
1130 static MonoReflectionType*
1131 ves_icall_type_from_handle (MonoType *handle)
1133 MonoDomain *domain = mono_domain_get ();
1134 MonoClass *klass = mono_class_from_mono_type (handle);
1136 MONO_ARCH_SAVE_REGS;
1138 mono_class_init (klass);
1139 return mono_type_get_object (domain, handle);
1143 ves_icall_System_Type_EqualsInternal (MonoReflectionType *type, MonoReflectionType *c)
1145 MONO_ARCH_SAVE_REGS;
1147 if (c && type->type && c->type)
1148 return mono_metadata_type_equal (type->type, c->type);
1153 /* System.TypeCode */
1172 TYPECODE_STRING = 18
1176 ves_icall_type_GetTypeCodeInternal (MonoReflectionType *type)
1178 int t = type->type->type;
1180 MONO_ARCH_SAVE_REGS;
1182 if (type->type->byref)
1183 return TYPECODE_OBJECT;
1187 case MONO_TYPE_VOID:
1188 return TYPECODE_OBJECT;
1189 case MONO_TYPE_BOOLEAN:
1190 return TYPECODE_BOOLEAN;
1192 return TYPECODE_BYTE;
1194 return TYPECODE_SBYTE;
1196 return TYPECODE_UINT16;
1198 return TYPECODE_INT16;
1199 case MONO_TYPE_CHAR:
1200 return TYPECODE_CHAR;
1204 return TYPECODE_OBJECT;
1206 return TYPECODE_UINT32;
1208 return TYPECODE_INT32;
1210 return TYPECODE_UINT64;
1212 return TYPECODE_INT64;
1214 return TYPECODE_SINGLE;
1216 return TYPECODE_DOUBLE;
1217 case MONO_TYPE_VALUETYPE:
1218 if (type->type->data.klass->enumtype) {
1219 t = type->type->data.klass->enum_basetype->type;
1222 MonoClass *k = type->type->data.klass;
1223 if (strcmp (k->name_space, "System") == 0) {
1224 if (strcmp (k->name, "Decimal") == 0)
1225 return TYPECODE_DECIMAL;
1226 else if (strcmp (k->name, "DateTime") == 0)
1227 return TYPECODE_DATETIME;
1230 return TYPECODE_OBJECT;
1231 case MONO_TYPE_STRING:
1232 return TYPECODE_STRING;
1233 case MONO_TYPE_SZARRAY:
1234 case MONO_TYPE_ARRAY:
1235 case MONO_TYPE_OBJECT:
1237 case MONO_TYPE_MVAR:
1238 case MONO_TYPE_TYPEDBYREF:
1239 return TYPECODE_OBJECT;
1240 case MONO_TYPE_CLASS:
1242 MonoClass *k = type->type->data.klass;
1243 if (strcmp (k->name_space, "System") == 0) {
1244 if (strcmp (k->name, "DBNull") == 0)
1245 return TYPECODE_DBNULL;
1248 return TYPECODE_OBJECT;
1249 case MONO_TYPE_GENERICINST:
1250 return TYPECODE_OBJECT;
1252 g_error ("type 0x%02x not handled in GetTypeCode()", t);
1258 ves_icall_type_is_subtype_of (MonoReflectionType *type, MonoReflectionType *c, MonoBoolean check_interfaces)
1264 MONO_ARCH_SAVE_REGS;
1266 g_assert (type != NULL);
1268 domain = ((MonoObject *)type)->vtable->domain;
1270 if (!c) /* FIXME: dont know what do do here */
1273 klass = mono_class_from_mono_type (type->type);
1274 klassc = mono_class_from_mono_type (c->type);
1276 if (type->type->byref)
1277 return klassc == mono_defaults.object_class;
1279 return mono_class_is_subclass_of (klass, klassc, check_interfaces);
1283 ves_icall_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType *c)
1289 MONO_ARCH_SAVE_REGS;
1291 g_assert (type != NULL);
1293 domain = ((MonoObject *)type)->vtable->domain;
1295 klass = mono_class_from_mono_type (type->type);
1296 klassc = mono_class_from_mono_type (c->type);
1298 if (type->type->byref && !c->type->byref)
1301 return mono_class_is_assignable_from (klass, klassc);
1305 ves_icall_type_IsInstanceOfType (MonoReflectionType *type, MonoObject *obj)
1307 MonoClass *klass = mono_class_from_mono_type (type->type);
1308 return mono_object_isinst (obj, klass) != NULL;
1312 ves_icall_get_attributes (MonoReflectionType *type)
1314 MonoClass *klass = mono_class_from_mono_type (type->type);
1316 MONO_ARCH_SAVE_REGS;
1318 return klass->flags;
1321 static MonoReflectionMarshal*
1322 ves_icall_System_Reflection_FieldInfo_GetUnmanagedMarshal (MonoReflectionField *field)
1324 MonoClass *klass = field->field->parent;
1325 MonoMarshalType *info;
1328 if (klass->generic_container ||
1329 (klass->generic_class && klass->generic_class->context.class_inst->is_open))
1332 info = mono_marshal_load_type_info (klass);
1334 for (i = 0; i < info->num_fields; ++i) {
1335 if (info->fields [i].field == field->field) {
1336 if (!info->fields [i].mspec)
1339 return mono_reflection_marshal_from_marshal_spec (field->object.vtable->domain, klass, info->fields [i].mspec);
1346 static MonoReflectionField*
1347 ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoClass *klass)
1352 klass = handle->parent;
1354 /* FIXME: check that handle is a field of klass or of a parent: return null
1355 * and throw the exception in managed code.
1357 return mono_field_get_object (mono_domain_get (), klass, handle);
1360 static MonoReflectionField*
1361 ves_icall_System_Reflection_FieldInfo_internal_from_handle (MonoClassField *handle)
1363 MONO_ARCH_SAVE_REGS;
1367 return mono_field_get_object (mono_domain_get (), handle->parent, handle);
1371 ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionField *field, MonoBoolean optional)
1373 MonoType *type = field->field->type;
1375 return type_array_from_modifiers (field->field->parent->image, type, optional);
1379 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
1381 MonoDomain *domain = mono_domain_get ();
1382 MonoMethodSignature* sig;
1383 MONO_ARCH_SAVE_REGS;
1385 sig = mono_method_signature (method);
1387 g_assert (mono_loader_get_last_error ());
1388 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
1391 info->parent = mono_type_get_object (domain, &method->klass->byval_arg);
1392 info->ret = mono_type_get_object (domain, sig->ret);
1393 info->attrs = method->flags;
1394 info->implattrs = method->iflags;
1395 if (sig->call_convention == MONO_CALL_DEFAULT)
1398 if (sig->call_convention == MONO_CALL_VARARG)
1403 info->callconv |= (sig->hasthis << 5) | (sig->explicit_this << 6);
1407 ves_icall_get_parameter_info (MonoMethod *method)
1409 MonoDomain *domain = mono_domain_get ();
1411 return mono_param_get_objects (domain, method);
1414 static MonoReflectionMarshal*
1415 ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod *method)
1417 MonoDomain *domain = mono_domain_get ();
1418 MonoReflectionMarshal* res = NULL;
1419 MonoMarshalSpec **mspecs;
1422 mspecs = g_new (MonoMarshalSpec*, mono_method_signature (method)->param_count + 1);
1423 mono_method_get_marshal_info (method, mspecs);
1426 res = mono_reflection_marshal_from_marshal_spec (domain, method->klass, mspecs [0]);
1428 for (i = mono_method_signature (method)->param_count; i >= 0; i--)
1430 mono_metadata_free_marshal_spec (mspecs [i]);
1437 ves_icall_MonoField_GetFieldOffset (MonoReflectionField *field)
1439 return field->field->offset - sizeof (MonoObject);
1442 static MonoReflectionType*
1443 ves_icall_MonoField_GetParentType (MonoReflectionField *field, MonoBoolean declaring)
1446 MONO_ARCH_SAVE_REGS;
1448 parent = declaring? field->field->parent: field->klass;
1450 return mono_type_get_object (mono_object_domain (field), &parent->byval_arg);
1454 ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj)
1457 MonoClassField *cf = field->field;
1461 MonoDomain *domain = mono_object_domain (field);
1463 gboolean is_static = FALSE;
1464 gboolean is_ref = FALSE;
1466 MONO_ARCH_SAVE_REGS;
1468 if (field->klass->image->assembly->ref_only)
1469 mono_raise_exception (mono_get_exception_invalid_operation (
1470 "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
1472 mono_class_init (field->klass);
1474 t = mono_type_get_underlying_type (cf->type);
1476 case MONO_TYPE_STRING:
1477 case MONO_TYPE_OBJECT:
1478 case MONO_TYPE_CLASS:
1479 case MONO_TYPE_ARRAY:
1480 case MONO_TYPE_SZARRAY:
1485 case MONO_TYPE_BOOLEAN:
1488 case MONO_TYPE_CHAR:
1497 case MONO_TYPE_VALUETYPE:
1500 case MONO_TYPE_GENERICINST:
1501 if (mono_type_generic_inst_is_valuetype (t)) {
1508 g_error ("type 0x%x not handled in "
1509 "ves_icall_Monofield_GetValue", t->type);
1514 if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) {
1516 vtable = mono_class_vtable (domain, cf->parent);
1517 if (!vtable->initialized && !(cf->type->attrs & FIELD_ATTRIBUTE_LITERAL))
1518 mono_runtime_class_init (vtable);
1523 mono_field_static_get_value (vtable, cf, &o);
1525 mono_field_get_value (obj, cf, &o);
1530 if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) {
1531 MonoClass *nklass = mono_class_from_mono_type (cf->type);
1534 /* Convert the Nullable structure into a boxed vtype */
1536 buf = (guint8*)vtable->data + cf->offset;
1538 buf = (guint8*)obj + cf->offset;
1540 return mono_nullable_box (buf, nklass);
1543 /* boxed value type */
1544 klass = mono_class_from_mono_type (cf->type);
1545 o = mono_object_new (domain, klass);
1546 v = ((gchar *) o) + sizeof (MonoObject);
1548 mono_field_static_get_value (vtable, cf, v);
1550 mono_field_get_value (obj, cf, v);
1557 ves_icall_FieldInfo_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value)
1559 MonoClassField *cf = field->field;
1562 MONO_ARCH_SAVE_REGS;
1564 if (field->klass->image->assembly->ref_only)
1565 mono_raise_exception (mono_get_exception_invalid_operation (
1566 "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
1568 v = (gchar *) value;
1569 if (!cf->type->byref) {
1570 switch (cf->type->type) {
1573 case MONO_TYPE_BOOLEAN:
1576 case MONO_TYPE_CHAR:
1585 case MONO_TYPE_VALUETYPE:
1587 v += sizeof (MonoObject);
1589 case MONO_TYPE_STRING:
1590 case MONO_TYPE_OBJECT:
1591 case MONO_TYPE_CLASS:
1592 case MONO_TYPE_ARRAY:
1593 case MONO_TYPE_SZARRAY:
1596 case MONO_TYPE_GENERICINST: {
1597 MonoGenericClass *gclass = cf->type->data.generic_class;
1598 g_assert (!gclass->context.class_inst->is_open);
1600 if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) {
1601 MonoClass *nklass = mono_class_from_mono_type (cf->type);
1602 MonoObject *nullable;
1605 * Convert the boxed vtype into a Nullable structure.
1606 * This is complicated by the fact that Nullables have
1607 * a variable structure.
1609 nullable = mono_object_new (mono_domain_get (), nklass);
1611 mono_nullable_init (mono_object_unbox (nullable), value, nklass);
1613 v = mono_object_unbox (nullable);
1616 if (gclass->container_class->valuetype && (v != NULL))
1617 v += sizeof (MonoObject);
1621 g_error ("type 0x%x not handled in "
1622 "ves_icall_FieldInfo_SetValueInternal", cf->type->type);
1627 if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) {
1628 MonoVTable *vtable = mono_class_vtable (mono_object_domain (field), cf->parent);
1629 if (!vtable->initialized)
1630 mono_runtime_class_init (vtable);
1631 mono_field_static_set_value (vtable, cf, v);
1633 mono_field_set_value (obj, cf, v);
1637 static MonoReflectionType*
1638 ves_icall_MonoGenericMethod_get_ReflectedType (MonoReflectionGenericMethod *rmethod)
1640 MonoMethod *method = rmethod->method.method;
1642 return mono_type_get_object (mono_object_domain (rmethod), &method->klass->byval_arg);
1645 /* From MonoProperty.cs */
1647 PInfo_Attributes = 1,
1648 PInfo_GetMethod = 1 << 1,
1649 PInfo_SetMethod = 1 << 2,
1650 PInfo_ReflectedType = 1 << 3,
1651 PInfo_DeclaringType = 1 << 4,
1656 ves_icall_get_property_info (MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
1658 MonoDomain *domain = mono_object_domain (property);
1660 MONO_ARCH_SAVE_REGS;
1662 if ((req_info & PInfo_ReflectedType) != 0)
1663 info->parent = mono_type_get_object (domain, &property->klass->byval_arg);
1664 else if ((req_info & PInfo_DeclaringType) != 0)
1665 info->parent = mono_type_get_object (domain, &property->property->parent->byval_arg);
1667 if ((req_info & PInfo_Name) != 0)
1668 info->name = mono_string_new (domain, property->property->name);
1670 if ((req_info & PInfo_Attributes) != 0)
1671 info->attrs = property->property->attrs;
1673 if ((req_info & PInfo_GetMethod) != 0)
1674 info->get = property->property->get ?
1675 mono_method_get_object (domain, property->property->get, NULL): NULL;
1677 if ((req_info & PInfo_SetMethod) != 0)
1678 info->set = property->property->set ?
1679 mono_method_get_object (domain, property->property->set, NULL): NULL;
1681 * There may be other methods defined for properties, though, it seems they are not exposed
1682 * in the reflection API
1687 ves_icall_get_event_info (MonoReflectionEvent *event, MonoEventInfo *info)
1689 MonoDomain *domain = mono_object_domain (event);
1691 MONO_ARCH_SAVE_REGS;
1693 info->reflected_type = mono_type_get_object (domain, &event->klass->byval_arg);
1694 info->declaring_type = mono_type_get_object (domain, &event->event->parent->byval_arg);
1696 info->name = mono_string_new (domain, event->event->name);
1697 info->attrs = event->event->attrs;
1698 info->add_method = event->event->add ? mono_method_get_object (domain, event->event->add, NULL): NULL;
1699 info->remove_method = event->event->remove ? mono_method_get_object (domain, event->event->remove, NULL): NULL;
1700 info->raise_method = event->event->raise ? mono_method_get_object (domain, event->event->raise, NULL): NULL;
1702 if (event->event->other) {
1704 while (event->event->other [n])
1706 info->other_methods = mono_array_new (domain, mono_defaults.method_info_class, n);
1708 for (i = 0; i < n; i++)
1709 mono_array_setref (info->other_methods, i, mono_method_get_object (domain, event->event->other [i], NULL));
1714 ves_icall_Type_GetInterfaces (MonoReflectionType* type)
1716 MonoDomain *domain = mono_object_domain (type);
1718 GPtrArray *ifaces = NULL;
1720 MonoClass *class = mono_class_from_mono_type (type->type);
1723 MonoGenericContext *context = NULL;
1725 MONO_ARCH_SAVE_REGS;
1727 if (class->generic_class && class->generic_class->context.class_inst->is_open) {
1728 context = mono_class_get_context (class);
1729 class = class->generic_class->container_class;
1732 mono_class_setup_vtable (class);
1734 slots = mono_bitset_new (class->max_interface_id + 1, 0);
1736 for (parent = class; parent; parent = parent->parent) {
1737 GPtrArray *tmp_ifaces = mono_class_get_implemented_interfaces (parent);
1739 for (i = 0; i < tmp_ifaces->len; ++i) {
1740 MonoClass *ic = g_ptr_array_index (tmp_ifaces, i);
1742 if (mono_bitset_test (slots, ic->interface_id))
1745 mono_bitset_set (slots, ic->interface_id);
1747 ifaces = g_ptr_array_new ();
1748 g_ptr_array_add (ifaces, ic);
1750 g_ptr_array_free (tmp_ifaces, TRUE);
1753 mono_bitset_free (slots);
1756 return mono_array_new (domain, mono_defaults.monotype_class, 0);
1758 intf = mono_array_new (domain, mono_defaults.monotype_class, ifaces->len);
1759 for (i = 0; i < ifaces->len; ++i) {
1760 MonoClass *ic = g_ptr_array_index (ifaces, i);
1761 MonoType *ret = &ic->byval_arg;
1762 if (context && ic->generic_class && ic->generic_class->context.class_inst->is_open)
1763 ret = mono_class_inflate_generic_type (ret, context);
1765 mono_array_setref (intf, i, mono_type_get_object (domain, ret));
1767 g_ptr_array_free (ifaces, TRUE);
1773 ves_icall_Type_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType *iface, MonoArray **targets, MonoArray **methods)
1775 MonoClass *class = mono_class_from_mono_type (type->type);
1776 MonoClass *iclass = mono_class_from_mono_type (iface->type);
1777 MonoReflectionMethod *member;
1780 int i = 0, len, ioffset;
1783 MONO_ARCH_SAVE_REGS;
1785 mono_class_setup_vtable (class);
1787 /* type doesn't implement iface: the exception is thrown in managed code */
1788 if (! MONO_CLASS_IMPLEMENTS_INTERFACE (class, iclass->interface_id))
1791 len = mono_class_num_methods (iclass);
1792 ioffset = mono_class_interface_offset (class, iclass);
1793 domain = mono_object_domain (type);
1794 *targets = mono_array_new (domain, mono_defaults.method_info_class, len);
1795 *methods = mono_array_new (domain, mono_defaults.method_info_class, len);
1798 while ((method = mono_class_get_methods (iclass, &iter))) {
1799 member = mono_method_get_object (domain, method, iclass);
1800 mono_array_setref (*methods, i, member);
1801 member = mono_method_get_object (domain, class->vtable [i + ioffset], class);
1802 mono_array_setref (*targets, i, member);
1809 ves_icall_Type_GetPacking (MonoReflectionType *type, guint32 *packing, guint32 *size)
1811 MonoClass *klass = mono_class_from_mono_type (type->type);
1813 g_assert (!klass->image->dynamic);
1815 mono_metadata_packing_from_typedef (klass->image, klass->type_token, packing, size);
1818 static MonoReflectionType*
1819 ves_icall_MonoType_GetElementType (MonoReflectionType *type)
1821 MonoClass *class = mono_class_from_mono_type (type->type);
1823 MONO_ARCH_SAVE_REGS;
1825 // GelElementType should only return a type for:
1826 // Array Pointer PassedByRef
1827 if (type->type->byref)
1828 return mono_type_get_object (mono_object_domain (type), &class->byval_arg);
1829 if (class->enumtype && class->enum_basetype) /* types that are modifierd typebuilkders may not have enum_basetype set */
1830 return mono_type_get_object (mono_object_domain (type), class->enum_basetype);
1831 else if (class->element_class && MONO_CLASS_IS_ARRAY (class))
1832 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
1833 else if (class->element_class && type->type->type == MONO_TYPE_PTR)
1834 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
1839 static MonoReflectionType*
1840 ves_icall_get_type_parent (MonoReflectionType *type)
1842 MonoClass *class = mono_class_from_mono_type (type->type);
1844 MONO_ARCH_SAVE_REGS;
1846 return class->parent ? mono_type_get_object (mono_object_domain (type), &class->parent->byval_arg): NULL;
1850 ves_icall_type_ispointer (MonoReflectionType *type)
1852 MONO_ARCH_SAVE_REGS;
1854 return type->type->type == MONO_TYPE_PTR;
1858 ves_icall_type_isprimitive (MonoReflectionType *type)
1860 MONO_ARCH_SAVE_REGS;
1862 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)));
1866 ves_icall_type_isbyref (MonoReflectionType *type)
1868 MONO_ARCH_SAVE_REGS;
1870 return type->type->byref;
1874 ves_icall_type_iscomobject (MonoReflectionType *type)
1876 MonoClass *klass = mono_class_from_mono_type (type->type);
1877 MONO_ARCH_SAVE_REGS;
1879 return (klass && klass->is_com_object);
1882 static MonoReflectionModule*
1883 ves_icall_MonoType_get_Module (MonoReflectionType *type)
1885 MonoClass *class = mono_class_from_mono_type (type->type);
1887 MONO_ARCH_SAVE_REGS;
1889 return mono_module_get_object (mono_object_domain (type), class->image);
1892 static MonoReflectionAssembly*
1893 ves_icall_MonoType_get_Assembly (MonoReflectionType *type)
1895 MonoDomain *domain = mono_domain_get ();
1896 MonoClass *class = mono_class_from_mono_type (type->type);
1898 MONO_ARCH_SAVE_REGS;
1900 return mono_assembly_get_object (domain, class->image->assembly);
1903 static MonoReflectionType*
1904 ves_icall_MonoType_get_DeclaringType (MonoReflectionType *type)
1906 MonoDomain *domain = mono_domain_get ();
1909 MONO_ARCH_SAVE_REGS;
1911 if (type->type->byref)
1913 if (type->type->type == MONO_TYPE_VAR)
1914 class = type->type->data.generic_param->owner->owner.klass;
1915 else if (type->type->type == MONO_TYPE_MVAR)
1916 class = type->type->data.generic_param->owner->owner.method->klass;
1918 class = mono_class_from_mono_type (type->type)->nested_in;
1920 return class ? mono_type_get_object (domain, &class->byval_arg) : NULL;
1923 static MonoReflectionType*
1924 ves_icall_MonoType_get_UnderlyingSystemType (MonoReflectionType *type)
1926 MonoDomain *domain = mono_domain_get ();
1927 MonoClass *class = mono_class_from_mono_type (type->type);
1929 MONO_ARCH_SAVE_REGS;
1931 if (class->enumtype && class->enum_basetype) /* types that are modified typebuilders may not have enum_basetype set */
1932 return mono_type_get_object (domain, class->enum_basetype);
1933 else if (class->element_class)
1934 return mono_type_get_object (domain, &class->element_class->byval_arg);
1940 ves_icall_MonoType_get_Name (MonoReflectionType *type)
1942 MonoDomain *domain = mono_domain_get ();
1943 MonoClass *class = mono_class_from_mono_type (type->type);
1945 MONO_ARCH_SAVE_REGS;
1947 if (type->type->byref) {
1948 char *n = g_strdup_printf ("%s&", class->name);
1949 MonoString *res = mono_string_new (domain, n);
1955 return mono_string_new (domain, class->name);
1960 ves_icall_MonoType_get_Namespace (MonoReflectionType *type)
1962 MonoDomain *domain = mono_domain_get ();
1963 MonoClass *class = mono_class_from_mono_type (type->type);
1965 MONO_ARCH_SAVE_REGS;
1967 while (class->nested_in)
1968 class = class->nested_in;
1970 if (class->name_space [0] == '\0')
1973 return mono_string_new (domain, class->name_space);
1977 ves_icall_MonoType_GetArrayRank (MonoReflectionType *type)
1979 MonoClass *class = mono_class_from_mono_type (type->type);
1981 MONO_ARCH_SAVE_REGS;
1987 ves_icall_MonoType_GetGenericArguments (MonoReflectionType *type)
1990 MonoClass *klass, *pklass;
1992 MONO_ARCH_SAVE_REGS;
1994 klass = mono_class_from_mono_type (type->type);
1996 if (klass->generic_container) {
1997 MonoGenericContainer *container = klass->generic_container;
1998 res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, container->type_argc);
1999 for (i = 0; i < container->type_argc; ++i) {
2000 pklass = mono_class_from_generic_parameter (&container->type_params [i], klass->image, FALSE);
2001 mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), &pklass->byval_arg));
2003 } else if (klass->generic_class) {
2004 MonoGenericInst *inst = klass->generic_class->context.class_inst;
2005 res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, inst->type_argc);
2006 for (i = 0; i < inst->type_argc; ++i)
2007 mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), inst->type_argv [i]));
2009 res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, 0);
2015 ves_icall_Type_get_IsGenericTypeDefinition (MonoReflectionType *type)
2018 MONO_ARCH_SAVE_REGS;
2020 if (type->type->byref)
2023 klass = mono_class_from_mono_type (type->type);
2025 return klass->generic_container != NULL;
2028 static MonoReflectionType*
2029 ves_icall_Type_GetGenericTypeDefinition_impl (MonoReflectionType *type)
2032 MONO_ARCH_SAVE_REGS;
2034 if (type->type->byref)
2037 klass = mono_class_from_mono_type (type->type);
2038 if (klass->generic_container) {
2039 return type; /* check this one */
2041 if (klass->generic_class) {
2042 MonoClass *generic_class = klass->generic_class->container_class;
2044 if (generic_class->wastypebuilder && generic_class->reflection_info)
2045 return generic_class->reflection_info;
2047 return mono_type_get_object (mono_object_domain (type), &generic_class->byval_arg);
2052 static MonoReflectionType*
2053 ves_icall_Type_MakeGenericType (MonoReflectionType *type, MonoArray *type_array)
2055 MonoType *geninst, **types;
2058 MONO_ARCH_SAVE_REGS;
2060 count = mono_array_length (type_array);
2061 types = g_new0 (MonoType *, count);
2063 for (i = 0; i < count; i++) {
2064 MonoReflectionType *t = mono_array_get (type_array, gpointer, i);
2065 types [i] = t->type;
2068 geninst = mono_reflection_bind_generic_parameters (type, count, types);
2073 return mono_type_get_object (mono_object_domain (type), geninst);
2077 ves_icall_Type_get_IsGenericInstance (MonoReflectionType *type)
2080 MONO_ARCH_SAVE_REGS;
2082 if (type->type->byref)
2085 klass = mono_class_from_mono_type (type->type);
2086 return klass->generic_class != NULL;
2090 ves_icall_Type_get_IsGenericType (MonoReflectionType *type)
2093 MONO_ARCH_SAVE_REGS;
2095 if (type->type->byref)
2098 klass = mono_class_from_mono_type (type->type);
2099 return klass->generic_class != NULL || klass->generic_container != NULL;
2103 ves_icall_Type_GetGenericParameterPosition (MonoReflectionType *type)
2105 MONO_ARCH_SAVE_REGS;
2107 if (is_generic_parameter (type->type))
2108 return type->type->data.generic_param->num;
2112 static GenericParameterAttributes
2113 ves_icall_Type_GetGenericParameterAttributes (MonoReflectionType *type)
2115 MONO_ARCH_SAVE_REGS;
2116 g_assert (is_generic_parameter (type->type));
2117 return type->type->data.generic_param->flags;
2121 ves_icall_Type_GetGenericParameterConstraints (MonoReflectionType *type)
2123 MonoGenericParam *param;
2129 MONO_ARCH_SAVE_REGS;
2131 domain = mono_object_domain (type);
2132 param = type->type->data.generic_param;
2133 for (count = 0, ptr = param->constraints; ptr && *ptr; ptr++, count++)
2136 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2137 for (i = 0; i < count; i++)
2138 mono_array_setref (res, i, mono_type_get_object (domain, ¶m->constraints [i]->byval_arg));
2145 ves_icall_MonoType_get_IsGenericParameter (MonoReflectionType *type)
2147 MONO_ARCH_SAVE_REGS;
2148 return is_generic_parameter (type->type);
2152 ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder *tb)
2154 MONO_ARCH_SAVE_REGS;
2155 return is_generic_parameter (tb->type.type);
2159 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
2160 MonoReflectionType *t)
2162 enumtype->type = t->type;
2165 static MonoReflectionType*
2166 ves_icall_MonoGenericClass_GetParentType (MonoReflectionGenericClass *type)
2168 MonoDynamicGenericClass *gclass;
2169 MonoReflectionType *parent = NULL;
2174 MONO_ARCH_SAVE_REGS;
2176 g_assert (type->type.type->data.generic_class->is_dynamic);
2177 gclass = (MonoDynamicGenericClass *) type->type.type->data.generic_class;
2179 domain = mono_object_domain (type);
2180 klass = mono_class_from_mono_type (type->generic_type->type);
2182 if (!klass->generic_class && !klass->generic_container)
2185 if (!strcmp (type->generic_type->object.vtable->klass->name, "TypeBuilder")) {
2186 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *) type->generic_type;
2187 parent = tb->parent;
2188 } else if (klass->wastypebuilder) {
2189 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *) type->generic_type;
2190 parent = tb->parent;
2192 MonoClass *pklass = klass->parent;
2194 parent = mono_type_get_object (domain, &pklass->byval_arg);
2197 if (!parent || (parent->type->type != MONO_TYPE_GENERICINST))
2200 inflated = mono_class_inflate_generic_type (
2201 parent->type, mono_generic_class_get_context ((MonoGenericClass *) gclass));
2203 return mono_type_get_object (domain, inflated);
2207 ves_icall_MonoGenericClass_GetInterfaces (MonoReflectionGenericClass *type)
2209 static MonoClass *System_Reflection_MonoGenericClass;
2210 MonoGenericClass *gclass;
2211 MonoReflectionTypeBuilder *tb = NULL;
2212 MonoClass *klass = NULL;
2217 MONO_ARCH_SAVE_REGS;
2219 if (!System_Reflection_MonoGenericClass) {
2220 System_Reflection_MonoGenericClass = mono_class_from_name (
2221 mono_defaults.corlib, "System.Reflection", "MonoGenericClass");
2222 g_assert (System_Reflection_MonoGenericClass);
2225 domain = mono_object_domain (type);
2227 gclass = type->type.type->data.generic_class;
2228 g_assert (gclass->is_dynamic);
2230 if (!strcmp (type->generic_type->object.vtable->klass->name, "TypeBuilder")) {
2231 tb = (MonoReflectionTypeBuilder *) type->generic_type;
2232 icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
2234 klass = gclass->container_class;
2235 mono_class_init (klass);
2236 icount = klass->interface_count;
2239 res = mono_array_new (domain, System_Reflection_MonoGenericClass, icount);
2241 for (i = 0; i < icount; i++) {
2242 MonoReflectionType *iface;
2246 iface = mono_array_get (tb->interfaces, MonoReflectionType *, i);
2249 it = &klass->interfaces [i]->byval_arg;
2251 it = mono_class_inflate_generic_type (it, mono_generic_class_get_context (gclass));
2253 iface = mono_type_get_object (domain, it);
2254 mono_array_setref (res, i, iface);
2260 static MonoReflectionMethod*
2261 ves_icall_MonoGenericClass_GetCorrespondingInflatedMethod (MonoReflectionGenericClass *type,
2262 MonoReflectionMethod* generic)
2264 MonoGenericClass *gclass;
2265 MonoDynamicGenericClass *dgclass;
2269 MONO_ARCH_SAVE_REGS;
2271 gclass = type->type.type->data.generic_class;
2272 g_assert (gclass->is_dynamic);
2274 dgclass = (MonoDynamicGenericClass *) gclass;
2276 domain = mono_object_domain (type);
2278 for (i = 0; i < dgclass->count_methods; i++)
2279 if (generic->method->token == dgclass->methods [i]->token)
2280 return mono_method_get_object (domain, dgclass->methods [i], NULL);
2285 static MonoReflectionMethod*
2286 ves_icall_MonoGenericClass_GetCorrespondingInflatedConstructor (MonoReflectionGenericClass *type,
2287 MonoReflectionMethod* generic)
2289 MonoGenericClass *gclass;
2290 MonoDynamicGenericClass *dgclass;
2294 MONO_ARCH_SAVE_REGS;
2296 gclass = type->type.type->data.generic_class;
2297 g_assert (gclass->is_dynamic);
2299 dgclass = (MonoDynamicGenericClass *) gclass;
2301 domain = mono_object_domain (type);
2303 for (i = 0; i < dgclass->count_ctors; i++)
2304 if (generic->method->token == dgclass->ctors [i]->token)
2305 return mono_method_get_object (domain, dgclass->ctors [i], NULL);
2311 static MonoReflectionField*
2312 ves_icall_MonoGenericClass_GetCorrespondingInflatedField (MonoReflectionGenericClass *type,
2313 MonoString* generic_name)
2315 MonoGenericClass *gclass;
2316 MonoDynamicGenericClass *dgclass;
2318 MonoClass *refclass;
2319 char *utf8_name = mono_string_to_utf8 (generic_name);
2322 MONO_ARCH_SAVE_REGS;
2324 gclass = type->type.type->data.generic_class;
2325 g_assert (gclass->is_dynamic);
2327 dgclass = (MonoDynamicGenericClass *) gclass;
2329 refclass = mono_class_from_mono_type (type->type.type);
2331 domain = mono_object_domain (type);
2333 for (i = 0; i < dgclass->count_fields; i++)
2334 if (strcmp (utf8_name, dgclass->fields [i].name) == 0) {
2336 return mono_field_get_object (domain, refclass, &dgclass->fields [i]);
2345 static MonoReflectionMethod*
2346 ves_icall_MonoType_GetCorrespondingInflatedMethod (MonoReflectionType *type,
2347 MonoReflectionMethod* generic)
2354 MONO_ARCH_SAVE_REGS;
2356 domain = ((MonoObject *)type)->vtable->domain;
2358 klass = mono_class_from_mono_type (type->type);
2361 while ((method = mono_class_get_methods (klass, &iter))) {
2362 if (method->token == generic->method->token)
2363 return mono_method_get_object (domain, method, klass);
2370 ves_icall_MonoGenericClass_GetMethods (MonoReflectionGenericClass *type,
2371 MonoReflectionType *reflected_type)
2373 MonoGenericClass *gclass;
2374 MonoDynamicGenericClass *dgclass;
2376 MonoClass *refclass;
2380 MONO_ARCH_SAVE_REGS;
2382 gclass = type->type.type->data.generic_class;
2383 g_assert (gclass->is_dynamic);
2384 dgclass = (MonoDynamicGenericClass *) gclass;
2386 refclass = mono_class_from_mono_type (reflected_type->type);
2388 domain = mono_object_domain (type);
2389 res = mono_array_new (domain, mono_defaults.method_info_class, dgclass->count_methods);
2391 for (i = 0; i < dgclass->count_methods; i++)
2392 mono_array_setref (res, i, mono_method_get_object (domain, dgclass->methods [i], refclass));
2398 ves_icall_MonoGenericClass_GetConstructors (MonoReflectionGenericClass *type,
2399 MonoReflectionType *reflected_type)
2401 static MonoClass *System_Reflection_ConstructorInfo;
2402 MonoGenericClass *gclass;
2403 MonoDynamicGenericClass *dgclass;
2405 MonoClass *refclass;
2409 MONO_ARCH_SAVE_REGS;
2411 if (!System_Reflection_ConstructorInfo)
2412 System_Reflection_ConstructorInfo = mono_class_from_name (
2413 mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
2415 gclass = type->type.type->data.generic_class;
2416 g_assert (gclass->is_dynamic);
2417 dgclass = (MonoDynamicGenericClass *) gclass;
2419 refclass = mono_class_from_mono_type (reflected_type->type);
2421 domain = mono_object_domain (type);
2422 res = mono_array_new (domain, System_Reflection_ConstructorInfo, dgclass->count_ctors);
2424 for (i = 0; i < dgclass->count_ctors; i++)
2425 mono_array_setref (res, i, mono_method_get_object (domain, dgclass->ctors [i], refclass));
2431 ves_icall_MonoGenericClass_GetFields (MonoReflectionGenericClass *type,
2432 MonoReflectionType *reflected_type)
2434 MonoGenericClass *gclass;
2435 MonoDynamicGenericClass *dgclass;
2437 MonoClass *refclass;
2441 MONO_ARCH_SAVE_REGS;
2443 gclass = type->type.type->data.generic_class;
2444 g_assert (gclass->is_dynamic);
2445 dgclass = (MonoDynamicGenericClass *) gclass;
2447 refclass = mono_class_from_mono_type (reflected_type->type);
2449 domain = mono_object_domain (type);
2450 res = mono_array_new (domain, mono_defaults.field_info_class, dgclass->count_fields);
2452 for (i = 0; i < dgclass->count_fields; i++)
2453 mono_array_setref (res, i, mono_field_get_object (domain, refclass, &dgclass->fields [i]));
2459 ves_icall_MonoGenericClass_GetProperties (MonoReflectionGenericClass *type,
2460 MonoReflectionType *reflected_type)
2462 static MonoClass *System_Reflection_PropertyInfo;
2463 MonoGenericClass *gclass;
2464 MonoDynamicGenericClass *dgclass;
2466 MonoClass *refclass;
2470 MONO_ARCH_SAVE_REGS;
2472 if (!System_Reflection_PropertyInfo)
2473 System_Reflection_PropertyInfo = mono_class_from_name (
2474 mono_defaults.corlib, "System.Reflection", "PropertyInfo");
2476 gclass = type->type.type->data.generic_class;
2477 g_assert (gclass->is_dynamic);
2478 dgclass = (MonoDynamicGenericClass *) gclass;
2480 refclass = mono_class_from_mono_type (reflected_type->type);
2482 domain = mono_object_domain (type);
2483 res = mono_array_new (domain, System_Reflection_PropertyInfo, dgclass->count_properties);
2485 for (i = 0; i < dgclass->count_properties; i++)
2486 mono_array_setref (res, i, mono_property_get_object (domain, refclass, &dgclass->properties [i]));
2492 ves_icall_MonoGenericClass_GetEvents (MonoReflectionGenericClass *type,
2493 MonoReflectionType *reflected_type)
2495 static MonoClass *System_Reflection_EventInfo;
2496 MonoGenericClass *gclass;
2497 MonoDynamicGenericClass *dgclass;
2499 MonoClass *refclass;
2503 MONO_ARCH_SAVE_REGS;
2505 if (!System_Reflection_EventInfo)
2506 System_Reflection_EventInfo = mono_class_from_name (
2507 mono_defaults.corlib, "System.Reflection", "EventInfo");
2509 gclass = type->type.type->data.generic_class;
2510 g_assert (gclass->is_dynamic);
2511 dgclass = (MonoDynamicGenericClass *) gclass;
2513 refclass = mono_class_from_mono_type (reflected_type->type);
2515 domain = mono_object_domain (type);
2516 res = mono_array_new (domain, System_Reflection_EventInfo, dgclass->count_events);
2518 for (i = 0; i < dgclass->count_events; i++)
2519 mono_array_setref (res, i, mono_event_get_object (domain, refclass, &dgclass->events [i]));
2524 static MonoReflectionMethod *
2525 ves_icall_MonoType_get_DeclaringMethod (MonoReflectionType *type)
2530 MONO_ARCH_SAVE_REGS;
2532 if (type->type->byref || type->type->type != MONO_TYPE_MVAR)
2535 method = type->type->data.generic_param->owner->owner.method;
2537 klass = mono_class_from_mono_type (type->type);
2538 return mono_method_get_object (mono_object_domain (type), method, klass);
2541 static MonoReflectionDllImportAttribute*
2542 ves_icall_MonoMethod_GetDllImportAttribute (MonoMethod *method)
2544 static MonoClass *DllImportAttributeClass = NULL;
2545 MonoDomain *domain = mono_domain_get ();
2546 MonoReflectionDllImportAttribute *attr;
2547 MonoImage *image = method->klass->image;
2548 MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method;
2549 MonoTableInfo *tables = image->tables;
2550 MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
2551 MonoTableInfo *mr = &tables [MONO_TABLE_MODULEREF];
2552 guint32 im_cols [MONO_IMPLMAP_SIZE];
2553 guint32 scope_token;
2554 const char *import = NULL;
2555 const char *scope = NULL;
2558 if (!method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)
2561 if (!DllImportAttributeClass) {
2562 DllImportAttributeClass =
2563 mono_class_from_name (mono_defaults.corlib,
2564 "System.Runtime.InteropServices", "DllImportAttribute");
2565 g_assert (DllImportAttributeClass);
2568 if (method->klass->image->dynamic) {
2569 MonoReflectionMethodAux *method_aux =
2570 g_hash_table_lookup (
2571 ((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
2573 import = method_aux->dllentry;
2574 scope = method_aux->dll;
2578 if (piinfo->implmap_idx) {
2579 mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
2581 piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
2582 import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
2583 scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
2584 scope = mono_metadata_string_heap (image, scope_token);
2587 flags = piinfo->piflags;
2589 attr = (MonoReflectionDllImportAttribute*)mono_object_new (domain, DllImportAttributeClass);
2591 MONO_OBJECT_SETREF (attr, dll, mono_string_new (domain, scope));
2592 MONO_OBJECT_SETREF (attr, entry_point, mono_string_new (domain, import));
2593 attr->call_conv = (flags & 0x700) >> 8;
2594 attr->charset = ((flags & 0x6) >> 1) + 1;
2595 if (attr->charset == 1)
2597 attr->exact_spelling = (flags & 0x1) != 0;
2598 attr->set_last_error = (flags & 0x40) != 0;
2599 attr->best_fit_mapping = (flags & 0x30) == 0x10;
2600 attr->throw_on_unmappable = (flags & 0x3000) == 0x1000;
2601 attr->preserve_sig = FALSE;
2606 static MonoReflectionMethod *
2607 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
2609 MonoMethodInflated *imethod;
2611 MONO_ARCH_SAVE_REGS;
2613 if (method->method->generic_container)
2616 if (!method->method->is_inflated)
2619 imethod = (MonoMethodInflated *) method->method;
2621 if (imethod->reflection_info)
2622 return imethod->reflection_info;
2624 return mono_method_get_object (
2625 mono_object_domain (method), imethod->declaring, NULL);
2629 ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethod *method)
2631 MONO_ARCH_SAVE_REGS;
2633 return mono_method_signature (method->method)->generic_param_count != 0;
2637 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method)
2639 MONO_ARCH_SAVE_REGS;
2641 return method->method->generic_container != NULL;
2645 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
2650 MONO_ARCH_SAVE_REGS;
2652 domain = mono_object_domain (method);
2654 if (method->method->is_inflated) {
2655 MonoGenericInst *inst = mono_method_get_context (method->method)->method_inst;
2658 count = inst->type_argc;
2659 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2661 for (i = 0; i < count; i++)
2662 mono_array_setref (res, i, mono_type_get_object (domain, inst->type_argv [i]));
2668 count = mono_method_signature (method->method)->generic_param_count;
2669 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2671 for (i = 0; i < count; i++) {
2672 MonoGenericParam *param = &method->method->generic_container->type_params [i];
2673 MonoClass *pklass = mono_class_from_generic_parameter (
2674 param, method->method->klass->image, TRUE);
2675 mono_array_setref (res, i,
2676 mono_type_get_object (domain, &pklass->byval_arg));
2683 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoArray *params)
2686 * Invoke from reflection is supposed to always be a virtual call (the API
2687 * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
2688 * greater flexibility.
2690 MonoMethod *m = method->method;
2694 MONO_ARCH_SAVE_REGS;
2696 if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
2698 if (!mono_object_isinst (this, m->klass))
2699 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
2700 m = mono_object_get_virtual_method (this, m);
2701 /* must pass the pointer to the value for valuetype methods */
2702 if (m->klass->valuetype)
2703 obj = mono_object_unbox (this);
2704 } else if (strcmp (m->name, ".ctor") && !m->wrapper_type)
2705 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
2708 pcount = params? mono_array_length (params): 0;
2709 if (pcount != mono_method_signature (m)->param_count)
2710 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
2712 if ((m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) && !strcmp (m->name, ".ctor") && !this)
2713 mono_raise_exception (mono_exception_from_name_msg (mono_defaults.corlib, "System", "MethodAccessException", "Cannot invoke constructor of an abstract class."));
2715 if (m->klass->image->assembly->ref_only)
2716 mono_raise_exception (mono_get_exception_invalid_operation ("It is illegal to invoke a method on a type loaded using the ReflectionOnly api."));
2718 if (m->klass->rank && !strcmp (m->name, ".ctor")) {
2721 guint32 *lower_bounds;
2722 pcount = mono_array_length (params);
2723 lengths = alloca (sizeof (guint32) * pcount);
2724 for (i = 0; i < pcount; ++i)
2725 lengths [i] = *(gint32*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
2727 if (m->klass->rank == pcount) {
2728 /* Only lengths provided. */
2729 lower_bounds = NULL;
2731 g_assert (pcount == (m->klass->rank * 2));
2732 /* lower bounds are first. */
2733 lower_bounds = lengths;
2734 lengths += m->klass->rank;
2737 return (MonoObject*)mono_array_new_full (mono_object_domain (params), m->klass, lengths, lower_bounds);
2739 return mono_runtime_invoke_array (m, obj, params, NULL);
2743 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this, MonoArray *params, MonoArray **outArgs)
2745 MonoDomain *domain = mono_object_domain (method);
2746 MonoMethod *m = method->method;
2747 MonoMethodSignature *sig = mono_method_signature (m);
2748 MonoArray *out_args;
2750 int i, j, outarg_count = 0;
2752 MONO_ARCH_SAVE_REGS;
2754 if (m->klass == mono_defaults.object_class) {
2756 if (!strcmp (m->name, "FieldGetter")) {
2757 MonoClass *k = this->vtable->klass;
2761 /* If this is a proxy, then it must be a CBO */
2762 if (k == mono_defaults.transparent_proxy_class) {
2763 MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
2764 this = tp->rp->unwrapped_server;
2766 k = this->vtable->klass;
2769 name = mono_array_get (params, MonoString *, 1);
2770 str = mono_string_to_utf8 (name);
2773 MonoClassField* field = mono_class_get_field_from_name (k, str);
2775 MonoClass *field_klass = mono_class_from_mono_type (field->type);
2776 if (field_klass->valuetype)
2777 result = mono_value_box (domain, field_klass, (char *)this + field->offset);
2779 result = *((gpointer *)((char *)this + field->offset));
2781 out_args = mono_array_new (domain, mono_defaults.object_class, 1);
2782 *outArgs = out_args;
2783 mono_array_setref (out_args, 0, result);
2791 g_assert_not_reached ();
2793 } else if (!strcmp (m->name, "FieldSetter")) {
2794 MonoClass *k = this->vtable->klass;
2800 /* If this is a proxy, then it must be a CBO */
2801 if (k == mono_defaults.transparent_proxy_class) {
2802 MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
2803 this = tp->rp->unwrapped_server;
2805 k = this->vtable->klass;
2808 name = mono_array_get (params, MonoString *, 1);
2809 str = mono_string_to_utf8 (name);
2812 MonoClassField* field = mono_class_get_field_from_name (k, str);
2814 MonoClass *field_klass = mono_class_from_mono_type (field->type);
2815 MonoObject *val = mono_array_get (params, gpointer, 2);
2817 if (field_klass->valuetype) {
2818 size = mono_type_size (field->type, &align);
2819 memcpy ((char *)this + field->offset,
2820 ((char *)val) + sizeof (MonoObject), size);
2822 *(MonoObject**)((char *)this + field->offset) = val;
2824 out_args = mono_array_new (domain, mono_defaults.object_class, 0);
2825 *outArgs = out_args;
2835 g_assert_not_reached ();
2840 for (i = 0; i < mono_array_length (params); i++) {
2841 if (sig->params [i]->byref)
2845 out_args = mono_array_new (domain, mono_defaults.object_class, outarg_count);
2847 /* handle constructors only for objects already allocated */
2848 if (!strcmp (method->method->name, ".ctor"))
2851 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
2852 g_assert (!method->method->klass->valuetype);
2853 result = mono_runtime_invoke_array (method->method, this, params, NULL);
2855 for (i = 0, j = 0; i < mono_array_length (params); i++) {
2856 if (sig->params [i]->byref) {
2858 arg = mono_array_get (params, gpointer, i);
2859 mono_array_setref (out_args, j, arg);
2864 *outArgs = out_args;
2870 read_enum_value (char *mem, int type)
2874 return *(guint8*)mem;
2876 return *(gint8*)mem;
2878 return *(guint16*)mem;
2880 return *(gint16*)mem;
2882 return *(guint32*)mem;
2884 return *(gint32*)mem;
2886 return *(guint64*)mem;
2888 return *(gint64*)mem;
2890 g_assert_not_reached ();
2896 write_enum_value (char *mem, int type, guint64 value)
2900 case MONO_TYPE_I1: {
2901 guint8 *p = (guint8*)mem;
2906 case MONO_TYPE_I2: {
2907 guint16 *p = (void*)mem;
2912 case MONO_TYPE_I4: {
2913 guint32 *p = (void*)mem;
2918 case MONO_TYPE_I8: {
2919 guint64 *p = (void*)mem;
2924 g_assert_not_reached ();
2930 ves_icall_System_Enum_ToObject (MonoReflectionType *type, MonoObject *obj)
2933 MonoClass *enumc, *objc;
2937 MONO_ARCH_SAVE_REGS;
2939 MONO_CHECK_ARG_NULL (type);
2940 MONO_CHECK_ARG_NULL (obj);
2942 domain = mono_object_domain (type);
2943 enumc = mono_class_from_mono_type (type->type);
2944 objc = obj->vtable->klass;
2946 if (!enumc->enumtype)
2947 mono_raise_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
2948 if (!((objc->enumtype) || (objc->byval_arg.type >= MONO_TYPE_I1 && objc->byval_arg.type <= MONO_TYPE_U8)))
2949 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."));
2951 res = mono_object_new (domain, enumc);
2952 val = read_enum_value ((char *)obj + sizeof (MonoObject), objc->enumtype? objc->enum_basetype->type: objc->byval_arg.type);
2953 write_enum_value ((char *)res + sizeof (MonoObject), enumc->enum_basetype->type, val);
2959 ves_icall_System_Enum_get_value (MonoObject *this)
2967 MONO_ARCH_SAVE_REGS;
2972 g_assert (this->vtable->klass->enumtype);
2974 enumc = mono_class_from_mono_type (this->vtable->klass->enum_basetype);
2975 res = mono_object_new (mono_object_domain (this), enumc);
2976 dst = (char *)res + sizeof (MonoObject);
2977 src = (char *)this + sizeof (MonoObject);
2978 size = mono_class_value_size (enumc, NULL);
2980 memcpy (dst, src, size);
2986 ves_icall_get_enum_info (MonoReflectionType *type, MonoEnumInfo *info)
2988 MonoDomain *domain = mono_object_domain (type);
2989 MonoClass *enumc = mono_class_from_mono_type (type->type);
2990 guint j = 0, nvalues, crow;
2992 MonoClassField *field;
2994 MONO_ARCH_SAVE_REGS;
2996 info->utype = mono_type_get_object (domain, enumc->enum_basetype);
2997 nvalues = mono_class_num_fields (enumc) ? mono_class_num_fields (enumc) - 1 : 0;
2998 info->names = mono_array_new (domain, mono_defaults.string_class, nvalues);
2999 info->values = mono_array_new (domain, enumc, nvalues);
3003 while ((field = mono_class_get_fields (enumc, &iter))) {
3007 if (strcmp ("value__", field->name) == 0)
3009 if (mono_field_is_deleted (field))
3011 mono_array_setref (info->names, j, mono_string_new (domain, field->name));
3014 crow = mono_metadata_get_constant_index (enumc->image, mono_class_get_field_token (field), crow + 1);
3015 field->def_type = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_TYPE);
3016 crow = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_VALUE);
3017 field->data = (gpointer)mono_metadata_blob_heap (enumc->image, crow);
3021 len = mono_metadata_decode_blob_size (p, &p);
3022 switch (enumc->enum_basetype->type) {
3025 mono_array_set (info->values, gchar, j, *p);
3027 case MONO_TYPE_CHAR:
3030 mono_array_set (info->values, gint16, j, read16 (p));
3034 mono_array_set (info->values, gint32, j, read32 (p));
3038 mono_array_set (info->values, gint64, j, read64 (p));
3041 g_error ("Implement type 0x%02x in get_enum_info", enumc->enum_basetype->type);
3048 BFLAGS_IgnoreCase = 1,
3049 BFLAGS_DeclaredOnly = 2,
3050 BFLAGS_Instance = 4,
3052 BFLAGS_Public = 0x10,
3053 BFLAGS_NonPublic = 0x20,
3054 BFLAGS_FlattenHierarchy = 0x40,
3055 BFLAGS_InvokeMethod = 0x100,
3056 BFLAGS_CreateInstance = 0x200,
3057 BFLAGS_GetField = 0x400,
3058 BFLAGS_SetField = 0x800,
3059 BFLAGS_GetProperty = 0x1000,
3060 BFLAGS_SetProperty = 0x2000,
3061 BFLAGS_ExactBinding = 0x10000,
3062 BFLAGS_SuppressChangeType = 0x20000,
3063 BFLAGS_OptionalParamBinding = 0x40000
3066 static MonoReflectionField *
3067 ves_icall_Type_GetField (MonoReflectionType *type, MonoString *name, guint32 bflags)
3070 MonoClass *startklass, *klass;
3072 MonoClassField *field;
3075 int (*compare_func) (const char *s1, const char *s2) = NULL;
3076 domain = ((MonoObject *)type)->vtable->domain;
3077 klass = startklass = mono_class_from_mono_type (type->type);
3079 MONO_ARCH_SAVE_REGS;
3082 mono_raise_exception (mono_get_exception_argument_null ("name"));
3083 if (type->type->byref)
3086 compare_func = (bflags & BFLAGS_IgnoreCase) ? g_strcasecmp : strcmp;
3089 if (klass->exception_type != MONO_EXCEPTION_NONE)
3090 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3093 while ((field = mono_class_get_fields (klass, &iter))) {
3096 if (field->type == NULL)
3098 if (mono_field_is_deleted (field))
3100 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3101 if (bflags & BFLAGS_Public)
3104 if (bflags & BFLAGS_NonPublic)
3110 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
3111 if (bflags & BFLAGS_Static)
3112 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3115 if (bflags & BFLAGS_Instance)
3122 utf8_name = mono_string_to_utf8 (name);
3124 if (compare_func (field->name, utf8_name)) {
3130 return mono_field_get_object (domain, klass, field);
3132 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3139 ves_icall_Type_GetFields_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3142 MonoClass *startklass, *klass, *refklass;
3147 MonoClassField *field;
3149 MONO_ARCH_SAVE_REGS;
3151 domain = ((MonoObject *)type)->vtable->domain;
3152 if (type->type->byref)
3153 return mono_array_new (domain, mono_defaults.field_info_class, 0);
3154 klass = startklass = mono_class_from_mono_type (type->type);
3155 refklass = mono_class_from_mono_type (reftype->type);
3159 res = mono_array_new (domain, mono_defaults.field_info_class, len);
3161 if (klass->exception_type != MONO_EXCEPTION_NONE)
3162 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3165 while ((field = mono_class_get_fields (klass, &iter))) {
3167 if (mono_field_is_deleted (field))
3169 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3170 if (bflags & BFLAGS_Public)
3173 if (bflags & BFLAGS_NonPublic) {
3174 /* Serialization currently depends on the old behavior.
3175 * if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE || startklass == klass)*/
3182 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
3183 if (bflags & BFLAGS_Static)
3184 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3187 if (bflags & BFLAGS_Instance)
3193 member = (MonoObject*)mono_field_get_object (domain, refklass, field);
3195 MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, len * 2);
3196 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3200 mono_array_setref (res, i, member);
3203 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3206 MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, i);
3207 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3210 * Better solution for the new GC.
3211 * res->max_length = i;
3218 ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
3221 MonoClass *startklass, *klass, *refklass;
3226 int i, len, match, nslots;
3227 guint32 method_slots_default [8];
3228 guint32 *method_slots;
3229 gchar *mname = NULL;
3230 int (*compare_func) (const char *s1, const char *s2) = NULL;
3232 MONO_ARCH_SAVE_REGS;
3234 domain = ((MonoObject *)type)->vtable->domain;
3235 if (type->type->byref)
3236 return mono_array_new (domain, mono_defaults.method_info_class, 0);
3237 klass = startklass = mono_class_from_mono_type (type->type);
3238 refklass = mono_class_from_mono_type (reftype->type);
3241 mname = mono_string_to_utf8 (name);
3242 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
3245 mono_class_setup_vtable (klass);
3247 if (is_generic_parameter (type->type))
3248 nslots = klass->parent->vtable_size;
3250 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : klass->vtable_size;
3251 if (nslots >= sizeof (method_slots_default) * 8) {
3252 method_slots = g_new0 (guint32, nslots / 32 + 1);
3254 method_slots = method_slots_default;
3255 memset (method_slots, 0, sizeof (method_slots_default));
3259 res = mono_array_new (domain, mono_defaults.method_info_class, len);
3261 mono_class_setup_vtable (klass);
3262 if (klass->exception_type != MONO_EXCEPTION_NONE)
3263 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3266 while ((method = mono_class_get_methods (klass, &iter))) {
3268 if (method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
3270 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3271 if (bflags & BFLAGS_Public)
3274 if (bflags & BFLAGS_NonPublic)
3280 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3281 if (bflags & BFLAGS_Static)
3282 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3285 if (bflags & BFLAGS_Instance)
3293 if (compare_func (mname, method->name))
3298 if (method->slot != -1) {
3299 g_assert (method->slot < nslots);
3300 if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
3302 method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
3305 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
3308 MonoArray *new_res = mono_array_new (domain, mono_defaults.method_info_class, len * 2);
3309 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3313 mono_array_setref (res, i, member);
3316 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3320 if (method_slots != method_slots_default)
3321 g_free (method_slots);
3323 MonoArray *new_res = mono_array_new (domain, mono_defaults.method_info_class, i);
3324 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3327 * Better solution for the new GC.
3328 * res->max_length = i;
3335 ves_icall_Type_GetConstructors_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3338 static MonoClass *System_Reflection_ConstructorInfo;
3339 MonoClass *startklass, *klass, *refklass;
3344 gpointer iter = NULL;
3346 MONO_ARCH_SAVE_REGS;
3348 domain = ((MonoObject *)type)->vtable->domain;
3349 if (type->type->byref)
3350 return mono_array_new (domain, mono_defaults.method_info_class, 0);
3351 klass = startklass = mono_class_from_mono_type (type->type);
3352 refklass = mono_class_from_mono_type (reftype->type);
3354 if (klass->exception_type != MONO_EXCEPTION_NONE)
3355 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3357 if (!System_Reflection_ConstructorInfo)
3358 System_Reflection_ConstructorInfo = mono_class_from_name (
3359 mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
3363 res = mono_array_new (domain, System_Reflection_ConstructorInfo, len);
3365 while ((method = mono_class_get_methods (klass, &iter))) {
3367 if (strcmp (method->name, ".ctor") && strcmp (method->name, ".cctor"))
3369 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3370 if (bflags & BFLAGS_Public)
3373 if (bflags & BFLAGS_NonPublic)
3379 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3380 if (bflags & BFLAGS_Static)
3381 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3384 if (bflags & BFLAGS_Instance)
3390 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
3393 MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, len * 2);
3394 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3398 mono_array_setref (res, i, member);
3402 MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, i);
3403 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3406 * Better solution for the new GC.
3407 * res->max_length = i;
3414 ves_icall_Type_GetPropertiesByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
3417 static MonoClass *System_Reflection_PropertyInfo;
3418 MonoClass *startklass, *klass;
3422 int i, match, nslots;
3425 guint32 method_slots_default [8];
3426 guint32 *method_slots;
3427 gchar *propname = NULL;
3428 int (*compare_func) (const char *s1, const char *s2) = NULL;
3431 MONO_ARCH_SAVE_REGS;
3433 if (!System_Reflection_PropertyInfo)
3434 System_Reflection_PropertyInfo = mono_class_from_name (
3435 mono_defaults.corlib, "System.Reflection", "PropertyInfo");
3437 domain = ((MonoObject *)type)->vtable->domain;
3438 if (type->type->byref)
3439 return mono_array_new (domain, System_Reflection_PropertyInfo, 0);
3440 klass = startklass = mono_class_from_mono_type (type->type);
3442 propname = mono_string_to_utf8 (name);
3443 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
3446 mono_class_setup_vtable (klass);
3448 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : klass->vtable_size;
3449 if (nslots >= sizeof (method_slots_default) * 8) {
3450 method_slots = g_new0 (guint32, nslots / 32 + 1);
3452 method_slots = method_slots_default;
3453 memset (method_slots, 0, sizeof (method_slots_default));
3457 res = mono_array_new (domain, System_Reflection_PropertyInfo, len);
3459 mono_class_setup_vtable (klass);
3460 if (klass->exception_type != MONO_EXCEPTION_NONE) {
3461 if (method_slots != method_slots_default)
3462 g_free (method_slots);
3465 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3469 while ((prop = mono_class_get_properties (klass, &iter))) {
3475 flags = method->flags;
3478 if ((prop->get && ((prop->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC)) ||
3479 (prop->set && ((prop->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC))) {
3480 if (bflags & BFLAGS_Public)
3483 if (bflags & BFLAGS_NonPublic)
3489 if (flags & METHOD_ATTRIBUTE_STATIC) {
3490 if (bflags & BFLAGS_Static)
3491 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3494 if (bflags & BFLAGS_Instance)
3503 if (compare_func (propname, prop->name))
3507 if (prop->get && prop->get->slot != -1) {
3508 if (method_slots [prop->get->slot >> 5] & (1 << (prop->get->slot & 0x1f)))
3510 method_slots [prop->get->slot >> 5] |= 1 << (prop->get->slot & 0x1f);
3512 if (prop->set && prop->set->slot != -1) {
3513 if (method_slots [prop->set->slot >> 5] & (1 << (prop->set->slot & 0x1f)))
3515 method_slots [prop->set->slot >> 5] |= 1 << (prop->set->slot & 0x1f);
3519 MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, len * 2);
3520 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3524 mono_array_setref (res, i, mono_property_get_object (domain, startklass, prop));
3527 if ((!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent)))
3531 if (method_slots != method_slots_default)
3532 g_free (method_slots);
3534 MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, i);
3535 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3538 * Better solution for the new GC.
3539 * res->max_length = i;
3545 static MonoReflectionEvent *
3546 ves_icall_MonoType_GetEvent (MonoReflectionType *type, MonoString *name, guint32 bflags)
3549 MonoClass *klass, *startklass;
3555 MONO_ARCH_SAVE_REGS;
3557 event_name = mono_string_to_utf8 (name);
3558 if (type->type->byref)
3560 klass = startklass = mono_class_from_mono_type (type->type);
3561 domain = mono_object_domain (type);
3564 if (klass->exception_type != MONO_EXCEPTION_NONE)
3565 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3568 while ((event = mono_class_get_events (klass, &iter))) {
3569 if (strcmp (event->name, event_name))
3572 method = event->add;
3574 method = event->remove;
3576 method = event->raise;
3578 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3579 if (!(bflags & BFLAGS_Public))
3582 if (!(bflags & BFLAGS_NonPublic))
3587 if (!(bflags & BFLAGS_NonPublic))
3590 g_free (event_name);
3591 return mono_event_get_object (domain, startklass, event);
3594 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3597 g_free (event_name);
3602 ves_icall_Type_GetEvents_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3605 static MonoClass *System_Reflection_EventInfo;
3606 MonoClass *startklass, *klass;
3613 MONO_ARCH_SAVE_REGS;
3615 if (!System_Reflection_EventInfo)
3616 System_Reflection_EventInfo = mono_class_from_name (
3617 mono_defaults.corlib, "System.Reflection", "EventInfo");
3619 domain = mono_object_domain (type);
3620 if (type->type->byref)
3621 return mono_array_new (domain, System_Reflection_EventInfo, 0);
3622 klass = startklass = mono_class_from_mono_type (type->type);
3626 res = mono_array_new (domain, System_Reflection_EventInfo, len);
3628 if (klass->exception_type != MONO_EXCEPTION_NONE)
3629 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3632 while ((event = mono_class_get_events (klass, &iter))) {
3634 method = event->add;
3636 method = event->remove;
3638 method = event->raise;
3640 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3641 if (bflags & BFLAGS_Public)
3644 if (bflags & BFLAGS_NonPublic)
3649 if (bflags & BFLAGS_NonPublic)
3655 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3656 if (bflags & BFLAGS_Static)
3657 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3660 if (bflags & BFLAGS_Instance)
3665 if (bflags & BFLAGS_Instance)
3671 MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, len * 2);
3672 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3676 mono_array_setref (res, i, mono_event_get_object (domain, startklass, event));
3679 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3682 MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, i);
3683 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3686 * Better solution for the new GC.
3687 * res->max_length = i;
3693 static MonoReflectionType *
3694 ves_icall_Type_GetNestedType (MonoReflectionType *type, MonoString *name, guint32 bflags)
3702 MONO_ARCH_SAVE_REGS;
3704 domain = ((MonoObject *)type)->vtable->domain;
3705 if (type->type->byref)
3707 klass = mono_class_from_mono_type (type->type);
3708 str = mono_string_to_utf8 (name);
3711 if (klass->exception_type != MONO_EXCEPTION_NONE)
3712 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3715 * If a nested type is generic, return its generic type definition.
3716 * Note that this means that the return value is essentially a
3717 * nested type of the generic type definition of @klass.
3719 * A note in MSDN claims that a generic type definition can have
3720 * nested types that aren't generic. In any case, the container of that
3721 * nested type would be the generic type definition.
3723 if (klass->generic_class)
3724 klass = klass->generic_class->container_class;
3726 for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
3728 nested = tmpn->data;
3729 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
3730 if (bflags & BFLAGS_Public)
3733 if (bflags & BFLAGS_NonPublic)
3738 if (strcmp (nested->name, str) == 0){
3740 return mono_type_get_object (domain, &nested->byval_arg);
3743 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3750 ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags)
3760 MONO_ARCH_SAVE_REGS;
3762 domain = ((MonoObject *)type)->vtable->domain;
3763 if (type->type->byref)
3764 return mono_array_new (domain, mono_defaults.monotype_class, 0);
3765 klass = mono_class_from_mono_type (type->type);
3766 if (klass->exception_type != MONO_EXCEPTION_NONE)
3767 mono_raise_exception (mono_class_get_exception_for_failure (klass));
3770 * If a nested type is generic, return its generic type definition.
3771 * Note that this means that the return value is essentially the set
3772 * of nested types of the generic type definition of @klass.
3774 * A note in MSDN claims that a generic type definition can have
3775 * nested types that aren't generic. In any case, the container of that
3776 * nested type would be the generic type definition.
3778 if (klass->generic_class)
3779 klass = klass->generic_class->container_class;
3783 res = mono_array_new (domain, mono_defaults.monotype_class, len);
3784 for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
3786 nested = tmpn->data;
3787 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
3788 if (bflags & BFLAGS_Public)
3791 if (bflags & BFLAGS_NonPublic)
3796 member = (MonoObject*)mono_type_get_object (domain, &nested->byval_arg);
3798 MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, len * 2);
3799 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3803 mono_array_setref (res, i, member);
3807 MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, i);
3808 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3811 * Better solution for the new GC.
3812 * res->max_length = i;
3818 static MonoReflectionType*
3819 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *assembly, MonoReflectionModule *module, MonoString *name, MonoBoolean throwOnError, MonoBoolean ignoreCase)
3822 MonoType *type = NULL;
3823 MonoTypeNameParse info;
3824 gboolean type_resolve;
3826 MONO_ARCH_SAVE_REGS;
3828 /* On MS.NET, this does not fire a TypeResolve event */
3829 type_resolve = TRUE;
3830 str = mono_string_to_utf8 (name);
3831 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
3832 if (!mono_reflection_parse_type (str, &info)) {
3834 g_list_free (info.modifiers);
3835 g_list_free (info.nested);
3836 if (throwOnError) /* uhm: this is a parse error, though... */
3837 mono_raise_exception (mono_get_exception_type_load (name, NULL));
3838 /*g_print ("failed parse\n");*/
3842 if (module != NULL) {
3844 type = mono_reflection_get_type (module->image, &info, ignoreCase, &type_resolve);
3849 if (assembly->assembly->dynamic) {
3850 /* Enumerate all modules */
3851 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
3855 if (abuilder->modules) {
3856 for (i = 0; i < mono_array_length (abuilder->modules); ++i) {
3857 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
3858 type = mono_reflection_get_type (&mb->dynamic_image->image, &info, ignoreCase, &type_resolve);
3864 if (!type && abuilder->loaded_modules) {
3865 for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) {
3866 MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
3867 type = mono_reflection_get_type (mod->image, &info, ignoreCase, &type_resolve);
3874 type = mono_reflection_get_type (assembly->assembly->image, &info, ignoreCase, &type_resolve);
3876 g_list_free (info.modifiers);
3877 g_list_free (info.nested);
3879 MonoException *e = NULL;
3882 e = mono_get_exception_type_load (name, NULL);
3884 mono_loader_clear_error ();
3887 mono_raise_exception (e);
3892 if (type->type == MONO_TYPE_CLASS) {
3893 MonoClass *klass = mono_type_get_class (type);
3894 /* need to report exceptions ? */
3895 if (throwOnError && klass->exception_type) {
3896 /* report SecurityException (or others) that occured when loading the assembly */
3897 MonoException *exc = mono_class_get_exception_for_failure (klass);
3898 mono_loader_clear_error ();
3899 mono_raise_exception (exc);
3900 } else if (klass->exception_type == MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND) {
3905 /* g_print ("got it\n"); */
3906 return mono_type_get_object (mono_object_domain (assembly), type);
3910 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *assembly, MonoBoolean escaped)
3912 MonoDomain *domain = mono_object_domain (assembly);
3913 MonoAssembly *mass = assembly->assembly;
3914 MonoString *res = NULL;
3918 MONO_ARCH_SAVE_REGS;
3920 if (g_path_is_absolute (mass->image->name))
3921 absolute = g_strdup (mass->image->name);
3923 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
3927 for (i = strlen (absolute) - 1; i >= 0; i--)
3928 if (absolute [i] == '\\')
3933 uri = g_filename_to_uri (absolute, NULL, NULL);
3935 uri = g_strconcat ("file://", absolute, NULL);
3939 res = mono_string_new (domain, uri);
3947 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssembly *assembly)
3949 MonoAssembly *mass = assembly->assembly;
3951 MONO_ARCH_SAVE_REGS;
3953 return mass->in_gac;
3956 static MonoReflectionAssembly*
3957 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoString *mname, MonoObject *evidence)
3961 MonoImageOpenStatus status;
3963 MONO_ARCH_SAVE_REGS;
3965 name = mono_string_to_utf8 (mname);
3966 res = mono_assembly_load_with_partial_name (name, &status);
3972 return mono_assembly_get_object (mono_domain_get (), res);
3976 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssembly *assembly)
3978 MonoDomain *domain = mono_object_domain (assembly);
3981 MONO_ARCH_SAVE_REGS;
3983 res = mono_string_new (domain, mono_image_get_filename (assembly->assembly->image));
3989 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssembly *assembly)
3991 MONO_ARCH_SAVE_REGS;
3993 return assembly->assembly->ref_only;
3997 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssembly *assembly)
3999 MonoDomain *domain = mono_object_domain (assembly);
4001 MONO_ARCH_SAVE_REGS;
4003 return mono_string_new (domain, assembly->assembly->image->version);
4006 static MonoReflectionMethod*
4007 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssembly *assembly)
4009 guint32 token = mono_image_get_entry_point (assembly->assembly->image);
4011 MONO_ARCH_SAVE_REGS;
4015 return mono_method_get_object (mono_object_domain (assembly), mono_get_method (assembly->assembly->image, token, NULL), NULL);
4018 static MonoReflectionModule*
4019 ves_icall_System_Reflection_Assembly_get_ManifestModule (MonoReflectionAssembly *assembly)
4021 return mono_module_get_object (mono_object_domain (assembly), assembly->assembly->image);
4025 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssembly *assembly)
4027 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4028 MonoArray *result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, table->rows);
4032 MONO_ARCH_SAVE_REGS;
4034 for (i = 0; i < table->rows; ++i) {
4035 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_MANIFEST_NAME));
4036 mono_array_setref (result, i, mono_string_new (mono_object_domain (assembly), val));
4042 create_version (MonoDomain *domain, guint32 major, guint32 minor, guint32 build, guint32 revision)
4044 static MonoClass *System_Version = NULL;
4045 static MonoMethod *create_version = NULL;
4049 if (!System_Version) {
4050 System_Version = mono_class_from_name (mono_defaults.corlib, "System", "Version");
4051 g_assert (System_Version);
4054 if (!create_version) {
4055 MonoMethodDesc *desc = mono_method_desc_new (":.ctor(int,int,int,int)", FALSE);
4056 create_version = mono_method_desc_search_in_class (desc, System_Version);
4057 g_assert (create_version);
4058 mono_method_desc_free (desc);
4064 args [3] = &revision;
4065 result = mono_object_new (domain, System_Version);
4066 mono_runtime_invoke (create_version, result, args, NULL);
4072 ves_icall_System_Reflection_Assembly_GetReferencedAssemblies (MonoReflectionAssembly *assembly)
4074 static MonoClass *System_Reflection_AssemblyName;
4076 MonoDomain *domain = mono_object_domain (assembly);
4078 static MonoMethod *create_culture = NULL;
4079 MonoImage *image = assembly->assembly->image;
4082 MONO_ARCH_SAVE_REGS;
4084 if (!System_Reflection_AssemblyName)
4085 System_Reflection_AssemblyName = mono_class_from_name (
4086 mono_defaults.corlib, "System.Reflection", "AssemblyName");
4088 t = &assembly->assembly->image->tables [MONO_TABLE_ASSEMBLYREF];
4091 result = mono_array_new (domain, System_Reflection_AssemblyName, count);
4094 MonoMethodDesc *desc = mono_method_desc_new (
4095 "System.Globalization.CultureInfo:CreateSpecificCulture(string)", TRUE);
4096 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4097 g_assert (create_culture);
4098 mono_method_desc_free (desc);
4101 for (i = 0; i < count; i++) {
4102 MonoReflectionAssemblyName *aname;
4103 guint32 cols [MONO_ASSEMBLYREF_SIZE];
4105 mono_metadata_decode_row (t, i, cols, MONO_ASSEMBLYREF_SIZE);
4107 aname = (MonoReflectionAssemblyName *) mono_object_new (
4108 domain, System_Reflection_AssemblyName);
4110 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_NAME])));
4112 aname->major = cols [MONO_ASSEMBLYREF_MAJOR_VERSION];
4113 aname->minor = cols [MONO_ASSEMBLYREF_MINOR_VERSION];
4114 aname->build = cols [MONO_ASSEMBLYREF_BUILD_NUMBER];
4115 aname->revision = cols [MONO_ASSEMBLYREF_REV_NUMBER];
4116 aname->flags = cols [MONO_ASSEMBLYREF_FLAGS];
4117 aname->versioncompat = 1; /* SameMachine (default) */
4118 aname->hashalg = ASSEMBLY_HASH_SHA1; /* SHA1 (default) */
4119 MONO_OBJECT_SETREF (aname, version, create_version (domain, aname->major, aname->minor, aname->build, aname->revision));
4121 if (create_culture) {
4123 args [0] = mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_CULTURE]));
4124 MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
4127 if (cols [MONO_ASSEMBLYREF_PUBLIC_KEY]) {
4128 const gchar *pkey_ptr = mono_metadata_blob_heap (image, cols [MONO_ASSEMBLYREF_PUBLIC_KEY]);
4129 guint32 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
4131 if ((cols [MONO_ASSEMBLYREF_FLAGS] & ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG)) {
4132 /* public key token isn't copied - the class library will
4133 automatically generate it from the public key if required */
4134 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4135 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
4137 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4138 memcpy (mono_array_addr (aname->keyToken, guint8, 0), pkey_ptr, pkey_len);
4142 /* note: this function doesn't return the codebase on purpose (i.e. it can
4143 be used under partial trust as path information isn't present). */
4145 mono_array_setref (result, i, aname);
4156 foreach_namespace (const char* key, gconstpointer val, NameSpaceInfo *info)
4158 MonoString *name = mono_string_new (mono_object_domain (info->res), key);
4160 mono_array_setref (info->res, info->idx, name);
4165 ves_icall_System_Reflection_Assembly_GetNamespaces (MonoReflectionAssembly *assembly)
4167 MonoImage *img = assembly->assembly->image;
4171 MONO_ARCH_SAVE_REGS;
4173 if (!img->name_cache)
4174 mono_image_init_name_cache (img);
4176 res = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, g_hash_table_size (img->name_cache));
4179 g_hash_table_foreach (img->name_cache, (GHFunc)foreach_namespace, &info);
4184 /* move this in some file in mono/util/ */
4186 g_concat_dir_and_file (const char *dir, const char *file)
4188 g_return_val_if_fail (dir != NULL, NULL);
4189 g_return_val_if_fail (file != NULL, NULL);
4192 * If the directory name doesn't have a / on the end, we need
4193 * to add one so we get a proper path to the file
4195 if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
4196 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
4198 return g_strconcat (dir, file, NULL);
4202 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssembly *assembly, MonoString *name, gint32 *size, MonoReflectionModule **ref_module)
4204 char *n = mono_string_to_utf8 (name);
4205 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4207 guint32 cols [MONO_MANIFEST_SIZE];
4208 guint32 impl, file_idx;
4212 MONO_ARCH_SAVE_REGS;
4214 for (i = 0; i < table->rows; ++i) {
4215 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4216 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4217 if (strcmp (val, n) == 0)
4221 if (i == table->rows)
4224 impl = cols [MONO_MANIFEST_IMPLEMENTATION];
4227 * this code should only be called after obtaining the
4228 * ResourceInfo and handling the other cases.
4230 g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
4231 file_idx = impl >> MONO_IMPLEMENTATION_BITS;
4233 module = mono_image_load_file_for_image (assembly->assembly->image, file_idx);
4238 module = assembly->assembly->image;
4240 *ref_module = mono_module_get_object (mono_domain_get (), module);
4242 return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
4246 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoManifestResourceInfo *info)
4248 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4250 guint32 cols [MONO_MANIFEST_SIZE];
4251 guint32 file_cols [MONO_FILE_SIZE];
4255 MONO_ARCH_SAVE_REGS;
4257 n = mono_string_to_utf8 (name);
4258 for (i = 0; i < table->rows; ++i) {
4259 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4260 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4261 if (strcmp (val, n) == 0)
4265 if (i == table->rows)
4268 if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
4269 info->location = RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST;
4272 switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
4273 case MONO_IMPLEMENTATION_FILE:
4274 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4275 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4276 mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
4277 val = mono_metadata_string_heap (assembly->assembly->image, file_cols [MONO_FILE_NAME]);
4278 MONO_OBJECT_SETREF (info, filename, mono_string_new (mono_object_domain (assembly), val));
4279 if (file_cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA)
4282 info->location = RESOURCE_LOCATION_EMBEDDED;
4285 case MONO_IMPLEMENTATION_ASSEMBLYREF:
4286 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4287 mono_assembly_load_reference (assembly->assembly->image, i - 1);
4288 if (assembly->assembly->image->references [i - 1] == (gpointer)-1) {
4289 char *msg = g_strdup_printf ("Assembly %d referenced from assembly %s not found ", i - 1, assembly->assembly->image->name);
4290 MonoException *ex = mono_get_exception_file_not_found2 (msg, NULL);
4292 mono_raise_exception (ex);
4294 MONO_OBJECT_SETREF (info, assembly, mono_assembly_get_object (mono_domain_get (), assembly->assembly->image->references [i - 1]));
4296 /* Obtain info recursively */
4297 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (info->assembly, name, info);
4298 info->location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
4301 case MONO_IMPLEMENTATION_EXP_TYPE:
4302 g_assert_not_reached ();
4311 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoBoolean resource_modules)
4313 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4314 MonoArray *result = NULL;
4319 MONO_ARCH_SAVE_REGS;
4321 /* check hash if needed */
4323 n = mono_string_to_utf8 (name);
4324 for (i = 0; i < table->rows; ++i) {
4325 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4326 if (strcmp (val, n) == 0) {
4329 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4330 fn = mono_string_new (mono_object_domain (assembly), n);
4332 return (MonoObject*)fn;
4340 for (i = 0; i < table->rows; ++i) {
4341 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA))
4345 result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, count);
4348 for (i = 0; i < table->rows; ++i) {
4349 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4350 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4351 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4352 mono_array_setref (result, count, mono_string_new (mono_object_domain (assembly), n));
4357 return (MonoObject*)result;
4361 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly *assembly)
4363 MonoDomain *domain = mono_domain_get();
4366 int i, j, file_count = 0;
4367 MonoImage **modules;
4368 guint32 module_count, real_module_count;
4369 MonoTableInfo *table;
4371 g_assert (assembly->assembly->image != NULL);
4373 if (assembly->assembly->dynamic) {
4374 MonoReflectionAssemblyBuilder *assemblyb = (MonoReflectionAssemblyBuilder*)assembly;
4376 if (assemblyb->modules)
4377 module_count = mono_array_length (assemblyb->modules);
4380 real_module_count = module_count;
4382 modules = g_new0 (MonoImage*, module_count);
4383 if (assemblyb->modules) {
4384 for (i = 0; i < mono_array_length (assemblyb->modules); ++i) {
4386 mono_array_get (assemblyb->modules, MonoReflectionModuleBuilder*, i)->module.image;
4391 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4392 file_count = table->rows;
4394 modules = assembly->assembly->image->modules;
4395 module_count = assembly->assembly->image->module_count;
4397 real_module_count = 0;
4398 for (i = 0; i < module_count; ++i)
4400 real_module_count ++;
4403 klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "Module");
4404 res = mono_array_new (domain, klass, 1 + real_module_count + file_count);
4406 mono_array_setref (res, 0, mono_module_get_object (domain, assembly->assembly->image));
4408 for (i = 0; i < module_count; ++i)
4410 mono_array_setref (res, j, mono_module_get_object (domain, modules[i]));
4414 for (i = 0; i < file_count; ++i, ++j)
4415 mono_array_setref (res, j, mono_module_file_get_object (domain, assembly->assembly->image, i));
4417 if (assembly->assembly->dynamic)
4423 static MonoReflectionMethod*
4424 ves_icall_GetCurrentMethod (void)
4426 MonoMethod *m = mono_method_get_last_managed ();
4428 MONO_ARCH_SAVE_REGS;
4430 return mono_method_get_object (mono_domain_get (), m, NULL);
4433 static MonoReflectionMethod*
4434 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType (MonoMethod *method, MonoType *type)
4436 /* FIXME check that method belongs to klass or a parent */
4439 klass = mono_class_from_mono_type (type);
4441 klass = method->klass;
4442 return mono_method_get_object (mono_domain_get (), method, klass);
4445 static MonoReflectionMethod*
4446 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternal (MonoMethod *method)
4448 return mono_method_get_object (mono_domain_get (), method, NULL);
4451 static MonoReflectionMethodBody*
4452 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod *method)
4454 return mono_method_body_get_object (mono_domain_get (), method);
4457 static MonoReflectionAssembly*
4458 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (void)
4460 MonoMethod *m = mono_method_get_last_managed ();
4462 MONO_ARCH_SAVE_REGS;
4464 return mono_assembly_get_object (mono_domain_get (), m->klass->image->assembly);
4468 static MonoReflectionAssembly*
4469 ves_icall_System_Reflection_Assembly_GetEntryAssembly (void)
4471 MonoDomain* domain = mono_domain_get ();
4473 MONO_ARCH_SAVE_REGS;
4475 if (!domain->entry_assembly)
4478 return mono_assembly_get_object (domain, domain->entry_assembly);
4481 static MonoReflectionAssembly*
4482 ves_icall_System_Reflection_Assembly_GetCallingAssembly (void)
4484 MonoMethod *m = mono_method_get_last_managed ();
4485 MonoMethod *dest = m;
4487 MONO_ARCH_SAVE_REGS;
4489 mono_stack_walk_no_il (get_caller, &dest);
4492 return mono_assembly_get_object (mono_domain_get (), dest->klass->image->assembly);
4496 ves_icall_System_MonoType_getFullName (MonoReflectionType *object, gboolean full_name,
4497 gboolean assembly_qualified)
4499 MonoDomain *domain = mono_object_domain (object);
4500 MonoTypeNameFormat format;
4504 MONO_ARCH_SAVE_REGS;
4506 format = assembly_qualified ?
4507 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
4508 MONO_TYPE_NAME_FORMAT_FULL_NAME;
4510 format = MONO_TYPE_NAME_FORMAT_REFLECTION;
4512 name = mono_type_get_name_full (object->type, format);
4516 if (full_name && (object->type->type == MONO_TYPE_VAR || object->type->type == MONO_TYPE_MVAR)) {
4521 res = mono_string_new (domain, name);
4528 fill_reflection_assembly_name (MonoDomain *domain, MonoReflectionAssemblyName *aname, MonoAssemblyName *name, const char *absolute, gboolean by_default_version)
4530 static MonoMethod *create_culture = NULL;
4533 const char *pkey_ptr;
4536 MONO_ARCH_SAVE_REGS;
4538 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, name->name));
4539 aname->major = name->major;
4540 aname->minor = name->minor;
4541 aname->build = name->build;
4542 aname->revision = name->revision;
4543 aname->hashalg = name->hash_alg;
4544 if (by_default_version)
4545 MONO_OBJECT_SETREF (aname, version, create_version (domain, name->major, name->minor, name->build, name->revision));
4547 codebase = g_filename_to_uri (absolute, NULL, NULL);
4549 MONO_OBJECT_SETREF (aname, codebase, mono_string_new (domain, codebase));
4553 if (!create_culture) {
4554 MonoMethodDesc *desc = mono_method_desc_new ("System.Globalization.CultureInfo:CreateSpecificCulture(string)", TRUE);
4555 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4556 g_assert (create_culture);
4557 mono_method_desc_free (desc);
4560 if (name->culture) {
4561 args [0] = mono_string_new (domain, name->culture);
4562 MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
4565 if (name->public_key) {
4566 pkey_ptr = (char*)name->public_key;
4567 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
4569 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4570 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
4573 /* MonoAssemblyName keeps the public key token as an hexadecimal string */
4574 if (name->public_key_token [0]) {
4578 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, 8));
4579 p = mono_array_addr (aname->keyToken, char, 0);
4581 for (i = 0, j = 0; i < 8; i++) {
4582 *p = g_ascii_xdigit_value (name->public_key_token [j++]) << 4;
4583 *p |= g_ascii_xdigit_value (name->public_key_token [j++]);
4590 ves_icall_System_Reflection_Assembly_FillName (MonoReflectionAssembly *assembly, MonoReflectionAssemblyName *aname)
4593 MonoAssembly *mass = assembly->assembly;
4595 MONO_ARCH_SAVE_REGS;
4597 if (g_path_is_absolute (mass->image->name)) {
4598 fill_reflection_assembly_name (mono_object_domain (assembly),
4599 aname, &mass->aname, mass->image->name, TRUE);
4602 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4604 fill_reflection_assembly_name (mono_object_domain (assembly),
4605 aname, &mass->aname, absolute, TRUE);
4611 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoString *fname, MonoReflectionAssemblyName *aname)
4614 MonoImageOpenStatus status = MONO_IMAGE_OK;
4617 MonoAssemblyName name;
4619 MONO_ARCH_SAVE_REGS;
4621 filename = mono_string_to_utf8 (fname);
4623 image = mono_image_open (filename, &status);
4629 if (status == MONO_IMAGE_IMAGE_INVALID)
4630 exc = mono_get_exception_bad_image_format2 (NULL, fname);
4632 exc = mono_get_exception_file_not_found2 (NULL, fname);
4633 mono_raise_exception (exc);
4636 res = mono_assembly_fill_assembly_name (image, &name);
4638 mono_image_close (image);
4640 mono_raise_exception (mono_get_exception_argument ("assemblyFile", "The file does not contain a manifest"));
4643 fill_reflection_assembly_name (mono_domain_get (), aname, &name, filename, TRUE);
4646 mono_image_close (image);
4650 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssembly *assembly,
4651 char **minimum, guint32 *minLength, char **optional, guint32 *optLength, char **refused, guint32 *refLength)
4653 MonoBoolean result = FALSE;
4654 MonoDeclSecurityEntry entry;
4656 /* SecurityAction.RequestMinimum */
4657 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQMIN, &entry)) {
4658 *minimum = entry.blob;
4659 *minLength = entry.size;
4662 /* SecurityAction.RequestOptional */
4663 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQOPT, &entry)) {
4664 *optional = entry.blob;
4665 *optLength = entry.size;
4668 /* SecurityAction.RequestRefuse */
4669 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQREFUSE, &entry)) {
4670 *refused = entry.blob;
4671 *refLength = entry.size;
4679 mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoBoolean exportedOnly)
4683 MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
4685 guint32 attrs, visibility;
4687 /* we start the count from 1 because we skip the special type <Module> */
4690 for (i = 1; i < tdef->rows; ++i) {
4691 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
4692 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
4693 if (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)
4697 count = tdef->rows - 1;
4699 res = mono_array_new (domain, mono_defaults.monotype_class, count);
4701 for (i = 1; i < tdef->rows; ++i) {
4702 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
4703 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
4704 if (!exportedOnly || (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)) {
4705 klass = mono_class_get_throw (image, (i + 1) | MONO_TOKEN_TYPE_DEF);
4706 if (mono_loader_get_last_error ())
4707 mono_loader_clear_error ();
4708 mono_array_setref (res, count, mono_type_get_object (domain, &klass->byval_arg));
4717 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly, MonoBoolean exportedOnly)
4719 MonoArray *res = NULL;
4720 MonoImage *image = NULL;
4721 MonoTableInfo *table = NULL;
4726 MONO_ARCH_SAVE_REGS;
4728 domain = mono_object_domain (assembly);
4730 if (assembly->assembly->dynamic) {
4731 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
4732 if (abuilder->modules) {
4733 for (i = 0; i < mono_array_length(abuilder->modules); i++) {
4734 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
4735 MonoArray *append = mb->types;
4736 /* The types array might not be fully filled up */
4737 if (append && mb->num_types > 0) {
4740 len1 = res ? mono_array_length (res) : 0;
4741 len2 = mb->num_types;
4742 new = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4744 mono_array_memcpy_refs (new, 0, res, 0, len1);
4745 mono_array_memcpy_refs (new, len1, append, 0, len2);
4751 * Replace TypeBuilders with the created types to be compatible
4755 for (i = 0; i < mono_array_length (res); ++i) {
4756 MonoReflectionTypeBuilder *tb = mono_array_get (res, MonoReflectionTypeBuilder*, i);
4758 mono_array_setref (res, i, tb->created);
4763 if (abuilder->loaded_modules)
4764 for (i = 0; i < mono_array_length(abuilder->loaded_modules); i++) {
4765 MonoReflectionModule *rm = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
4766 MonoArray *append = mono_module_get_types (domain, rm->image, exportedOnly);
4767 if (append && mono_array_length (append) > 0) {
4770 len1 = res ? mono_array_length (res) : 0;
4771 len2 = mono_array_length (append);
4772 new = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4774 mono_array_memcpy_refs (new, 0, res, 0, len1);
4775 mono_array_memcpy_refs (new, len1, append, 0, len2);
4782 return mono_array_new (domain, mono_defaults.monotype_class, 0);
4784 image = assembly->assembly->image;
4785 table = &image->tables [MONO_TABLE_FILE];
4786 res = mono_module_get_types (domain, image, exportedOnly);
4788 /* Append data from all modules in the assembly */
4789 for (i = 0; i < table->rows; ++i) {
4790 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4791 MonoImage *loaded_image = mono_assembly_load_module (image->assembly, i + 1);
4793 MonoArray *res2 = mono_module_get_types (domain, loaded_image, exportedOnly);
4794 /* Append the new types to the end of the array */
4795 if (mono_array_length (res2) > 0) {
4799 len1 = mono_array_length (res);
4800 len2 = mono_array_length (res2);
4801 res3 = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4802 mono_array_memcpy_refs (res3, 0, res, 0, len1);
4803 mono_array_memcpy_refs (res3, len1, res2, 0, len2);
4810 /* the ReflectionTypeLoadException must have all the types (Types property),
4811 * NULL replacing types which throws an exception. The LoaderException must
4812 * contain all exceptions for NULL items.
4815 len = mono_array_length (res);
4817 for (i = 0; i < len; i++) {
4818 MonoReflectionType *t = mono_array_get (res, gpointer, i);
4819 MonoClass *klass = mono_type_get_class (t->type);
4820 if ((klass != NULL) && klass->exception_type) {
4821 /* keep the class in the list */
4822 list = g_list_append (list, klass);
4823 /* and replace Type with NULL */
4824 mono_array_setref (res, i, NULL);
4830 MonoException *exc = NULL;
4831 MonoArray *exl = NULL;
4832 int length = g_list_length (list);
4834 mono_loader_clear_error ();
4836 exl = mono_array_new (domain, mono_defaults.exception_class, length);
4837 for (i = 0, tmp = list; i < length; i++, tmp = tmp->next) {
4838 MonoException *exc = mono_class_get_exception_for_failure (tmp->data);
4839 mono_array_setref (exl, i, exc);
4844 exc = mono_get_exception_reflection_type_load (res, exl);
4845 mono_loader_clear_error ();
4846 mono_raise_exception (exc);
4853 ves_icall_System_Reflection_AssemblyName_ParseName (MonoReflectionAssemblyName *name, MonoString *assname)
4855 MonoAssemblyName aname;
4856 MonoDomain *domain = mono_object_domain (name);
4858 gboolean is_version_defined;
4860 val = mono_string_to_utf8 (assname);
4861 if (!mono_assembly_name_parse_full (val, &aname, TRUE, &is_version_defined))
4864 fill_reflection_assembly_name (domain, name, &aname, "", is_version_defined);
4866 mono_assembly_name_free (&aname);
4867 g_free ((guint8*) aname.public_key);
4873 static MonoReflectionType*
4874 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModule *module)
4876 MonoDomain *domain = mono_object_domain (module);
4879 MONO_ARCH_SAVE_REGS;
4881 g_assert (module->image);
4883 if (module->image->dynamic && ((MonoDynamicImage*)(module->image))->initial_image)
4884 /* These images do not have a global type */
4887 klass = mono_class_get (module->image, 1 | MONO_TOKEN_TYPE_DEF);
4888 return mono_type_get_object (domain, &klass->byval_arg);
4892 ves_icall_System_Reflection_Module_Close (MonoReflectionModule *module)
4894 /*if (module->image)
4895 mono_image_close (module->image);*/
4899 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModule *module)
4901 MonoDomain *domain = mono_object_domain (module);
4903 MONO_ARCH_SAVE_REGS;
4905 g_assert (module->image);
4906 return mono_string_new (domain, module->image->guid);
4910 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine)
4912 if (image->dynamic) {
4913 MonoDynamicImage *dyn = (MonoDynamicImage*)image;
4914 *pe_kind = dyn->pe_kind;
4915 *machine = dyn->machine;
4918 *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
4919 *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
4924 ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage *image)
4926 return (image->md_version_major << 16) | (image->md_version_minor);
4930 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModule *module)
4932 MONO_ARCH_SAVE_REGS;
4935 return mono_array_new (mono_object_domain (module), mono_defaults.monotype_class, 0);
4937 return mono_module_get_types (mono_object_domain (module), module->image, FALSE);
4941 mono_metadata_memberref_is_method (MonoImage *image, guint32 token)
4943 guint32 cols [MONO_MEMBERREF_SIZE];
4945 mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
4946 sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
4947 mono_metadata_decode_blob_size (sig, &sig);
4948 return (*sig != 0x6);
4952 init_generic_context_from_args (MonoGenericContext *context, MonoArray *type_args, MonoArray *method_args)
4955 context->class_inst = mono_metadata_get_generic_inst (mono_array_length (type_args),
4956 mono_array_addr (type_args, MonoType*, 0));
4958 context->class_inst = NULL;
4960 context->method_inst = mono_metadata_get_generic_inst (mono_array_length (method_args),
4961 mono_array_addr (method_args, MonoType*, 0));
4963 context->method_inst = NULL;
4967 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
4970 int table = mono_metadata_token_table (token);
4971 int index = mono_metadata_token_index (token);
4972 MonoGenericContext context;
4974 *error = ResolveTokenError_Other;
4976 /* Validate token */
4977 if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) &&
4978 (table != MONO_TABLE_TYPESPEC)) {
4979 *error = ResolveTokenError_BadTable;
4983 if (image->dynamic) {
4984 if (type_args || method_args)
4985 mono_raise_exception (mono_get_exception_not_implemented (NULL));
4986 return mono_lookup_dynamic_token (image, token);
4989 if ((index <= 0) || (index > image->tables [table].rows)) {
4990 *error = ResolveTokenError_OutOfRange;
4994 init_generic_context_from_args (&context, type_args, method_args);
4995 klass = mono_class_get_full (image, token, &context);
4998 return &klass->byval_arg;
5004 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5006 int table = mono_metadata_token_table (token);
5007 int index = mono_metadata_token_index (token);
5008 MonoGenericContext context;
5011 *error = ResolveTokenError_Other;
5013 /* Validate token */
5014 if ((table != MONO_TABLE_METHOD) && (table != MONO_TABLE_METHODSPEC) &&
5015 (table != MONO_TABLE_MEMBERREF)) {
5016 *error = ResolveTokenError_BadTable;
5020 if (image->dynamic) {
5021 if (type_args || method_args)
5022 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5023 /* FIXME: validate memberref token type */
5024 return mono_lookup_dynamic_token (image, token);
5027 if ((index <= 0) || (index > image->tables [table].rows)) {
5028 *error = ResolveTokenError_OutOfRange;
5031 if ((table == MONO_TABLE_MEMBERREF) && (!mono_metadata_memberref_is_method (image, token))) {
5032 *error = ResolveTokenError_BadTable;
5036 init_generic_context_from_args (&context, type_args, method_args);
5037 method = mono_get_method_full (image, token, NULL, &context);
5043 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
5045 int index = mono_metadata_token_index (token);
5047 *error = ResolveTokenError_Other;
5049 /* Validate token */
5050 if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
5051 *error = ResolveTokenError_BadTable;
5056 return mono_lookup_dynamic_token (image, token);
5058 if ((index <= 0) || (index >= image->heap_us.size)) {
5059 *error = ResolveTokenError_OutOfRange;
5063 /* FIXME: What to do if the index points into the middle of a string ? */
5065 return mono_ldstr (mono_domain_get (), image, index);
5068 static MonoClassField*
5069 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5072 int table = mono_metadata_token_table (token);
5073 int index = mono_metadata_token_index (token);
5074 MonoGenericContext context;
5075 MonoClassField *field;
5077 *error = ResolveTokenError_Other;
5079 /* Validate token */
5080 if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
5081 *error = ResolveTokenError_BadTable;
5085 if (image->dynamic) {
5086 if (type_args || method_args)
5087 mono_raise_exception (mono_get_exception_not_implemented (NULL));
5088 /* FIXME: validate memberref token type */
5089 return mono_lookup_dynamic_token (image, token);
5092 if ((index <= 0) || (index > image->tables [table].rows)) {
5093 *error = ResolveTokenError_OutOfRange;
5096 if ((table == MONO_TABLE_MEMBERREF) && (mono_metadata_memberref_is_method (image, token))) {
5097 *error = ResolveTokenError_BadTable;
5101 init_generic_context_from_args (&context, type_args, method_args);
5102 field = mono_field_from_token (image, token, &klass, &context);
5109 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5111 int table = mono_metadata_token_table (token);
5113 *error = ResolveTokenError_Other;
5116 case MONO_TABLE_TYPEDEF:
5117 case MONO_TABLE_TYPEREF:
5118 case MONO_TABLE_TYPESPEC: {
5119 MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, type_args, method_args, error);
5121 return (MonoObject*)mono_type_get_object (mono_domain_get (), t);
5125 case MONO_TABLE_METHOD:
5126 case MONO_TABLE_METHODSPEC: {
5127 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5129 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
5133 case MONO_TABLE_FIELD: {
5134 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5136 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
5140 case MONO_TABLE_MEMBERREF:
5141 if (mono_metadata_memberref_is_method (image, token)) {
5142 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5144 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
5149 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5151 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
5158 *error = ResolveTokenError_BadTable;
5165 ves_icall_System_Reflection_Module_ResolveSignature (MonoImage *image, guint32 token, MonoResolveTokenError *error)
5167 int table = mono_metadata_token_table (token);
5168 int idx = mono_metadata_token_index (token);
5169 MonoTableInfo *tables = image->tables;
5174 *error = ResolveTokenError_OutOfRange;
5176 /* FIXME: Support other tables ? */
5177 if (table != MONO_TABLE_STANDALONESIG)
5183 if ((idx == 0) || (idx > tables [MONO_TABLE_STANDALONESIG].rows))
5186 sig = mono_metadata_decode_row_col (&tables [MONO_TABLE_STANDALONESIG], idx - 1, 0);
5188 ptr = mono_metadata_blob_heap (image, sig);
5189 len = mono_metadata_decode_blob_size (ptr, &ptr);
5191 res = mono_array_new (mono_domain_get (), mono_defaults.byte_class, len);
5192 memcpy (mono_array_addr (res, guint8, 0), ptr, len);
5196 static MonoReflectionType*
5197 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
5200 int isbyref = 0, rank;
5201 char *str = mono_string_to_utf8 (smodifiers);
5204 MONO_ARCH_SAVE_REGS;
5206 klass = mono_class_from_mono_type (tb->type.type);
5208 /* logic taken from mono_reflection_parse_type(): keep in sync */
5212 if (isbyref) { /* only one level allowed by the spec */
5219 return mono_type_get_object (mono_object_domain (tb), &klass->this_arg);
5222 klass = mono_ptr_class_get (&klass->byval_arg);
5223 mono_class_init (klass);
5234 else if (*p != '*') { /* '*' means unknown lower bound */
5245 klass = mono_array_class_get (klass, rank);
5246 mono_class_init (klass);
5253 return mono_type_get_object (mono_object_domain (tb), &klass->byval_arg);
5257 ves_icall_Type_IsArrayImpl (MonoReflectionType *t)
5262 MONO_ARCH_SAVE_REGS;
5265 res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
5270 static MonoReflectionType *
5271 ves_icall_Type_make_array_type (MonoReflectionType *type, int rank)
5273 MonoClass *klass, *aklass;
5275 MONO_ARCH_SAVE_REGS;
5277 klass = mono_class_from_mono_type (type->type);
5278 aklass = mono_array_class_get (klass, rank);
5280 return mono_type_get_object (mono_object_domain (type), &aklass->byval_arg);
5283 static MonoReflectionType *
5284 ves_icall_Type_make_byref_type (MonoReflectionType *type)
5288 MONO_ARCH_SAVE_REGS;
5290 klass = mono_class_from_mono_type (type->type);
5292 return mono_type_get_object (mono_object_domain (type), &klass->this_arg);
5295 static MonoReflectionType *
5296 ves_icall_Type_MakePointerType (MonoReflectionType *type)
5300 MONO_ARCH_SAVE_REGS;
5302 pklass = mono_ptr_class_get (type->type);
5304 return mono_type_get_object (mono_object_domain (type), &pklass->byval_arg);
5308 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
5309 MonoReflectionMethod *info)
5311 MonoClass *delegate_class = mono_class_from_mono_type (type->type);
5312 MonoObject *delegate;
5315 MONO_ARCH_SAVE_REGS;
5317 mono_assert (delegate_class->parent == mono_defaults.multicastdelegate_class);
5319 delegate = mono_object_new (mono_object_domain (type), delegate_class);
5321 func = mono_compile_method (info->method);
5323 mono_delegate_ctor (delegate, target, func);
5329 ves_icall_System_Delegate_SetMulticastInvoke (MonoDelegate *this)
5334 /* Find the Invoke method */
5336 while ((invoke = mono_class_get_methods (this->object.vtable->klass, &iter))) {
5337 if (!strcmp (invoke->name, "Invoke"))
5342 this->invoke_impl = mono_compile_method (mono_marshal_get_delegate_invoke (invoke));
5346 * Magic number to convert a time which is relative to
5347 * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
5349 #define EPOCH_ADJUST ((guint64)62135596800LL)
5352 * Magic number to convert FILETIME base Jan 1, 1601 to DateTime - base Jan, 1, 0001
5354 #define FILETIME_ADJUST ((guint64)504911232000000000LL)
5357 * This returns Now in UTC
5360 ves_icall_System_DateTime_GetNow (void)
5362 #ifdef PLATFORM_WIN32
5366 GetSystemTime (&st);
5367 SystemTimeToFileTime (&st, &ft);
5368 return (gint64) FILETIME_ADJUST + ((((gint64)ft.dwHighDateTime)<<32) | ft.dwLowDateTime);
5370 /* FIXME: put this in io-layer and call it GetLocalTime */
5374 MONO_ARCH_SAVE_REGS;
5376 if (gettimeofday (&tv, NULL) == 0) {
5377 res = (((gint64)tv.tv_sec + EPOCH_ADJUST)* 1000000 + tv.tv_usec)*10;
5380 /* fixme: raise exception */
5385 #ifdef PLATFORM_WIN32
5386 /* convert a SYSTEMTIME which is of the form "last thursday in october" to a real date */
5388 convert_to_absolute_date(SYSTEMTIME *date)
5390 #define IS_LEAP(y) ((y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0))
5391 static int days_in_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5392 static int leap_days_in_month[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5393 /* from the calendar FAQ */
5394 int a = (14 - date->wMonth) / 12;
5395 int y = date->wYear - a;
5396 int m = date->wMonth + 12 * a - 2;
5397 int d = (1 + y + y/4 - y/100 + y/400 + (31*m)/12) % 7;
5399 /* d is now the day of the week for the first of the month (0 == Sunday) */
5401 int day_of_week = date->wDayOfWeek;
5403 /* set day_in_month to the first day in the month which falls on day_of_week */
5404 int day_in_month = 1 + (day_of_week - d);
5405 if (day_in_month <= 0)
5408 /* wDay is 1 for first weekday in month, 2 for 2nd ... 5 means last - so work that out allowing for days in the month */
5409 date->wDay = day_in_month + (date->wDay - 1) * 7;
5410 if (date->wDay > (IS_LEAP(date->wYear) ? leap_days_in_month[date->wMonth - 1] : days_in_month[date->wMonth - 1]))
5415 #ifndef PLATFORM_WIN32
5417 * Return's the offset from GMT of a local time.
5419 * tm is a local time
5420 * t is the same local time as seconds.
5423 gmt_offset(struct tm *tm, time_t t)
5425 #if defined (HAVE_TM_GMTOFF)
5426 return tm->tm_gmtoff;
5431 g.tm_isdst = tm->tm_isdst;
5433 return (int)difftime(t, t2);
5438 * This is heavily based on zdump.c from glibc 2.2.
5440 * * data[0]: start of daylight saving time (in DateTime ticks).
5441 * * data[1]: end of daylight saving time (in DateTime ticks).
5442 * * data[2]: utcoffset (in TimeSpan ticks).
5443 * * data[3]: additional offset when daylight saving (in TimeSpan ticks).
5444 * * name[0]: name of this timezone when not daylight saving.
5445 * * name[1]: name of this timezone when daylight saving.
5447 * FIXME: This only works with "standard" Unix dates (years between 1900 and 2100) while
5448 * the class library allows years between 1 and 9999.
5450 * Returns true on success and zero on failure.
5453 ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year, MonoArray **data, MonoArray **names)
5455 #ifndef PLATFORM_WIN32
5456 MonoDomain *domain = mono_domain_get ();
5457 struct tm start, tt;
5461 int is_daylight = 0, day;
5464 MONO_ARCH_SAVE_REGS;
5466 MONO_CHECK_ARG_NULL (data);
5467 MONO_CHECK_ARG_NULL (names);
5469 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5470 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5473 * no info is better than crashing: we'll need our own tz data
5474 * to make this work properly, anyway. The range is probably
5475 * reduced to 1970 .. 2037 because that is what mktime is
5476 * guaranteed to support (we get into an infinite loop
5480 memset (&start, 0, sizeof (start));
5483 start.tm_year = year-1900;
5485 t = mktime (&start);
5487 if ((year < 1970) || (year > 2037) || (t == -1)) {
5489 tt = *localtime (&t);
5490 strftime (tzone, sizeof (tzone), "%Z", &tt);
5491 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5492 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5496 gmtoff = gmt_offset (&start, t);
5498 /* For each day of the year, calculate the tm_gmtoff. */
5499 for (day = 0; day < 365; day++) {
5502 tt = *localtime (&t);
5504 /* Daylight saving starts or ends here. */
5505 if (gmt_offset (&tt, t) != gmtoff) {
5509 /* Try to find the exact hour when daylight saving starts/ends. */
5513 tt1 = *localtime (&t1);
5514 } while (gmt_offset (&tt1, t1) != gmtoff);
5516 /* Try to find the exact minute when daylight saving starts/ends. */
5519 tt1 = *localtime (&t1);
5520 } while (gmt_offset (&tt1, t1) == gmtoff);
5522 strftime (tzone, sizeof (tzone), "%Z", &tt);
5524 /* Write data, if we're already in daylight saving, we're done. */
5526 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5527 mono_array_set ((*data), gint64, 1, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
5530 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5531 mono_array_set ((*data), gint64, 0, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
5535 /* This is only set once when we enter daylight saving. */
5536 mono_array_set ((*data), gint64, 2, (gint64)gmtoff * 10000000L);
5537 mono_array_set ((*data), gint64, 3, (gint64)(gmt_offset (&tt, t) - gmtoff) * 10000000L);
5539 gmtoff = gmt_offset (&tt, t);
5544 strftime (tzone, sizeof (tzone), "%Z", &tt);
5545 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5546 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5547 mono_array_set ((*data), gint64, 0, 0);
5548 mono_array_set ((*data), gint64, 1, 0);
5549 mono_array_set ((*data), gint64, 2, (gint64) gmtoff * 10000000L);
5550 mono_array_set ((*data), gint64, 3, 0);
5555 MonoDomain *domain = mono_domain_get ();
5556 TIME_ZONE_INFORMATION tz_info;
5561 tz_id = GetTimeZoneInformation (&tz_info);
5562 if (tz_id == TIME_ZONE_ID_INVALID)
5565 MONO_CHECK_ARG_NULL (data);
5566 MONO_CHECK_ARG_NULL (names);
5568 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5569 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5571 for (i = 0; i < 32; ++i)
5572 if (!tz_info.DaylightName [i])
5574 mono_array_setref ((*names), 1, mono_string_new_utf16 (domain, tz_info.DaylightName, i));
5575 for (i = 0; i < 32; ++i)
5576 if (!tz_info.StandardName [i])
5578 mono_array_setref ((*names), 0, mono_string_new_utf16 (domain, tz_info.StandardName, i));
5580 if ((year <= 1601) || (year > 30827)) {
5582 * According to MSDN, the MS time functions can't handle dates outside
5588 /* even if the timezone has no daylight savings it may have Bias (e.g. GMT+13 it seems) */
5589 if (tz_id != TIME_ZONE_ID_UNKNOWN) {
5590 tz_info.StandardDate.wYear = year;
5591 convert_to_absolute_date(&tz_info.StandardDate);
5592 err = SystemTimeToFileTime (&tz_info.StandardDate, &ft);
5594 mono_array_set ((*data), gint64, 1, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
5595 tz_info.DaylightDate.wYear = year;
5596 convert_to_absolute_date(&tz_info.DaylightDate);
5597 err = SystemTimeToFileTime (&tz_info.DaylightDate, &ft);
5599 mono_array_set ((*data), gint64, 0, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
5601 mono_array_set ((*data), gint64, 2, (tz_info.Bias + tz_info.StandardBias) * -600000000LL);
5602 mono_array_set ((*data), gint64, 3, (tz_info.DaylightBias - tz_info.StandardBias) * -600000000LL);
5609 ves_icall_System_Object_obj_address (MonoObject *this)
5611 MONO_ARCH_SAVE_REGS;
5618 static inline gint32
5619 mono_array_get_byte_length (MonoArray *array)
5625 klass = array->obj.vtable->klass;
5627 if (array->bounds == NULL)
5628 length = array->max_length;
5631 for (i = 0; i < klass->rank; ++ i)
5632 length *= array->bounds [i].length;
5635 switch (klass->element_class->byval_arg.type) {
5638 case MONO_TYPE_BOOLEAN:
5642 case MONO_TYPE_CHAR:
5650 return length * sizeof (gpointer);
5661 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array)
5663 MONO_ARCH_SAVE_REGS;
5665 return mono_array_get_byte_length (array);
5669 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx)
5671 MONO_ARCH_SAVE_REGS;
5673 return mono_array_get (array, gint8, idx);
5677 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value)
5679 MONO_ARCH_SAVE_REGS;
5681 mono_array_set (array, gint8, idx, value);
5685 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count)
5687 guint8 *src_buf, *dest_buf;
5689 MONO_ARCH_SAVE_REGS;
5691 /* watch out for integer overflow */
5692 if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count))
5695 src_buf = (guint8 *)src->vector + src_offset;
5696 dest_buf = (guint8 *)dest->vector + dest_offset;
5699 memcpy (dest_buf, src_buf, count);
5701 memmove (dest_buf, src_buf, count); /* Source and dest are the same array */
5707 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this, MonoString *class_name)
5709 MonoDomain *domain = mono_object_domain (this);
5711 MonoRealProxy *rp = ((MonoRealProxy *)this);
5712 MonoTransparentProxy *tp;
5716 MONO_ARCH_SAVE_REGS;
5718 res = mono_object_new (domain, mono_defaults.transparent_proxy_class);
5719 tp = (MonoTransparentProxy*) res;
5721 MONO_OBJECT_SETREF (tp, rp, rp);
5722 type = ((MonoReflectionType *)rp->class_to_proxy)->type;
5723 klass = mono_class_from_mono_type (type);
5725 tp->custom_type_info = (mono_object_isinst (this, mono_defaults.iremotingtypeinfo_class) != NULL);
5726 tp->remote_class = mono_remote_class (domain, class_name, klass);
5728 res->vtable = mono_remote_class_vtable (domain, tp->remote_class, rp);
5732 static MonoReflectionType *
5733 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
5735 return mono_type_get_object (mono_object_domain (tp), &tp->remote_class->proxy_class->byval_arg);
5738 /* System.Environment */
5741 ves_icall_System_Environment_get_MachineName (void)
5743 #if defined (PLATFORM_WIN32)
5748 len = MAX_COMPUTERNAME_LENGTH + 1;
5749 buf = g_new (gunichar2, len);
5752 if (GetComputerName (buf, (PDWORD) &len))
5753 result = mono_string_new_utf16 (mono_domain_get (), buf, len);
5761 if (gethostname (buf, sizeof (buf)) == 0)
5762 result = mono_string_new (mono_domain_get (), buf);
5771 ves_icall_System_Environment_get_Platform (void)
5773 MONO_ARCH_SAVE_REGS;
5775 #if defined (PLATFORM_WIN32)
5785 ves_icall_System_Environment_get_NewLine (void)
5787 MONO_ARCH_SAVE_REGS;
5789 #if defined (PLATFORM_WIN32)
5790 return mono_string_new (mono_domain_get (), "\r\n");
5792 return mono_string_new (mono_domain_get (), "\n");
5797 ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name)
5802 MONO_ARCH_SAVE_REGS;
5807 utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
5808 value = g_getenv (utf8_name);
5815 return mono_string_new (mono_domain_get (), value);
5819 * There is no standard way to get at environ.
5822 #ifndef __MINGW32_VERSION
5829 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
5837 MONO_ARCH_SAVE_REGS;
5840 for (e = environ; *e != 0; ++ e)
5843 domain = mono_domain_get ();
5844 names = mono_array_new (domain, mono_defaults.string_class, n);
5847 for (e = environ; *e != 0; ++ e) {
5848 parts = g_strsplit (*e, "=", 2);
5850 str = mono_string_new (domain, *parts);
5851 mono_array_setref (names, n, str);
5863 * If your platform lacks setenv/unsetenv, you must upgrade your glib.
5865 #if !GLIB_CHECK_VERSION(2,4,0)
5866 #define g_setenv(a,b,c) setenv(a,b,c)
5867 #define g_unsetenv(a) unsetenv(a)
5871 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
5873 #ifdef PLATFORM_WIN32
5874 gunichar2 *utf16_name, *utf16_value;
5876 gchar *utf8_name, *utf8_value;
5879 MONO_ARCH_SAVE_REGS;
5881 #ifdef PLATFORM_WIN32
5882 utf16_name = mono_string_to_utf16 (name);
5883 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
5884 SetEnvironmentVariable (utf16_name, NULL);
5885 g_free (utf16_name);
5889 utf16_value = mono_string_to_utf16 (value);
5891 SetEnvironmentVariable (utf16_name, utf16_value);
5893 g_free (utf16_name);
5894 g_free (utf16_value);
5896 utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
5898 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
5899 g_unsetenv (utf8_name);
5904 utf8_value = mono_string_to_utf8 (value);
5905 g_setenv (utf8_name, utf8_value, TRUE);
5908 g_free (utf8_value);
5913 * Returns: the number of milliseconds elapsed since the system started.
5916 ves_icall_System_Environment_get_TickCount (void)
5918 return GetTickCount ();
5923 ves_icall_System_Environment_Exit (int result)
5925 MONO_ARCH_SAVE_REGS;
5927 mono_runtime_set_shutting_down ();
5929 /* Suspend all managed threads since the runtime is going away */
5930 mono_thread_suspend_all_other_threads ();
5932 mono_runtime_quit ();
5934 /* we may need to do some cleanup here... */
5939 ves_icall_System_Environment_GetGacPath (void)
5941 return mono_string_new (mono_domain_get (), mono_assembly_getrootdir ());
5945 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
5947 #if defined (PLATFORM_WIN32)
5948 #ifndef CSIDL_FLAG_CREATE
5949 #define CSIDL_FLAG_CREATE 0x8000
5952 WCHAR path [MAX_PATH];
5953 /* Create directory if no existing */
5954 if (SUCCEEDED (SHGetFolderPathW (NULL, folder | CSIDL_FLAG_CREATE, NULL, 0, path))) {
5958 return mono_string_new_utf16 (mono_domain_get (), path, len);
5961 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
5963 return mono_string_new (mono_domain_get (), "");
5967 ves_icall_System_Environment_GetLogicalDrives (void)
5969 gunichar2 buf [128], *ptr, *dname;
5971 gint initial_size = 127, size = 128;
5974 MonoString *drivestr;
5975 MonoDomain *domain = mono_domain_get ();
5978 MONO_ARCH_SAVE_REGS;
5983 while (size > initial_size) {
5984 size = GetLogicalDriveStrings (initial_size, ptr);
5985 if (size > initial_size) {
5988 ptr = g_malloc0 ((size + 1) * sizeof (gunichar2));
5989 initial_size = size;
6003 result = mono_array_new (domain, mono_defaults.string_class, ndrives);
6008 while (*u16) { u16++; len ++; }
6009 drivestr = mono_string_new_utf16 (domain, dname, len);
6010 mono_array_setref (result, ndrives++, drivestr);
6021 ves_icall_System_Environment_InternalGetHome (void)
6023 MONO_ARCH_SAVE_REGS;
6025 return mono_string_new (mono_domain_get (), g_get_home_dir ());
6028 static const char *encodings [] = {
6030 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
6031 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
6032 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
6034 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
6035 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
6036 "x_unicode_2_0_utf_7",
6038 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
6039 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
6041 "utf_16", "UTF_16LE", "ucs_2", "unicode",
6044 "unicodefffe", "utf_16be",
6051 * Returns the internal codepage, if the value of "int_code_page" is
6052 * 1 at entry, and we can not compute a suitable code page number,
6053 * returns the code page as a string
6056 ves_icall_System_Text_Encoding_InternalCodePage (gint32 *int_code_page)
6061 char *codepage = NULL;
6063 int want_name = *int_code_page;
6066 *int_code_page = -1;
6067 MONO_ARCH_SAVE_REGS;
6069 g_get_charset (&cset);
6070 c = codepage = strdup (cset);
6071 for (c = codepage; *c; c++){
6072 if (isascii (*c) && isalpha (*c))
6077 /* g_print ("charset: %s\n", cset); */
6079 /* handle some common aliases */
6082 for (i = 0; p != 0; ){
6083 if ((gssize) p < 7){
6085 p = encodings [++i];
6088 if (strcmp (p, codepage) == 0){
6089 *int_code_page = code;
6092 p = encodings [++i];
6095 if (strstr (codepage, "utf_8") != NULL)
6096 *int_code_page |= 0x10000000;
6099 if (want_name && *int_code_page == -1)
6100 return mono_string_new (mono_domain_get (), cset);
6106 ves_icall_System_Environment_get_HasShutdownStarted (void)
6108 if (mono_runtime_is_shutting_down ())
6111 if (mono_domain_is_unloading (mono_domain_get ()))
6118 ves_icall_MonoMethodMessage_InitMessage (MonoMethodMessage *this,
6119 MonoReflectionMethod *method,
6120 MonoArray *out_args)
6122 MONO_ARCH_SAVE_REGS;
6124 mono_message_init (mono_object_domain (this), this, method, out_args);
6128 ves_icall_IsTransparentProxy (MonoObject *proxy)
6130 MONO_ARCH_SAVE_REGS;
6135 if (proxy->vtable->klass == mono_defaults.transparent_proxy_class)
6142 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6147 MONO_ARCH_SAVE_REGS;
6149 klass = mono_class_from_mono_type (type->type);
6150 vtable = mono_class_vtable (mono_domain_get (), klass);
6152 if (enable) vtable->remote = 1;
6153 else vtable->remote = 0;
6157 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type)
6162 MONO_ARCH_SAVE_REGS;
6164 domain = mono_object_domain (type);
6165 klass = mono_class_from_mono_type (type->type);
6167 if (klass->rank >= 1) {
6168 g_assert (klass->rank == 1);
6169 return (MonoObject *) mono_array_new (domain, klass->element_class, 0);
6171 /* Bypass remoting object creation check */
6172 return mono_object_new_alloc_specific (mono_class_vtable (domain, klass));
6177 ves_icall_System_IO_get_temp_path (void)
6179 MONO_ARCH_SAVE_REGS;
6181 return mono_string_new (mono_domain_get (), g_get_tmp_dir ());
6185 ves_icall_RuntimeMethod_GetFunctionPointer (MonoMethod *method)
6187 MONO_ARCH_SAVE_REGS;
6189 return mono_compile_method (method);
6193 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
6198 MONO_ARCH_SAVE_REGS;
6200 path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
6202 #if defined (PLATFORM_WIN32)
6203 /* Avoid mixing '/' and '\\' */
6206 for (i = strlen (path) - 1; i >= 0; i--)
6207 if (path [i] == '/')
6211 mcpath = mono_string_new (mono_domain_get (), path);
6218 ves_icall_System_Configuration_DefaultConfig_get_bundled_machine_config (void)
6220 const gchar *machine_config;
6222 MONO_ARCH_SAVE_REGS;
6224 machine_config = mono_get_machine_config ();
6226 if (!machine_config)
6229 return mono_string_new (mono_domain_get (), machine_config);
6233 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
6238 MONO_ARCH_SAVE_REGS;
6240 path = g_path_get_dirname (mono_get_config_dir ());
6242 #if defined (PLATFORM_WIN32)
6243 /* Avoid mixing '/' and '\\' */
6246 for (i = strlen (path) - 1; i >= 0; i--)
6247 if (path [i] == '/')
6251 ipath = mono_string_new (mono_domain_get (), path);
6258 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
6260 #if defined (PLATFORM_WIN32)
6261 OutputDebugString (mono_string_chars (message));
6263 g_warning ("WriteWindowsDebugString called and PLATFORM_WIN32 not defined!\n");
6267 /* Only used for value types */
6269 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
6274 MONO_ARCH_SAVE_REGS;
6276 domain = mono_object_domain (type);
6277 klass = mono_class_from_mono_type (type->type);
6279 if (mono_class_is_nullable (klass))
6280 /* No arguments -> null */
6283 return mono_object_new (domain, klass);
6286 static MonoReflectionMethod *
6287 ves_icall_MonoMethod_get_base_definition (MonoReflectionMethod *m)
6289 MonoClass *klass, *parent;
6290 MonoMethod *method = m->method;
6291 MonoMethod *result = NULL;
6293 MONO_ARCH_SAVE_REGS;
6295 if (method->klass == NULL)
6298 if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
6299 MONO_CLASS_IS_INTERFACE (method->klass) ||
6300 method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
6303 klass = method->klass;
6304 if (klass->generic_class)
6305 klass = klass->generic_class->container_class;
6307 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
6308 for (parent = klass->parent; parent != NULL; parent = parent->parent) {
6309 mono_class_setup_vtable (parent);
6310 if (parent->vtable_size <= method->slot)
6315 if (klass == method->klass)
6318 result = klass->vtable [method->slot];
6319 if (result == NULL) {
6320 /* It is an abstract method */
6321 gpointer iter = NULL;
6322 while ((result = mono_class_get_methods (klass, &iter)))
6323 if (result->slot == method->slot)
6330 return mono_method_get_object (mono_domain_get (), result, NULL);
6334 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
6336 MONO_ARCH_SAVE_REGS;
6338 iter->sig = *(MonoMethodSignature**)argsp;
6340 g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
6341 g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
6344 /* FIXME: it's not documented what start is exactly... */
6348 guint32 i, arg_size;
6350 iter->args = argsp + sizeof (gpointer);
6351 #ifndef MONO_ARCH_REGPARMS
6352 for (i = 0; i < iter->sig->sentinelpos; ++i) {
6353 arg_size = mono_type_stack_size (iter->sig->params [i], &align);
6354 iter->args = (char*)iter->args + arg_size;
6358 iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
6360 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
6364 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
6366 guint32 i, arg_size;
6369 MONO_ARCH_SAVE_REGS;
6371 i = iter->sig->sentinelpos + iter->next_arg;
6373 g_assert (i < iter->sig->param_count);
6375 res.type = iter->sig->params [i];
6376 res.klass = mono_class_from_mono_type (res.type);
6377 /* FIXME: endianess issue... */
6378 res.value = iter->args;
6379 arg_size = mono_type_stack_size (res.type, &align);
6380 iter->args = (char*)iter->args + arg_size;
6383 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6389 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
6391 guint32 i, arg_size;
6394 MONO_ARCH_SAVE_REGS;
6396 i = iter->sig->sentinelpos + iter->next_arg;
6398 g_assert (i < iter->sig->param_count);
6400 while (i < iter->sig->param_count) {
6401 if (!mono_metadata_type_equal (type, iter->sig->params [i]))
6403 res.type = iter->sig->params [i];
6404 res.klass = mono_class_from_mono_type (res.type);
6405 /* FIXME: endianess issue... */
6406 res.value = iter->args;
6407 arg_size = mono_type_stack_size (res.type, &align);
6408 iter->args = (char*)iter->args + arg_size;
6410 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6413 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
6422 mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
6425 MONO_ARCH_SAVE_REGS;
6427 i = iter->sig->sentinelpos + iter->next_arg;
6429 g_assert (i < iter->sig->param_count);
6431 return iter->sig->params [i];
6435 mono_TypedReference_ToObject (MonoTypedRef tref)
6437 MONO_ARCH_SAVE_REGS;
6439 if (MONO_TYPE_IS_REFERENCE (tref.type)) {
6440 MonoObject** objp = tref.value;
6444 return mono_value_box (mono_domain_get (), tref.klass, tref.value);
6448 mono_TypedReference_ToObjectInternal (MonoType *type, gpointer value, MonoClass *klass)
6450 MONO_ARCH_SAVE_REGS;
6452 if (MONO_TYPE_IS_REFERENCE (type)) {
6453 MonoObject** objp = value;
6457 return mono_value_box (mono_domain_get (), klass, value);
6461 prelink_method (MonoMethod *method)
6463 const char *exc_class, *exc_arg;
6464 if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
6466 mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
6468 mono_raise_exception(
6469 mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg ) );
6471 /* create the wrapper, too? */
6475 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
6477 MONO_ARCH_SAVE_REGS;
6478 prelink_method (method->method);
6482 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
6484 MonoClass *klass = mono_class_from_mono_type (type->type);
6486 gpointer iter = NULL;
6487 MONO_ARCH_SAVE_REGS;
6489 while ((m = mono_class_get_methods (klass, &iter)))
6493 /* These parameters are "readonly" in corlib/System/Char.cs */
6495 ves_icall_System_Char_GetDataTablePointers (guint8 const **category_data,
6496 guint8 const **numeric_data,
6497 gdouble const **numeric_data_values,
6498 guint16 const **to_lower_data_low,
6499 guint16 const **to_lower_data_high,
6500 guint16 const **to_upper_data_low,
6501 guint16 const **to_upper_data_high)
6503 *category_data = CategoryData;
6504 *numeric_data = NumericData;
6505 *numeric_data_values = NumericDataValues;
6506 *to_lower_data_low = ToLowerDataLow;
6507 *to_lower_data_high = ToLowerDataHigh;
6508 *to_upper_data_low = ToUpperDataLow;
6509 *to_upper_data_high = ToUpperDataHigh;
6513 ves_icall_MonoDebugger_GetMethodToken (MonoReflectionMethod *method)
6515 return method->method->token;
6519 * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
6520 * and avoid useless allocations.
6523 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional)
6527 for (i = 0; i < type->num_mods; ++i) {
6528 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
6533 res = mono_array_new (mono_domain_get (), mono_defaults.systemtype_class, count);
6535 for (i = 0; i < type->num_mods; ++i) {
6536 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
6537 MonoClass *klass = mono_class_get (image, type->modifiers [i].token);
6538 mono_array_setref (res, count, mono_type_get_object (mono_domain_get (), &klass->byval_arg));
6546 param_info_get_type_modifiers (MonoReflectionParameter *param, MonoBoolean optional)
6548 MonoType *type = param->ClassImpl->type;
6549 MonoReflectionMethod *method = (MonoReflectionMethod*)param->MemberImpl;
6550 MonoImage *image = method->method->klass->image;
6551 int pos = param->PositionImpl;
6552 MonoMethodSignature *sig = mono_method_signature (method->method);
6556 type = sig->params [pos];
6558 return type_array_from_modifiers (image, type, optional);
6562 get_property_type (MonoProperty *prop)
6564 MonoMethodSignature *sig;
6566 sig = mono_method_signature (prop->get);
6568 } else if (prop->set) {
6569 sig = mono_method_signature (prop->set);
6570 return sig->params [sig->param_count - 1];
6576 property_info_get_type_modifiers (MonoReflectionProperty *property, MonoBoolean optional)
6578 MonoType *type = get_property_type (property->property);
6579 MonoImage *image = property->klass->image;
6583 return type_array_from_modifiers (image, type, optional);
6587 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
6589 MonoCustomAttrInfo *cinfo;
6592 cinfo = mono_reflection_get_custom_attrs_info (obj);
6595 found = mono_custom_attrs_has_attr (cinfo, mono_class_from_mono_type (attr_type->type));
6597 mono_custom_attrs_free (cinfo);
6602 custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
6604 MonoArray *res = mono_reflection_get_custom_attrs_by_type (obj, attr_type ? mono_class_from_mono_type (attr_type->type) : NULL);
6606 if (mono_loader_get_last_error ()) {
6607 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
6608 g_assert_not_reached ();
6615 GCHandle_CheckCurrentDomain (guint32 gchandle)
6617 return mono_gchandle_is_in_domain (gchandle, mono_domain_get ());
6621 ves_icall_Mono_Runtime_GetDisplayName (void)
6623 static const char display_name_str [] = "Mono " VERSION;
6624 MonoString *display_name = mono_string_new (mono_domain_get (), display_name_str);
6625 return display_name;
6630 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
6631 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
6632 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 62, 128, 128, 128, 63,
6633 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 0, 128, 128,
6634 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
6635 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 128, 128, 128, 128, 128,
6636 128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
6637 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
6641 base64_to_byte_array (gunichar2 *start, gint ilength, MonoBoolean allowWhitespaceOnly)
6646 gunichar2 last, prev_last;
6654 last = prev_last = 0;
6655 for (i = 0; i < ilength; i++) {
6657 if (c >= sizeof (dbase64)) {
6658 exc = mono_exception_from_name_msg (mono_get_corlib (),
6659 "System", "FormatException",
6660 "Invalid character found.");
6661 mono_raise_exception (exc);
6662 } else if (isspace (c)) {
6670 olength = ilength - ignored;
6672 if (allowWhitespaceOnly && olength == 0) {
6673 return mono_array_new (mono_domain_get (), mono_defaults.byte_class, 0);
6676 if ((olength & 3) != 0 || olength <= 0) {
6677 exc = mono_exception_from_name_msg (mono_get_corlib (), "System",
6678 "FormatException", "Invalid length.");
6679 mono_raise_exception (exc);
6682 olength = (olength * 3) / 4;
6686 if (prev_last == '=')
6689 result = mono_array_new (mono_domain_get (), mono_defaults.byte_class, olength);
6690 res_ptr = mono_array_addr (result, guchar, 0);
6691 for (i = 0; i < ilength; ) {
6694 for (k = 0; k < 4 && i < ilength;) {
6700 if (((b [k] = dbase64 [c]) & 0x80) != 0) {
6701 exc = mono_exception_from_name_msg (mono_get_corlib (),
6702 "System", "FormatException",
6703 "Invalid character found.");
6704 mono_raise_exception (exc);
6709 *res_ptr++ = (b [0] << 2) | (b [1] >> 4);
6711 *res_ptr++ = (b [1] << 4) | (b [2] >> 2);
6713 *res_ptr++ = (b [2] << 6) | b [3];
6715 while (i < ilength && isspace (start [i]))
6723 InternalFromBase64String (MonoString *str, MonoBoolean allowWhitespaceOnly)
6725 MONO_ARCH_SAVE_REGS;
6727 return base64_to_byte_array (mono_string_chars (str),
6728 mono_string_length (str), allowWhitespaceOnly);
6732 InternalFromBase64CharArray (MonoArray *input, gint offset, gint length)
6734 MONO_ARCH_SAVE_REGS;
6736 return base64_to_byte_array (mono_array_addr (input, gunichar2, offset),
6740 #define ICALL_TYPE(id,name,first)
6741 #define ICALL(id,name,func) Icall_ ## id,
6744 #include "metadata/icall-def.h"
6750 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
6751 #define ICALL(id,name,func)
6753 #include "metadata/icall-def.h"
6759 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
6760 #define ICALL(id,name,func)
6762 guint16 first_icall;
6765 static const IcallTypeDesc
6766 icall_type_descs [] = {
6767 #include "metadata/icall-def.h"
6771 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
6774 #define ICALL_TYPE(id,name,first)
6777 #ifdef HAVE_ARRAY_ELEM_INIT
6778 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
6779 #define MSGSTRFIELD1(line) str##line
6781 static const struct msgstrtn_t {
6782 #define ICALL(id,name,func)
6784 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
6785 #include "metadata/icall-def.h"
6787 } icall_type_names_str = {
6788 #define ICALL_TYPE(id,name,first) (name),
6789 #include "metadata/icall-def.h"
6792 static const guint16 icall_type_names_idx [] = {
6793 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
6794 #include "metadata/icall-def.h"
6797 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
6799 static const struct msgstr_t {
6801 #define ICALL_TYPE(id,name,first)
6802 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
6803 #include "metadata/icall-def.h"
6805 } icall_names_str = {
6806 #define ICALL(id,name,func) (name),
6807 #include "metadata/icall-def.h"
6810 static const guint16 icall_names_idx [] = {
6811 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
6812 #include "metadata/icall-def.h"
6815 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
6821 #define ICALL_TYPE(id,name,first) name,
6822 #define ICALL(id,name,func)
6823 static const char* const
6824 icall_type_names [] = {
6825 #include "metadata/icall-def.h"
6829 #define icall_type_name_get(id) (icall_type_names [(id)])
6833 #define ICALL_TYPE(id,name,first)
6834 #define ICALL(id,name,func) name,
6835 static const char* const
6837 #include "metadata/icall-def.h"
6840 #define icall_name_get(id) icall_names [(id)]
6842 #endif /* !HAVE_ARRAY_ELEM_INIT */
6846 #define ICALL_TYPE(id,name,first)
6847 #define ICALL(id,name,func) func,
6848 static const gconstpointer
6849 icall_functions [] = {
6850 #include "metadata/icall-def.h"
6854 static GHashTable *icall_hash = NULL;
6855 static GHashTable *jit_icall_hash_name = NULL;
6856 static GHashTable *jit_icall_hash_addr = NULL;
6859 mono_icall_init (void)
6863 /* check that tables are sorted: disable in release */
6866 const char *prev_class = NULL;
6867 const char *prev_method;
6869 for (i = 0; i < Icall_type_num; ++i) {
6870 const IcallTypeDesc *desc;
6873 if (prev_class && strcmp (prev_class, icall_type_name_get (i)) >= 0)
6874 g_print ("class %s should come before class %s\n", icall_type_name_get (i), prev_class);
6875 prev_class = icall_type_name_get (i);
6876 desc = &icall_type_descs [i];
6877 num_icalls = icall_desc_num_icalls (desc);
6878 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
6879 for (j = 0; j < num_icalls; ++j) {
6880 const char *methodn = icall_name_get (desc->first_icall + j);
6881 if (prev_method && strcmp (prev_method, methodn) >= 0)
6882 g_print ("method %s should come before method %s\n", methodn, prev_method);
6883 prev_method = methodn;
6888 icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
6892 mono_icall_cleanup (void)
6894 g_hash_table_destroy (icall_hash);
6895 g_hash_table_destroy (jit_icall_hash_name);
6896 g_hash_table_destroy (jit_icall_hash_addr);
6900 mono_add_internal_call (const char *name, gconstpointer method)
6902 mono_loader_lock ();
6904 g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
6906 mono_loader_unlock ();
6909 #ifdef HAVE_ARRAY_ELEM_INIT
6911 compare_method_imap (const void *key, const void *elem)
6913 const char* method_name = (const char*)&icall_names_str + (*(guint16*)elem);
6914 return strcmp (key, method_name);
6918 find_method_icall (const IcallTypeDesc *imap, const char *name)
6920 const guint16 *nameslot = bsearch (name, icall_names_idx + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names_idx [0]), compare_method_imap);
6923 return (gpointer)icall_functions [(nameslot - &icall_names_idx [0])];
6927 compare_class_imap (const void *key, const void *elem)
6929 const char* class_name = (const char*)&icall_type_names_str + (*(guint16*)elem);
6930 return strcmp (key, class_name);
6933 static const IcallTypeDesc*
6934 find_class_icalls (const char *name)
6936 const guint16 *nameslot = bsearch (name, icall_type_names_idx, Icall_type_num, sizeof (icall_type_names_idx [0]), compare_class_imap);
6939 return &icall_type_descs [nameslot - &icall_type_names_idx [0]];
6944 compare_method_imap (const void *key, const void *elem)
6946 const char** method_name = (const char**)elem;
6947 return strcmp (key, *method_name);
6951 find_method_icall (const IcallTypeDesc *imap, const char *name)
6953 const char **nameslot = bsearch (name, icall_names + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names [0]), compare_method_imap);
6956 return (gpointer)icall_functions [(nameslot - icall_names)];
6960 compare_class_imap (const void *key, const void *elem)
6962 const char** class_name = (const char**)elem;
6963 return strcmp (key, *class_name);
6966 static const IcallTypeDesc*
6967 find_class_icalls (const char *name)
6969 const char **nameslot = bsearch (name, icall_type_names, Icall_type_num, sizeof (icall_type_names [0]), compare_class_imap);
6972 return &icall_type_descs [nameslot - icall_type_names];
6978 * we should probably export this as an helper (handle nested types).
6979 * Returns the number of chars written in buf.
6982 concat_class_name (char *buf, int bufsize, MonoClass *klass)
6984 int nspacelen, cnamelen;
6985 nspacelen = strlen (klass->name_space);
6986 cnamelen = strlen (klass->name);
6987 if (nspacelen + cnamelen + 2 > bufsize)
6990 memcpy (buf, klass->name_space, nspacelen);
6991 buf [nspacelen ++] = '.';
6993 memcpy (buf + nspacelen, klass->name, cnamelen);
6994 buf [nspacelen + cnamelen] = 0;
6995 return nspacelen + cnamelen;
6999 mono_lookup_internal_call (MonoMethod *method)
7004 int typelen = 0, mlen, siglen;
7006 const IcallTypeDesc *imap;
7008 g_assert (method != NULL);
7010 if (method->is_inflated)
7011 method = ((MonoMethodInflated *) method)->declaring;
7013 if (method->klass->nested_in) {
7014 int pos = concat_class_name (mname, sizeof (mname)-2, method->klass->nested_in);
7018 mname [pos++] = '/';
7021 typelen = concat_class_name (mname+pos, sizeof (mname)-pos-1, method->klass);
7027 typelen = concat_class_name (mname, sizeof (mname), method->klass);
7032 imap = find_class_icalls (mname);
7034 mname [typelen] = ':';
7035 mname [typelen + 1] = ':';
7037 mlen = strlen (method->name);
7038 memcpy (mname + typelen + 2, method->name, mlen);
7039 sigstart = mname + typelen + 2 + mlen;
7042 tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
7043 siglen = strlen (tmpsig);
7044 if (typelen + mlen + siglen + 6 > sizeof (mname))
7047 memcpy (sigstart + 1, tmpsig, siglen);
7048 sigstart [siglen + 1] = ')';
7049 sigstart [siglen + 2] = 0;
7052 mono_loader_lock ();
7054 res = g_hash_table_lookup (icall_hash, mname);
7056 mono_loader_unlock ();
7059 /* try without signature */
7061 res = g_hash_table_lookup (icall_hash, mname);
7063 mono_loader_unlock ();
7067 /* it wasn't found in the static call tables */
7069 mono_loader_unlock ();
7072 res = find_method_icall (imap, sigstart - mlen);
7074 mono_loader_unlock ();
7077 /* try _with_ signature */
7079 res = find_method_icall (imap, sigstart - mlen);
7081 mono_loader_unlock ();
7085 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname);
7086 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
7087 g_print ("The out of sync library is: %s\n", method->klass->image->name);
7088 g_print ("\nWhen you update one from cvs you need to update, compile and install\nthe other too.\n");
7089 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");
7090 g_print ("If you see other errors or faults after this message they are probably related\n");
7091 g_print ("and you need to fix your mono install first.\n");
7093 mono_loader_unlock ();
7099 type_from_typename (char *typename)
7101 MonoClass *klass = NULL; /* assignment to shut GCC warning up */
7103 if (!strcmp (typename, "int"))
7104 klass = mono_defaults.int_class;
7105 else if (!strcmp (typename, "ptr"))
7106 klass = mono_defaults.int_class;
7107 else if (!strcmp (typename, "void"))
7108 klass = mono_defaults.void_class;
7109 else if (!strcmp (typename, "int32"))
7110 klass = mono_defaults.int32_class;
7111 else if (!strcmp (typename, "uint32"))
7112 klass = mono_defaults.uint32_class;
7113 else if (!strcmp (typename, "int8"))
7114 klass = mono_defaults.sbyte_class;
7115 else if (!strcmp (typename, "uint8"))
7116 klass = mono_defaults.byte_class;
7117 else if (!strcmp (typename, "int16"))
7118 klass = mono_defaults.int16_class;
7119 else if (!strcmp (typename, "uint16"))
7120 klass = mono_defaults.uint16_class;
7121 else if (!strcmp (typename, "long"))
7122 klass = mono_defaults.int64_class;
7123 else if (!strcmp (typename, "ulong"))
7124 klass = mono_defaults.uint64_class;
7125 else if (!strcmp (typename, "float"))
7126 klass = mono_defaults.single_class;
7127 else if (!strcmp (typename, "double"))
7128 klass = mono_defaults.double_class;
7129 else if (!strcmp (typename, "object"))
7130 klass = mono_defaults.object_class;
7131 else if (!strcmp (typename, "obj"))
7132 klass = mono_defaults.object_class;
7135 g_assert_not_reached ();
7137 return &klass->byval_arg;
7140 MonoMethodSignature*
7141 mono_create_icall_signature (const char *sigstr)
7146 MonoMethodSignature *res;
7148 mono_loader_lock ();
7149 res = g_hash_table_lookup (mono_defaults.corlib->helper_signatures, sigstr);
7151 mono_loader_unlock ();
7155 parts = g_strsplit (sigstr, " ", 256);
7164 res = mono_metadata_signature_alloc (mono_defaults.corlib, len - 1);
7167 #ifdef PLATFORM_WIN32
7169 * Under windows, the default pinvoke calling convention is STDCALL but
7172 res->call_convention = MONO_CALL_C;
7175 res->ret = type_from_typename (parts [0]);
7176 for (i = 1; i < len; ++i) {
7177 res->params [i - 1] = type_from_typename (parts [i]);
7182 g_hash_table_insert (mono_defaults.corlib->helper_signatures, (gpointer)sigstr, res);
7184 mono_loader_unlock ();
7190 mono_find_jit_icall_by_name (const char *name)
7192 MonoJitICallInfo *info;
7193 g_assert (jit_icall_hash_name);
7195 mono_loader_lock ();
7196 info = g_hash_table_lookup (jit_icall_hash_name, name);
7197 mono_loader_unlock ();
7202 mono_find_jit_icall_by_addr (gconstpointer addr)
7204 MonoJitICallInfo *info;
7205 g_assert (jit_icall_hash_addr);
7207 mono_loader_lock ();
7208 info = g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
7209 mono_loader_unlock ();
7215 mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
7217 mono_loader_lock ();
7218 g_hash_table_insert (jit_icall_hash_addr, (gpointer)wrapper, info);
7219 mono_loader_unlock ();
7223 mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
7225 MonoJitICallInfo *info;
7230 mono_loader_lock ();
7232 if (!jit_icall_hash_name) {
7233 jit_icall_hash_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
7234 jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
7237 if (g_hash_table_lookup (jit_icall_hash_name, name)) {
7238 g_warning ("jit icall already defined \"%s\"\n", name);
7239 g_assert_not_reached ();
7242 info = g_new0 (MonoJitICallInfo, 1);
7249 info->wrapper = func;
7251 info->wrapper = NULL;
7254 g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
7255 g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
7257 mono_loader_unlock ();