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 static inline MonoBoolean
75 is_generic_parameter (MonoType *type)
77 return !type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR);
81 * We expect a pointer to a char, not a string
84 mono_double_ParseImpl (char *ptr, double *result)
93 *result = strtod (ptr, &endptr);
96 *result = bsd_strtod (ptr, &endptr);
99 if (!*ptr || (endptr && *endptr))
106 mono_class_get_throw (MonoImage *image, guint32 type_token)
108 MonoClass *class = mono_class_get (image, type_token);
109 MonoLoaderError *error;
115 error = mono_loader_get_last_error ();
116 g_assert (error != NULL);
118 ex = mono_loader_error_prepare_exception (error);
119 mono_raise_exception (ex);
124 ves_icall_System_Array_GetValueImpl (MonoObject *this, guint32 pos)
133 ao = (MonoArray *)this;
134 ac = (MonoClass *)ao->obj.vtable->klass;
136 esize = mono_array_element_size (ac);
137 ea = (gpointer*)((char*)ao->vector + (pos * esize));
139 if (ac->element_class->valuetype)
140 return mono_value_box (this->vtable->domain, ac->element_class, ea);
146 ves_icall_System_Array_GetValue (MonoObject *this, MonoObject *idxs)
154 MONO_CHECK_ARG_NULL (idxs);
156 io = (MonoArray *)idxs;
157 ic = (MonoClass *)io->obj.vtable->klass;
159 ao = (MonoArray *)this;
160 ac = (MonoClass *)ao->obj.vtable->klass;
162 g_assert (ic->rank == 1);
163 if (io->bounds != NULL || io->max_length != ac->rank)
164 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
166 ind = (gint32 *)io->vector;
168 if (ao->bounds == NULL) {
169 if (*ind < 0 || *ind >= ao->max_length)
170 mono_raise_exception (mono_get_exception_index_out_of_range ());
172 return ves_icall_System_Array_GetValueImpl (this, *ind);
175 for (i = 0; i < ac->rank; i++)
176 if ((ind [i] < ao->bounds [i].lower_bound) ||
177 (ind [i] >= ao->bounds [i].length + ao->bounds [i].lower_bound))
178 mono_raise_exception (mono_get_exception_index_out_of_range ());
180 pos = ind [0] - ao->bounds [0].lower_bound;
181 for (i = 1; i < ac->rank; i++)
182 pos = pos*ao->bounds [i].length + ind [i] -
183 ao->bounds [i].lower_bound;
185 return ves_icall_System_Array_GetValueImpl (this, pos);
189 ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32 pos)
191 MonoClass *ac, *vc, *ec;
203 vc = value->vtable->klass;
207 ac = this->obj.vtable->klass;
208 ec = ac->element_class;
210 esize = mono_array_element_size (ac);
211 ea = (gpointer*)((char*)this->vector + (pos * esize));
212 va = (gpointer*)((char*)value + sizeof (MonoObject));
215 memset (ea, 0, esize);
219 #define NO_WIDENING_CONVERSION G_STMT_START{\
220 mono_raise_exception (mono_get_exception_argument ( \
221 "value", "not a widening conversion")); \
224 #define CHECK_WIDENING_CONVERSION(extra) G_STMT_START{\
225 if (esize < vsize + (extra)) \
226 mono_raise_exception (mono_get_exception_argument ( \
227 "value", "not a widening conversion")); \
230 #define INVALID_CAST G_STMT_START{\
231 mono_raise_exception (mono_get_exception_invalid_cast ()); \
234 /* Check element (destination) type. */
235 switch (ec->byval_arg.type) {
236 case MONO_TYPE_STRING:
237 switch (vc->byval_arg.type) {
238 case MONO_TYPE_STRING:
244 case MONO_TYPE_BOOLEAN:
245 switch (vc->byval_arg.type) {
246 case MONO_TYPE_BOOLEAN:
259 NO_WIDENING_CONVERSION;
266 if (!ec->valuetype) {
267 if (!mono_object_isinst (value, ec))
269 *ea = (gpointer)value;
273 if (mono_object_isinst (value, ec)) {
274 memcpy (ea, (char *)value + sizeof (MonoObject), esize);
281 vsize = mono_class_instance_size (vc) - sizeof (MonoObject);
283 et = ec->byval_arg.type;
284 if (et == MONO_TYPE_VALUETYPE && ec->byval_arg.data.klass->enumtype)
285 et = ec->byval_arg.data.klass->enum_basetype->type;
287 vt = vc->byval_arg.type;
288 if (vt == MONO_TYPE_VALUETYPE && vc->byval_arg.data.klass->enumtype)
289 vt = vc->byval_arg.data.klass->enum_basetype->type;
291 #define ASSIGN_UNSIGNED(etype) G_STMT_START{\
297 case MONO_TYPE_CHAR: \
298 CHECK_WIDENING_CONVERSION(0); \
299 *(etype *) ea = (etype) u64; \
301 /* You can't assign a signed value to an unsigned array. */ \
306 /* You can't assign a floating point number to an integer array. */ \
309 NO_WIDENING_CONVERSION; \
313 #define ASSIGN_SIGNED(etype) G_STMT_START{\
319 CHECK_WIDENING_CONVERSION(0); \
320 *(etype *) ea = (etype) i64; \
322 /* You can assign an unsigned value to a signed array if the array's */ \
323 /* element size is larger than the value size. */ \
328 case MONO_TYPE_CHAR: \
329 CHECK_WIDENING_CONVERSION(1); \
330 *(etype *) ea = (etype) u64; \
332 /* You can't assign a floating point number to an integer array. */ \
335 NO_WIDENING_CONVERSION; \
339 #define ASSIGN_REAL(etype) G_STMT_START{\
343 CHECK_WIDENING_CONVERSION(0); \
344 *(etype *) ea = (etype) r64; \
346 /* All integer values fit into a floating point array, so we don't */ \
347 /* need to CHECK_WIDENING_CONVERSION here. */ \
352 *(etype *) ea = (etype) i64; \
358 case MONO_TYPE_CHAR: \
359 *(etype *) ea = (etype) u64; \
366 u64 = *(guint8 *) va;
369 u64 = *(guint16 *) va;
372 u64 = *(guint32 *) va;
375 u64 = *(guint64 *) va;
381 i64 = *(gint16 *) va;
384 i64 = *(gint32 *) va;
387 i64 = *(gint64 *) va;
390 r64 = *(gfloat *) va;
393 r64 = *(gdouble *) va;
396 u64 = *(guint16 *) va;
398 case MONO_TYPE_BOOLEAN:
399 /* Boolean is only compatible with itself. */
412 NO_WIDENING_CONVERSION;
419 /* If we can't do a direct copy, let's try a widening conversion. */
422 ASSIGN_UNSIGNED (guint16);
424 ASSIGN_UNSIGNED (guint8);
426 ASSIGN_UNSIGNED (guint16);
428 ASSIGN_UNSIGNED (guint32);
430 ASSIGN_UNSIGNED (guint64);
432 ASSIGN_SIGNED (gint8);
434 ASSIGN_SIGNED (gint16);
436 ASSIGN_SIGNED (gint32);
438 ASSIGN_SIGNED (gint64);
440 ASSIGN_REAL (gfloat);
442 ASSIGN_REAL (gdouble);
446 /* Not reached, INVALID_CAST does not return. Just to avoid a compiler warning ... */
450 #undef NO_WIDENING_CONVERSION
451 #undef CHECK_WIDENING_CONVERSION
452 #undef ASSIGN_UNSIGNED
458 ves_icall_System_Array_SetValue (MonoArray *this, MonoObject *value,
466 MONO_CHECK_ARG_NULL (idxs);
468 ic = idxs->obj.vtable->klass;
469 ac = this->obj.vtable->klass;
471 g_assert (ic->rank == 1);
472 if (idxs->bounds != NULL || idxs->max_length != ac->rank)
473 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
475 ind = (gint32 *)idxs->vector;
477 if (this->bounds == NULL) {
478 if (*ind < 0 || *ind >= this->max_length)
479 mono_raise_exception (mono_get_exception_index_out_of_range ());
481 ves_icall_System_Array_SetValueImpl (this, value, *ind);
485 for (i = 0; i < ac->rank; i++)
486 if ((ind [i] < this->bounds [i].lower_bound) ||
487 (ind [i] >= this->bounds [i].length + this->bounds [i].lower_bound))
488 mono_raise_exception (mono_get_exception_index_out_of_range ());
490 pos = ind [0] - this->bounds [0].lower_bound;
491 for (i = 1; i < ac->rank; i++)
492 pos = pos * this->bounds [i].length + ind [i] -
493 this->bounds [i].lower_bound;
495 ves_icall_System_Array_SetValueImpl (this, value, pos);
499 ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
504 gboolean bounded = FALSE;
508 MONO_CHECK_ARG_NULL (type);
509 MONO_CHECK_ARG_NULL (lengths);
511 MONO_CHECK_ARG (lengths, mono_array_length (lengths) > 0);
513 MONO_CHECK_ARG (bounds, mono_array_length (lengths) == mono_array_length (bounds));
515 for (i = 0; i < mono_array_length (lengths); i++)
516 if (mono_array_get (lengths, gint32, i) < 0)
517 mono_raise_exception (mono_get_exception_argument_out_of_range (NULL));
519 if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint32, 0) != 0))
520 /* vectors are not the same as one dimensional arrays with no-zero bounds */
525 aklass = mono_bounded_array_class_get (mono_class_from_mono_type (type->type), mono_array_length (lengths), bounded);
527 sizes = alloca (aklass->rank * sizeof(guint32) * 2);
528 for (i = 0; i < aklass->rank; ++i) {
529 sizes [i] = mono_array_get (lengths, guint32, i);
531 sizes [i + aklass->rank] = mono_array_get (bounds, guint32, i);
533 sizes [i + aklass->rank] = 0;
536 array = mono_array_new_full (mono_object_domain (type), aklass, sizes, sizes + aklass->rank);
542 ves_icall_System_Array_GetRank (MonoObject *this)
546 return this->vtable->klass->rank;
550 ves_icall_System_Array_GetLength (MonoArray *this, gint32 dimension)
552 gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
556 if ((dimension < 0) || (dimension >= rank))
557 mono_raise_exception (mono_get_exception_index_out_of_range ());
559 if (this->bounds == NULL)
560 return this->max_length;
562 return this->bounds [dimension].length;
566 ves_icall_System_Array_GetLowerBound (MonoArray *this, gint32 dimension)
568 gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
572 if ((dimension < 0) || (dimension >= rank))
573 mono_raise_exception (mono_get_exception_index_out_of_range ());
575 if (this->bounds == NULL)
578 return this->bounds [dimension].lower_bound;
582 ves_icall_System_Array_ClearInternal (MonoArray *arr, int idx, int length)
584 int sz = mono_array_element_size (mono_object_class (arr));
585 memset (mono_array_addr_with_size (arr, sz, idx), 0, length * sz);
589 ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* dest, int dest_idx, int length)
594 MonoClass *src_class;
595 MonoClass *dest_class;
600 if (source->obj.vtable->klass->rank != dest->obj.vtable->klass->rank)
603 if (source->bounds || dest->bounds)
606 if ((dest_idx + length > mono_array_length (dest)) ||
607 (source_idx + length > mono_array_length (source)))
610 src_class = source->obj.vtable->klass->element_class;
611 dest_class = dest->obj.vtable->klass->element_class;
614 * Handle common cases.
617 /* Case1: object[] -> valuetype[] (ArrayList::ToArray) */
618 if (src_class == mono_defaults.object_class && dest_class->valuetype) {
619 int has_refs = dest_class->has_references;
620 for (i = source_idx; i < source_idx + length; ++i) {
621 MonoObject *elem = mono_array_get (source, MonoObject*, i);
622 if (elem && !mono_object_isinst (elem, dest_class))
626 element_size = mono_array_element_size (dest->obj.vtable->klass);
627 memset (mono_array_addr_with_size (dest, element_size, dest_idx), 0, element_size * length);
628 for (i = 0; i < length; ++i) {
629 MonoObject *elem = mono_array_get (source, MonoObject*, source_idx + i);
630 void *addr = mono_array_addr_with_size (dest, element_size, dest_idx + i);
634 mono_value_copy (addr, (char *)elem + sizeof (MonoObject), dest_class);
636 memcpy (addr, (char *)elem + sizeof (MonoObject), element_size);
641 /* Check if we're copying a char[] <==> (u)short[] */
642 if (src_class != dest_class) {
643 if (dest_class->valuetype || dest_class->enumtype || src_class->valuetype || src_class->enumtype)
646 if (mono_class_is_subclass_of (src_class, dest_class, FALSE))
648 /* Case2: object[] -> reftype[] (ArrayList::ToArray) */
649 else if (mono_class_is_subclass_of (dest_class, src_class, FALSE))
650 for (i = source_idx; i < source_idx + length; ++i) {
651 MonoObject *elem = mono_array_get (source, MonoObject*, i);
652 if (elem && !mono_object_isinst (elem, dest_class))
659 if (dest_class->valuetype) {
660 element_size = mono_array_element_size (source->obj.vtable->klass);
661 source_addr = mono_array_addr_with_size (source, element_size, source_idx);
662 if (dest_class->has_references) {
663 mono_value_copy_array (dest, dest_idx, source_addr, length);
665 dest_addr = mono_array_addr_with_size (dest, element_size, dest_idx);
666 memmove (dest_addr, source_addr, element_size * length);
669 mono_array_memcpy_refs (dest, dest_idx, source, source_idx, length);
676 ves_icall_System_Array_GetGenericValueImpl (MonoObject *this, guint32 pos, gpointer value)
685 ao = (MonoArray *)this;
686 ac = (MonoClass *)ao->obj.vtable->klass;
688 esize = mono_array_element_size (ac);
689 ea = (gpointer*)((char*)ao->vector + (pos * esize));
691 memcpy (value, ea, esize);
695 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoArray *array, MonoClassField *field_handle)
697 MonoClass *klass = array->obj.vtable->klass;
698 guint32 size = mono_array_element_size (klass);
700 size *= array->max_length;
702 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
704 guint ## n *data = (guint ## n *) mono_array_addr (array, char, 0); \
705 guint ## n *src = (guint ## n *) field_handle->data; \
706 guint ## n *end = (guint ## n *)((char*)src + size); \
708 for (; src < end; data++, src++) { \
709 *data = read ## n (src); \
713 /* printf ("Initialize array with elements of %s type\n", klass->element_class->name); */
715 switch (mono_type_get_underlying_type (&klass->element_class->byval_arg)->type) {
732 memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
736 memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
738 if (klass->element_class->byval_arg.type == MONO_TYPE_R8) {
741 double *data = (double*)mono_array_addr (array, double, 0);
743 for (i = 0; i < size; i++, data++) {
753 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData (void)
757 return offsetof (MonoString, chars);
761 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue (MonoObject *obj)
765 if ((obj == NULL) || (! (obj->vtable->klass->valuetype)))
768 return mono_object_clone (obj);
772 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (MonoType *handle)
778 MONO_CHECK_ARG_NULL (handle);
780 klass = mono_class_from_mono_type (handle);
781 MONO_CHECK_ARG (handle, klass);
783 /* This will call the type constructor */
784 if (! (klass->flags & TYPE_ATTRIBUTE_INTERFACE))
785 mono_runtime_class_init (mono_class_vtable (mono_domain_get (), klass));
789 ves_icall_System_Object_MemberwiseClone (MonoObject *this)
793 return mono_object_clone (this);
797 ves_icall_System_ValueType_InternalGetHashCode (MonoObject *this, MonoArray **fields)
800 MonoObject **values = NULL;
804 MonoClassField* field;
809 klass = mono_object_class (this);
811 if (mono_class_num_fields (klass) == 0)
812 return mono_object_hash (this);
815 * Compute the starting value of the hashcode for fields of primitive
816 * types, and return the remaining fields in an array to the managed side.
817 * This way, we can avoid costly reflection operations in managed code.
820 while ((field = mono_class_get_fields (klass, &iter))) {
821 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
823 if (mono_field_is_deleted (field))
825 /* FIXME: Add more types */
826 switch (field->type->type) {
828 result ^= *(gint32*)((guint8*)this + field->offset);
830 case MONO_TYPE_STRING: {
832 s = *(MonoString**)((guint8*)this + field->offset);
834 result ^= mono_string_hash (s);
839 values = g_newa (MonoObject*, mono_class_num_fields (klass));
840 o = mono_field_get_value_object (mono_object_domain (this), field, this);
841 values [count++] = o;
847 *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
848 for (i = 0; i < count; ++i)
849 mono_array_setref (*fields, i, values [i]);
857 ves_icall_System_ValueType_Equals (MonoObject *this, MonoObject *that, MonoArray **fields)
860 MonoObject **values = NULL;
862 MonoClassField* field;
868 MONO_CHECK_ARG_NULL (that);
870 if (this->vtable != that->vtable)
873 klass = mono_object_class (this);
876 * Do the comparison for fields of primitive type and return a result if
877 * possible. Otherwise, return the remaining fields in an array to the
878 * managed side. This way, we can avoid costly reflection operations in
883 while ((field = mono_class_get_fields (klass, &iter))) {
884 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
886 if (mono_field_is_deleted (field))
888 /* FIXME: Add more types */
889 switch (field->type->type) {
891 if (*(gint32*)((guint8*)this + field->offset) != *(gint32*)((guint8*)that + field->offset))
894 case MONO_TYPE_STRING: {
896 guint32 s1len, s2len;
897 s1 = *(MonoString**)((guint8*)this + field->offset);
898 s2 = *(MonoString**)((guint8*)that + field->offset);
901 if ((s1 == NULL) || (s2 == NULL))
903 s1len = mono_string_length (s1);
904 s2len = mono_string_length (s2);
908 if (memcmp (mono_string_chars (s1), mono_string_chars (s2), s1len * sizeof (gunichar2)) != 0)
914 values = g_newa (MonoObject*, mono_class_num_fields (klass) * 2);
915 o = mono_field_get_value_object (mono_object_domain (this), field, this);
916 values [count++] = o;
917 o = mono_field_get_value_object (mono_object_domain (this), field, that);
918 values [count++] = o;
924 *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
925 for (i = 0; i < count; ++i)
926 mono_array_setref (*fields, i, values [i]);
933 static MonoReflectionType *
934 ves_icall_System_Object_GetType (MonoObject *obj)
938 if (obj->vtable->klass != mono_defaults.transparent_proxy_class)
939 return mono_type_get_object (mono_object_domain (obj), &obj->vtable->klass->byval_arg);
941 return mono_type_get_object (mono_object_domain (obj), &((MonoTransparentProxy*)obj)->remote_class->proxy_class->byval_arg);
945 mono_type_type_from_obj (MonoReflectionType *mtype, MonoObject *obj)
949 mtype->type = &obj->vtable->klass->byval_arg;
950 g_assert (mtype->type->type);
954 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj)
958 MONO_CHECK_ARG_NULL (obj);
960 return mono_image_create_token (mb->dynamic_image, obj, TRUE);
964 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder *mb,
965 MonoReflectionMethod *method,
966 MonoArray *opt_param_types)
970 MONO_CHECK_ARG_NULL (method);
972 return mono_image_create_method_token (
973 mb->dynamic_image, (MonoObject *) method, opt_param_types);
977 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder *mb, HANDLE file)
981 mono_image_create_pefile (mb, file);
985 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
989 mono_image_build_metadata (mb);
993 get_caller (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
995 MonoMethod **dest = data;
997 /* skip unmanaged frames */
1012 static MonoReflectionType *
1013 type_from_name (const char *str, MonoBoolean ignoreCase)
1015 MonoType *type = NULL;
1016 MonoAssembly *assembly = NULL;
1017 MonoTypeNameParse info;
1018 char *temp_str = g_strdup (str);
1019 gboolean type_resolve = FALSE;
1021 MONO_ARCH_SAVE_REGS;
1023 /* mono_reflection_parse_type() mangles the string */
1024 if (!mono_reflection_parse_type (temp_str, &info)) {
1025 g_list_free (info.modifiers);
1026 g_list_free (info.nested);
1031 if (info.assembly.name) {
1032 assembly = mono_assembly_load (&info.assembly, NULL, NULL);
1034 MonoMethod *m = mono_method_get_last_managed ();
1035 MonoMethod *dest = m;
1037 mono_stack_walk_no_il (get_caller, &dest);
1042 * FIXME: mono_method_get_last_managed() sometimes returns NULL, thus
1043 * causing ves_icall_System_Reflection_Assembly_GetCallingAssembly()
1044 * to crash. This only seems to happen in some strange remoting
1045 * scenarios and I was unable to figure out what's happening there.
1046 * Dec 10, 2005 - Martin.
1050 assembly = dest->klass->image->assembly;
1052 g_warning (G_STRLOC);
1057 type = mono_reflection_get_type (assembly->image, &info, ignoreCase, &type_resolve);
1059 if (!info.assembly.name && !type) /* try mscorlib */
1060 type = mono_reflection_get_type (NULL, &info, ignoreCase, &type_resolve);
1062 g_list_free (info.modifiers);
1063 g_list_free (info.nested);
1069 return mono_type_get_object (mono_domain_get (), type);
1073 MonoReflectionType *
1074 mono_type_get (const char *str)
1076 char *copy = g_strdup (str);
1077 MonoReflectionType *type = type_from_name (copy, FALSE);
1084 static MonoReflectionType*
1085 ves_icall_type_from_name (MonoString *name,
1086 MonoBoolean throwOnError,
1087 MonoBoolean ignoreCase)
1089 char *str = mono_string_to_utf8 (name);
1090 MonoReflectionType *type;
1092 type = type_from_name (str, ignoreCase);
1095 MonoException *e = NULL;
1098 e = mono_get_exception_type_load (name, NULL);
1100 mono_loader_clear_error ();
1102 mono_raise_exception (e);
1109 static MonoReflectionType*
1110 ves_icall_type_from_handle (MonoType *handle)
1112 MonoDomain *domain = mono_domain_get ();
1113 MonoClass *klass = mono_class_from_mono_type (handle);
1115 MONO_ARCH_SAVE_REGS;
1117 mono_class_init (klass);
1118 return mono_type_get_object (domain, handle);
1122 ves_icall_System_Type_EqualsInternal (MonoReflectionType *type, MonoReflectionType *c)
1124 MONO_ARCH_SAVE_REGS;
1126 if (c && type->type && c->type)
1127 return mono_metadata_type_equal (type->type, c->type);
1132 /* System.TypeCode */
1151 TYPECODE_STRING = 18
1155 ves_icall_type_GetTypeCodeInternal (MonoReflectionType *type)
1157 int t = type->type->type;
1159 MONO_ARCH_SAVE_REGS;
1161 if (type->type->byref)
1162 return TYPECODE_OBJECT;
1166 case MONO_TYPE_VOID:
1167 return TYPECODE_OBJECT;
1168 case MONO_TYPE_BOOLEAN:
1169 return TYPECODE_BOOLEAN;
1171 return TYPECODE_BYTE;
1173 return TYPECODE_SBYTE;
1175 return TYPECODE_UINT16;
1177 return TYPECODE_INT16;
1178 case MONO_TYPE_CHAR:
1179 return TYPECODE_CHAR;
1183 return TYPECODE_OBJECT;
1185 return TYPECODE_UINT32;
1187 return TYPECODE_INT32;
1189 return TYPECODE_UINT64;
1191 return TYPECODE_INT64;
1193 return TYPECODE_SINGLE;
1195 return TYPECODE_DOUBLE;
1196 case MONO_TYPE_VALUETYPE:
1197 if (type->type->data.klass->enumtype) {
1198 t = type->type->data.klass->enum_basetype->type;
1201 MonoClass *k = type->type->data.klass;
1202 if (strcmp (k->name_space, "System") == 0) {
1203 if (strcmp (k->name, "Decimal") == 0)
1204 return TYPECODE_DECIMAL;
1205 else if (strcmp (k->name, "DateTime") == 0)
1206 return TYPECODE_DATETIME;
1209 return TYPECODE_OBJECT;
1210 case MONO_TYPE_STRING:
1211 return TYPECODE_STRING;
1212 case MONO_TYPE_SZARRAY:
1213 case MONO_TYPE_ARRAY:
1214 case MONO_TYPE_OBJECT:
1216 case MONO_TYPE_MVAR:
1217 case MONO_TYPE_TYPEDBYREF:
1218 return TYPECODE_OBJECT;
1219 case MONO_TYPE_CLASS:
1221 MonoClass *k = type->type->data.klass;
1222 if (strcmp (k->name_space, "System") == 0) {
1223 if (strcmp (k->name, "DBNull") == 0)
1224 return TYPECODE_DBNULL;
1227 return TYPECODE_OBJECT;
1228 case MONO_TYPE_GENERICINST:
1229 return TYPECODE_OBJECT;
1231 g_error ("type 0x%02x not handled in GetTypeCode()", t);
1237 ves_icall_type_is_subtype_of (MonoReflectionType *type, MonoReflectionType *c, MonoBoolean check_interfaces)
1243 MONO_ARCH_SAVE_REGS;
1245 g_assert (type != NULL);
1247 domain = ((MonoObject *)type)->vtable->domain;
1249 if (!c) /* FIXME: dont know what do do here */
1252 klass = mono_class_from_mono_type (type->type);
1253 klassc = mono_class_from_mono_type (c->type);
1255 if (type->type->byref)
1256 return klassc == mono_defaults.object_class;
1258 return mono_class_is_subclass_of (klass, klassc, check_interfaces);
1262 ves_icall_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType *c)
1268 MONO_ARCH_SAVE_REGS;
1270 g_assert (type != NULL);
1272 domain = ((MonoObject *)type)->vtable->domain;
1274 klass = mono_class_from_mono_type (type->type);
1275 klassc = mono_class_from_mono_type (c->type);
1277 if (type->type->byref && !c->type->byref)
1280 return mono_class_is_assignable_from (klass, klassc);
1284 ves_icall_type_IsInstanceOfType (MonoReflectionType *type, MonoObject *obj)
1286 MonoClass *klass = mono_class_from_mono_type (type->type);
1287 return mono_object_isinst (obj, klass) != NULL;
1291 ves_icall_get_attributes (MonoReflectionType *type)
1293 MonoClass *klass = mono_class_from_mono_type (type->type);
1295 MONO_ARCH_SAVE_REGS;
1297 return klass->flags;
1300 static MonoReflectionMarshal*
1301 ves_icall_System_Reflection_FieldInfo_GetUnmanagedMarshal (MonoReflectionField *field)
1303 MonoClass *klass = field->field->parent;
1304 MonoMarshalType *info;
1307 if (klass->generic_container ||
1308 (klass->generic_class && klass->generic_class->context.class_inst->is_open))
1311 info = mono_marshal_load_type_info (klass);
1313 for (i = 0; i < info->num_fields; ++i) {
1314 if (info->fields [i].field == field->field) {
1315 if (!info->fields [i].mspec)
1318 return mono_reflection_marshal_from_marshal_spec (field->object.vtable->domain, klass, info->fields [i].mspec);
1325 static MonoReflectionField*
1326 ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoClass *klass)
1331 klass = handle->parent;
1333 /* FIXME: check that handle is a field of klass or of a parent: return null
1334 * and throw the exception in managed code.
1336 return mono_field_get_object (mono_domain_get (), klass, handle);
1339 static MonoReflectionField*
1340 ves_icall_System_Reflection_FieldInfo_internal_from_handle (MonoClassField *handle)
1342 MONO_ARCH_SAVE_REGS;
1346 return mono_field_get_object (mono_domain_get (), handle->parent, handle);
1350 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
1352 MonoDomain *domain = mono_domain_get ();
1353 MonoMethodSignature* sig;
1354 MONO_ARCH_SAVE_REGS;
1356 if (method->is_inflated)
1357 method = mono_get_inflated_method (method);
1359 sig = mono_method_signature (method);
1361 g_assert (mono_loader_get_last_error ());
1362 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
1365 info->parent = mono_type_get_object (domain, &method->klass->byval_arg);
1366 info->ret = mono_type_get_object (domain, sig->ret);
1367 info->attrs = method->flags;
1368 info->implattrs = method->iflags;
1369 if (sig->call_convention == MONO_CALL_DEFAULT)
1372 if (sig->call_convention == MONO_CALL_VARARG)
1377 info->callconv |= (sig->hasthis << 5) | (sig->explicit_this << 6);
1381 ves_icall_get_parameter_info (MonoMethod *method)
1383 MonoDomain *domain = mono_domain_get ();
1385 MONO_ARCH_SAVE_REGS;
1387 if (method->is_inflated)
1388 method = mono_get_inflated_method (method);
1390 return mono_param_get_objects (domain, method);
1393 static MonoReflectionMarshal*
1394 ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod *method)
1396 MonoDomain *domain = mono_domain_get ();
1397 MonoReflectionMarshal* res = NULL;
1398 MonoMarshalSpec **mspecs;
1401 MONO_ARCH_SAVE_REGS;
1403 if (method->is_inflated)
1404 method = mono_get_inflated_method (method);
1406 mspecs = g_new (MonoMarshalSpec*, mono_method_signature (method)->param_count + 1);
1407 mono_method_get_marshal_info (method, mspecs);
1410 res = mono_reflection_marshal_from_marshal_spec (domain, method->klass, mspecs [0]);
1412 for (i = mono_method_signature (method)->param_count; i >= 0; i--)
1414 mono_metadata_free_marshal_spec (mspecs [i]);
1421 ves_icall_MonoField_GetFieldOffset (MonoReflectionField *field)
1423 return field->field->offset - sizeof (MonoObject);
1426 static MonoReflectionType*
1427 ves_icall_MonoField_GetParentType (MonoReflectionField *field, MonoBoolean declaring)
1430 MONO_ARCH_SAVE_REGS;
1432 parent = declaring? field->field->parent: field->klass;
1434 return mono_type_get_object (mono_object_domain (field), &parent->byval_arg);
1438 ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj)
1441 MonoClassField *cf = field->field;
1445 MonoDomain *domain = mono_object_domain (field);
1447 gboolean is_static = FALSE;
1448 gboolean is_ref = FALSE;
1450 MONO_ARCH_SAVE_REGS;
1452 if (field->klass->image->assembly->ref_only)
1453 mono_raise_exception (mono_get_exception_invalid_operation (
1454 "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
1456 mono_class_init (field->klass);
1458 t = mono_type_get_underlying_type (cf->type);
1460 case MONO_TYPE_STRING:
1461 case MONO_TYPE_OBJECT:
1462 case MONO_TYPE_CLASS:
1463 case MONO_TYPE_ARRAY:
1464 case MONO_TYPE_SZARRAY:
1469 case MONO_TYPE_BOOLEAN:
1472 case MONO_TYPE_CHAR:
1481 case MONO_TYPE_VALUETYPE:
1484 case MONO_TYPE_GENERICINST:
1485 if (mono_type_generic_inst_is_valuetype (t)) {
1492 g_error ("type 0x%x not handled in "
1493 "ves_icall_Monofield_GetValue", t->type);
1498 if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) {
1500 vtable = mono_class_vtable (domain, cf->parent);
1501 if (!vtable->initialized && !(cf->type->attrs & FIELD_ATTRIBUTE_LITERAL))
1502 mono_runtime_class_init (vtable);
1507 mono_field_static_get_value (vtable, cf, &o);
1509 mono_field_get_value (obj, cf, &o);
1514 if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) {
1515 MonoClass *nklass = mono_class_from_mono_type (cf->type);
1518 /* Convert the Nullable structure into a boxed vtype */
1520 buf = (guint8*)vtable->data + cf->offset;
1522 buf = (guint8*)obj + cf->offset;
1524 return mono_nullable_box (buf, nklass);
1527 /* boxed value type */
1528 klass = mono_class_from_mono_type (cf->type);
1529 o = mono_object_new (domain, klass);
1530 v = ((gchar *) o) + sizeof (MonoObject);
1532 mono_field_static_get_value (vtable, cf, v);
1534 mono_field_get_value (obj, cf, v);
1541 ves_icall_FieldInfo_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value)
1543 MonoClassField *cf = field->field;
1546 MONO_ARCH_SAVE_REGS;
1548 if (field->klass->image->assembly->ref_only)
1549 mono_raise_exception (mono_get_exception_invalid_operation (
1550 "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
1552 v = (gchar *) value;
1553 if (!cf->type->byref) {
1554 switch (cf->type->type) {
1557 case MONO_TYPE_BOOLEAN:
1560 case MONO_TYPE_CHAR:
1569 case MONO_TYPE_VALUETYPE:
1571 v += sizeof (MonoObject);
1573 case MONO_TYPE_STRING:
1574 case MONO_TYPE_OBJECT:
1575 case MONO_TYPE_CLASS:
1576 case MONO_TYPE_ARRAY:
1577 case MONO_TYPE_SZARRAY:
1580 case MONO_TYPE_GENERICINST: {
1581 MonoGenericClass *gclass = cf->type->data.generic_class;
1582 g_assert (!gclass->context.class_inst->is_open);
1584 if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) {
1585 MonoClass *nklass = mono_class_from_mono_type (cf->type);
1589 * Convert the boxed vtype into a Nullable structure.
1590 * This is complicated by the fact that Nullables have
1591 * a variable structure.
1593 /* Allocate using alloca so it gets GC tracking */
1594 buf = alloca (nklass->instance_size);
1596 mono_nullable_init (buf, value, nklass);
1601 if (gclass->container_class->valuetype && (v != NULL))
1602 v += sizeof (MonoObject);
1606 g_error ("type 0x%x not handled in "
1607 "ves_icall_FieldInfo_SetValueInternal", cf->type->type);
1612 if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) {
1613 MonoVTable *vtable = mono_class_vtable (mono_object_domain (field), cf->parent);
1614 if (!vtable->initialized)
1615 mono_runtime_class_init (vtable);
1616 mono_field_static_set_value (vtable, cf, v);
1618 mono_field_set_value (obj, cf, v);
1622 static MonoReflectionType*
1623 ves_icall_MonoGenericMethod_get_ReflectedType (MonoReflectionGenericMethod *rmethod)
1625 MonoMethod *method = mono_get_inflated_method (rmethod->method.method);
1627 return mono_type_get_object (mono_object_domain (rmethod), &method->klass->byval_arg);
1630 /* From MonoProperty.cs */
1632 PInfo_Attributes = 1,
1633 PInfo_GetMethod = 1 << 1,
1634 PInfo_SetMethod = 1 << 2,
1635 PInfo_ReflectedType = 1 << 3,
1636 PInfo_DeclaringType = 1 << 4,
1641 ves_icall_get_property_info (MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
1643 MonoDomain *domain = mono_object_domain (property);
1645 MONO_ARCH_SAVE_REGS;
1647 if ((req_info & PInfo_ReflectedType) != 0)
1648 info->parent = mono_type_get_object (domain, &property->klass->byval_arg);
1649 else if ((req_info & PInfo_DeclaringType) != 0)
1650 info->parent = mono_type_get_object (domain, &property->property->parent->byval_arg);
1652 if ((req_info & PInfo_Name) != 0)
1653 info->name = mono_string_new (domain, property->property->name);
1655 if ((req_info & PInfo_Attributes) != 0)
1656 info->attrs = property->property->attrs;
1658 if ((req_info & PInfo_GetMethod) != 0)
1659 info->get = property->property->get ?
1660 mono_method_get_object (domain, property->property->get, NULL): NULL;
1662 if ((req_info & PInfo_SetMethod) != 0)
1663 info->set = property->property->set ?
1664 mono_method_get_object (domain, property->property->set, NULL): NULL;
1666 * There may be other methods defined for properties, though, it seems they are not exposed
1667 * in the reflection API
1672 ves_icall_get_event_info (MonoReflectionEvent *event, MonoEventInfo *info)
1674 MonoDomain *domain = mono_object_domain (event);
1676 MONO_ARCH_SAVE_REGS;
1678 info->reflected_type = mono_type_get_object (domain, &event->klass->byval_arg);
1679 info->declaring_type = mono_type_get_object (domain, &event->event->parent->byval_arg);
1681 info->name = mono_string_new (domain, event->event->name);
1682 info->attrs = event->event->attrs;
1683 info->add_method = event->event->add ? mono_method_get_object (domain, event->event->add, NULL): NULL;
1684 info->remove_method = event->event->remove ? mono_method_get_object (domain, event->event->remove, NULL): NULL;
1685 info->raise_method = event->event->raise ? mono_method_get_object (domain, event->event->raise, NULL): NULL;
1687 if (event->event->other) {
1689 while (event->event->other [n])
1691 info->other_methods = mono_array_new (domain, mono_defaults.method_info_class, n);
1693 for (i = 0; i < n; i++)
1694 mono_array_setref (info->other_methods, i, mono_method_get_object (domain, event->event->other [i], NULL));
1699 ves_icall_Type_GetInterfaces (MonoReflectionType* type)
1701 MonoDomain *domain = mono_object_domain (type);
1703 GPtrArray *ifaces = NULL;
1705 MonoClass *class = mono_class_from_mono_type (type->type);
1708 MonoGenericContext *context = NULL;
1710 MONO_ARCH_SAVE_REGS;
1712 if (class->generic_class && class->generic_class->context.class_inst->is_open) {
1713 context = mono_class_get_context (class);
1714 class = class->generic_class->container_class;
1717 mono_class_setup_vtable (class);
1719 slots = mono_bitset_new (class->max_interface_id + 1, 0);
1721 for (parent = class; parent; parent = parent->parent) {
1722 GPtrArray *tmp_ifaces = mono_class_get_implemented_interfaces (parent);
1724 for (i = 0; i < tmp_ifaces->len; ++i) {
1725 MonoClass *ic = g_ptr_array_index (tmp_ifaces, i);
1727 if (mono_bitset_test (slots, ic->interface_id))
1730 mono_bitset_set (slots, ic->interface_id);
1732 ifaces = g_ptr_array_new ();
1733 g_ptr_array_add (ifaces, ic);
1735 g_ptr_array_free (tmp_ifaces, TRUE);
1738 mono_bitset_free (slots);
1741 return mono_array_new (domain, mono_defaults.monotype_class, 0);
1743 intf = mono_array_new (domain, mono_defaults.monotype_class, ifaces->len);
1744 for (i = 0; i < ifaces->len; ++i) {
1745 MonoClass *ic = g_ptr_array_index (ifaces, i);
1746 MonoType *ret = &ic->byval_arg;
1747 if (context && ic->generic_class && ic->generic_class->context.class_inst->is_open)
1748 ret = mono_class_inflate_generic_type (ret, context);
1750 mono_array_setref (intf, i, mono_type_get_object (domain, ret));
1752 g_ptr_array_free (ifaces, TRUE);
1758 ves_icall_Type_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType *iface, MonoArray **targets, MonoArray **methods)
1760 MonoClass *class = mono_class_from_mono_type (type->type);
1761 MonoClass *iclass = mono_class_from_mono_type (iface->type);
1762 MonoReflectionMethod *member;
1765 int i = 0, len, ioffset;
1768 MONO_ARCH_SAVE_REGS;
1770 mono_class_setup_vtable (class);
1772 /* type doesn't implement iface: the exception is thrown in managed code */
1773 if (! MONO_CLASS_IMPLEMENTS_INTERFACE (class, iclass->interface_id))
1776 len = mono_class_num_methods (iclass);
1777 ioffset = mono_class_interface_offset (class, iclass);
1778 domain = mono_object_domain (type);
1779 *targets = mono_array_new (domain, mono_defaults.method_info_class, len);
1780 *methods = mono_array_new (domain, mono_defaults.method_info_class, len);
1783 while ((method = mono_class_get_methods (iclass, &iter))) {
1784 member = mono_method_get_object (domain, method, iclass);
1785 mono_array_setref (*methods, i, member);
1786 member = mono_method_get_object (domain, class->vtable [i + ioffset], class);
1787 mono_array_setref (*targets, i, member);
1794 ves_icall_Type_GetPacking (MonoReflectionType *type, guint32 *packing, guint32 *size)
1796 MonoClass *klass = mono_class_from_mono_type (type->type);
1798 g_assert (!klass->image->dynamic);
1800 mono_metadata_packing_from_typedef (klass->image, klass->type_token, packing, size);
1803 static MonoReflectionType*
1804 ves_icall_MonoType_GetElementType (MonoReflectionType *type)
1806 MonoClass *class = mono_class_from_mono_type (type->type);
1808 MONO_ARCH_SAVE_REGS;
1810 // GelElementType should only return a type for:
1811 // Array Pointer PassedByRef
1812 if (type->type->byref)
1813 return mono_type_get_object (mono_object_domain (type), &class->byval_arg);
1814 if (class->enumtype && class->enum_basetype) /* types that are modifierd typebuilkders may not have enum_basetype set */
1815 return mono_type_get_object (mono_object_domain (type), class->enum_basetype);
1816 else if (class->element_class && MONO_CLASS_IS_ARRAY (class))
1817 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
1818 else if (class->element_class && type->type->type == MONO_TYPE_PTR)
1819 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
1824 static MonoReflectionType*
1825 ves_icall_get_type_parent (MonoReflectionType *type)
1827 MonoClass *class = mono_class_from_mono_type (type->type);
1829 MONO_ARCH_SAVE_REGS;
1831 return class->parent ? mono_type_get_object (mono_object_domain (type), &class->parent->byval_arg): NULL;
1835 ves_icall_type_ispointer (MonoReflectionType *type)
1837 MONO_ARCH_SAVE_REGS;
1839 return type->type->type == MONO_TYPE_PTR;
1843 ves_icall_type_isprimitive (MonoReflectionType *type)
1845 MONO_ARCH_SAVE_REGS;
1847 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)));
1851 ves_icall_type_isbyref (MonoReflectionType *type)
1853 MONO_ARCH_SAVE_REGS;
1855 return type->type->byref;
1859 ves_icall_type_iscomobject (MonoReflectionType *type)
1861 MonoClass *klass = mono_class_from_mono_type (type->type);
1862 MONO_ARCH_SAVE_REGS;
1864 return (klass && klass->is_com_object);
1867 static MonoReflectionModule*
1868 ves_icall_MonoType_get_Module (MonoReflectionType *type)
1870 MonoClass *class = mono_class_from_mono_type (type->type);
1872 MONO_ARCH_SAVE_REGS;
1874 return mono_module_get_object (mono_object_domain (type), class->image);
1877 static MonoReflectionAssembly*
1878 ves_icall_MonoType_get_Assembly (MonoReflectionType *type)
1880 MonoDomain *domain = mono_domain_get ();
1881 MonoClass *class = mono_class_from_mono_type (type->type);
1883 MONO_ARCH_SAVE_REGS;
1885 return mono_assembly_get_object (domain, class->image->assembly);
1888 static MonoReflectionType*
1889 ves_icall_MonoType_get_DeclaringType (MonoReflectionType *type)
1891 MonoDomain *domain = mono_domain_get ();
1894 MONO_ARCH_SAVE_REGS;
1896 if (type->type->byref)
1898 if (type->type->type == MONO_TYPE_VAR)
1899 class = type->type->data.generic_param->owner->owner.klass;
1900 else if (type->type->type == MONO_TYPE_MVAR)
1901 class = type->type->data.generic_param->owner->owner.method->klass;
1903 class = mono_class_from_mono_type (type->type)->nested_in;
1905 return class ? mono_type_get_object (domain, &class->byval_arg) : NULL;
1908 static MonoReflectionType*
1909 ves_icall_MonoType_get_UnderlyingSystemType (MonoReflectionType *type)
1911 MonoDomain *domain = mono_domain_get ();
1912 MonoClass *class = mono_class_from_mono_type (type->type);
1914 MONO_ARCH_SAVE_REGS;
1916 if (class->enumtype && class->enum_basetype) /* types that are modified typebuilders may not have enum_basetype set */
1917 return mono_type_get_object (domain, class->enum_basetype);
1918 else if (class->element_class)
1919 return mono_type_get_object (domain, &class->element_class->byval_arg);
1925 ves_icall_MonoType_get_Name (MonoReflectionType *type)
1927 MonoDomain *domain = mono_domain_get ();
1928 MonoClass *class = mono_class_from_mono_type (type->type);
1930 MONO_ARCH_SAVE_REGS;
1932 if (type->type->byref) {
1933 char *n = g_strdup_printf ("%s&", class->name);
1934 MonoString *res = mono_string_new (domain, n);
1940 return mono_string_new (domain, class->name);
1945 ves_icall_MonoType_get_Namespace (MonoReflectionType *type)
1947 MonoDomain *domain = mono_domain_get ();
1948 MonoClass *class = mono_class_from_mono_type (type->type);
1950 MONO_ARCH_SAVE_REGS;
1952 while (class->nested_in)
1953 class = class->nested_in;
1955 if (class->name_space [0] == '\0')
1958 return mono_string_new (domain, class->name_space);
1962 ves_icall_MonoType_GetArrayRank (MonoReflectionType *type)
1964 MonoClass *class = mono_class_from_mono_type (type->type);
1966 MONO_ARCH_SAVE_REGS;
1972 ves_icall_MonoType_GetGenericArguments (MonoReflectionType *type)
1975 MonoClass *klass, *pklass;
1977 MONO_ARCH_SAVE_REGS;
1979 klass = mono_class_from_mono_type (type->type);
1981 if (klass->generic_container) {
1982 MonoGenericContainer *container = klass->generic_container;
1983 res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, container->type_argc);
1984 for (i = 0; i < container->type_argc; ++i) {
1985 pklass = mono_class_from_generic_parameter (&container->type_params [i], klass->image, FALSE);
1986 mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), &pklass->byval_arg));
1988 } else if (klass->generic_class) {
1989 MonoGenericInst *inst = klass->generic_class->context.class_inst;
1990 res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, inst->type_argc);
1991 for (i = 0; i < inst->type_argc; ++i)
1992 mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), inst->type_argv [i]));
1994 res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, 0);
2000 ves_icall_Type_get_IsGenericTypeDefinition (MonoReflectionType *type)
2003 MONO_ARCH_SAVE_REGS;
2005 if (type->type->byref)
2008 klass = mono_class_from_mono_type (type->type);
2010 return klass->generic_container != NULL;
2013 static MonoReflectionType*
2014 ves_icall_Type_GetGenericTypeDefinition_impl (MonoReflectionType *type)
2017 MONO_ARCH_SAVE_REGS;
2019 if (type->type->byref)
2022 klass = mono_class_from_mono_type (type->type);
2023 if (klass->generic_container) {
2024 return type; /* check this one */
2026 if (klass->generic_class) {
2027 MonoClass *generic_class = klass->generic_class->container_class;
2029 if (generic_class->wastypebuilder && generic_class->reflection_info)
2030 return generic_class->reflection_info;
2032 return mono_type_get_object (mono_object_domain (type), &generic_class->byval_arg);
2037 static MonoReflectionType*
2038 ves_icall_Type_MakeGenericType (MonoReflectionType *type, MonoArray *type_array)
2040 MonoType *geninst, **types;
2043 MONO_ARCH_SAVE_REGS;
2045 count = mono_array_length (type_array);
2046 types = g_new0 (MonoType *, count);
2048 for (i = 0; i < count; i++) {
2049 MonoReflectionType *t = mono_array_get (type_array, gpointer, i);
2050 types [i] = t->type;
2053 geninst = mono_reflection_bind_generic_parameters (type, count, types);
2058 return mono_type_get_object (mono_object_domain (type), geninst);
2062 ves_icall_Type_get_IsGenericInstance (MonoReflectionType *type)
2065 MONO_ARCH_SAVE_REGS;
2067 if (type->type->byref)
2070 klass = mono_class_from_mono_type (type->type);
2071 return klass->generic_class != NULL;
2075 ves_icall_Type_get_IsGenericType (MonoReflectionType *type)
2078 MONO_ARCH_SAVE_REGS;
2080 if (type->type->byref)
2083 klass = mono_class_from_mono_type (type->type);
2084 return klass->generic_class != NULL || klass->generic_container != NULL;
2088 ves_icall_Type_GetGenericParameterPosition (MonoReflectionType *type)
2090 MONO_ARCH_SAVE_REGS;
2092 if (is_generic_parameter (type->type))
2093 return type->type->data.generic_param->num;
2097 static GenericParameterAttributes
2098 ves_icall_Type_GetGenericParameterAttributes (MonoReflectionType *type)
2100 MONO_ARCH_SAVE_REGS;
2101 g_assert (is_generic_parameter (type->type));
2102 return type->type->data.generic_param->flags;
2106 ves_icall_Type_GetGenericParameterConstraints (MonoReflectionType *type)
2108 MonoGenericParam *param;
2114 MONO_ARCH_SAVE_REGS;
2116 domain = mono_object_domain (type);
2117 param = type->type->data.generic_param;
2118 for (count = 0, ptr = param->constraints; ptr && *ptr; ptr++, count++)
2121 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2122 for (i = 0; i < count; i++)
2123 mono_array_setref (res, i, mono_type_get_object (domain, ¶m->constraints [i]->byval_arg));
2130 ves_icall_MonoType_get_IsGenericParameter (MonoReflectionType *type)
2132 MONO_ARCH_SAVE_REGS;
2133 return is_generic_parameter (type->type);
2137 ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder *tb)
2139 MONO_ARCH_SAVE_REGS;
2140 return is_generic_parameter (tb->type.type);
2144 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
2145 MonoReflectionType *t)
2147 enumtype->type = t->type;
2150 static MonoReflectionType*
2151 ves_icall_MonoGenericClass_GetParentType (MonoReflectionGenericClass *type)
2153 MonoDynamicGenericClass *gclass;
2154 MonoReflectionType *parent = NULL;
2159 MONO_ARCH_SAVE_REGS;
2161 g_assert (type->type.type->data.generic_class->is_dynamic);
2162 gclass = (MonoDynamicGenericClass *) type->type.type->data.generic_class;
2164 domain = mono_object_domain (type);
2165 klass = mono_class_from_mono_type (type->generic_type->type);
2167 if (!klass->generic_class && !klass->generic_container)
2170 if (!strcmp (type->generic_type->object.vtable->klass->name, "TypeBuilder")) {
2171 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *) type->generic_type;
2172 parent = tb->parent;
2173 } else if (klass->wastypebuilder) {
2174 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *) type->generic_type;
2175 parent = tb->parent;
2177 MonoClass *pklass = klass->parent;
2179 parent = mono_type_get_object (domain, &pklass->byval_arg);
2182 if (!parent || (parent->type->type != MONO_TYPE_GENERICINST))
2185 inflated = mono_class_inflate_generic_type (
2186 parent->type, mono_generic_class_get_context ((MonoGenericClass *) gclass));
2188 return mono_type_get_object (domain, inflated);
2192 ves_icall_MonoGenericClass_GetInterfaces (MonoReflectionGenericClass *type)
2194 static MonoClass *System_Reflection_MonoGenericClass;
2195 MonoGenericClass *gclass;
2196 MonoReflectionTypeBuilder *tb = NULL;
2197 MonoClass *klass = NULL;
2202 MONO_ARCH_SAVE_REGS;
2204 if (!System_Reflection_MonoGenericClass) {
2205 System_Reflection_MonoGenericClass = mono_class_from_name (
2206 mono_defaults.corlib, "System.Reflection", "MonoGenericClass");
2207 g_assert (System_Reflection_MonoGenericClass);
2210 domain = mono_object_domain (type);
2212 gclass = type->type.type->data.generic_class;
2213 g_assert (gclass->is_dynamic);
2215 if (!strcmp (type->generic_type->object.vtable->klass->name, "TypeBuilder")) {
2216 tb = (MonoReflectionTypeBuilder *) type->generic_type;
2217 icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
2219 klass = gclass->container_class;
2220 mono_class_init (klass);
2221 icount = klass->interface_count;
2224 res = mono_array_new (domain, System_Reflection_MonoGenericClass, icount);
2226 for (i = 0; i < icount; i++) {
2227 MonoReflectionType *iface;
2231 iface = mono_array_get (tb->interfaces, MonoReflectionType *, i);
2234 it = &klass->interfaces [i]->byval_arg;
2236 it = mono_class_inflate_generic_type (it, mono_generic_class_get_context (gclass));
2238 iface = mono_type_get_object (domain, it);
2239 mono_array_setref (res, i, iface);
2245 static MonoReflectionMethod*
2246 ves_icall_MonoGenericClass_GetCorrespondingInflatedMethod (MonoReflectionGenericClass *type,
2247 MonoReflectionMethod* generic)
2249 MonoGenericClass *gclass;
2250 MonoDynamicGenericClass *dgclass;
2254 MONO_ARCH_SAVE_REGS;
2256 gclass = type->type.type->data.generic_class;
2257 g_assert (gclass->is_dynamic);
2259 dgclass = (MonoDynamicGenericClass *) gclass;
2261 domain = mono_object_domain (type);
2263 for (i = 0; i < dgclass->count_methods; i++)
2264 if (generic->method->token == dgclass->methods [i]->token)
2265 return mono_method_get_object (domain, dgclass->methods [i], NULL);
2270 static MonoReflectionMethod*
2271 ves_icall_MonoGenericClass_GetCorrespondingInflatedConstructor (MonoReflectionGenericClass *type,
2272 MonoReflectionMethod* generic)
2274 MonoGenericClass *gclass;
2275 MonoDynamicGenericClass *dgclass;
2279 MONO_ARCH_SAVE_REGS;
2281 gclass = type->type.type->data.generic_class;
2282 g_assert (gclass->is_dynamic);
2284 dgclass = (MonoDynamicGenericClass *) gclass;
2286 domain = mono_object_domain (type);
2288 for (i = 0; i < dgclass->count_ctors; i++)
2289 if (generic->method->token == dgclass->ctors [i]->token)
2290 return mono_method_get_object (domain, dgclass->ctors [i], NULL);
2296 static MonoReflectionField*
2297 ves_icall_MonoGenericClass_GetCorrespondingInflatedField (MonoReflectionGenericClass *type,
2298 MonoString* generic_name)
2300 MonoGenericClass *gclass;
2301 MonoDynamicGenericClass *dgclass;
2303 MonoClass *refclass;
2304 char *utf8_name = mono_string_to_utf8 (generic_name);
2307 MONO_ARCH_SAVE_REGS;
2309 gclass = type->type.type->data.generic_class;
2310 g_assert (gclass->is_dynamic);
2312 dgclass = (MonoDynamicGenericClass *) gclass;
2314 refclass = mono_class_from_mono_type (type->type.type);
2316 domain = mono_object_domain (type);
2318 for (i = 0; i < dgclass->count_fields; i++)
2319 if (strcmp (utf8_name, dgclass->fields [i].name) == 0) {
2321 return mono_field_get_object (domain, refclass, &dgclass->fields [i]);
2330 static MonoReflectionMethod*
2331 ves_icall_MonoType_GetCorrespondingInflatedMethod (MonoReflectionType *type,
2332 MonoReflectionMethod* generic)
2339 MONO_ARCH_SAVE_REGS;
2341 domain = ((MonoObject *)type)->vtable->domain;
2343 klass = mono_class_from_mono_type (type->type);
2346 while ((method = mono_class_get_methods (klass, &iter))) {
2347 if (method->token == generic->method->token)
2348 return mono_method_get_object (domain, method, klass);
2355 ves_icall_MonoGenericClass_GetMethods (MonoReflectionGenericClass *type,
2356 MonoReflectionType *reflected_type)
2358 MonoGenericClass *gclass;
2359 MonoDynamicGenericClass *dgclass;
2361 MonoClass *refclass;
2365 MONO_ARCH_SAVE_REGS;
2367 gclass = type->type.type->data.generic_class;
2368 g_assert (gclass->is_dynamic);
2369 dgclass = (MonoDynamicGenericClass *) gclass;
2371 refclass = mono_class_from_mono_type (reflected_type->type);
2373 domain = mono_object_domain (type);
2374 res = mono_array_new (domain, mono_defaults.method_info_class, dgclass->count_methods);
2376 for (i = 0; i < dgclass->count_methods; i++)
2377 mono_array_setref (res, i, mono_method_get_object (domain, dgclass->methods [i], refclass));
2383 ves_icall_MonoGenericClass_GetConstructors (MonoReflectionGenericClass *type,
2384 MonoReflectionType *reflected_type)
2386 static MonoClass *System_Reflection_ConstructorInfo;
2387 MonoGenericClass *gclass;
2388 MonoDynamicGenericClass *dgclass;
2390 MonoClass *refclass;
2394 MONO_ARCH_SAVE_REGS;
2396 if (!System_Reflection_ConstructorInfo)
2397 System_Reflection_ConstructorInfo = mono_class_from_name (
2398 mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
2400 gclass = type->type.type->data.generic_class;
2401 g_assert (gclass->is_dynamic);
2402 dgclass = (MonoDynamicGenericClass *) gclass;
2404 refclass = mono_class_from_mono_type (reflected_type->type);
2406 domain = mono_object_domain (type);
2407 res = mono_array_new (domain, System_Reflection_ConstructorInfo, dgclass->count_ctors);
2409 for (i = 0; i < dgclass->count_ctors; i++)
2410 mono_array_setref (res, i, mono_method_get_object (domain, dgclass->ctors [i], refclass));
2416 ves_icall_MonoGenericClass_GetFields (MonoReflectionGenericClass *type,
2417 MonoReflectionType *reflected_type)
2419 MonoGenericClass *gclass;
2420 MonoDynamicGenericClass *dgclass;
2422 MonoClass *refclass;
2426 MONO_ARCH_SAVE_REGS;
2428 gclass = type->type.type->data.generic_class;
2429 g_assert (gclass->is_dynamic);
2430 dgclass = (MonoDynamicGenericClass *) gclass;
2432 refclass = mono_class_from_mono_type (reflected_type->type);
2434 domain = mono_object_domain (type);
2435 res = mono_array_new (domain, mono_defaults.field_info_class, dgclass->count_fields);
2437 for (i = 0; i < dgclass->count_fields; i++)
2438 mono_array_setref (res, i, mono_field_get_object (domain, refclass, &dgclass->fields [i]));
2444 ves_icall_MonoGenericClass_GetProperties (MonoReflectionGenericClass *type,
2445 MonoReflectionType *reflected_type)
2447 static MonoClass *System_Reflection_PropertyInfo;
2448 MonoGenericClass *gclass;
2449 MonoDynamicGenericClass *dgclass;
2451 MonoClass *refclass;
2455 MONO_ARCH_SAVE_REGS;
2457 if (!System_Reflection_PropertyInfo)
2458 System_Reflection_PropertyInfo = mono_class_from_name (
2459 mono_defaults.corlib, "System.Reflection", "PropertyInfo");
2461 gclass = type->type.type->data.generic_class;
2462 g_assert (gclass->is_dynamic);
2463 dgclass = (MonoDynamicGenericClass *) gclass;
2465 refclass = mono_class_from_mono_type (reflected_type->type);
2467 domain = mono_object_domain (type);
2468 res = mono_array_new (domain, System_Reflection_PropertyInfo, dgclass->count_properties);
2470 for (i = 0; i < dgclass->count_properties; i++)
2471 mono_array_setref (res, i, mono_property_get_object (domain, refclass, &dgclass->properties [i]));
2477 ves_icall_MonoGenericClass_GetEvents (MonoReflectionGenericClass *type,
2478 MonoReflectionType *reflected_type)
2480 static MonoClass *System_Reflection_EventInfo;
2481 MonoGenericClass *gclass;
2482 MonoDynamicGenericClass *dgclass;
2484 MonoClass *refclass;
2488 MONO_ARCH_SAVE_REGS;
2490 if (!System_Reflection_EventInfo)
2491 System_Reflection_EventInfo = mono_class_from_name (
2492 mono_defaults.corlib, "System.Reflection", "EventInfo");
2494 gclass = type->type.type->data.generic_class;
2495 g_assert (gclass->is_dynamic);
2496 dgclass = (MonoDynamicGenericClass *) gclass;
2498 refclass = mono_class_from_mono_type (reflected_type->type);
2500 domain = mono_object_domain (type);
2501 res = mono_array_new (domain, System_Reflection_EventInfo, dgclass->count_events);
2503 for (i = 0; i < dgclass->count_events; i++)
2504 mono_array_setref (res, i, mono_event_get_object (domain, refclass, &dgclass->events [i]));
2509 static MonoReflectionMethod *
2510 ves_icall_MonoType_get_DeclaringMethod (MonoReflectionType *type)
2515 MONO_ARCH_SAVE_REGS;
2517 if (type->type->byref || type->type->type != MONO_TYPE_MVAR)
2520 method = type->type->data.generic_param->owner->owner.method;
2522 klass = mono_class_from_mono_type (type->type);
2523 return mono_method_get_object (mono_object_domain (type), method, klass);
2526 static MonoReflectionDllImportAttribute*
2527 ves_icall_MonoMethod_GetDllImportAttribute (MonoMethod *method)
2529 static MonoClass *DllImportAttributeClass = NULL;
2530 MonoDomain *domain = mono_domain_get ();
2531 MonoReflectionDllImportAttribute *attr;
2532 MonoImage *image = method->klass->image;
2533 MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method;
2534 MonoTableInfo *tables = image->tables;
2535 MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
2536 MonoTableInfo *mr = &tables [MONO_TABLE_MODULEREF];
2537 guint32 im_cols [MONO_IMPLMAP_SIZE];
2538 guint32 scope_token;
2539 const char *import = NULL;
2540 const char *scope = NULL;
2543 if (!method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)
2546 if (!DllImportAttributeClass) {
2547 DllImportAttributeClass =
2548 mono_class_from_name (mono_defaults.corlib,
2549 "System.Runtime.InteropServices", "DllImportAttribute");
2550 g_assert (DllImportAttributeClass);
2553 if (method->klass->image->dynamic) {
2554 MonoReflectionMethodAux *method_aux =
2555 g_hash_table_lookup (
2556 ((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
2558 import = method_aux->dllentry;
2559 scope = method_aux->dll;
2563 if (piinfo->implmap_idx) {
2564 mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
2566 piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
2567 import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
2568 scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
2569 scope = mono_metadata_string_heap (image, scope_token);
2572 flags = piinfo->piflags;
2574 attr = (MonoReflectionDllImportAttribute*)mono_object_new (domain, DllImportAttributeClass);
2576 MONO_OBJECT_SETREF (attr, dll, mono_string_new (domain, scope));
2577 MONO_OBJECT_SETREF (attr, entry_point, mono_string_new (domain, import));
2578 attr->call_conv = (flags & 0x700) >> 8;
2579 attr->charset = ((flags & 0x6) >> 1) + 1;
2580 if (attr->charset == 1)
2582 attr->exact_spelling = (flags & 0x1) != 0;
2583 attr->set_last_error = (flags & 0x40) != 0;
2584 attr->best_fit_mapping = (flags & 0x30) == 0x10;
2585 attr->throw_on_unmappable = (flags & 0x3000) == 0x1000;
2586 attr->preserve_sig = FALSE;
2591 static MonoReflectionMethod *
2592 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
2594 MonoMethodInflated *imethod;
2596 MONO_ARCH_SAVE_REGS;
2598 if (!method->method->is_inflated) {
2599 if (mono_method_signature (method->method)->generic_param_count)
2605 imethod = (MonoMethodInflated *) method->method;
2607 if (imethod->reflection_info)
2608 return imethod->reflection_info;
2610 return mono_method_get_object (
2611 mono_object_domain (method), imethod->declaring, NULL);
2615 ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethod *method)
2617 MONO_ARCH_SAVE_REGS;
2619 return mono_method_signature (method->method)->generic_param_count != 0;
2623 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method)
2625 MONO_ARCH_SAVE_REGS;
2627 return method->method->generic_container &&
2628 (mono_method_signature (method->method)->generic_param_count != 0);
2632 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
2637 MONO_ARCH_SAVE_REGS;
2639 domain = mono_object_domain (method);
2641 if (method->method->is_inflated) {
2642 MonoGenericInst *inst = mono_method_get_context (method->method)->method_inst;
2645 count = inst->type_argc;
2646 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2648 for (i = 0; i < count; i++)
2649 mono_array_setref (res, i, mono_type_get_object (domain, inst->type_argv [i]));
2655 count = mono_method_signature (method->method)->generic_param_count;
2656 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2658 for (i = 0; i < count; i++) {
2659 MonoGenericParam *param = &method->method->generic_container->type_params [i];
2660 MonoClass *pklass = mono_class_from_generic_parameter (
2661 param, method->method->klass->image, TRUE);
2662 mono_array_setref (res, i,
2663 mono_type_get_object (domain, &pklass->byval_arg));
2670 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoArray *params)
2673 * Invoke from reflection is supposed to always be a virtual call (the API
2674 * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
2675 * greater flexibility.
2677 MonoMethod *m = mono_get_inflated_method (method->method);
2681 MONO_ARCH_SAVE_REGS;
2683 if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
2685 if (!mono_object_isinst (this, m->klass))
2686 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
2687 m = mono_object_get_virtual_method (this, m);
2688 /* must pass the pointer to the value for valuetype methods */
2689 if (m->klass->valuetype)
2690 obj = mono_object_unbox (this);
2691 } else if (strcmp (m->name, ".ctor") && !m->wrapper_type)
2692 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
2695 pcount = params? mono_array_length (params): 0;
2696 if (pcount != mono_method_signature (m)->param_count)
2697 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
2699 if ((m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) && !strcmp (m->name, ".ctor") && !this)
2700 mono_raise_exception (mono_exception_from_name_msg (mono_defaults.corlib, "System", "MethodAccessException", "Cannot invoke constructor of an abstract class."));
2702 if (m->klass->image->assembly->ref_only)
2703 mono_raise_exception (mono_get_exception_invalid_operation ("It is illegal to invoke a method on a type loaded using the ReflectionOnly api."));
2705 if (m->klass->rank && !strcmp (m->name, ".ctor")) {
2708 guint32 *lower_bounds;
2709 pcount = mono_array_length (params);
2710 lengths = alloca (sizeof (guint32) * pcount);
2711 for (i = 0; i < pcount; ++i)
2712 lengths [i] = *(gint32*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
2714 if (m->klass->rank == pcount) {
2715 /* Only lengths provided. */
2716 lower_bounds = NULL;
2718 g_assert (pcount == (m->klass->rank * 2));
2719 /* lower bounds are first. */
2720 lower_bounds = lengths;
2721 lengths += m->klass->rank;
2724 return (MonoObject*)mono_array_new_full (mono_object_domain (params), m->klass, lengths, lower_bounds);
2726 return mono_runtime_invoke_array (m, obj, params, NULL);
2730 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this, MonoArray *params, MonoArray **outArgs)
2732 MonoDomain *domain = mono_object_domain (method);
2733 MonoMethod *m = method->method;
2734 MonoMethodSignature *sig = mono_method_signature (m);
2735 MonoArray *out_args;
2737 int i, j, outarg_count = 0;
2739 MONO_ARCH_SAVE_REGS;
2741 if (m->klass == mono_defaults.object_class) {
2743 if (!strcmp (m->name, "FieldGetter")) {
2744 MonoClass *k = this->vtable->klass;
2748 /* If this is a proxy, then it must be a CBO */
2749 if (k == mono_defaults.transparent_proxy_class) {
2750 MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
2751 this = tp->rp->unwrapped_server;
2753 k = this->vtable->klass;
2756 name = mono_array_get (params, MonoString *, 1);
2757 str = mono_string_to_utf8 (name);
2760 MonoClassField* field = mono_class_get_field_from_name (k, str);
2762 MonoClass *field_klass = mono_class_from_mono_type (field->type);
2763 if (field_klass->valuetype)
2764 result = mono_value_box (domain, field_klass, (char *)this + field->offset);
2766 result = *((gpointer *)((char *)this + field->offset));
2768 out_args = mono_array_new (domain, mono_defaults.object_class, 1);
2769 *outArgs = out_args;
2770 mono_array_setref (out_args, 0, result);
2778 g_assert_not_reached ();
2780 } else if (!strcmp (m->name, "FieldSetter")) {
2781 MonoClass *k = this->vtable->klass;
2787 /* If this is a proxy, then it must be a CBO */
2788 if (k == mono_defaults.transparent_proxy_class) {
2789 MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
2790 this = tp->rp->unwrapped_server;
2792 k = this->vtable->klass;
2795 name = mono_array_get (params, MonoString *, 1);
2796 str = mono_string_to_utf8 (name);
2799 MonoClassField* field = mono_class_get_field_from_name (k, str);
2801 MonoClass *field_klass = mono_class_from_mono_type (field->type);
2802 MonoObject *val = mono_array_get (params, gpointer, 2);
2804 if (field_klass->valuetype) {
2805 size = mono_type_size (field->type, &align);
2806 memcpy ((char *)this + field->offset,
2807 ((char *)val) + sizeof (MonoObject), size);
2809 *(MonoObject**)((char *)this + field->offset) = val;
2811 out_args = mono_array_new (domain, mono_defaults.object_class, 0);
2812 *outArgs = out_args;
2822 g_assert_not_reached ();
2827 for (i = 0; i < mono_array_length (params); i++) {
2828 if (sig->params [i]->byref)
2832 out_args = mono_array_new (domain, mono_defaults.object_class, outarg_count);
2834 /* handle constructors only for objects already allocated */
2835 if (!strcmp (method->method->name, ".ctor"))
2838 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
2839 g_assert (!method->method->klass->valuetype);
2840 result = mono_runtime_invoke_array (method->method, this, params, NULL);
2842 for (i = 0, j = 0; i < mono_array_length (params); i++) {
2843 if (sig->params [i]->byref) {
2845 arg = mono_array_get (params, gpointer, i);
2846 mono_array_setref (out_args, j, arg);
2851 *outArgs = out_args;
2857 read_enum_value (char *mem, int type)
2861 return *(guint8*)mem;
2863 return *(gint8*)mem;
2865 return *(guint16*)mem;
2867 return *(gint16*)mem;
2869 return *(guint32*)mem;
2871 return *(gint32*)mem;
2873 return *(guint64*)mem;
2875 return *(gint64*)mem;
2877 g_assert_not_reached ();
2883 write_enum_value (char *mem, int type, guint64 value)
2887 case MONO_TYPE_I1: {
2888 guint8 *p = (guint8*)mem;
2893 case MONO_TYPE_I2: {
2894 guint16 *p = (void*)mem;
2899 case MONO_TYPE_I4: {
2900 guint32 *p = (void*)mem;
2905 case MONO_TYPE_I8: {
2906 guint64 *p = (void*)mem;
2911 g_assert_not_reached ();
2917 ves_icall_System_Enum_ToObject (MonoReflectionType *type, MonoObject *obj)
2920 MonoClass *enumc, *objc;
2924 MONO_ARCH_SAVE_REGS;
2926 MONO_CHECK_ARG_NULL (type);
2927 MONO_CHECK_ARG_NULL (obj);
2929 domain = mono_object_domain (type);
2930 enumc = mono_class_from_mono_type (type->type);
2931 objc = obj->vtable->klass;
2933 if (!enumc->enumtype)
2934 mono_raise_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
2935 if (!((objc->enumtype) || (objc->byval_arg.type >= MONO_TYPE_I1 && objc->byval_arg.type <= MONO_TYPE_U8)))
2936 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."));
2938 res = mono_object_new (domain, enumc);
2939 val = read_enum_value ((char *)obj + sizeof (MonoObject), objc->enumtype? objc->enum_basetype->type: objc->byval_arg.type);
2940 write_enum_value ((char *)res + sizeof (MonoObject), enumc->enum_basetype->type, val);
2946 ves_icall_System_Enum_get_value (MonoObject *this)
2954 MONO_ARCH_SAVE_REGS;
2959 g_assert (this->vtable->klass->enumtype);
2961 enumc = mono_class_from_mono_type (this->vtable->klass->enum_basetype);
2962 res = mono_object_new (mono_object_domain (this), enumc);
2963 dst = (char *)res + sizeof (MonoObject);
2964 src = (char *)this + sizeof (MonoObject);
2965 size = mono_class_value_size (enumc, NULL);
2967 memcpy (dst, src, size);
2973 ves_icall_get_enum_info (MonoReflectionType *type, MonoEnumInfo *info)
2975 MonoDomain *domain = mono_object_domain (type);
2976 MonoClass *enumc = mono_class_from_mono_type (type->type);
2977 guint j = 0, nvalues, crow;
2979 MonoClassField *field;
2981 MONO_ARCH_SAVE_REGS;
2983 info->utype = mono_type_get_object (domain, enumc->enum_basetype);
2984 nvalues = mono_class_num_fields (enumc) ? mono_class_num_fields (enumc) - 1 : 0;
2985 info->names = mono_array_new (domain, mono_defaults.string_class, nvalues);
2986 info->values = mono_array_new (domain, enumc, nvalues);
2990 while ((field = mono_class_get_fields (enumc, &iter))) {
2994 if (strcmp ("value__", field->name) == 0)
2996 if (mono_field_is_deleted (field))
2998 mono_array_setref (info->names, j, mono_string_new (domain, field->name));
3001 crow = mono_metadata_get_constant_index (enumc->image, mono_class_get_field_token (field), crow + 1);
3002 field->def_type = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_TYPE);
3003 crow = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_VALUE);
3004 field->data = (gpointer)mono_metadata_blob_heap (enumc->image, crow);
3008 len = mono_metadata_decode_blob_size (p, &p);
3009 switch (enumc->enum_basetype->type) {
3012 mono_array_set (info->values, gchar, j, *p);
3014 case MONO_TYPE_CHAR:
3017 mono_array_set (info->values, gint16, j, read16 (p));
3021 mono_array_set (info->values, gint32, j, read32 (p));
3025 mono_array_set (info->values, gint64, j, read64 (p));
3028 g_error ("Implement type 0x%02x in get_enum_info", enumc->enum_basetype->type);
3035 BFLAGS_IgnoreCase = 1,
3036 BFLAGS_DeclaredOnly = 2,
3037 BFLAGS_Instance = 4,
3039 BFLAGS_Public = 0x10,
3040 BFLAGS_NonPublic = 0x20,
3041 BFLAGS_FlattenHierarchy = 0x40,
3042 BFLAGS_InvokeMethod = 0x100,
3043 BFLAGS_CreateInstance = 0x200,
3044 BFLAGS_GetField = 0x400,
3045 BFLAGS_SetField = 0x800,
3046 BFLAGS_GetProperty = 0x1000,
3047 BFLAGS_SetProperty = 0x2000,
3048 BFLAGS_ExactBinding = 0x10000,
3049 BFLAGS_SuppressChangeType = 0x20000,
3050 BFLAGS_OptionalParamBinding = 0x40000
3053 static MonoReflectionField *
3054 ves_icall_Type_GetField (MonoReflectionType *type, MonoString *name, guint32 bflags)
3057 MonoClass *startklass, *klass;
3059 MonoClassField *field;
3062 int (*compare_func) (const char *s1, const char *s2) = NULL;
3063 domain = ((MonoObject *)type)->vtable->domain;
3064 klass = startklass = mono_class_from_mono_type (type->type);
3066 MONO_ARCH_SAVE_REGS;
3069 mono_raise_exception (mono_get_exception_argument_null ("name"));
3070 if (type->type->byref)
3073 compare_func = (bflags & BFLAGS_IgnoreCase) ? g_strcasecmp : strcmp;
3077 while ((field = mono_class_get_fields (klass, &iter))) {
3079 if (mono_field_is_deleted (field))
3081 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3082 if (bflags & BFLAGS_Public)
3085 if (bflags & BFLAGS_NonPublic)
3091 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
3092 if (bflags & BFLAGS_Static)
3093 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3096 if (bflags & BFLAGS_Instance)
3103 utf8_name = mono_string_to_utf8 (name);
3105 if (compare_func (field->name, utf8_name)) {
3111 return mono_field_get_object (domain, klass, field);
3113 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3120 ves_icall_Type_GetFields_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3123 MonoClass *startklass, *klass, *refklass;
3128 MonoClassField *field;
3130 MONO_ARCH_SAVE_REGS;
3132 domain = ((MonoObject *)type)->vtable->domain;
3133 if (type->type->byref)
3134 return mono_array_new (domain, mono_defaults.field_info_class, 0);
3135 klass = startklass = mono_class_from_mono_type (type->type);
3136 refklass = mono_class_from_mono_type (reftype->type);
3140 res = mono_array_new (domain, mono_defaults.field_info_class, len);
3143 while ((field = mono_class_get_fields (klass, &iter))) {
3145 if (mono_field_is_deleted (field))
3147 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3148 if (bflags & BFLAGS_Public)
3151 if (bflags & BFLAGS_NonPublic) {
3152 /* Serialization currently depends on the old behavior.
3153 * if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE || startklass == klass)*/
3160 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
3161 if (bflags & BFLAGS_Static)
3162 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3165 if (bflags & BFLAGS_Instance)
3171 member = (MonoObject*)mono_field_get_object (domain, refklass, field);
3173 MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, len * 2);
3174 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3178 mono_array_setref (res, i, member);
3181 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3184 MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, i);
3185 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3188 * Better solution for the new GC.
3189 * res->max_length = i;
3196 ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
3199 MonoClass *startklass, *klass, *refklass;
3204 int i, len, match, nslots;
3205 guint32 method_slots_default [8];
3206 guint32 *method_slots;
3207 gchar *mname = NULL;
3208 int (*compare_func) (const char *s1, const char *s2) = NULL;
3210 MONO_ARCH_SAVE_REGS;
3212 domain = ((MonoObject *)type)->vtable->domain;
3213 if (type->type->byref)
3214 return mono_array_new (domain, mono_defaults.method_info_class, 0);
3215 klass = startklass = mono_class_from_mono_type (type->type);
3216 refklass = mono_class_from_mono_type (reftype->type);
3219 mname = mono_string_to_utf8 (name);
3220 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
3223 mono_class_setup_vtable (klass);
3225 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : klass->vtable_size;
3226 if (nslots >= sizeof (method_slots_default) * 8) {
3227 method_slots = g_new0 (guint32, nslots / 32 + 1);
3229 method_slots = method_slots_default;
3230 memset (method_slots, 0, sizeof (method_slots_default));
3234 res = mono_array_new (domain, mono_defaults.method_info_class, len);
3236 mono_class_setup_vtable (klass);
3238 while ((method = mono_class_get_methods (klass, &iter))) {
3240 if (method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
3242 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3243 if (bflags & BFLAGS_Public)
3246 if (bflags & BFLAGS_NonPublic)
3252 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3253 if (bflags & BFLAGS_Static)
3254 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3257 if (bflags & BFLAGS_Instance)
3265 if (compare_func (mname, method->name))
3270 if (method->slot != -1) {
3271 g_assert (method->slot < nslots);
3272 if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
3274 method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
3277 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
3280 MonoArray *new_res = mono_array_new (domain, mono_defaults.method_info_class, len * 2);
3281 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3285 mono_array_setref (res, i, member);
3288 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3292 if (method_slots != method_slots_default)
3293 g_free (method_slots);
3295 MonoArray *new_res = mono_array_new (domain, mono_defaults.method_info_class, i);
3296 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3299 * Better solution for the new GC.
3300 * res->max_length = i;
3307 ves_icall_Type_GetConstructors_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3310 static MonoClass *System_Reflection_ConstructorInfo;
3311 MonoClass *startklass, *klass, *refklass;
3316 gpointer iter = NULL;
3318 MONO_ARCH_SAVE_REGS;
3320 domain = ((MonoObject *)type)->vtable->domain;
3321 if (type->type->byref)
3322 return mono_array_new (domain, mono_defaults.method_info_class, 0);
3323 klass = startklass = mono_class_from_mono_type (type->type);
3324 refklass = mono_class_from_mono_type (reftype->type);
3326 if (!System_Reflection_ConstructorInfo)
3327 System_Reflection_ConstructorInfo = mono_class_from_name (
3328 mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
3332 res = mono_array_new (domain, System_Reflection_ConstructorInfo, len);
3334 while ((method = mono_class_get_methods (klass, &iter))) {
3336 if (strcmp (method->name, ".ctor") && strcmp (method->name, ".cctor"))
3338 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3339 if (bflags & BFLAGS_Public)
3342 if (bflags & BFLAGS_NonPublic)
3348 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3349 if (bflags & BFLAGS_Static)
3350 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3353 if (bflags & BFLAGS_Instance)
3359 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
3362 MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, len * 2);
3363 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3367 mono_array_setref (res, i, member);
3371 MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, i);
3372 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3375 * Better solution for the new GC.
3376 * res->max_length = i;
3383 ves_icall_Type_GetPropertiesByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
3386 static MonoClass *System_Reflection_PropertyInfo;
3387 MonoClass *startklass, *klass;
3391 int i, match, nslots;
3394 guint32 method_slots_default [8];
3395 guint32 *method_slots;
3396 gchar *propname = NULL;
3397 int (*compare_func) (const char *s1, const char *s2) = NULL;
3400 MONO_ARCH_SAVE_REGS;
3402 if (!System_Reflection_PropertyInfo)
3403 System_Reflection_PropertyInfo = mono_class_from_name (
3404 mono_defaults.corlib, "System.Reflection", "PropertyInfo");
3406 domain = ((MonoObject *)type)->vtable->domain;
3407 if (type->type->byref)
3408 return mono_array_new (domain, System_Reflection_PropertyInfo, 0);
3409 klass = startklass = mono_class_from_mono_type (type->type);
3411 propname = mono_string_to_utf8 (name);
3412 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
3415 mono_class_setup_vtable (klass);
3417 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : klass->vtable_size;
3418 if (nslots >= sizeof (method_slots_default) * 8) {
3419 method_slots = g_new0 (guint32, nslots / 32 + 1);
3421 method_slots = method_slots_default;
3422 memset (method_slots, 0, sizeof (method_slots_default));
3426 res = mono_array_new (domain, System_Reflection_PropertyInfo, len);
3428 mono_class_setup_vtable (klass);
3430 while ((prop = mono_class_get_properties (klass, &iter))) {
3436 flags = method->flags;
3439 if ((prop->get && ((prop->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC)) ||
3440 (prop->set && ((prop->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC))) {
3441 if (bflags & BFLAGS_Public)
3444 if (bflags & BFLAGS_NonPublic)
3450 if (flags & METHOD_ATTRIBUTE_STATIC) {
3451 if (bflags & BFLAGS_Static)
3452 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3455 if (bflags & BFLAGS_Instance)
3464 if (compare_func (propname, prop->name))
3468 if (prop->get && prop->get->slot != -1) {
3469 if (method_slots [prop->get->slot >> 5] & (1 << (prop->get->slot & 0x1f)))
3471 method_slots [prop->get->slot >> 5] |= 1 << (prop->get->slot & 0x1f);
3473 if (prop->set && prop->set->slot != -1) {
3474 if (method_slots [prop->set->slot >> 5] & (1 << (prop->set->slot & 0x1f)))
3476 method_slots [prop->set->slot >> 5] |= 1 << (prop->set->slot & 0x1f);
3480 MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, len * 2);
3481 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3485 mono_array_setref (res, i, mono_property_get_object (domain, startklass, prop));
3488 if ((!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent)))
3492 if (method_slots != method_slots_default)
3493 g_free (method_slots);
3495 MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, i);
3496 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3499 * Better solution for the new GC.
3500 * res->max_length = i;
3506 static MonoReflectionEvent *
3507 ves_icall_MonoType_GetEvent (MonoReflectionType *type, MonoString *name, guint32 bflags)
3510 MonoClass *klass, *startklass;
3516 MONO_ARCH_SAVE_REGS;
3518 event_name = mono_string_to_utf8 (name);
3519 if (type->type->byref)
3521 klass = startklass = mono_class_from_mono_type (type->type);
3522 domain = mono_object_domain (type);
3526 while ((event = mono_class_get_events (klass, &iter))) {
3527 if (strcmp (event->name, event_name))
3530 method = event->add;
3532 method = event->remove;
3534 method = event->raise;
3536 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3537 if (!(bflags & BFLAGS_Public))
3540 if (!(bflags & BFLAGS_NonPublic))
3545 if (!(bflags & BFLAGS_NonPublic))
3548 g_free (event_name);
3549 return mono_event_get_object (domain, startklass, event);
3552 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3555 g_free (event_name);
3560 ves_icall_Type_GetEvents_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3563 static MonoClass *System_Reflection_EventInfo;
3564 MonoClass *startklass, *klass;
3571 MONO_ARCH_SAVE_REGS;
3573 if (!System_Reflection_EventInfo)
3574 System_Reflection_EventInfo = mono_class_from_name (
3575 mono_defaults.corlib, "System.Reflection", "EventInfo");
3577 domain = mono_object_domain (type);
3578 if (type->type->byref)
3579 return mono_array_new (domain, System_Reflection_EventInfo, 0);
3580 klass = startklass = mono_class_from_mono_type (type->type);
3584 res = mono_array_new (domain, System_Reflection_EventInfo, len);
3587 while ((event = mono_class_get_events (klass, &iter))) {
3589 method = event->add;
3591 method = event->remove;
3593 method = event->raise;
3595 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3596 if (bflags & BFLAGS_Public)
3599 if (bflags & BFLAGS_NonPublic)
3604 if (bflags & BFLAGS_NonPublic)
3610 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3611 if (bflags & BFLAGS_Static)
3612 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3615 if (bflags & BFLAGS_Instance)
3620 if (bflags & BFLAGS_Instance)
3626 MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, len * 2);
3627 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3631 mono_array_setref (res, i, mono_event_get_object (domain, startklass, event));
3634 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3637 MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, i);
3638 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3641 * Better solution for the new GC.
3642 * res->max_length = i;
3648 static MonoReflectionType *
3649 ves_icall_Type_GetNestedType (MonoReflectionType *type, MonoString *name, guint32 bflags)
3657 MONO_ARCH_SAVE_REGS;
3659 domain = ((MonoObject *)type)->vtable->domain;
3660 if (type->type->byref)
3662 klass = mono_class_from_mono_type (type->type);
3663 str = mono_string_to_utf8 (name);
3667 * If a nested type is generic, return its generic type definition.
3668 * Note that this means that the return value is essentially a
3669 * nested type of the generic type definition of @klass.
3671 * A note in MSDN claims that a generic type definition can have
3672 * nested types that aren't generic. In any case, the container of that
3673 * nested type would be the generic type definition.
3675 if (klass->generic_class)
3676 klass = klass->generic_class->container_class;
3678 for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
3680 nested = tmpn->data;
3681 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
3682 if (bflags & BFLAGS_Public)
3685 if (bflags & BFLAGS_NonPublic)
3690 if (strcmp (nested->name, str) == 0){
3692 return mono_type_get_object (domain, &nested->byval_arg);
3695 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3702 ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags)
3712 MONO_ARCH_SAVE_REGS;
3714 domain = ((MonoObject *)type)->vtable->domain;
3715 if (type->type->byref)
3716 return mono_array_new (domain, mono_defaults.monotype_class, 0);
3717 klass = mono_class_from_mono_type (type->type);
3720 * If a nested type is generic, return its generic type definition.
3721 * Note that this means that the return value is essentially the set
3722 * of nested types of the generic type definition of @klass.
3724 * A note in MSDN claims that a generic type definition can have
3725 * nested types that aren't generic. In any case, the container of that
3726 * nested type would be the generic type definition.
3728 if (klass->generic_class)
3729 klass = klass->generic_class->container_class;
3733 res = mono_array_new (domain, mono_defaults.monotype_class, len);
3734 for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
3736 nested = tmpn->data;
3737 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
3738 if (bflags & BFLAGS_Public)
3741 if (bflags & BFLAGS_NonPublic)
3746 member = (MonoObject*)mono_type_get_object (domain, &nested->byval_arg);
3748 MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, len * 2);
3749 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3753 mono_array_setref (res, i, member);
3757 MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, i);
3758 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3761 * Better solution for the new GC.
3762 * res->max_length = i;
3768 static MonoReflectionType*
3769 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *assembly, MonoReflectionModule *module, MonoString *name, MonoBoolean throwOnError, MonoBoolean ignoreCase)
3772 MonoType *type = NULL;
3773 MonoTypeNameParse info;
3774 gboolean type_resolve;
3776 MONO_ARCH_SAVE_REGS;
3778 /* On MS.NET, this does not fire a TypeResolve event */
3779 type_resolve = TRUE;
3780 str = mono_string_to_utf8 (name);
3781 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
3782 if (!mono_reflection_parse_type (str, &info)) {
3784 g_list_free (info.modifiers);
3785 g_list_free (info.nested);
3786 if (throwOnError) /* uhm: this is a parse error, though... */
3787 mono_raise_exception (mono_get_exception_type_load (name, NULL));
3788 /*g_print ("failed parse\n");*/
3792 if (module != NULL) {
3794 type = mono_reflection_get_type (module->image, &info, ignoreCase, &type_resolve);
3799 if (assembly->assembly->dynamic) {
3800 /* Enumerate all modules */
3801 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
3805 if (abuilder->modules) {
3806 for (i = 0; i < mono_array_length (abuilder->modules); ++i) {
3807 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
3808 type = mono_reflection_get_type (&mb->dynamic_image->image, &info, ignoreCase, &type_resolve);
3814 if (!type && abuilder->loaded_modules) {
3815 for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) {
3816 MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
3817 type = mono_reflection_get_type (mod->image, &info, ignoreCase, &type_resolve);
3824 type = mono_reflection_get_type (assembly->assembly->image, &info, ignoreCase, &type_resolve);
3826 g_list_free (info.modifiers);
3827 g_list_free (info.nested);
3829 MonoException *e = NULL;
3832 e = mono_get_exception_type_load (name, NULL);
3834 mono_loader_clear_error ();
3837 mono_raise_exception (e);
3842 if (type->type == MONO_TYPE_CLASS) {
3843 MonoClass *klass = mono_type_get_class (type);
3844 /* need to report exceptions ? */
3845 if (throwOnError && klass->exception_type) {
3846 /* report SecurityException (or others) that occured when loading the assembly */
3847 MonoException *exc = mono_class_get_exception_for_failure (klass);
3848 mono_loader_clear_error ();
3849 mono_raise_exception (exc);
3850 } else if (klass->exception_type == MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND) {
3855 /* g_print ("got it\n"); */
3856 return mono_type_get_object (mono_object_domain (assembly), type);
3860 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *assembly, MonoBoolean escaped)
3862 MonoDomain *domain = mono_object_domain (assembly);
3863 MonoAssembly *mass = assembly->assembly;
3864 MonoString *res = NULL;
3868 MONO_ARCH_SAVE_REGS;
3870 if (g_path_is_absolute (mass->image->name))
3871 absolute = g_strdup (mass->image->name);
3873 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
3877 for (i = strlen (absolute) - 1; i >= 0; i--)
3878 if (absolute [i] == '\\')
3883 uri = g_filename_to_uri (absolute, NULL, NULL);
3885 uri = g_strconcat ("file://", absolute, NULL);
3889 res = mono_string_new (domain, uri);
3897 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssembly *assembly)
3899 MonoAssembly *mass = assembly->assembly;
3901 MONO_ARCH_SAVE_REGS;
3903 return mass->in_gac;
3906 static MonoReflectionAssembly*
3907 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoString *mname, MonoObject *evidence)
3911 MonoImageOpenStatus status;
3913 MONO_ARCH_SAVE_REGS;
3915 name = mono_string_to_utf8 (mname);
3916 res = mono_assembly_load_with_partial_name (name, &status);
3922 return mono_assembly_get_object (mono_domain_get (), res);
3926 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssembly *assembly)
3928 MonoDomain *domain = mono_object_domain (assembly);
3931 MONO_ARCH_SAVE_REGS;
3933 res = mono_string_new (domain, mono_image_get_filename (assembly->assembly->image));
3939 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssembly *assembly)
3941 MONO_ARCH_SAVE_REGS;
3943 return assembly->assembly->ref_only;
3947 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssembly *assembly)
3949 MonoDomain *domain = mono_object_domain (assembly);
3951 MONO_ARCH_SAVE_REGS;
3953 return mono_string_new (domain, assembly->assembly->image->version);
3956 static MonoReflectionMethod*
3957 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssembly *assembly)
3959 guint32 token = mono_image_get_entry_point (assembly->assembly->image);
3961 MONO_ARCH_SAVE_REGS;
3965 return mono_method_get_object (mono_object_domain (assembly), mono_get_method (assembly->assembly->image, token, NULL), NULL);
3968 static MonoReflectionModule*
3969 ves_icall_System_Reflection_Assembly_get_ManifestModule (MonoReflectionAssembly *assembly)
3971 return mono_module_get_object (mono_object_domain (assembly), assembly->assembly->image);
3975 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssembly *assembly)
3977 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
3978 MonoArray *result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, table->rows);
3982 MONO_ARCH_SAVE_REGS;
3984 for (i = 0; i < table->rows; ++i) {
3985 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_MANIFEST_NAME));
3986 mono_array_setref (result, i, mono_string_new (mono_object_domain (assembly), val));
3992 create_version (MonoDomain *domain, guint32 major, guint32 minor, guint32 build, guint32 revision)
3994 static MonoClass *System_Version = NULL;
3995 static MonoMethod *create_version = NULL;
3999 if (!System_Version) {
4000 System_Version = mono_class_from_name (mono_defaults.corlib, "System", "Version");
4001 g_assert (System_Version);
4004 if (!create_version) {
4005 MonoMethodDesc *desc = mono_method_desc_new (":.ctor(int,int,int,int)", FALSE);
4006 create_version = mono_method_desc_search_in_class (desc, System_Version);
4007 g_assert (create_version);
4008 mono_method_desc_free (desc);
4014 args [3] = &revision;
4015 result = mono_object_new (domain, System_Version);
4016 mono_runtime_invoke (create_version, result, args, NULL);
4022 ves_icall_System_Reflection_Assembly_GetReferencedAssemblies (MonoReflectionAssembly *assembly)
4024 static MonoClass *System_Reflection_AssemblyName;
4026 MonoDomain *domain = mono_object_domain (assembly);
4028 static MonoMethod *create_culture = NULL;
4029 MonoImage *image = assembly->assembly->image;
4032 MONO_ARCH_SAVE_REGS;
4034 if (!System_Reflection_AssemblyName)
4035 System_Reflection_AssemblyName = mono_class_from_name (
4036 mono_defaults.corlib, "System.Reflection", "AssemblyName");
4038 t = &assembly->assembly->image->tables [MONO_TABLE_ASSEMBLYREF];
4041 result = mono_array_new (domain, System_Reflection_AssemblyName, count);
4044 MonoMethodDesc *desc = mono_method_desc_new (
4045 "System.Globalization.CultureInfo:CreateSpecificCulture(string)", TRUE);
4046 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4047 g_assert (create_culture);
4048 mono_method_desc_free (desc);
4051 for (i = 0; i < count; i++) {
4052 MonoReflectionAssemblyName *aname;
4053 guint32 cols [MONO_ASSEMBLYREF_SIZE];
4055 mono_metadata_decode_row (t, i, cols, MONO_ASSEMBLYREF_SIZE);
4057 aname = (MonoReflectionAssemblyName *) mono_object_new (
4058 domain, System_Reflection_AssemblyName);
4060 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_NAME])));
4062 aname->major = cols [MONO_ASSEMBLYREF_MAJOR_VERSION];
4063 aname->minor = cols [MONO_ASSEMBLYREF_MINOR_VERSION];
4064 aname->build = cols [MONO_ASSEMBLYREF_BUILD_NUMBER];
4065 aname->revision = cols [MONO_ASSEMBLYREF_REV_NUMBER];
4066 aname->flags = cols [MONO_ASSEMBLYREF_FLAGS];
4067 aname->versioncompat = 1; /* SameMachine (default) */
4068 aname->hashalg = ASSEMBLY_HASH_SHA1; /* SHA1 (default) */
4069 MONO_OBJECT_SETREF (aname, version, create_version (domain, aname->major, aname->minor, aname->build, aname->revision));
4071 if (create_culture) {
4073 args [0] = mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_CULTURE]));
4074 MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
4077 if (cols [MONO_ASSEMBLYREF_PUBLIC_KEY]) {
4078 const gchar *pkey_ptr = mono_metadata_blob_heap (image, cols [MONO_ASSEMBLYREF_PUBLIC_KEY]);
4079 guint32 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
4081 if ((cols [MONO_ASSEMBLYREF_FLAGS] & ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG)) {
4082 /* public key token isn't copied - the class library will
4083 automatically generate it from the public key if required */
4084 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4085 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
4087 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4088 memcpy (mono_array_addr (aname->keyToken, guint8, 0), pkey_ptr, pkey_len);
4092 /* note: this function doesn't return the codebase on purpose (i.e. it can
4093 be used under partial trust as path information isn't present). */
4095 mono_array_setref (result, i, aname);
4106 foreach_namespace (const char* key, gconstpointer val, NameSpaceInfo *info)
4108 MonoString *name = mono_string_new (mono_object_domain (info->res), key);
4110 mono_array_setref (info->res, info->idx, name);
4115 ves_icall_System_Reflection_Assembly_GetNamespaces (MonoReflectionAssembly *assembly)
4117 MonoImage *img = assembly->assembly->image;
4121 MONO_ARCH_SAVE_REGS;
4123 if (!img->name_cache)
4124 mono_image_init_name_cache (img);
4126 res = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, g_hash_table_size (img->name_cache));
4129 g_hash_table_foreach (img->name_cache, (GHFunc)foreach_namespace, &info);
4134 /* move this in some file in mono/util/ */
4136 g_concat_dir_and_file (const char *dir, const char *file)
4138 g_return_val_if_fail (dir != NULL, NULL);
4139 g_return_val_if_fail (file != NULL, NULL);
4142 * If the directory name doesn't have a / on the end, we need
4143 * to add one so we get a proper path to the file
4145 if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
4146 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
4148 return g_strconcat (dir, file, NULL);
4152 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssembly *assembly, MonoString *name, gint32 *size, MonoReflectionModule **ref_module)
4154 char *n = mono_string_to_utf8 (name);
4155 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4157 guint32 cols [MONO_MANIFEST_SIZE];
4158 guint32 impl, file_idx;
4162 MONO_ARCH_SAVE_REGS;
4164 for (i = 0; i < table->rows; ++i) {
4165 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4166 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4167 if (strcmp (val, n) == 0)
4171 if (i == table->rows)
4174 impl = cols [MONO_MANIFEST_IMPLEMENTATION];
4177 * this code should only be called after obtaining the
4178 * ResourceInfo and handling the other cases.
4180 g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
4181 file_idx = impl >> MONO_IMPLEMENTATION_BITS;
4183 module = mono_image_load_file_for_image (assembly->assembly->image, file_idx);
4188 module = assembly->assembly->image;
4190 *ref_module = mono_module_get_object (mono_domain_get (), module);
4192 return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
4196 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoManifestResourceInfo *info)
4198 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4200 guint32 cols [MONO_MANIFEST_SIZE];
4201 guint32 file_cols [MONO_FILE_SIZE];
4205 MONO_ARCH_SAVE_REGS;
4207 n = mono_string_to_utf8 (name);
4208 for (i = 0; i < table->rows; ++i) {
4209 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4210 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4211 if (strcmp (val, n) == 0)
4215 if (i == table->rows)
4218 if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
4219 info->location = RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST;
4222 switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
4223 case MONO_IMPLEMENTATION_FILE:
4224 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4225 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4226 mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
4227 val = mono_metadata_string_heap (assembly->assembly->image, file_cols [MONO_FILE_NAME]);
4228 MONO_OBJECT_SETREF (info, filename, mono_string_new (mono_object_domain (assembly), val));
4229 if (file_cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA)
4232 info->location = RESOURCE_LOCATION_EMBEDDED;
4235 case MONO_IMPLEMENTATION_ASSEMBLYREF:
4236 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4237 mono_assembly_load_reference (assembly->assembly->image, i - 1);
4238 if (assembly->assembly->image->references [i - 1] == (gpointer)-1) {
4239 char *msg = g_strdup_printf ("Assembly %d referenced from assembly %s not found ", i - 1, assembly->assembly->image->name);
4240 MonoException *ex = mono_get_exception_file_not_found2 (msg, NULL);
4242 mono_raise_exception (ex);
4244 MONO_OBJECT_SETREF (info, assembly, mono_assembly_get_object (mono_domain_get (), assembly->assembly->image->references [i - 1]));
4246 /* Obtain info recursively */
4247 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (info->assembly, name, info);
4248 info->location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
4251 case MONO_IMPLEMENTATION_EXP_TYPE:
4252 g_assert_not_reached ();
4261 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoBoolean resource_modules)
4263 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4264 MonoArray *result = NULL;
4269 MONO_ARCH_SAVE_REGS;
4271 /* check hash if needed */
4273 n = mono_string_to_utf8 (name);
4274 for (i = 0; i < table->rows; ++i) {
4275 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4276 if (strcmp (val, n) == 0) {
4279 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4280 fn = mono_string_new (mono_object_domain (assembly), n);
4282 return (MonoObject*)fn;
4290 for (i = 0; i < table->rows; ++i) {
4291 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA))
4295 result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, count);
4298 for (i = 0; i < table->rows; ++i) {
4299 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4300 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4301 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4302 mono_array_setref (result, count, mono_string_new (mono_object_domain (assembly), n));
4307 return (MonoObject*)result;
4311 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly *assembly)
4313 MonoDomain *domain = mono_domain_get();
4316 int i, j, file_count = 0;
4317 MonoImage **modules;
4318 guint32 module_count, real_module_count;
4319 MonoTableInfo *table;
4321 g_assert (assembly->assembly->image != NULL);
4323 if (assembly->assembly->dynamic) {
4324 MonoReflectionAssemblyBuilder *assemblyb = (MonoReflectionAssemblyBuilder*)assembly;
4326 if (assemblyb->modules)
4327 module_count = mono_array_length (assemblyb->modules);
4330 real_module_count = module_count;
4332 modules = g_new0 (MonoImage*, module_count);
4333 if (assemblyb->modules) {
4334 for (i = 0; i < mono_array_length (assemblyb->modules); ++i) {
4336 mono_array_get (assemblyb->modules, MonoReflectionModuleBuilder*, i)->module.image;
4341 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4342 file_count = table->rows;
4344 modules = assembly->assembly->image->modules;
4345 module_count = assembly->assembly->image->module_count;
4347 real_module_count = 0;
4348 for (i = 0; i < module_count; ++i)
4350 real_module_count ++;
4353 klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "Module");
4354 res = mono_array_new (domain, klass, 1 + real_module_count + file_count);
4356 mono_array_setref (res, 0, mono_module_get_object (domain, assembly->assembly->image));
4358 for (i = 0; i < module_count; ++i)
4360 mono_array_setref (res, j, mono_module_get_object (domain, modules[i]));
4364 for (i = 0; i < file_count; ++i, ++j)
4365 mono_array_setref (res, j, mono_module_file_get_object (domain, assembly->assembly->image, i));
4367 if (assembly->assembly->dynamic)
4373 static MonoReflectionMethod*
4374 ves_icall_GetCurrentMethod (void)
4376 MonoMethod *m = mono_method_get_last_managed ();
4378 MONO_ARCH_SAVE_REGS;
4380 return mono_method_get_object (mono_domain_get (), m, NULL);
4383 static MonoReflectionMethod*
4384 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType (MonoMethod *method, MonoType *type)
4386 /* FIXME check that method belongs to klass or a parent */
4389 klass = mono_class_from_mono_type (type);
4391 klass = method->klass;
4392 return mono_method_get_object (mono_domain_get (), method, klass);
4395 static MonoReflectionMethod*
4396 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternal (MonoMethod *method)
4398 return mono_method_get_object (mono_domain_get (), method, NULL);
4401 static MonoReflectionMethodBody*
4402 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod *method)
4404 return mono_method_body_get_object (mono_domain_get (), method);
4407 static MonoReflectionAssembly*
4408 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (void)
4410 MonoMethod *m = mono_method_get_last_managed ();
4412 MONO_ARCH_SAVE_REGS;
4414 return mono_assembly_get_object (mono_domain_get (), m->klass->image->assembly);
4418 static MonoReflectionAssembly*
4419 ves_icall_System_Reflection_Assembly_GetEntryAssembly (void)
4421 MonoDomain* domain = mono_domain_get ();
4423 MONO_ARCH_SAVE_REGS;
4425 if (!domain->entry_assembly)
4428 return mono_assembly_get_object (domain, domain->entry_assembly);
4431 static MonoReflectionAssembly*
4432 ves_icall_System_Reflection_Assembly_GetCallingAssembly (void)
4434 MonoMethod *m = mono_method_get_last_managed ();
4435 MonoMethod *dest = m;
4437 MONO_ARCH_SAVE_REGS;
4439 mono_stack_walk_no_il (get_caller, &dest);
4442 return mono_assembly_get_object (mono_domain_get (), dest->klass->image->assembly);
4446 ves_icall_System_MonoType_getFullName (MonoReflectionType *object, gboolean full_name,
4447 gboolean assembly_qualified)
4449 MonoDomain *domain = mono_object_domain (object);
4450 MonoTypeNameFormat format;
4454 MONO_ARCH_SAVE_REGS;
4456 format = assembly_qualified ?
4457 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
4458 MONO_TYPE_NAME_FORMAT_FULL_NAME;
4460 format = MONO_TYPE_NAME_FORMAT_REFLECTION;
4462 name = mono_type_get_name_full (object->type, format);
4466 if (full_name && (object->type->type == MONO_TYPE_VAR || object->type->type == MONO_TYPE_MVAR))
4469 res = mono_string_new (domain, name);
4476 fill_reflection_assembly_name (MonoDomain *domain, MonoReflectionAssemblyName *aname, MonoAssemblyName *name, const char *absolute, gboolean by_default_version)
4478 static MonoMethod *create_culture = NULL;
4481 const char *pkey_ptr;
4484 MONO_ARCH_SAVE_REGS;
4486 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, name->name));
4487 aname->major = name->major;
4488 aname->minor = name->minor;
4489 aname->build = name->build;
4490 aname->revision = name->revision;
4491 aname->hashalg = name->hash_alg;
4492 if (by_default_version)
4493 MONO_OBJECT_SETREF (aname, version, create_version (domain, name->major, name->minor, name->build, name->revision));
4495 codebase = g_filename_to_uri (absolute, NULL, NULL);
4497 MONO_OBJECT_SETREF (aname, codebase, mono_string_new (domain, codebase));
4501 if (!create_culture) {
4502 MonoMethodDesc *desc = mono_method_desc_new ("System.Globalization.CultureInfo:CreateSpecificCulture(string)", TRUE);
4503 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4504 g_assert (create_culture);
4505 mono_method_desc_free (desc);
4508 if (name->culture) {
4509 args [0] = mono_string_new (domain, name->culture);
4510 MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
4513 if (name->public_key) {
4514 pkey_ptr = (char*)name->public_key;
4515 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
4517 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4518 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
4521 /* MonoAssemblyName keeps the public key token as an hexadecimal string */
4522 if (name->public_key_token [0]) {
4526 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, 8));
4527 p = mono_array_addr (aname->keyToken, char, 0);
4529 for (i = 0, j = 0; i < 8; i++) {
4530 *p = g_ascii_xdigit_value (name->public_key_token [j++]) << 4;
4531 *p |= g_ascii_xdigit_value (name->public_key_token [j++]);
4538 ves_icall_System_Reflection_Assembly_FillName (MonoReflectionAssembly *assembly, MonoReflectionAssemblyName *aname)
4541 MonoAssembly *mass = assembly->assembly;
4543 MONO_ARCH_SAVE_REGS;
4545 if (g_path_is_absolute (mass->image->name)) {
4546 fill_reflection_assembly_name (mono_object_domain (assembly),
4547 aname, &mass->aname, mass->image->name, TRUE);
4550 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4552 fill_reflection_assembly_name (mono_object_domain (assembly),
4553 aname, &mass->aname, absolute, TRUE);
4559 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoString *fname, MonoReflectionAssemblyName *aname)
4562 MonoImageOpenStatus status = MONO_IMAGE_OK;
4565 MonoAssemblyName name;
4567 MONO_ARCH_SAVE_REGS;
4569 filename = mono_string_to_utf8 (fname);
4571 image = mono_image_open (filename, &status);
4577 if (status == MONO_IMAGE_IMAGE_INVALID)
4578 exc = mono_get_exception_bad_image_format2 (NULL, fname);
4580 exc = mono_get_exception_file_not_found2 (NULL, fname);
4581 mono_raise_exception (exc);
4584 res = mono_assembly_fill_assembly_name (image, &name);
4586 mono_image_close (image);
4588 mono_raise_exception (mono_get_exception_argument ("assemblyFile", "The file does not contain a manifest"));
4591 fill_reflection_assembly_name (mono_domain_get (), aname, &name, filename, TRUE);
4594 mono_image_close (image);
4598 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssembly *assembly,
4599 char **minimum, guint32 *minLength, char **optional, guint32 *optLength, char **refused, guint32 *refLength)
4601 MonoBoolean result = FALSE;
4602 MonoDeclSecurityEntry entry;
4604 /* SecurityAction.RequestMinimum */
4605 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQMIN, &entry)) {
4606 *minimum = entry.blob;
4607 *minLength = entry.size;
4610 /* SecurityAction.RequestOptional */
4611 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQOPT, &entry)) {
4612 *optional = entry.blob;
4613 *optLength = entry.size;
4616 /* SecurityAction.RequestRefuse */
4617 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQREFUSE, &entry)) {
4618 *refused = entry.blob;
4619 *refLength = entry.size;
4627 mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoBoolean exportedOnly)
4631 MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
4633 guint32 attrs, visibility;
4635 /* we start the count from 1 because we skip the special type <Module> */
4638 for (i = 1; i < tdef->rows; ++i) {
4639 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
4640 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
4641 if (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)
4645 count = tdef->rows - 1;
4647 res = mono_array_new (domain, mono_defaults.monotype_class, count);
4649 for (i = 1; i < tdef->rows; ++i) {
4650 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
4651 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
4652 if (!exportedOnly || (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)) {
4653 klass = mono_class_get_throw (image, (i + 1) | MONO_TOKEN_TYPE_DEF);
4654 if (mono_loader_get_last_error ())
4655 mono_loader_clear_error ();
4656 mono_array_setref (res, count, mono_type_get_object (domain, &klass->byval_arg));
4665 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly, MonoBoolean exportedOnly)
4667 MonoArray *res = NULL;
4668 MonoImage *image = NULL;
4669 MonoTableInfo *table = NULL;
4674 MONO_ARCH_SAVE_REGS;
4676 domain = mono_object_domain (assembly);
4678 if (assembly->assembly->dynamic) {
4679 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
4680 if (abuilder->modules) {
4681 for (i = 0; i < mono_array_length(abuilder->modules); i++) {
4682 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
4683 MonoArray *append = mb->types;
4684 /* The types array might not be fully filled up */
4685 if (append && mb->num_types > 0) {
4688 len1 = res ? mono_array_length (res) : 0;
4689 len2 = mb->num_types;
4690 new = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4692 mono_array_memcpy_refs (new, 0, res, 0, len1);
4693 mono_array_memcpy_refs (new, len1, append, 0, len2);
4699 * Replace TypeBuilders with the created types to be compatible
4703 for (i = 0; i < mono_array_length (res); ++i) {
4704 MonoReflectionTypeBuilder *tb = mono_array_get (res, MonoReflectionTypeBuilder*, i);
4706 mono_array_setref (res, i, tb->created);
4711 if (abuilder->loaded_modules)
4712 for (i = 0; i < mono_array_length(abuilder->loaded_modules); i++) {
4713 MonoReflectionModule *rm = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
4714 MonoArray *append = mono_module_get_types (domain, rm->image, exportedOnly);
4715 if (append && mono_array_length (append) > 0) {
4718 len1 = res ? mono_array_length (res) : 0;
4719 len2 = mono_array_length (append);
4720 new = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4722 mono_array_memcpy_refs (new, 0, res, 0, len1);
4723 mono_array_memcpy_refs (new, len1, append, 0, len2);
4730 return mono_array_new (domain, mono_defaults.monotype_class, 0);
4732 image = assembly->assembly->image;
4733 table = &image->tables [MONO_TABLE_FILE];
4734 res = mono_module_get_types (domain, image, exportedOnly);
4736 /* Append data from all modules in the assembly */
4737 for (i = 0; i < table->rows; ++i) {
4738 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4739 MonoImage *loaded_image = mono_assembly_load_module (image->assembly, i + 1);
4741 MonoArray *res2 = mono_module_get_types (domain, loaded_image, exportedOnly);
4742 /* Append the new types to the end of the array */
4743 if (mono_array_length (res2) > 0) {
4747 len1 = mono_array_length (res);
4748 len2 = mono_array_length (res2);
4749 res3 = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4750 mono_array_memcpy_refs (res3, 0, res, 0, len1);
4751 mono_array_memcpy_refs (res3, len1, res2, 0, len2);
4758 /* the ReflectionTypeLoadException must have all the types (Types property),
4759 * NULL replacing types which throws an exception. The LoaderException must
4760 * contain all exceptions for NULL items.
4763 len = mono_array_length (res);
4765 for (i = 0; i < len; i++) {
4766 MonoReflectionType *t = mono_array_get (res, gpointer, i);
4767 MonoClass *klass = mono_type_get_class (t->type);
4768 if ((klass != NULL) && klass->exception_type) {
4769 /* keep the class in the list */
4770 list = g_list_append (list, klass);
4771 /* and replace Type with NULL */
4772 mono_array_setref (res, i, NULL);
4778 MonoException *exc = NULL;
4779 MonoArray *exl = NULL;
4780 int length = g_list_length (list);
4782 mono_loader_clear_error ();
4784 exl = mono_array_new (domain, mono_defaults.exception_class, length);
4785 for (i = 0, tmp = list; i < length; i++, tmp = tmp->next) {
4786 MonoException *exc = mono_class_get_exception_for_failure (tmp->data);
4787 mono_array_setref (exl, i, exc);
4792 exc = mono_get_exception_reflection_type_load (res, exl);
4793 mono_loader_clear_error ();
4794 mono_raise_exception (exc);
4801 ves_icall_System_Reflection_AssemblyName_ParseName (MonoReflectionAssemblyName *name, MonoString *assname)
4803 MonoAssemblyName aname;
4804 MonoDomain *domain = mono_object_domain (name);
4806 gboolean is_version_defined;
4808 val = mono_string_to_utf8 (assname);
4809 if (!mono_assembly_name_parse_full (val, &aname, TRUE, &is_version_defined))
4812 fill_reflection_assembly_name (domain, name, &aname, "", is_version_defined);
4814 mono_assembly_name_free (&aname);
4815 g_free ((guint8*) aname.public_key);
4821 static MonoReflectionType*
4822 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModule *module)
4824 MonoDomain *domain = mono_object_domain (module);
4827 MONO_ARCH_SAVE_REGS;
4829 g_assert (module->image);
4831 if (module->image->dynamic && ((MonoDynamicImage*)(module->image))->initial_image)
4832 /* These images do not have a global type */
4835 klass = mono_class_get (module->image, 1 | MONO_TOKEN_TYPE_DEF);
4836 return mono_type_get_object (domain, &klass->byval_arg);
4840 ves_icall_System_Reflection_Module_Close (MonoReflectionModule *module)
4842 /*if (module->image)
4843 mono_image_close (module->image);*/
4847 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModule *module)
4849 MonoDomain *domain = mono_object_domain (module);
4851 MONO_ARCH_SAVE_REGS;
4853 g_assert (module->image);
4854 return mono_string_new (domain, module->image->guid);
4858 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine)
4860 if (image->dynamic) {
4861 MonoDynamicImage *dyn = (MonoDynamicImage*)image;
4862 *pe_kind = dyn->pe_kind;
4863 *machine = dyn->machine;
4866 *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
4867 *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
4872 ves_icall_System_Reflection_Module_get_MDStreamVersion (MonoReflectionModule *module)
4874 MonoImage *image = module->image;
4877 mono_raise_exception (mono_get_exception_not_supported (""));
4879 return (image->md_version_major << 16) | (image->md_version_minor);
4883 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModule *module)
4885 MONO_ARCH_SAVE_REGS;
4888 return mono_array_new (mono_object_domain (module), mono_defaults.monotype_class, 0);
4890 return mono_module_get_types (mono_object_domain (module), module->image, FALSE);
4894 mono_metadata_memberref_is_method (MonoImage *image, guint32 token)
4896 guint32 cols [MONO_MEMBERREF_SIZE];
4898 mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
4899 sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
4900 mono_metadata_decode_blob_size (sig, &sig);
4901 return (*sig != 0x6);
4905 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
4908 int table = mono_metadata_token_table (token);
4909 int index = mono_metadata_token_index (token);
4911 *error = ResolveTokenError_Other;
4913 /* Validate token */
4914 if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) &&
4915 (table != MONO_TABLE_TYPESPEC)) {
4916 *error = ResolveTokenError_BadTable;
4921 return mono_lookup_dynamic_token (image, token);
4923 if ((index <= 0) || (index > image->tables [table].rows)) {
4924 *error = ResolveTokenError_OutOfRange;
4928 klass = mono_class_get (image, token);
4930 return &klass->byval_arg;
4936 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
4938 int table = mono_metadata_token_table (token);
4939 int index = mono_metadata_token_index (token);
4941 *error = ResolveTokenError_Other;
4943 /* Validate token */
4944 if ((table != MONO_TABLE_METHOD) && (table != MONO_TABLE_METHODSPEC) &&
4945 (table != MONO_TABLE_MEMBERREF)) {
4946 *error = ResolveTokenError_BadTable;
4951 /* FIXME: validate memberref token type */
4952 return mono_lookup_dynamic_token (image, token);
4954 if ((index <= 0) || (index > image->tables [table].rows)) {
4955 *error = ResolveTokenError_OutOfRange;
4958 if ((table == MONO_TABLE_MEMBERREF) && (!mono_metadata_memberref_is_method (image, token))) {
4959 *error = ResolveTokenError_BadTable;
4963 return mono_get_method (image, token, NULL);
4967 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
4969 int index = mono_metadata_token_index (token);
4971 *error = ResolveTokenError_Other;
4973 /* Validate token */
4974 if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
4975 *error = ResolveTokenError_BadTable;
4980 return mono_lookup_dynamic_token (image, token);
4982 if ((index <= 0) || (index >= image->heap_us.size)) {
4983 *error = ResolveTokenError_OutOfRange;
4987 /* FIXME: What to do if the index points into the middle of a string ? */
4989 return mono_ldstr (mono_domain_get (), image, index);
4992 static MonoClassField*
4993 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
4996 int table = mono_metadata_token_table (token);
4997 int index = mono_metadata_token_index (token);
4999 *error = ResolveTokenError_Other;
5001 /* Validate token */
5002 if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
5003 *error = ResolveTokenError_BadTable;
5008 /* FIXME: validate memberref token type */
5009 return mono_lookup_dynamic_token (image, token);
5011 if ((index <= 0) || (index > image->tables [table].rows)) {
5012 *error = ResolveTokenError_OutOfRange;
5015 if ((table == MONO_TABLE_MEMBERREF) && (mono_metadata_memberref_is_method (image, token))) {
5016 *error = ResolveTokenError_BadTable;
5020 return mono_field_from_token (image, token, &klass, NULL);
5025 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
5027 int table = mono_metadata_token_table (token);
5029 *error = ResolveTokenError_Other;
5032 case MONO_TABLE_TYPEDEF:
5033 case MONO_TABLE_TYPEREF:
5034 case MONO_TABLE_TYPESPEC: {
5035 MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, error);
5037 return (MonoObject*)mono_type_get_object (mono_domain_get (), t);
5041 case MONO_TABLE_METHOD:
5042 case MONO_TABLE_METHODSPEC: {
5043 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, error);
5045 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
5049 case MONO_TABLE_FIELD: {
5050 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, error);
5052 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
5056 case MONO_TABLE_MEMBERREF:
5057 if (mono_metadata_memberref_is_method (image, token)) {
5058 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, error);
5060 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
5065 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, error);
5067 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
5074 *error = ResolveTokenError_BadTable;
5080 static MonoReflectionType*
5081 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
5084 int isbyref = 0, rank;
5085 char *str = mono_string_to_utf8 (smodifiers);
5088 MONO_ARCH_SAVE_REGS;
5090 klass = mono_class_from_mono_type (tb->type.type);
5092 /* logic taken from mono_reflection_parse_type(): keep in sync */
5096 if (isbyref) { /* only one level allowed by the spec */
5103 return mono_type_get_object (mono_object_domain (tb), &klass->this_arg);
5106 klass = mono_ptr_class_get (&klass->byval_arg);
5107 mono_class_init (klass);
5118 else if (*p != '*') { /* '*' means unknown lower bound */
5129 klass = mono_array_class_get (klass, rank);
5130 mono_class_init (klass);
5137 return mono_type_get_object (mono_object_domain (tb), &klass->byval_arg);
5141 ves_icall_Type_IsArrayImpl (MonoReflectionType *t)
5146 MONO_ARCH_SAVE_REGS;
5149 res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
5154 static MonoReflectionType *
5155 ves_icall_Type_make_array_type (MonoReflectionType *type, int rank)
5157 MonoClass *klass, *aklass;
5159 MONO_ARCH_SAVE_REGS;
5161 klass = mono_class_from_mono_type (type->type);
5162 aklass = mono_array_class_get (klass, rank);
5164 return mono_type_get_object (mono_object_domain (type), &aklass->byval_arg);
5167 static MonoReflectionType *
5168 ves_icall_Type_make_byref_type (MonoReflectionType *type)
5172 MONO_ARCH_SAVE_REGS;
5174 klass = mono_class_from_mono_type (type->type);
5176 return mono_type_get_object (mono_object_domain (type), &klass->this_arg);
5179 static MonoReflectionType *
5180 ves_icall_Type_MakePointerType (MonoReflectionType *type)
5184 MONO_ARCH_SAVE_REGS;
5186 pklass = mono_ptr_class_get (type->type);
5188 return mono_type_get_object (mono_object_domain (type), &pklass->byval_arg);
5192 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
5193 MonoReflectionMethod *info)
5195 MonoClass *delegate_class = mono_class_from_mono_type (type->type);
5196 MonoObject *delegate;
5199 MONO_ARCH_SAVE_REGS;
5201 mono_assert (delegate_class->parent == mono_defaults.multicastdelegate_class);
5203 delegate = mono_object_new (mono_object_domain (type), delegate_class);
5205 func = mono_compile_method (info->method);
5207 mono_delegate_ctor (delegate, target, func);
5213 ves_icall_System_Delegate_SetMulticastInvoke (MonoDelegate *this)
5218 /* Find the Invoke method */
5220 while ((invoke = mono_class_get_methods (this->object.vtable->klass, &iter))) {
5221 if (!strcmp (invoke->name, "Invoke"))
5226 this->invoke_impl = mono_compile_method (mono_marshal_get_delegate_invoke (invoke));
5230 * Magic number to convert a time which is relative to
5231 * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
5233 #define EPOCH_ADJUST ((guint64)62135596800LL)
5236 * Magic number to convert FILETIME base Jan 1, 1601 to DateTime - base Jan, 1, 0001
5238 #define FILETIME_ADJUST ((guint64)504911232000000000LL)
5241 * This returns Now in UTC
5244 ves_icall_System_DateTime_GetNow (void)
5246 #ifdef PLATFORM_WIN32
5250 GetSystemTime (&st);
5251 SystemTimeToFileTime (&st, &ft);
5252 return (gint64) FILETIME_ADJUST + ((((gint64)ft.dwHighDateTime)<<32) | ft.dwLowDateTime);
5254 /* FIXME: put this in io-layer and call it GetLocalTime */
5258 MONO_ARCH_SAVE_REGS;
5260 if (gettimeofday (&tv, NULL) == 0) {
5261 res = (((gint64)tv.tv_sec + EPOCH_ADJUST)* 1000000 + tv.tv_usec)*10;
5264 /* fixme: raise exception */
5269 #ifdef PLATFORM_WIN32
5270 /* convert a SYSTEMTIME which is of the form "last thursday in october" to a real date */
5272 convert_to_absolute_date(SYSTEMTIME *date)
5274 #define IS_LEAP(y) ((y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0))
5275 static int days_in_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5276 static int leap_days_in_month[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5277 /* from the calendar FAQ */
5278 int a = (14 - date->wMonth) / 12;
5279 int y = date->wYear - a;
5280 int m = date->wMonth + 12 * a - 2;
5281 int d = (1 + y + y/4 - y/100 + y/400 + (31*m)/12) % 7;
5283 /* d is now the day of the week for the first of the month (0 == Sunday) */
5285 int day_of_week = date->wDayOfWeek;
5287 /* set day_in_month to the first day in the month which falls on day_of_week */
5288 int day_in_month = 1 + (day_of_week - d);
5289 if (day_in_month <= 0)
5292 /* wDay is 1 for first weekday in month, 2 for 2nd ... 5 means last - so work that out allowing for days in the month */
5293 date->wDay = day_in_month + (date->wDay - 1) * 7;
5294 if (date->wDay > (IS_LEAP(date->wYear) ? leap_days_in_month[date->wMonth - 1] : days_in_month[date->wMonth - 1]))
5299 #ifndef PLATFORM_WIN32
5301 * Return's the offset from GMT of a local time.
5303 * tm is a local time
5304 * t is the same local time as seconds.
5307 gmt_offset(struct tm *tm, time_t t)
5309 #if defined (HAVE_TM_GMTOFF)
5310 return tm->tm_gmtoff;
5315 g.tm_isdst = tm->tm_isdst;
5317 return (int)difftime(t, t2);
5322 * This is heavily based on zdump.c from glibc 2.2.
5324 * * data[0]: start of daylight saving time (in DateTime ticks).
5325 * * data[1]: end of daylight saving time (in DateTime ticks).
5326 * * data[2]: utcoffset (in TimeSpan ticks).
5327 * * data[3]: additional offset when daylight saving (in TimeSpan ticks).
5328 * * name[0]: name of this timezone when not daylight saving.
5329 * * name[1]: name of this timezone when daylight saving.
5331 * FIXME: This only works with "standard" Unix dates (years between 1900 and 2100) while
5332 * the class library allows years between 1 and 9999.
5334 * Returns true on success and zero on failure.
5337 ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year, MonoArray **data, MonoArray **names)
5339 #ifndef PLATFORM_WIN32
5340 MonoDomain *domain = mono_domain_get ();
5341 struct tm start, tt;
5345 int is_daylight = 0, day;
5348 MONO_ARCH_SAVE_REGS;
5350 MONO_CHECK_ARG_NULL (data);
5351 MONO_CHECK_ARG_NULL (names);
5353 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5354 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5357 * no info is better than crashing: we'll need our own tz data
5358 * to make this work properly, anyway. The range is probably
5359 * reduced to 1970 .. 2037 because that is what mktime is
5360 * guaranteed to support (we get into an infinite loop
5364 memset (&start, 0, sizeof (start));
5367 start.tm_year = year-1900;
5369 t = mktime (&start);
5371 if ((year < 1970) || (year > 2037) || (t == -1)) {
5373 tt = *localtime (&t);
5374 strftime (tzone, sizeof (tzone), "%Z", &tt);
5375 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5376 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5380 gmtoff = gmt_offset (&start, t);
5382 /* For each day of the year, calculate the tm_gmtoff. */
5383 for (day = 0; day < 365; day++) {
5386 tt = *localtime (&t);
5388 /* Daylight saving starts or ends here. */
5389 if (gmt_offset (&tt, t) != gmtoff) {
5393 /* Try to find the exact hour when daylight saving starts/ends. */
5397 tt1 = *localtime (&t1);
5398 } while (gmt_offset (&tt1, t1) != gmtoff);
5400 /* Try to find the exact minute when daylight saving starts/ends. */
5403 tt1 = *localtime (&t1);
5404 } while (gmt_offset (&tt1, t1) == gmtoff);
5406 strftime (tzone, sizeof (tzone), "%Z", &tt);
5408 /* Write data, if we're already in daylight saving, we're done. */
5410 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5411 mono_array_set ((*data), gint64, 1, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
5414 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5415 mono_array_set ((*data), gint64, 0, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
5419 /* This is only set once when we enter daylight saving. */
5420 mono_array_set ((*data), gint64, 2, (gint64)gmtoff * 10000000L);
5421 mono_array_set ((*data), gint64, 3, (gint64)(gmt_offset (&tt, t) - gmtoff) * 10000000L);
5423 gmtoff = gmt_offset (&tt, t);
5428 strftime (tzone, sizeof (tzone), "%Z", &tt);
5429 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5430 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5431 mono_array_set ((*data), gint64, 0, 0);
5432 mono_array_set ((*data), gint64, 1, 0);
5433 mono_array_set ((*data), gint64, 2, (gint64) gmtoff * 10000000L);
5434 mono_array_set ((*data), gint64, 3, 0);
5439 MonoDomain *domain = mono_domain_get ();
5440 TIME_ZONE_INFORMATION tz_info;
5445 tz_id = GetTimeZoneInformation (&tz_info);
5446 if (tz_id == TIME_ZONE_ID_INVALID)
5449 MONO_CHECK_ARG_NULL (data);
5450 MONO_CHECK_ARG_NULL (names);
5452 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5453 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5455 for (i = 0; i < 32; ++i)
5456 if (!tz_info.DaylightName [i])
5458 mono_array_setref ((*names), 1, mono_string_new_utf16 (domain, tz_info.DaylightName, i));
5459 for (i = 0; i < 32; ++i)
5460 if (!tz_info.StandardName [i])
5462 mono_array_setref ((*names), 0, mono_string_new_utf16 (domain, tz_info.StandardName, i));
5464 if ((year <= 1601) || (year > 30827)) {
5466 * According to MSDN, the MS time functions can't handle dates outside
5472 /* even if the timezone has no daylight savings it may have Bias (e.g. GMT+13 it seems) */
5473 if (tz_id != TIME_ZONE_ID_UNKNOWN) {
5474 tz_info.StandardDate.wYear = year;
5475 convert_to_absolute_date(&tz_info.StandardDate);
5476 err = SystemTimeToFileTime (&tz_info.StandardDate, &ft);
5478 mono_array_set ((*data), gint64, 1, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
5479 tz_info.DaylightDate.wYear = year;
5480 convert_to_absolute_date(&tz_info.DaylightDate);
5481 err = SystemTimeToFileTime (&tz_info.DaylightDate, &ft);
5483 mono_array_set ((*data), gint64, 0, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
5485 mono_array_set ((*data), gint64, 2, (tz_info.Bias + tz_info.StandardBias) * -600000000LL);
5486 mono_array_set ((*data), gint64, 3, (tz_info.DaylightBias - tz_info.StandardBias) * -600000000LL);
5493 ves_icall_System_Object_obj_address (MonoObject *this)
5495 MONO_ARCH_SAVE_REGS;
5502 static inline gint32
5503 mono_array_get_byte_length (MonoArray *array)
5509 klass = array->obj.vtable->klass;
5511 if (array->bounds == NULL)
5512 length = array->max_length;
5515 for (i = 0; i < klass->rank; ++ i)
5516 length *= array->bounds [i].length;
5519 switch (klass->element_class->byval_arg.type) {
5522 case MONO_TYPE_BOOLEAN:
5526 case MONO_TYPE_CHAR:
5534 return length * sizeof (gpointer);
5545 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array)
5547 MONO_ARCH_SAVE_REGS;
5549 return mono_array_get_byte_length (array);
5553 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx)
5555 MONO_ARCH_SAVE_REGS;
5557 return mono_array_get (array, gint8, idx);
5561 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value)
5563 MONO_ARCH_SAVE_REGS;
5565 mono_array_set (array, gint8, idx, value);
5569 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count)
5571 guint8 *src_buf, *dest_buf;
5573 MONO_ARCH_SAVE_REGS;
5575 /* watch out for integer overflow */
5576 if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count))
5579 src_buf = (guint8 *)src->vector + src_offset;
5580 dest_buf = (guint8 *)dest->vector + dest_offset;
5583 memcpy (dest_buf, src_buf, count);
5585 memmove (dest_buf, src_buf, count); /* Source and dest are the same array */
5591 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this, MonoString *class_name)
5593 MonoDomain *domain = mono_object_domain (this);
5595 MonoRealProxy *rp = ((MonoRealProxy *)this);
5596 MonoTransparentProxy *tp;
5600 MONO_ARCH_SAVE_REGS;
5602 res = mono_object_new (domain, mono_defaults.transparent_proxy_class);
5603 tp = (MonoTransparentProxy*) res;
5605 MONO_OBJECT_SETREF (tp, rp, rp);
5606 type = ((MonoReflectionType *)rp->class_to_proxy)->type;
5607 klass = mono_class_from_mono_type (type);
5609 tp->custom_type_info = (mono_object_isinst (this, mono_defaults.iremotingtypeinfo_class) != NULL);
5610 tp->remote_class = mono_remote_class (domain, class_name, klass);
5612 res->vtable = mono_remote_class_vtable (domain, tp->remote_class, rp);
5616 static MonoReflectionType *
5617 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
5619 return mono_type_get_object (mono_object_domain (tp), &tp->remote_class->proxy_class->byval_arg);
5622 /* System.Environment */
5625 ves_icall_System_Environment_get_MachineName (void)
5627 #if defined (PLATFORM_WIN32)
5632 len = MAX_COMPUTERNAME_LENGTH + 1;
5633 buf = g_new (gunichar2, len);
5636 if (GetComputerName (buf, (PDWORD) &len))
5637 result = mono_string_new_utf16 (mono_domain_get (), buf, len);
5645 if (gethostname (buf, sizeof (buf)) == 0)
5646 result = mono_string_new (mono_domain_get (), buf);
5655 ves_icall_System_Environment_get_Platform (void)
5657 MONO_ARCH_SAVE_REGS;
5659 #if defined (PLATFORM_WIN32)
5669 ves_icall_System_Environment_get_NewLine (void)
5671 MONO_ARCH_SAVE_REGS;
5673 #if defined (PLATFORM_WIN32)
5674 return mono_string_new (mono_domain_get (), "\r\n");
5676 return mono_string_new (mono_domain_get (), "\n");
5681 ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name)
5686 MONO_ARCH_SAVE_REGS;
5691 utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
5692 value = g_getenv (utf8_name);
5699 return mono_string_new (mono_domain_get (), value);
5703 * There is no standard way to get at environ.
5706 #ifndef __MINGW32_VERSION
5713 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
5721 MONO_ARCH_SAVE_REGS;
5724 for (e = environ; *e != 0; ++ e)
5727 domain = mono_domain_get ();
5728 names = mono_array_new (domain, mono_defaults.string_class, n);
5731 for (e = environ; *e != 0; ++ e) {
5732 parts = g_strsplit (*e, "=", 2);
5734 str = mono_string_new (domain, *parts);
5735 mono_array_setref (names, n, str);
5747 * If your platform lacks setenv/unsetenv, you must upgrade your glib.
5749 #if !GLIB_CHECK_VERSION(2,4,0)
5750 #define g_setenv(a,b,c) setenv(a,b,c)
5751 #define g_unsetenv(a) unsetenv(a)
5755 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
5757 #ifdef PLATFORM_WIN32
5758 gunichar2 *utf16_name, *utf16_value;
5760 gchar *utf8_name, *utf8_value;
5763 MONO_ARCH_SAVE_REGS;
5765 #ifdef PLATFORM_WIN32
5766 utf16_name = mono_string_to_utf16 (name);
5767 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
5768 SetEnvironmentVariable (utf16_name, NULL);
5769 g_free (utf16_name);
5773 utf16_value = mono_string_to_utf16 (value);
5775 SetEnvironmentVariable (utf16_name, utf16_value);
5777 g_free (utf16_name);
5778 g_free (utf16_value);
5780 utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
5782 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
5783 g_unsetenv (utf8_name);
5788 utf8_value = mono_string_to_utf8 (value);
5789 g_setenv (utf8_name, utf8_value, TRUE);
5792 g_free (utf8_value);
5797 * Returns: the number of milliseconds elapsed since the system started.
5800 ves_icall_System_Environment_get_TickCount (void)
5802 return GetTickCount ();
5807 ves_icall_System_Environment_Exit (int result)
5809 MONO_ARCH_SAVE_REGS;
5811 mono_runtime_set_shutting_down ();
5813 /* Suspend all managed threads since the runtime is going away */
5814 mono_thread_suspend_all_other_threads ();
5816 mono_runtime_quit ();
5818 /* we may need to do some cleanup here... */
5823 ves_icall_System_Environment_GetGacPath (void)
5825 return mono_string_new (mono_domain_get (), mono_assembly_getrootdir ());
5829 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
5831 #if defined (PLATFORM_WIN32)
5832 #ifndef CSIDL_FLAG_CREATE
5833 #define CSIDL_FLAG_CREATE 0x8000
5836 WCHAR path [MAX_PATH];
5837 /* Create directory if no existing */
5838 if (SUCCEEDED (SHGetFolderPathW (NULL, folder | CSIDL_FLAG_CREATE, NULL, 0, path))) {
5842 return mono_string_new_utf16 (mono_domain_get (), path, len);
5845 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
5847 return mono_string_new (mono_domain_get (), "");
5851 ves_icall_System_Environment_GetLogicalDrives (void)
5853 gunichar2 buf [128], *ptr, *dname;
5855 gint initial_size = 127, size = 128;
5858 MonoString *drivestr;
5859 MonoDomain *domain = mono_domain_get ();
5862 MONO_ARCH_SAVE_REGS;
5867 while (size > initial_size) {
5868 size = GetLogicalDriveStrings (initial_size, ptr);
5869 if (size > initial_size) {
5872 ptr = g_malloc0 ((size + 1) * sizeof (gunichar2));
5873 initial_size = size;
5887 result = mono_array_new (domain, mono_defaults.string_class, ndrives);
5892 while (*u16) { u16++; len ++; }
5893 drivestr = mono_string_new_utf16 (domain, dname, len);
5894 mono_array_setref (result, ndrives++, drivestr);
5905 ves_icall_System_Environment_InternalGetHome (void)
5907 MONO_ARCH_SAVE_REGS;
5909 return mono_string_new (mono_domain_get (), g_get_home_dir ());
5912 static const char *encodings [] = {
5914 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
5915 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
5916 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
5918 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
5919 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
5920 "x_unicode_2_0_utf_7",
5922 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
5923 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
5925 "utf_16", "UTF_16LE", "ucs_2", "unicode",
5928 "unicodefffe", "utf_16be",
5935 * Returns the internal codepage, if the value of "int_code_page" is
5936 * 1 at entry, and we can not compute a suitable code page number,
5937 * returns the code page as a string
5940 ves_icall_System_Text_Encoding_InternalCodePage (gint32 *int_code_page)
5945 char *codepage = NULL;
5947 int want_name = *int_code_page;
5950 *int_code_page = -1;
5951 MONO_ARCH_SAVE_REGS;
5953 g_get_charset (&cset);
5954 c = codepage = strdup (cset);
5955 for (c = codepage; *c; c++){
5956 if (isascii (*c) && isalpha (*c))
5961 /* g_print ("charset: %s\n", cset); */
5963 /* handle some common aliases */
5966 for (i = 0; p != 0; ){
5967 if ((gssize) p < 7){
5969 p = encodings [++i];
5972 if (strcmp (p, codepage) == 0){
5973 *int_code_page = code;
5976 p = encodings [++i];
5979 if (strstr (codepage, "utf_8") != NULL)
5980 *int_code_page |= 0x10000000;
5983 if (want_name && *int_code_page == -1)
5984 return mono_string_new (mono_domain_get (), cset);
5990 ves_icall_System_Environment_get_HasShutdownStarted (void)
5992 if (mono_runtime_is_shutting_down ())
5995 if (mono_domain_is_unloading (mono_domain_get ()))
6002 ves_icall_MonoMethodMessage_InitMessage (MonoMethodMessage *this,
6003 MonoReflectionMethod *method,
6004 MonoArray *out_args)
6006 MONO_ARCH_SAVE_REGS;
6008 mono_message_init (mono_object_domain (this), this, method, out_args);
6012 ves_icall_IsTransparentProxy (MonoObject *proxy)
6014 MONO_ARCH_SAVE_REGS;
6019 if (proxy->vtable->klass == mono_defaults.transparent_proxy_class)
6026 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6031 MONO_ARCH_SAVE_REGS;
6033 klass = mono_class_from_mono_type (type->type);
6034 vtable = mono_class_vtable (mono_domain_get (), klass);
6036 if (enable) vtable->remote = 1;
6037 else vtable->remote = 0;
6041 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type)
6046 MONO_ARCH_SAVE_REGS;
6048 domain = mono_object_domain (type);
6049 klass = mono_class_from_mono_type (type->type);
6051 if (klass->rank >= 1) {
6052 g_assert (klass->rank == 1);
6053 return (MonoObject *) mono_array_new (domain, klass->element_class, 0);
6055 /* Bypass remoting object creation check */
6056 return mono_object_new_alloc_specific (mono_class_vtable (domain, klass));
6061 ves_icall_System_IO_get_temp_path (void)
6063 MONO_ARCH_SAVE_REGS;
6065 return mono_string_new (mono_domain_get (), g_get_tmp_dir ());
6069 ves_icall_RuntimeMethod_GetFunctionPointer (MonoMethod *method)
6071 MONO_ARCH_SAVE_REGS;
6073 return mono_compile_method (method);
6077 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
6082 MONO_ARCH_SAVE_REGS;
6084 path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
6086 #if defined (PLATFORM_WIN32)
6087 /* Avoid mixing '/' and '\\' */
6090 for (i = strlen (path) - 1; i >= 0; i--)
6091 if (path [i] == '/')
6095 mcpath = mono_string_new (mono_domain_get (), path);
6102 ves_icall_System_Configuration_DefaultConfig_get_bundled_machine_config (void)
6104 const gchar *machine_config;
6106 MONO_ARCH_SAVE_REGS;
6108 machine_config = mono_get_machine_config ();
6110 if (!machine_config)
6113 return mono_string_new (mono_domain_get (), machine_config);
6117 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
6122 MONO_ARCH_SAVE_REGS;
6124 path = g_path_get_dirname (mono_get_config_dir ());
6126 #if defined (PLATFORM_WIN32)
6127 /* Avoid mixing '/' and '\\' */
6130 for (i = strlen (path) - 1; i >= 0; i--)
6131 if (path [i] == '/')
6135 ipath = mono_string_new (mono_domain_get (), path);
6142 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
6144 #if defined (PLATFORM_WIN32)
6145 OutputDebugString (mono_string_chars (message));
6147 g_warning ("WriteWindowsDebugString called and PLATFORM_WIN32 not defined!\n");
6151 /* Only used for value types */
6153 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
6158 MONO_ARCH_SAVE_REGS;
6160 domain = mono_object_domain (type);
6161 klass = mono_class_from_mono_type (type->type);
6163 if (mono_class_is_nullable (klass))
6164 /* No arguments -> null */
6167 return mono_object_new (domain, klass);
6170 static MonoReflectionMethod *
6171 ves_icall_MonoMethod_get_base_definition (MonoReflectionMethod *m)
6173 MonoClass *klass, *parent;
6174 MonoMethod *method = m->method;
6175 MonoMethod *result = NULL;
6177 MONO_ARCH_SAVE_REGS;
6179 if (method->klass == NULL)
6182 if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
6183 MONO_CLASS_IS_INTERFACE (method->klass) ||
6184 method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
6187 klass = method->klass;
6188 if (klass->generic_class)
6189 klass = klass->generic_class->container_class;
6191 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
6192 for (parent = klass->parent; parent != NULL; parent = parent->parent) {
6193 mono_class_setup_vtable (parent);
6194 if (parent->vtable_size <= method->slot)
6199 if (klass == method->klass)
6202 result = klass->vtable [method->slot];
6203 if (result == NULL) {
6204 /* It is an abstract method */
6205 gpointer iter = NULL;
6206 while ((result = mono_class_get_methods (klass, &iter)))
6207 if (result->slot == method->slot)
6214 return mono_method_get_object (mono_domain_get (), result, NULL);
6218 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
6220 MONO_ARCH_SAVE_REGS;
6222 iter->sig = *(MonoMethodSignature**)argsp;
6224 g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
6225 g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
6228 /* FIXME: it's not documented what start is exactly... */
6232 guint32 i, arg_size;
6234 iter->args = argsp + sizeof (gpointer);
6235 #ifndef MONO_ARCH_REGPARMS
6236 for (i = 0; i < iter->sig->sentinelpos; ++i) {
6237 arg_size = mono_type_stack_size (iter->sig->params [i], &align);
6238 iter->args = (char*)iter->args + arg_size;
6242 iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
6244 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
6248 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
6250 guint32 i, arg_size;
6253 MONO_ARCH_SAVE_REGS;
6255 i = iter->sig->sentinelpos + iter->next_arg;
6257 g_assert (i < iter->sig->param_count);
6259 res.type = iter->sig->params [i];
6260 res.klass = mono_class_from_mono_type (res.type);
6261 /* FIXME: endianess issue... */
6262 res.value = iter->args;
6263 arg_size = mono_type_stack_size (res.type, &align);
6264 iter->args = (char*)iter->args + arg_size;
6267 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6273 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
6275 guint32 i, arg_size;
6278 MONO_ARCH_SAVE_REGS;
6280 i = iter->sig->sentinelpos + iter->next_arg;
6282 g_assert (i < iter->sig->param_count);
6284 while (i < iter->sig->param_count) {
6285 if (!mono_metadata_type_equal (type, iter->sig->params [i]))
6287 res.type = iter->sig->params [i];
6288 res.klass = mono_class_from_mono_type (res.type);
6289 /* FIXME: endianess issue... */
6290 res.value = iter->args;
6291 arg_size = mono_type_stack_size (res.type, &align);
6292 iter->args = (char*)iter->args + arg_size;
6294 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6297 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
6306 mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
6309 MONO_ARCH_SAVE_REGS;
6311 i = iter->sig->sentinelpos + iter->next_arg;
6313 g_assert (i < iter->sig->param_count);
6315 return iter->sig->params [i];
6319 mono_TypedReference_ToObject (MonoTypedRef tref)
6321 MONO_ARCH_SAVE_REGS;
6323 if (MONO_TYPE_IS_REFERENCE (tref.type)) {
6324 MonoObject** objp = tref.value;
6328 return mono_value_box (mono_domain_get (), tref.klass, tref.value);
6332 mono_TypedReference_ToObjectInternal (MonoType *type, gpointer value, MonoClass *klass)
6334 MONO_ARCH_SAVE_REGS;
6336 if (MONO_TYPE_IS_REFERENCE (type)) {
6337 MonoObject** objp = value;
6341 return mono_value_box (mono_domain_get (), klass, value);
6345 prelink_method (MonoMethod *method)
6347 const char *exc_class, *exc_arg;
6348 if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
6350 mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
6352 mono_raise_exception(
6353 mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg ) );
6355 /* create the wrapper, too? */
6359 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
6361 MONO_ARCH_SAVE_REGS;
6362 prelink_method (method->method);
6366 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
6368 MonoClass *klass = mono_class_from_mono_type (type->type);
6370 gpointer iter = NULL;
6371 MONO_ARCH_SAVE_REGS;
6373 while ((m = mono_class_get_methods (klass, &iter)))
6377 /* These parameters are "readonly" in corlib/System/Char.cs */
6379 ves_icall_System_Char_GetDataTablePointers (guint8 const **category_data,
6380 guint8 const **numeric_data,
6381 gdouble const **numeric_data_values,
6382 guint16 const **to_lower_data_low,
6383 guint16 const **to_lower_data_high,
6384 guint16 const **to_upper_data_low,
6385 guint16 const **to_upper_data_high)
6387 *category_data = CategoryData;
6388 *numeric_data = NumericData;
6389 *numeric_data_values = NumericDataValues;
6390 *to_lower_data_low = ToLowerDataLow;
6391 *to_lower_data_high = ToLowerDataHigh;
6392 *to_upper_data_low = ToUpperDataLow;
6393 *to_upper_data_high = ToUpperDataHigh;
6397 ves_icall_MonoDebugger_GetMethodToken (MonoReflectionMethod *method)
6399 return method->method->token;
6403 * We eturn NULL for no modifiers so the corlib code can return Type.EmptyTypes
6404 * and avoid useless allocations.
6407 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional)
6411 for (i = 0; i < type->num_mods; ++i) {
6412 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
6417 res = mono_array_new (mono_domain_get (), mono_defaults.systemtype_class, count);
6419 for (i = 0; i < type->num_mods; ++i) {
6420 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
6421 MonoClass *klass = mono_class_get (image, type->modifiers [i].token);
6422 mono_array_setref (res, count, mono_type_get_object (mono_domain_get (), &klass->byval_arg));
6430 param_info_get_type_modifiers (MonoReflectionParameter *param, MonoBoolean optional)
6432 MonoType *type = param->ClassImpl->type;
6433 MonoReflectionMethod *method = (MonoReflectionMethod*)param->MemberImpl;
6434 MonoImage *image = method->method->klass->image;
6435 int pos = param->PositionImpl;
6436 MonoMethodSignature *sig = mono_method_signature (method->method);
6440 type = sig->params [pos];
6442 return type_array_from_modifiers (image, type, optional);
6446 get_property_type (MonoProperty *prop)
6448 MonoMethodSignature *sig;
6450 sig = mono_method_signature (prop->get);
6452 } else if (prop->set) {
6453 sig = mono_method_signature (prop->set);
6454 return sig->params [sig->param_count - 1];
6460 property_info_get_type_modifiers (MonoReflectionProperty *property, MonoBoolean optional)
6462 MonoType *type = get_property_type (property->property);
6463 MonoImage *image = property->klass->image;
6467 return type_array_from_modifiers (image, type, optional);
6471 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
6473 MonoCustomAttrInfo *cinfo;
6476 cinfo = mono_reflection_get_custom_attrs_info (obj);
6479 found = mono_custom_attrs_has_attr (cinfo, mono_class_from_mono_type (attr_type->type));
6481 mono_custom_attrs_free (cinfo);
6486 custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
6488 MonoArray *res = mono_reflection_get_custom_attrs_by_type (obj, attr_type ? mono_class_from_mono_type (attr_type->type) : NULL);
6490 if (mono_loader_get_last_error ()) {
6491 mono_raise_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
6492 g_assert_not_reached ();
6499 GCHandle_CheckCurrentDomain (guint32 gchandle)
6501 return mono_gchandle_is_in_domain (gchandle, mono_domain_get ());
6505 ves_icall_Mono_Runtime_GetDisplayName (void)
6507 static const char display_name_str [] = "Mono " VERSION;
6508 MonoString *display_name = mono_string_new (mono_domain_get (), display_name_str);
6509 return display_name;
6514 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
6515 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
6516 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 62, 128, 128, 128, 63,
6517 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 0, 128, 128,
6518 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
6519 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 128, 128, 128, 128, 128,
6520 128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
6521 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
6525 base64_to_byte_array (gunichar2 *start, gint ilength, MonoBoolean allowWhitespaceOnly)
6530 gunichar2 last, prev_last;
6538 last = prev_last = 0;
6539 for (i = 0; i < ilength; i++) {
6541 if (c >= sizeof (dbase64)) {
6542 exc = mono_exception_from_name_msg (mono_get_corlib (),
6543 "System", "FormatException",
6544 "Invalid character found.");
6545 mono_raise_exception (exc);
6546 } else if (isspace (c)) {
6554 olength = ilength - ignored;
6556 if (allowWhitespaceOnly && olength == 0) {
6557 return mono_array_new (mono_domain_get (), mono_defaults.byte_class, 0);
6560 if ((olength & 3) != 0 || olength <= 0) {
6561 exc = mono_exception_from_name_msg (mono_get_corlib (), "System",
6562 "FormatException", "Invalid length.");
6563 mono_raise_exception (exc);
6566 olength = (olength * 3) / 4;
6570 if (prev_last == '=')
6573 result = mono_array_new (mono_domain_get (), mono_defaults.byte_class, olength);
6574 res_ptr = mono_array_addr (result, guchar, 0);
6575 for (i = 0; i < ilength; ) {
6578 for (k = 0; k < 4 && i < ilength;) {
6584 if (((b [k] = dbase64 [c]) & 0x80) != 0) {
6585 exc = mono_exception_from_name_msg (mono_get_corlib (),
6586 "System", "FormatException",
6587 "Invalid character found.");
6588 mono_raise_exception (exc);
6593 *res_ptr++ = (b [0] << 2) | (b [1] >> 4);
6595 *res_ptr++ = (b [1] << 4) | (b [2] >> 2);
6597 *res_ptr++ = (b [2] << 6) | b [3];
6599 while (i < ilength && isspace (start [i]))
6607 InternalFromBase64String (MonoString *str, MonoBoolean allowWhitespaceOnly)
6609 MONO_ARCH_SAVE_REGS;
6611 return base64_to_byte_array (mono_string_chars (str),
6612 mono_string_length (str), allowWhitespaceOnly);
6616 InternalFromBase64CharArray (MonoArray *input, gint offset, gint length)
6618 MONO_ARCH_SAVE_REGS;
6620 return base64_to_byte_array (mono_array_addr (input, gunichar2, offset),
6624 #define ICALL_TYPE(id,name,first)
6625 #define ICALL(id,name,func) Icall_ ## id,
6628 #include "metadata/icall-def.h"
6634 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
6635 #define ICALL(id,name,func)
6637 #include "metadata/icall-def.h"
6643 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
6644 #define ICALL(id,name,func)
6646 guint16 first_icall;
6649 static const IcallTypeDesc
6650 icall_type_descs [] = {
6651 #include "metadata/icall-def.h"
6655 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
6658 #define ICALL_TYPE(id,name,first)
6661 #ifdef HAVE_ARRAY_ELEM_INIT
6662 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
6663 #define MSGSTRFIELD1(line) str##line
6665 static const struct msgstrtn_t {
6666 #define ICALL(id,name,func)
6668 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
6669 #include "metadata/icall-def.h"
6671 } icall_type_names_str = {
6672 #define ICALL_TYPE(id,name,first) (name),
6673 #include "metadata/icall-def.h"
6676 static const guint16 icall_type_names_idx [] = {
6677 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
6678 #include "metadata/icall-def.h"
6681 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
6683 static const struct msgstr_t {
6685 #define ICALL_TYPE(id,name,first)
6686 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
6687 #include "metadata/icall-def.h"
6689 } icall_names_str = {
6690 #define ICALL(id,name,func) (name),
6691 #include "metadata/icall-def.h"
6694 static const guint16 icall_names_idx [] = {
6695 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
6696 #include "metadata/icall-def.h"
6699 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
6705 #define ICALL_TYPE(id,name,first) name,
6706 #define ICALL(id,name,func)
6707 static const char* const
6708 icall_type_names [] = {
6709 #include "metadata/icall-def.h"
6713 #define icall_type_name_get(id) (icall_type_names [(id)])
6717 #define ICALL_TYPE(id,name,first)
6718 #define ICALL(id,name,func) name,
6719 static const char* const
6721 #include "metadata/icall-def.h"
6724 #define icall_name_get(id) icall_names [(id)]
6726 #endif /* !HAVE_ARRAY_ELEM_INIT */
6730 #define ICALL_TYPE(id,name,first)
6731 #define ICALL(id,name,func) func,
6732 static const gconstpointer
6733 icall_functions [] = {
6734 #include "metadata/icall-def.h"
6738 static GHashTable *icall_hash = NULL;
6739 static GHashTable *jit_icall_hash_name = NULL;
6740 static GHashTable *jit_icall_hash_addr = NULL;
6743 mono_icall_init (void)
6747 /* check that tables are sorted: disable in release */
6750 const char *prev_class = NULL;
6751 const char *prev_method;
6753 for (i = 0; i < Icall_type_num; ++i) {
6754 const IcallTypeDesc *desc;
6757 if (prev_class && strcmp (prev_class, icall_type_name_get (i)) >= 0)
6758 g_print ("class %s should come before class %s\n", icall_type_name_get (i), prev_class);
6759 prev_class = icall_type_name_get (i);
6760 desc = &icall_type_descs [i];
6761 num_icalls = icall_desc_num_icalls (desc);
6762 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
6763 for (j = 0; j < num_icalls; ++j) {
6764 const char *methodn = icall_name_get (desc->first_icall + j);
6765 if (prev_method && strcmp (prev_method, methodn) >= 0)
6766 g_print ("method %s should come before method %s\n", methodn, prev_method);
6767 prev_method = methodn;
6772 icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
6776 mono_icall_cleanup (void)
6778 g_hash_table_destroy (icall_hash);
6779 g_hash_table_destroy (jit_icall_hash_name);
6780 g_hash_table_destroy (jit_icall_hash_addr);
6784 mono_add_internal_call (const char *name, gconstpointer method)
6786 mono_loader_lock ();
6788 g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
6790 mono_loader_unlock ();
6793 #ifdef HAVE_ARRAY_ELEM_INIT
6795 compare_method_imap (const void *key, const void *elem)
6797 const char* method_name = (const char*)&icall_names_str + (*(guint16*)elem);
6798 return strcmp (key, method_name);
6802 find_method_icall (const IcallTypeDesc *imap, const char *name)
6804 const guint16 *nameslot = bsearch (name, icall_names_idx + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names_idx [0]), compare_method_imap);
6807 return (gpointer)icall_functions [(nameslot - &icall_names_idx [0])];
6811 compare_class_imap (const void *key, const void *elem)
6813 const char* class_name = (const char*)&icall_type_names_str + (*(guint16*)elem);
6814 return strcmp (key, class_name);
6817 static const IcallTypeDesc*
6818 find_class_icalls (const char *name)
6820 const guint16 *nameslot = bsearch (name, icall_type_names_idx, Icall_type_num, sizeof (icall_type_names_idx [0]), compare_class_imap);
6823 return &icall_type_descs [nameslot - &icall_type_names_idx [0]];
6828 compare_method_imap (const void *key, const void *elem)
6830 const char** method_name = (const char**)elem;
6831 return strcmp (key, *method_name);
6835 find_method_icall (const IcallTypeDesc *imap, const char *name)
6837 const char **nameslot = bsearch (name, icall_names + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names [0]), compare_method_imap);
6840 return (gpointer)icall_functions [(nameslot - icall_names)];
6844 compare_class_imap (const void *key, const void *elem)
6846 const char** class_name = (const char**)elem;
6847 return strcmp (key, *class_name);
6850 static const IcallTypeDesc*
6851 find_class_icalls (const char *name)
6853 const char **nameslot = bsearch (name, icall_type_names, Icall_type_num, sizeof (icall_type_names [0]), compare_class_imap);
6856 return &icall_type_descs [nameslot - icall_type_names];
6862 * we should probably export this as an helper (handle nested types).
6863 * Returns the number of chars written in buf.
6866 concat_class_name (char *buf, int bufsize, MonoClass *klass)
6868 int nspacelen, cnamelen;
6869 nspacelen = strlen (klass->name_space);
6870 cnamelen = strlen (klass->name);
6871 if (nspacelen + cnamelen + 2 > bufsize)
6874 memcpy (buf, klass->name_space, nspacelen);
6875 buf [nspacelen ++] = '.';
6877 memcpy (buf + nspacelen, klass->name, cnamelen);
6878 buf [nspacelen + cnamelen] = 0;
6879 return nspacelen + cnamelen;
6883 mono_lookup_internal_call (MonoMethod *method)
6888 int typelen = 0, mlen, siglen;
6890 const IcallTypeDesc *imap;
6892 g_assert (method != NULL);
6894 if (method->is_inflated)
6895 method = ((MonoMethodInflated *) method)->declaring;
6897 if (method->klass->nested_in) {
6898 int pos = concat_class_name (mname, sizeof (mname)-2, method->klass->nested_in);
6902 mname [pos++] = '/';
6905 typelen = concat_class_name (mname+pos, sizeof (mname)-pos-1, method->klass);
6911 typelen = concat_class_name (mname, sizeof (mname), method->klass);
6916 imap = find_class_icalls (mname);
6918 mname [typelen] = ':';
6919 mname [typelen + 1] = ':';
6921 mlen = strlen (method->name);
6922 memcpy (mname + typelen + 2, method->name, mlen);
6923 sigstart = mname + typelen + 2 + mlen;
6926 tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
6927 siglen = strlen (tmpsig);
6928 if (typelen + mlen + siglen + 6 > sizeof (mname))
6931 memcpy (sigstart + 1, tmpsig, siglen);
6932 sigstart [siglen + 1] = ')';
6933 sigstart [siglen + 2] = 0;
6936 mono_loader_lock ();
6938 res = g_hash_table_lookup (icall_hash, mname);
6940 mono_loader_unlock ();
6943 /* try without signature */
6945 res = g_hash_table_lookup (icall_hash, mname);
6947 mono_loader_unlock ();
6951 /* it wasn't found in the static call tables */
6953 mono_loader_unlock ();
6956 res = find_method_icall (imap, sigstart - mlen);
6958 mono_loader_unlock ();
6961 /* try _with_ signature */
6963 res = find_method_icall (imap, sigstart - mlen);
6965 mono_loader_unlock ();
6969 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname);
6970 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
6971 g_print ("The out of sync library is: %s\n", method->klass->image->name);
6972 g_print ("\nWhen you update one from cvs you need to update, compile and install\nthe other too.\n");
6973 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");
6974 g_print ("If you see other errors or faults after this message they are probably related\n");
6975 g_print ("and you need to fix your mono install first.\n");
6977 mono_loader_unlock ();
6983 type_from_typename (char *typename)
6985 MonoClass *klass = NULL; /* assignment to shut GCC warning up */
6987 if (!strcmp (typename, "int"))
6988 klass = mono_defaults.int_class;
6989 else if (!strcmp (typename, "ptr"))
6990 klass = mono_defaults.int_class;
6991 else if (!strcmp (typename, "void"))
6992 klass = mono_defaults.void_class;
6993 else if (!strcmp (typename, "int32"))
6994 klass = mono_defaults.int32_class;
6995 else if (!strcmp (typename, "uint32"))
6996 klass = mono_defaults.uint32_class;
6997 else if (!strcmp (typename, "int8"))
6998 klass = mono_defaults.sbyte_class;
6999 else if (!strcmp (typename, "uint8"))
7000 klass = mono_defaults.byte_class;
7001 else if (!strcmp (typename, "int16"))
7002 klass = mono_defaults.int16_class;
7003 else if (!strcmp (typename, "uint16"))
7004 klass = mono_defaults.uint16_class;
7005 else if (!strcmp (typename, "long"))
7006 klass = mono_defaults.int64_class;
7007 else if (!strcmp (typename, "ulong"))
7008 klass = mono_defaults.uint64_class;
7009 else if (!strcmp (typename, "float"))
7010 klass = mono_defaults.single_class;
7011 else if (!strcmp (typename, "double"))
7012 klass = mono_defaults.double_class;
7013 else if (!strcmp (typename, "object"))
7014 klass = mono_defaults.object_class;
7015 else if (!strcmp (typename, "obj"))
7016 klass = mono_defaults.object_class;
7019 g_assert_not_reached ();
7021 return &klass->byval_arg;
7024 MonoMethodSignature*
7025 mono_create_icall_signature (const char *sigstr)
7030 MonoMethodSignature *res;
7032 mono_loader_lock ();
7033 res = g_hash_table_lookup (mono_defaults.corlib->helper_signatures, sigstr);
7035 mono_loader_unlock ();
7039 parts = g_strsplit (sigstr, " ", 256);
7048 res = mono_metadata_signature_alloc (mono_defaults.corlib, len - 1);
7051 #ifdef PLATFORM_WIN32
7053 * Under windows, the default pinvoke calling convention is STDCALL but
7056 res->call_convention = MONO_CALL_C;
7059 res->ret = type_from_typename (parts [0]);
7060 for (i = 1; i < len; ++i) {
7061 res->params [i - 1] = type_from_typename (parts [i]);
7066 g_hash_table_insert (mono_defaults.corlib->helper_signatures, (gpointer)sigstr, res);
7068 mono_loader_unlock ();
7074 mono_find_jit_icall_by_name (const char *name)
7076 MonoJitICallInfo *info;
7077 g_assert (jit_icall_hash_name);
7079 mono_loader_lock ();
7080 info = g_hash_table_lookup (jit_icall_hash_name, name);
7081 mono_loader_unlock ();
7086 mono_find_jit_icall_by_addr (gconstpointer addr)
7088 MonoJitICallInfo *info;
7089 g_assert (jit_icall_hash_addr);
7091 mono_loader_lock ();
7092 info = g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
7093 mono_loader_unlock ();
7099 mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
7101 mono_loader_lock ();
7102 g_hash_table_insert (jit_icall_hash_addr, (gpointer)wrapper, info);
7103 mono_loader_unlock ();
7107 mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
7109 MonoJitICallInfo *info;
7114 mono_loader_lock ();
7116 if (!jit_icall_hash_name) {
7117 jit_icall_hash_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
7118 jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
7121 if (g_hash_table_lookup (jit_icall_hash_name, name)) {
7122 g_warning ("jit icall already defined \"%s\"\n", name);
7123 g_assert_not_reached ();
7126 info = g_new0 (MonoJitICallInfo, 1);
7133 info->wrapper = func;
7135 info->wrapper = NULL;
7138 g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
7139 g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
7141 mono_loader_unlock ();