5 * Dietmar Maurer (dietmar@ximian.com)
6 * Paolo Molaro (lupus@ximian.com)
7 * Patrik Torstensson (patrik.torstensson@labs2.com)
9 * (C) 2001 Ximian, Inc.
19 #if defined (PLATFORM_WIN32)
23 #include <mono/metadata/object.h>
24 #include <mono/metadata/threads.h>
25 #include <mono/metadata/threads-types.h>
26 #include <mono/metadata/threadpool.h>
27 #include <mono/metadata/monitor.h>
28 #include <mono/metadata/reflection.h>
29 #include <mono/metadata/assembly.h>
30 #include <mono/metadata/tabledefs.h>
31 #include <mono/metadata/exception.h>
32 #include <mono/metadata/file-io.h>
33 #include <mono/metadata/console-io.h>
34 #include <mono/metadata/socket-io.h>
35 #include <mono/metadata/mono-endian.h>
36 #include <mono/metadata/tokentype.h>
37 #include <mono/metadata/domain-internals.h>
38 #include <mono/metadata/metadata-internals.h>
39 #include <mono/metadata/class-internals.h>
40 #include <mono/metadata/marshal.h>
41 #include <mono/metadata/gc-internal.h>
42 #include <mono/metadata/mono-gc.h>
43 #include <mono/metadata/rand.h>
44 #include <mono/metadata/sysmath.h>
45 #include <mono/metadata/string-icalls.h>
46 #include <mono/metadata/debug-helpers.h>
47 #include <mono/metadata/process.h>
48 #include <mono/metadata/environment.h>
49 #include <mono/metadata/profiler-private.h>
50 #include <mono/metadata/locales.h>
51 #include <mono/metadata/filewatcher.h>
52 #include <mono/metadata/char-conversions.h>
53 #include <mono/metadata/security.h>
54 #include <mono/metadata/mono-config.h>
55 #include <mono/metadata/cil-coff.h>
56 #include <mono/metadata/security-manager.h>
57 #include <mono/io-layer/io-layer.h>
58 #include <mono/utils/strtod.h>
59 #include <mono/utils/monobitset.h>
61 #if defined (PLATFORM_WIN32)
67 static MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void);
70 static inline MonoBoolean
71 is_generic_parameter (MonoType *type)
73 return !type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR);
77 * We expect a pointer to a char, not a string
80 mono_double_ParseImpl (char *ptr, double *result)
89 *result = strtod (ptr, &endptr);
92 *result = bsd_strtod (ptr, &endptr);
95 if (!*ptr || (endptr && *endptr))
102 mono_class_get_throw (MonoImage *image, guint32 type_token)
104 MonoClass *class = mono_class_get (image, type_token);
105 MonoLoaderError *error;
111 error = mono_loader_get_last_error ();
112 g_assert (error != NULL);
114 ex = mono_loader_error_prepare_exception (error);
115 mono_raise_exception (ex);
120 ves_icall_System_Array_GetValueImpl (MonoObject *this, guint32 pos)
129 ao = (MonoArray *)this;
130 ac = (MonoClass *)ao->obj.vtable->klass;
132 esize = mono_array_element_size (ac);
133 ea = (gpointer*)((char*)ao->vector + (pos * esize));
135 if (ac->element_class->valuetype)
136 return mono_value_box (this->vtable->domain, ac->element_class, ea);
142 ves_icall_System_Array_GetValue (MonoObject *this, MonoObject *idxs)
150 MONO_CHECK_ARG_NULL (idxs);
152 io = (MonoArray *)idxs;
153 ic = (MonoClass *)io->obj.vtable->klass;
155 ao = (MonoArray *)this;
156 ac = (MonoClass *)ao->obj.vtable->klass;
158 g_assert (ic->rank == 1);
159 if (io->bounds != NULL || io->max_length != ac->rank)
160 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
162 ind = (gint32 *)io->vector;
164 if (ao->bounds == NULL) {
165 if (*ind < 0 || *ind >= ao->max_length)
166 mono_raise_exception (mono_get_exception_index_out_of_range ());
168 return ves_icall_System_Array_GetValueImpl (this, *ind);
171 for (i = 0; i < ac->rank; i++)
172 if ((ind [i] < ao->bounds [i].lower_bound) ||
173 (ind [i] >= ao->bounds [i].length + ao->bounds [i].lower_bound))
174 mono_raise_exception (mono_get_exception_index_out_of_range ());
176 pos = ind [0] - ao->bounds [0].lower_bound;
177 for (i = 1; i < ac->rank; i++)
178 pos = pos*ao->bounds [i].length + ind [i] -
179 ao->bounds [i].lower_bound;
181 return ves_icall_System_Array_GetValueImpl (this, pos);
185 ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32 pos)
187 MonoClass *ac, *vc, *ec;
199 vc = value->vtable->klass;
203 ac = this->obj.vtable->klass;
204 ec = ac->element_class;
206 esize = mono_array_element_size (ac);
207 ea = (gpointer*)((char*)this->vector + (pos * esize));
208 va = (gpointer*)((char*)value + sizeof (MonoObject));
211 memset (ea, 0, esize);
215 #define NO_WIDENING_CONVERSION G_STMT_START{\
216 mono_raise_exception (mono_get_exception_argument ( \
217 "value", "not a widening conversion")); \
220 #define CHECK_WIDENING_CONVERSION(extra) G_STMT_START{\
221 if (esize < vsize + (extra)) \
222 mono_raise_exception (mono_get_exception_argument ( \
223 "value", "not a widening conversion")); \
226 #define INVALID_CAST G_STMT_START{\
227 mono_raise_exception (mono_get_exception_invalid_cast ()); \
230 /* Check element (destination) type. */
231 switch (ec->byval_arg.type) {
232 case MONO_TYPE_STRING:
233 switch (vc->byval_arg.type) {
234 case MONO_TYPE_STRING:
240 case MONO_TYPE_BOOLEAN:
241 switch (vc->byval_arg.type) {
242 case MONO_TYPE_BOOLEAN:
255 NO_WIDENING_CONVERSION;
262 if (!ec->valuetype) {
263 if (!mono_object_isinst (value, ec))
265 *ea = (gpointer)value;
269 if (mono_object_isinst (value, ec)) {
270 memcpy (ea, (char *)value + sizeof (MonoObject), esize);
277 vsize = mono_class_instance_size (vc) - sizeof (MonoObject);
279 et = ec->byval_arg.type;
280 if (et == MONO_TYPE_VALUETYPE && ec->byval_arg.data.klass->enumtype)
281 et = ec->byval_arg.data.klass->enum_basetype->type;
283 vt = vc->byval_arg.type;
284 if (vt == MONO_TYPE_VALUETYPE && vc->byval_arg.data.klass->enumtype)
285 vt = vc->byval_arg.data.klass->enum_basetype->type;
287 #define ASSIGN_UNSIGNED(etype) G_STMT_START{\
293 case MONO_TYPE_CHAR: \
294 CHECK_WIDENING_CONVERSION(0); \
295 *(etype *) ea = (etype) u64; \
297 /* You can't assign a signed value to an unsigned array. */ \
302 /* You can't assign a floating point number to an integer array. */ \
305 NO_WIDENING_CONVERSION; \
309 #define ASSIGN_SIGNED(etype) G_STMT_START{\
315 CHECK_WIDENING_CONVERSION(0); \
316 *(etype *) ea = (etype) i64; \
318 /* You can assign an unsigned value to a signed array if the array's */ \
319 /* element size is larger than the value size. */ \
324 case MONO_TYPE_CHAR: \
325 CHECK_WIDENING_CONVERSION(1); \
326 *(etype *) ea = (etype) u64; \
328 /* You can't assign a floating point number to an integer array. */ \
331 NO_WIDENING_CONVERSION; \
335 #define ASSIGN_REAL(etype) G_STMT_START{\
339 CHECK_WIDENING_CONVERSION(0); \
340 *(etype *) ea = (etype) r64; \
342 /* All integer values fit into a floating point array, so we don't */ \
343 /* need to CHECK_WIDENING_CONVERSION here. */ \
348 *(etype *) ea = (etype) i64; \
354 case MONO_TYPE_CHAR: \
355 *(etype *) ea = (etype) u64; \
362 u64 = *(guint8 *) va;
365 u64 = *(guint16 *) va;
368 u64 = *(guint32 *) va;
371 u64 = *(guint64 *) va;
377 i64 = *(gint16 *) va;
380 i64 = *(gint32 *) va;
383 i64 = *(gint64 *) va;
386 r64 = *(gfloat *) va;
389 r64 = *(gdouble *) va;
392 u64 = *(guint16 *) va;
394 case MONO_TYPE_BOOLEAN:
395 /* Boolean is only compatible with itself. */
408 NO_WIDENING_CONVERSION;
415 /* If we can't do a direct copy, let's try a widening conversion. */
418 ASSIGN_UNSIGNED (guint16);
420 ASSIGN_UNSIGNED (guint8);
422 ASSIGN_UNSIGNED (guint16);
424 ASSIGN_UNSIGNED (guint32);
426 ASSIGN_UNSIGNED (guint64);
428 ASSIGN_SIGNED (gint8);
430 ASSIGN_SIGNED (gint16);
432 ASSIGN_SIGNED (gint32);
434 ASSIGN_SIGNED (gint64);
436 ASSIGN_REAL (gfloat);
438 ASSIGN_REAL (gdouble);
442 /* Not reached, INVALID_CAST does not return. Just to avoid a compiler warning ... */
446 #undef NO_WIDENING_CONVERSION
447 #undef CHECK_WIDENING_CONVERSION
448 #undef ASSIGN_UNSIGNED
454 ves_icall_System_Array_SetValue (MonoArray *this, MonoObject *value,
462 MONO_CHECK_ARG_NULL (idxs);
464 ic = idxs->obj.vtable->klass;
465 ac = this->obj.vtable->klass;
467 g_assert (ic->rank == 1);
468 if (idxs->bounds != NULL || idxs->max_length != ac->rank)
469 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
471 ind = (gint32 *)idxs->vector;
473 if (this->bounds == NULL) {
474 if (*ind < 0 || *ind >= this->max_length)
475 mono_raise_exception (mono_get_exception_index_out_of_range ());
477 ves_icall_System_Array_SetValueImpl (this, value, *ind);
481 for (i = 0; i < ac->rank; i++)
482 if ((ind [i] < this->bounds [i].lower_bound) ||
483 (ind [i] >= this->bounds [i].length + this->bounds [i].lower_bound))
484 mono_raise_exception (mono_get_exception_index_out_of_range ());
486 pos = ind [0] - this->bounds [0].lower_bound;
487 for (i = 1; i < ac->rank; i++)
488 pos = pos * this->bounds [i].length + ind [i] -
489 this->bounds [i].lower_bound;
491 ves_icall_System_Array_SetValueImpl (this, value, pos);
495 ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
500 gboolean bounded = FALSE;
504 MONO_CHECK_ARG_NULL (type);
505 MONO_CHECK_ARG_NULL (lengths);
507 MONO_CHECK_ARG (lengths, mono_array_length (lengths) > 0);
509 MONO_CHECK_ARG (bounds, mono_array_length (lengths) == mono_array_length (bounds));
511 for (i = 0; i < mono_array_length (lengths); i++)
512 if (mono_array_get (lengths, gint32, i) < 0)
513 mono_raise_exception (mono_get_exception_argument_out_of_range (NULL));
515 if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint32, 0) != 0))
516 /* vectors are not the same as one dimensional arrays with no-zero bounds */
521 aklass = mono_bounded_array_class_get (mono_class_from_mono_type (type->type), mono_array_length (lengths), bounded);
523 sizes = alloca (aklass->rank * sizeof(guint32) * 2);
524 for (i = 0; i < aklass->rank; ++i) {
525 sizes [i] = mono_array_get (lengths, guint32, i);
527 sizes [i + aklass->rank] = mono_array_get (bounds, guint32, i);
529 sizes [i + aklass->rank] = 0;
532 array = mono_array_new_full (mono_object_domain (type), aklass, sizes, sizes + aklass->rank);
538 ves_icall_System_Array_GetRank (MonoObject *this)
542 return this->vtable->klass->rank;
546 ves_icall_System_Array_GetLength (MonoArray *this, gint32 dimension)
548 gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
552 if ((dimension < 0) || (dimension >= rank))
553 mono_raise_exception (mono_get_exception_index_out_of_range ());
555 if (this->bounds == NULL)
556 return this->max_length;
558 return this->bounds [dimension].length;
562 ves_icall_System_Array_GetLowerBound (MonoArray *this, gint32 dimension)
564 gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
568 if ((dimension < 0) || (dimension >= rank))
569 mono_raise_exception (mono_get_exception_index_out_of_range ());
571 if (this->bounds == NULL)
574 return this->bounds [dimension].lower_bound;
578 ves_icall_System_Array_ClearInternal (MonoArray *arr, int idx, int length)
580 int sz = mono_array_element_size (mono_object_class (arr));
581 memset (mono_array_addr_with_size (arr, sz, idx), 0, length * sz);
585 ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* dest, int dest_idx, int length)
590 MonoClass *src_class;
591 MonoClass *dest_class;
596 if (source->obj.vtable->klass->rank != dest->obj.vtable->klass->rank)
599 if (source->bounds || dest->bounds)
602 if ((dest_idx + length > mono_array_length (dest)) ||
603 (source_idx + length > mono_array_length (source)))
606 src_class = source->obj.vtable->klass->element_class;
607 dest_class = dest->obj.vtable->klass->element_class;
610 * Handle common cases.
613 /* Case1: object[] -> valuetype[] (ArrayList::ToArray) */
614 if (src_class == mono_defaults.object_class && dest_class->valuetype) {
615 int has_refs = dest_class->has_references;
616 for (i = source_idx; i < source_idx + length; ++i) {
617 MonoObject *elem = mono_array_get (source, MonoObject*, i);
618 if (elem && !mono_object_isinst (elem, dest_class))
622 element_size = mono_array_element_size (dest->obj.vtable->klass);
623 memset (mono_array_addr_with_size (dest, element_size, dest_idx), 0, element_size * length);
624 for (i = 0; i < length; ++i) {
625 MonoObject *elem = mono_array_get (source, MonoObject*, source_idx + i);
626 void *addr = mono_array_addr_with_size (dest, element_size, dest_idx + i);
630 mono_value_copy (addr, (char *)elem + sizeof (MonoObject), dest_class);
632 memcpy (addr, (char *)elem + sizeof (MonoObject), element_size);
637 /* Check if we're copying a char[] <==> (u)short[] */
638 if (src_class != dest_class) {
639 if (dest_class->valuetype || dest_class->enumtype || src_class->valuetype || src_class->enumtype)
642 if (mono_class_is_subclass_of (src_class, dest_class, FALSE))
644 /* Case2: object[] -> reftype[] (ArrayList::ToArray) */
645 else if (mono_class_is_subclass_of (dest_class, src_class, FALSE))
646 for (i = source_idx; i < source_idx + length; ++i) {
647 MonoObject *elem = mono_array_get (source, MonoObject*, i);
648 if (elem && !mono_object_isinst (elem, dest_class))
655 if (dest_class->valuetype) {
656 element_size = mono_array_element_size (source->obj.vtable->klass);
657 source_addr = mono_array_addr_with_size (source, element_size, source_idx);
658 if (dest_class->has_references) {
659 mono_value_copy_array (dest, dest_idx, source_addr, length);
661 dest_addr = mono_array_addr_with_size (dest, element_size, dest_idx);
662 memmove (dest_addr, source_addr, element_size * length);
665 mono_array_memcpy_refs (dest, dest_idx, source, source_idx, length);
672 ves_icall_System_Array_GetGenericValueImpl (MonoObject *this, guint32 pos, gpointer value)
681 ao = (MonoArray *)this;
682 ac = (MonoClass *)ao->obj.vtable->klass;
684 esize = mono_array_element_size (ac);
685 ea = (gpointer*)((char*)ao->vector + (pos * esize));
687 memcpy (value, ea, esize);
691 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoArray *array, MonoClassField *field_handle)
693 MonoClass *klass = array->obj.vtable->klass;
694 guint32 size = mono_array_element_size (klass);
696 size *= array->max_length;
698 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
700 guint ## n *data = (guint ## n *) mono_array_addr (array, char, 0); \
701 guint ## n *src = (guint ## n *) field_handle->data; \
702 guint ## n *end = (guint ## n *)((char*)src + size); \
704 for (; src < end; data++, src++) { \
705 *data = read ## n (src); \
709 /* printf ("Initialize array with elements of %s type\n", klass->element_class->name); */
711 switch (mono_type_get_underlying_type (&klass->element_class->byval_arg)->type) {
728 memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
732 memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
734 if (klass->element_class->byval_arg.type == MONO_TYPE_R8) {
737 double *data = (double*)mono_array_addr (array, double, 0);
739 for (i = 0; i < size; i++, data++) {
749 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData (void)
753 return offsetof (MonoString, chars);
757 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue (MonoObject *obj)
761 if ((obj == NULL) || (! (obj->vtable->klass->valuetype)))
764 return mono_object_clone (obj);
768 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (MonoType *handle)
774 MONO_CHECK_ARG_NULL (handle);
776 klass = mono_class_from_mono_type (handle);
777 MONO_CHECK_ARG (handle, klass);
779 /* This will call the type constructor */
780 if (! (klass->flags & TYPE_ATTRIBUTE_INTERFACE))
781 mono_runtime_class_init (mono_class_vtable (mono_domain_get (), klass));
785 ves_icall_System_Object_MemberwiseClone (MonoObject *this)
789 return mono_object_clone (this);
793 ves_icall_System_ValueType_InternalGetHashCode (MonoObject *this, MonoArray **fields)
796 MonoObject **values = NULL;
800 MonoClassField* field;
805 klass = mono_object_class (this);
807 if (mono_class_num_fields (klass) == 0)
808 return mono_object_hash (this);
811 * Compute the starting value of the hashcode for fields of primitive
812 * types, and return the remaining fields in an array to the managed side.
813 * This way, we can avoid costly reflection operations in managed code.
816 while ((field = mono_class_get_fields (klass, &iter))) {
817 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
819 if (mono_field_is_deleted (field))
821 /* FIXME: Add more types */
822 switch (field->type->type) {
824 result ^= *(gint32*)((guint8*)this + field->offset);
826 case MONO_TYPE_STRING: {
828 s = *(MonoString**)((guint8*)this + field->offset);
830 result ^= mono_string_hash (s);
835 values = g_newa (MonoObject*, mono_class_num_fields (klass));
836 o = mono_field_get_value_object (mono_object_domain (this), field, this);
837 values [count++] = o;
843 *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
844 for (i = 0; i < count; ++i)
845 mono_array_setref (*fields, i, values [i]);
853 ves_icall_System_ValueType_Equals (MonoObject *this, MonoObject *that, MonoArray **fields)
856 MonoObject **values = NULL;
858 MonoClassField* field;
864 MONO_CHECK_ARG_NULL (that);
866 if (this->vtable != that->vtable)
869 klass = mono_object_class (this);
872 * Do the comparison for fields of primitive type and return a result if
873 * possible. Otherwise, return the remaining fields in an array to the
874 * managed side. This way, we can avoid costly reflection operations in
879 while ((field = mono_class_get_fields (klass, &iter))) {
880 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
882 if (mono_field_is_deleted (field))
884 /* FIXME: Add more types */
885 switch (field->type->type) {
887 if (*(gint32*)((guint8*)this + field->offset) != *(gint32*)((guint8*)that + field->offset))
890 case MONO_TYPE_STRING: {
892 guint32 s1len, s2len;
893 s1 = *(MonoString**)((guint8*)this + field->offset);
894 s2 = *(MonoString**)((guint8*)that + field->offset);
897 if ((s1 == NULL) || (s2 == NULL))
899 s1len = mono_string_length (s1);
900 s2len = mono_string_length (s2);
904 if (memcmp (mono_string_chars (s1), mono_string_chars (s2), s1len * sizeof (gunichar2)) != 0)
910 values = g_newa (MonoObject*, mono_class_num_fields (klass) * 2);
911 o = mono_field_get_value_object (mono_object_domain (this), field, this);
912 values [count++] = o;
913 o = mono_field_get_value_object (mono_object_domain (this), field, that);
914 values [count++] = o;
920 *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
921 for (i = 0; i < count; ++i)
922 mono_array_setref (*fields, i, values [i]);
929 static MonoReflectionType *
930 ves_icall_System_Object_GetType (MonoObject *obj)
934 if (obj->vtable->klass != mono_defaults.transparent_proxy_class)
935 return mono_type_get_object (mono_object_domain (obj), &obj->vtable->klass->byval_arg);
937 return mono_type_get_object (mono_object_domain (obj), &((MonoTransparentProxy*)obj)->remote_class->proxy_class->byval_arg);
941 mono_type_type_from_obj (MonoReflectionType *mtype, MonoObject *obj)
945 mtype->type = &obj->vtable->klass->byval_arg;
946 g_assert (mtype->type->type);
950 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj)
954 MONO_CHECK_ARG_NULL (obj);
956 return mono_image_create_token (mb->dynamic_image, obj, TRUE);
960 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder *mb,
961 MonoReflectionMethod *method,
962 MonoArray *opt_param_types)
966 MONO_CHECK_ARG_NULL (method);
968 return mono_image_create_method_token (
969 mb->dynamic_image, (MonoObject *) method, opt_param_types);
973 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder *mb, HANDLE file)
977 mono_image_create_pefile (mb, file);
981 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
985 mono_image_build_metadata (mb);
989 get_caller (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
991 MonoMethod **dest = data;
993 /* skip unmanaged frames */
1008 static MonoReflectionType *
1009 type_from_name (const char *str, MonoBoolean ignoreCase)
1011 MonoType *type = NULL;
1012 MonoAssembly *assembly = NULL;
1013 MonoTypeNameParse info;
1014 char *temp_str = g_strdup (str);
1015 gboolean type_resolve = FALSE;
1017 MONO_ARCH_SAVE_REGS;
1019 /* mono_reflection_parse_type() mangles the string */
1020 if (!mono_reflection_parse_type (temp_str, &info)) {
1021 g_list_free (info.modifiers);
1022 g_list_free (info.nested);
1027 if (info.assembly.name) {
1028 assembly = mono_assembly_load (&info.assembly, NULL, NULL);
1030 MonoMethod *m = mono_method_get_last_managed ();
1031 MonoMethod *dest = m;
1033 mono_stack_walk_no_il (get_caller, &dest);
1038 * FIXME: mono_method_get_last_managed() sometimes returns NULL, thus
1039 * causing ves_icall_System_Reflection_Assembly_GetCallingAssembly()
1040 * to crash. This only seems to happen in some strange remoting
1041 * scenarios and I was unable to figure out what's happening there.
1042 * Dec 10, 2005 - Martin.
1046 assembly = dest->klass->image->assembly;
1048 g_warning (G_STRLOC);
1053 type = mono_reflection_get_type (assembly->image, &info, ignoreCase, &type_resolve);
1055 if (!info.assembly.name && !type) /* try mscorlib */
1056 type = mono_reflection_get_type (NULL, &info, ignoreCase, &type_resolve);
1058 g_list_free (info.modifiers);
1059 g_list_free (info.nested);
1065 return mono_type_get_object (mono_domain_get (), type);
1069 MonoReflectionType *
1070 mono_type_get (const char *str)
1072 char *copy = g_strdup (str);
1073 MonoReflectionType *type = type_from_name (copy, FALSE);
1080 static MonoReflectionType*
1081 ves_icall_type_from_name (MonoString *name,
1082 MonoBoolean throwOnError,
1083 MonoBoolean ignoreCase)
1085 char *str = mono_string_to_utf8 (name);
1086 MonoReflectionType *type;
1088 type = type_from_name (str, ignoreCase);
1091 MonoException *e = NULL;
1094 e = mono_get_exception_type_load (name, NULL);
1096 mono_loader_clear_error ();
1098 mono_raise_exception (e);
1105 static MonoReflectionType*
1106 ves_icall_type_from_handle (MonoType *handle)
1108 MonoDomain *domain = mono_domain_get ();
1109 MonoClass *klass = mono_class_from_mono_type (handle);
1111 MONO_ARCH_SAVE_REGS;
1113 mono_class_init (klass);
1114 return mono_type_get_object (domain, handle);
1118 ves_icall_System_Type_EqualsInternal (MonoReflectionType *type, MonoReflectionType *c)
1120 MONO_ARCH_SAVE_REGS;
1122 if (c && type->type && c->type)
1123 return mono_metadata_type_equal (type->type, c->type);
1128 /* System.TypeCode */
1147 TYPECODE_STRING = 18
1151 ves_icall_type_GetTypeCodeInternal (MonoReflectionType *type)
1153 int t = type->type->type;
1155 MONO_ARCH_SAVE_REGS;
1157 if (type->type->byref)
1158 return TYPECODE_OBJECT;
1162 case MONO_TYPE_VOID:
1163 return TYPECODE_OBJECT;
1164 case MONO_TYPE_BOOLEAN:
1165 return TYPECODE_BOOLEAN;
1167 return TYPECODE_BYTE;
1169 return TYPECODE_SBYTE;
1171 return TYPECODE_UINT16;
1173 return TYPECODE_INT16;
1174 case MONO_TYPE_CHAR:
1175 return TYPECODE_CHAR;
1179 return TYPECODE_OBJECT;
1181 return TYPECODE_UINT32;
1183 return TYPECODE_INT32;
1185 return TYPECODE_UINT64;
1187 return TYPECODE_INT64;
1189 return TYPECODE_SINGLE;
1191 return TYPECODE_DOUBLE;
1192 case MONO_TYPE_VALUETYPE:
1193 if (type->type->data.klass->enumtype) {
1194 t = type->type->data.klass->enum_basetype->type;
1197 MonoClass *k = type->type->data.klass;
1198 if (strcmp (k->name_space, "System") == 0) {
1199 if (strcmp (k->name, "Decimal") == 0)
1200 return TYPECODE_DECIMAL;
1201 else if (strcmp (k->name, "DateTime") == 0)
1202 return TYPECODE_DATETIME;
1205 return TYPECODE_OBJECT;
1206 case MONO_TYPE_STRING:
1207 return TYPECODE_STRING;
1208 case MONO_TYPE_SZARRAY:
1209 case MONO_TYPE_ARRAY:
1210 case MONO_TYPE_OBJECT:
1212 case MONO_TYPE_MVAR:
1213 case MONO_TYPE_TYPEDBYREF:
1214 return TYPECODE_OBJECT;
1215 case MONO_TYPE_CLASS:
1217 MonoClass *k = type->type->data.klass;
1218 if (strcmp (k->name_space, "System") == 0) {
1219 if (strcmp (k->name, "DBNull") == 0)
1220 return TYPECODE_DBNULL;
1223 return TYPECODE_OBJECT;
1224 case MONO_TYPE_GENERICINST:
1225 return TYPECODE_OBJECT;
1227 g_error ("type 0x%02x not handled in GetTypeCode()", t);
1233 ves_icall_type_is_subtype_of (MonoReflectionType *type, MonoReflectionType *c, MonoBoolean check_interfaces)
1239 MONO_ARCH_SAVE_REGS;
1241 g_assert (type != NULL);
1243 domain = ((MonoObject *)type)->vtable->domain;
1245 if (!c) /* FIXME: dont know what do do here */
1248 klass = mono_class_from_mono_type (type->type);
1249 klassc = mono_class_from_mono_type (c->type);
1251 if (type->type->byref)
1252 return klassc == mono_defaults.object_class;
1254 return mono_class_is_subclass_of (klass, klassc, check_interfaces);
1258 ves_icall_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType *c)
1264 MONO_ARCH_SAVE_REGS;
1266 g_assert (type != NULL);
1268 domain = ((MonoObject *)type)->vtable->domain;
1270 klass = mono_class_from_mono_type (type->type);
1271 klassc = mono_class_from_mono_type (c->type);
1273 if (type->type->byref && !c->type->byref)
1276 return mono_class_is_assignable_from (klass, klassc);
1280 ves_icall_type_IsInstanceOfType (MonoReflectionType *type, MonoObject *obj)
1282 MonoClass *klass = mono_class_from_mono_type (type->type);
1283 return mono_object_isinst (obj, klass) != NULL;
1287 ves_icall_get_attributes (MonoReflectionType *type)
1289 MonoClass *klass = mono_class_from_mono_type (type->type);
1291 MONO_ARCH_SAVE_REGS;
1293 return klass->flags;
1296 static MonoReflectionMarshal*
1297 ves_icall_System_Reflection_FieldInfo_GetUnmanagedMarshal (MonoReflectionField *field)
1299 MonoClass *klass = field->field->parent;
1300 MonoMarshalType *info;
1303 if (klass->generic_container ||
1304 (klass->generic_class && klass->generic_class->inst->is_open))
1307 info = mono_marshal_load_type_info (klass);
1309 for (i = 0; i < info->num_fields; ++i) {
1310 if (info->fields [i].field == field->field) {
1311 if (!info->fields [i].mspec)
1314 return mono_reflection_marshal_from_marshal_spec (field->object.vtable->domain, klass, info->fields [i].mspec);
1321 static MonoReflectionField*
1322 ves_icall_System_Reflection_FieldInfo_internal_from_handle (MonoClassField *handle)
1324 MONO_ARCH_SAVE_REGS;
1328 return mono_field_get_object (mono_domain_get (), handle->parent, handle);
1332 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
1334 MonoDomain *domain = mono_domain_get ();
1335 MonoMethodSignature* sig;
1336 MONO_ARCH_SAVE_REGS;
1338 if (method->is_inflated)
1339 method = mono_get_inflated_method (method);
1341 sig = mono_method_signature (method);
1343 info->parent = mono_type_get_object (domain, &method->klass->byval_arg);
1344 info->ret = mono_type_get_object (domain, sig->ret);
1345 info->attrs = method->flags;
1346 info->implattrs = method->iflags;
1347 if (sig->call_convention == MONO_CALL_DEFAULT)
1350 if (sig->call_convention == MONO_CALL_VARARG)
1355 info->callconv |= (sig->hasthis << 5) | (sig->explicit_this << 6);
1359 ves_icall_get_parameter_info (MonoMethod *method)
1361 MonoDomain *domain = mono_domain_get ();
1363 MONO_ARCH_SAVE_REGS;
1365 if (method->is_inflated)
1366 method = mono_get_inflated_method (method);
1368 return mono_param_get_objects (domain, method);
1371 static MonoReflectionMarshal*
1372 ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod *method)
1374 MonoDomain *domain = mono_domain_get ();
1375 MonoReflectionMarshal* res = NULL;
1376 MonoMarshalSpec **mspecs;
1379 MONO_ARCH_SAVE_REGS;
1381 if (method->is_inflated)
1382 method = mono_get_inflated_method (method);
1384 mspecs = g_new (MonoMarshalSpec*, mono_method_signature (method)->param_count + 1);
1385 mono_method_get_marshal_info (method, mspecs);
1388 res = mono_reflection_marshal_from_marshal_spec (domain, method->klass, mspecs [0]);
1390 for (i = mono_method_signature (method)->param_count; i >= 0; i--)
1392 mono_metadata_free_marshal_spec (mspecs [i]);
1399 ves_icall_MonoField_GetFieldOffset (MonoReflectionField *field)
1401 return field->field->offset - sizeof (MonoObject);
1404 static MonoReflectionType*
1405 ves_icall_MonoField_GetParentType (MonoReflectionField *field, MonoBoolean declaring)
1408 MONO_ARCH_SAVE_REGS;
1410 parent = declaring? field->field->parent: field->klass;
1412 return mono_type_get_object (mono_object_domain (field), &parent->byval_arg);
1416 ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj)
1419 MonoClassField *cf = field->field;
1423 MonoDomain *domain = mono_object_domain (field);
1425 gboolean is_static = FALSE;
1426 gboolean is_ref = FALSE;
1428 MONO_ARCH_SAVE_REGS;
1430 if (field->klass->image->assembly->ref_only)
1431 mono_raise_exception (mono_get_exception_invalid_operation (
1432 "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
1434 mono_class_init (field->klass);
1436 t = mono_type_get_underlying_type (cf->type);
1438 case MONO_TYPE_STRING:
1439 case MONO_TYPE_OBJECT:
1440 case MONO_TYPE_CLASS:
1441 case MONO_TYPE_ARRAY:
1442 case MONO_TYPE_SZARRAY:
1447 case MONO_TYPE_BOOLEAN:
1450 case MONO_TYPE_CHAR:
1459 case MONO_TYPE_VALUETYPE:
1462 case MONO_TYPE_GENERICINST:
1463 if (mono_type_generic_inst_is_valuetype (t)) {
1470 g_error ("type 0x%x not handled in "
1471 "ves_icall_Monofield_GetValue", t->type);
1476 if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) {
1478 vtable = mono_class_vtable (domain, cf->parent);
1479 if (!vtable->initialized && !(cf->type->attrs & FIELD_ATTRIBUTE_LITERAL))
1480 mono_runtime_class_init (vtable);
1485 mono_field_static_get_value (vtable, cf, &o);
1487 mono_field_get_value (obj, cf, &o);
1492 if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) {
1493 MonoClass *nklass = mono_class_from_mono_type (cf->type);
1496 /* Convert the Nullable structure into a boxed vtype */
1498 buf = (guint8*)vtable->data + cf->offset;
1500 buf = (guint8*)obj + cf->offset;
1502 return mono_nullable_box (buf, nklass);
1505 /* boxed value type */
1506 klass = mono_class_from_mono_type (cf->type);
1507 o = mono_object_new (domain, klass);
1508 v = ((gchar *) o) + sizeof (MonoObject);
1510 mono_field_static_get_value (vtable, cf, v);
1512 mono_field_get_value (obj, cf, v);
1519 ves_icall_FieldInfo_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value)
1521 MonoClassField *cf = field->field;
1524 MONO_ARCH_SAVE_REGS;
1526 if (field->klass->image->assembly->ref_only)
1527 mono_raise_exception (mono_get_exception_invalid_operation (
1528 "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
1530 v = (gchar *) value;
1531 if (!cf->type->byref) {
1532 switch (cf->type->type) {
1535 case MONO_TYPE_BOOLEAN:
1538 case MONO_TYPE_CHAR:
1547 case MONO_TYPE_VALUETYPE:
1549 v += sizeof (MonoObject);
1551 case MONO_TYPE_STRING:
1552 case MONO_TYPE_OBJECT:
1553 case MONO_TYPE_CLASS:
1554 case MONO_TYPE_ARRAY:
1555 case MONO_TYPE_SZARRAY:
1558 case MONO_TYPE_GENERICINST: {
1559 MonoGenericClass *gclass = cf->type->data.generic_class;
1560 g_assert (!gclass->inst->is_open);
1562 if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) {
1563 MonoClass *nklass = mono_class_from_mono_type (cf->type);
1567 * Convert the boxed vtype into a Nullable structure.
1568 * This is complicated by the fact that Nullables have
1569 * a variable structure.
1571 /* Allocate using alloca so it gets GC tracking */
1572 buf = alloca (nklass->instance_size);
1574 mono_nullable_init (buf, value, nklass);
1579 if (gclass->container_class->valuetype && (v != NULL))
1580 v += sizeof (MonoObject);
1584 g_error ("type 0x%x not handled in "
1585 "ves_icall_FieldInfo_SetValueInternal", cf->type->type);
1590 if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) {
1591 MonoVTable *vtable = mono_class_vtable (mono_object_domain (field), cf->parent);
1592 if (!vtable->initialized)
1593 mono_runtime_class_init (vtable);
1594 mono_field_static_set_value (vtable, cf, v);
1596 mono_field_set_value (obj, cf, v);
1600 static MonoReflectionType*
1601 ves_icall_MonoGenericMethod_get_ReflectedType (MonoReflectionGenericMethod *rmethod)
1603 MonoMethod *method = mono_get_inflated_method (rmethod->method.method);
1605 return mono_type_get_object (mono_object_domain (rmethod), &method->klass->byval_arg);
1608 /* From MonoProperty.cs */
1610 PInfo_Attributes = 1,
1611 PInfo_GetMethod = 1 << 1,
1612 PInfo_SetMethod = 1 << 2,
1613 PInfo_ReflectedType = 1 << 3,
1614 PInfo_DeclaringType = 1 << 4,
1619 ves_icall_get_property_info (MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
1621 MonoDomain *domain = mono_object_domain (property);
1623 MONO_ARCH_SAVE_REGS;
1625 if ((req_info & PInfo_ReflectedType) != 0)
1626 info->parent = mono_type_get_object (domain, &property->klass->byval_arg);
1627 else if ((req_info & PInfo_DeclaringType) != 0)
1628 info->parent = mono_type_get_object (domain, &property->property->parent->byval_arg);
1630 if ((req_info & PInfo_Name) != 0)
1631 info->name = mono_string_new (domain, property->property->name);
1633 if ((req_info & PInfo_Attributes) != 0)
1634 info->attrs = property->property->attrs;
1636 if ((req_info & PInfo_GetMethod) != 0)
1637 info->get = property->property->get ?
1638 mono_method_get_object (domain, property->property->get, NULL): NULL;
1640 if ((req_info & PInfo_SetMethod) != 0)
1641 info->set = property->property->set ?
1642 mono_method_get_object (domain, property->property->set, NULL): NULL;
1644 * There may be other methods defined for properties, though, it seems they are not exposed
1645 * in the reflection API
1650 ves_icall_get_event_info (MonoReflectionEvent *event, MonoEventInfo *info)
1652 MonoDomain *domain = mono_object_domain (event);
1654 MONO_ARCH_SAVE_REGS;
1656 info->reflected_type = mono_type_get_object (domain, &event->klass->byval_arg);
1657 info->declaring_type = mono_type_get_object (domain, &event->event->parent->byval_arg);
1659 info->name = mono_string_new (domain, event->event->name);
1660 info->attrs = event->event->attrs;
1661 info->add_method = event->event->add ? mono_method_get_object (domain, event->event->add, NULL): NULL;
1662 info->remove_method = event->event->remove ? mono_method_get_object (domain, event->event->remove, NULL): NULL;
1663 info->raise_method = event->event->raise ? mono_method_get_object (domain, event->event->raise, NULL): NULL;
1665 if (event->event->other) {
1667 while (event->event->other [n])
1669 info->other_methods = mono_array_new (domain, mono_defaults.method_info_class, n);
1671 for (i = 0; i < n; i++)
1672 mono_array_setref (info->other_methods, i, mono_method_get_object (domain, event->event->other [i], NULL));
1677 ves_icall_Type_GetInterfaces (MonoReflectionType* type)
1679 MonoDomain *domain = mono_object_domain (type);
1681 GPtrArray *ifaces = NULL;
1683 MonoClass *class = mono_class_from_mono_type (type->type);
1686 MonoGenericContext *context = NULL;
1688 MONO_ARCH_SAVE_REGS;
1690 /* open generic-instance classes can share their interface_id */
1691 if (class->generic_class && class->generic_class->inst->is_open) {
1692 context = mono_class_get_context (class);
1693 class = class->generic_class->container_class;
1696 mono_class_setup_vtable (class);
1698 slots = mono_bitset_new (class->max_interface_id + 1, 0);
1700 for (parent = class; parent; parent = parent->parent) {
1701 GPtrArray *tmp_ifaces = mono_class_get_implemented_interfaces (parent);
1703 for (i = 0; i < tmp_ifaces->len; ++i) {
1704 MonoClass *ic = g_ptr_array_index (tmp_ifaces, i);
1706 if (mono_bitset_test (slots, ic->interface_id))
1709 mono_bitset_set (slots, ic->interface_id);
1711 ifaces = g_ptr_array_new ();
1712 g_ptr_array_add (ifaces, ic);
1714 g_ptr_array_free (tmp_ifaces, TRUE);
1717 mono_bitset_free (slots);
1720 return mono_array_new (domain, mono_defaults.monotype_class, 0);
1722 intf = mono_array_new (domain, mono_defaults.monotype_class, ifaces->len);
1723 for (i = 0; i < ifaces->len; ++i) {
1724 MonoClass *ic = g_ptr_array_index (ifaces, i);
1725 MonoType *ret = &ic->byval_arg;
1726 if (context && ic->generic_class && ic->generic_class->inst->is_open)
1727 ret = mono_class_inflate_generic_type (ret, context);
1729 mono_array_setref (intf, i, mono_type_get_object (domain, ret));
1731 g_ptr_array_free (ifaces, TRUE);
1737 ves_icall_Type_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType *iface, MonoArray **targets, MonoArray **methods)
1739 MonoClass *class = mono_class_from_mono_type (type->type);
1740 MonoClass *iclass = mono_class_from_mono_type (iface->type);
1741 MonoReflectionMethod *member;
1744 int i = 0, len, ioffset;
1747 MONO_ARCH_SAVE_REGS;
1749 mono_class_setup_vtable (class);
1751 /* type doesn't implement iface: the exception is thrown in managed code */
1752 if ((iclass->interface_id > class->max_interface_id) || !class->interface_offsets [iclass->interface_id])
1755 len = mono_class_num_methods (iclass);
1756 ioffset = class->interface_offsets [iclass->interface_id];
1757 domain = mono_object_domain (type);
1758 *targets = mono_array_new (domain, mono_defaults.method_info_class, len);
1759 *methods = mono_array_new (domain, mono_defaults.method_info_class, len);
1762 while ((method = mono_class_get_methods (iclass, &iter))) {
1763 member = mono_method_get_object (domain, method, iclass);
1764 mono_array_setref (*methods, i, member);
1765 member = mono_method_get_object (domain, class->vtable [i + ioffset], class);
1766 mono_array_setref (*targets, i, member);
1773 ves_icall_Type_GetPacking (MonoReflectionType *type, guint32 *packing, guint32 *size)
1775 MonoClass *klass = mono_class_from_mono_type (type->type);
1777 g_assert (!klass->image->dynamic);
1779 mono_metadata_packing_from_typedef (klass->image, klass->type_token, packing, size);
1782 static MonoReflectionType*
1783 ves_icall_MonoType_GetElementType (MonoReflectionType *type)
1785 MonoClass *class = mono_class_from_mono_type (type->type);
1787 MONO_ARCH_SAVE_REGS;
1789 // GelElementType should only return a type for:
1790 // Array Pointer PassedByRef
1791 if (type->type->byref)
1792 return mono_type_get_object (mono_object_domain (type), &class->byval_arg);
1793 if (class->enumtype && class->enum_basetype) /* types that are modifierd typebuilkders may not have enum_basetype set */
1794 return mono_type_get_object (mono_object_domain (type), class->enum_basetype);
1795 else if (class->element_class && MONO_CLASS_IS_ARRAY (class))
1796 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
1797 else if (class->element_class && type->type->type == MONO_TYPE_PTR)
1798 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
1803 static MonoReflectionType*
1804 ves_icall_get_type_parent (MonoReflectionType *type)
1806 MonoClass *class = mono_class_from_mono_type (type->type);
1808 MONO_ARCH_SAVE_REGS;
1810 return class->parent ? mono_type_get_object (mono_object_domain (type), &class->parent->byval_arg): NULL;
1814 ves_icall_type_ispointer (MonoReflectionType *type)
1816 MONO_ARCH_SAVE_REGS;
1818 return type->type->type == MONO_TYPE_PTR;
1822 ves_icall_type_isprimitive (MonoReflectionType *type)
1824 MONO_ARCH_SAVE_REGS;
1826 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)));
1830 ves_icall_type_isbyref (MonoReflectionType *type)
1832 MONO_ARCH_SAVE_REGS;
1834 return type->type->byref;
1838 ves_icall_type_iscomobject (MonoReflectionType *type)
1840 MonoClass *klass = mono_class_from_mono_type (type->type);
1841 MONO_ARCH_SAVE_REGS;
1843 return (klass && klass->is_com_object);
1846 static MonoReflectionModule*
1847 ves_icall_MonoType_get_Module (MonoReflectionType *type)
1849 MonoClass *class = mono_class_from_mono_type (type->type);
1851 MONO_ARCH_SAVE_REGS;
1853 return mono_module_get_object (mono_object_domain (type), class->image);
1856 static MonoReflectionAssembly*
1857 ves_icall_MonoType_get_Assembly (MonoReflectionType *type)
1859 MonoDomain *domain = mono_domain_get ();
1860 MonoClass *class = mono_class_from_mono_type (type->type);
1862 MONO_ARCH_SAVE_REGS;
1864 return mono_assembly_get_object (domain, class->image->assembly);
1867 static MonoReflectionType*
1868 ves_icall_MonoType_get_DeclaringType (MonoReflectionType *type)
1870 MonoDomain *domain = mono_domain_get ();
1873 MONO_ARCH_SAVE_REGS;
1875 if (type->type->byref)
1877 if (type->type->type == MONO_TYPE_VAR)
1878 class = type->type->data.generic_param->owner->owner.klass;
1879 else if (type->type->type == MONO_TYPE_MVAR)
1880 class = type->type->data.generic_param->owner->owner.method->klass;
1882 class = mono_class_from_mono_type (type->type)->nested_in;
1884 return class ? mono_type_get_object (domain, &class->byval_arg) : NULL;
1887 static MonoReflectionType*
1888 ves_icall_MonoType_get_UnderlyingSystemType (MonoReflectionType *type)
1890 MonoDomain *domain = mono_domain_get ();
1891 MonoClass *class = mono_class_from_mono_type (type->type);
1893 MONO_ARCH_SAVE_REGS;
1895 if (class->enumtype && class->enum_basetype) /* types that are modified typebuilders may not have enum_basetype set */
1896 return mono_type_get_object (domain, class->enum_basetype);
1897 else if (class->element_class)
1898 return mono_type_get_object (domain, &class->element_class->byval_arg);
1904 ves_icall_MonoType_get_Name (MonoReflectionType *type)
1906 MonoDomain *domain = mono_domain_get ();
1907 MonoClass *class = mono_class_from_mono_type (type->type);
1909 MONO_ARCH_SAVE_REGS;
1911 if (type->type->byref) {
1912 char *n = g_strdup_printf ("%s&", class->name);
1913 MonoString *res = mono_string_new (domain, n);
1919 return mono_string_new (domain, class->name);
1924 ves_icall_MonoType_get_Namespace (MonoReflectionType *type)
1926 MonoDomain *domain = mono_domain_get ();
1927 MonoClass *class = mono_class_from_mono_type (type->type);
1929 MONO_ARCH_SAVE_REGS;
1931 while (class->nested_in)
1932 class = class->nested_in;
1934 if (class->name_space [0] == '\0')
1937 return mono_string_new (domain, class->name_space);
1941 ves_icall_MonoType_GetArrayRank (MonoReflectionType *type)
1943 MonoClass *class = mono_class_from_mono_type (type->type);
1945 MONO_ARCH_SAVE_REGS;
1951 ves_icall_MonoType_GetGenericArguments (MonoReflectionType *type)
1954 MonoClass *klass, *pklass;
1956 MONO_ARCH_SAVE_REGS;
1958 klass = mono_class_from_mono_type (type->type);
1960 if (klass->generic_container) {
1961 MonoGenericContainer *container = klass->generic_container;
1962 res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, container->type_argc);
1963 for (i = 0; i < container->type_argc; ++i) {
1964 pklass = mono_class_from_generic_parameter (&container->type_params [i], klass->image, FALSE);
1965 mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), &pklass->byval_arg));
1967 } else if (klass->generic_class) {
1968 MonoGenericInst *inst = klass->generic_class->inst;
1969 res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, inst->type_argc);
1970 for (i = 0; i < inst->type_argc; ++i)
1971 mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), inst->type_argv [i]));
1973 res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, 0);
1979 ves_icall_Type_get_IsGenericTypeDefinition (MonoReflectionType *type)
1982 MONO_ARCH_SAVE_REGS;
1984 if (type->type->byref)
1987 klass = mono_class_from_mono_type (type->type);
1989 return klass->generic_container != NULL;
1992 static MonoReflectionType*
1993 ves_icall_Type_GetGenericTypeDefinition_impl (MonoReflectionType *type)
1996 MONO_ARCH_SAVE_REGS;
1998 if (type->type->byref)
2001 klass = mono_class_from_mono_type (type->type);
2002 if (klass->generic_container) {
2003 return type; /* check this one */
2005 if (klass->generic_class) {
2006 MonoClass *generic_class = klass->generic_class->container_class;
2008 if (generic_class->wastypebuilder && generic_class->reflection_info)
2009 return generic_class->reflection_info;
2011 return mono_type_get_object (mono_object_domain (type), &generic_class->byval_arg);
2016 static MonoReflectionType*
2017 ves_icall_Type_MakeGenericType (MonoReflectionType *type, MonoArray *type_array)
2019 MonoType *geninst, **types;
2022 MONO_ARCH_SAVE_REGS;
2024 count = mono_array_length (type_array);
2025 types = g_new0 (MonoType *, count);
2027 for (i = 0; i < count; i++) {
2028 MonoReflectionType *t = mono_array_get (type_array, gpointer, i);
2029 types [i] = t->type;
2032 geninst = mono_reflection_bind_generic_parameters (type, count, types);
2037 return mono_type_get_object (mono_object_domain (type), geninst);
2041 ves_icall_Type_get_IsGenericInstance (MonoReflectionType *type)
2044 MONO_ARCH_SAVE_REGS;
2046 if (type->type->byref)
2049 klass = mono_class_from_mono_type (type->type);
2050 return klass->generic_class != NULL;
2054 ves_icall_Type_get_IsGenericType (MonoReflectionType *type)
2057 MONO_ARCH_SAVE_REGS;
2059 if (type->type->byref)
2062 klass = mono_class_from_mono_type (type->type);
2063 return klass->generic_class != NULL || klass->generic_container != NULL;
2067 ves_icall_Type_GetGenericParameterPosition (MonoReflectionType *type)
2069 MONO_ARCH_SAVE_REGS;
2071 if (is_generic_parameter (type->type))
2072 return type->type->data.generic_param->num;
2076 static GenericParameterAttributes
2077 ves_icall_Type_GetGenericParameterAttributes (MonoReflectionType *type)
2079 MONO_ARCH_SAVE_REGS;
2080 g_assert (is_generic_parameter (type->type));
2081 return type->type->data.generic_param->flags;
2085 ves_icall_Type_GetGenericParameterConstraints (MonoReflectionType *type)
2087 MonoGenericParam *param;
2093 MONO_ARCH_SAVE_REGS;
2095 domain = mono_object_domain (type);
2096 param = type->type->data.generic_param;
2097 for (count = 0, ptr = param->constraints; ptr && *ptr; ptr++, count++)
2100 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2101 for (i = 0; i < count; i++)
2102 mono_array_setref (res, i, mono_type_get_object (domain, ¶m->constraints [i]->byval_arg));
2109 ves_icall_MonoType_get_IsGenericParameter (MonoReflectionType *type)
2111 MONO_ARCH_SAVE_REGS;
2112 return is_generic_parameter (type->type);
2116 ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder *tb)
2118 MONO_ARCH_SAVE_REGS;
2119 return is_generic_parameter (tb->type.type);
2123 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
2124 MonoReflectionType *t)
2126 enumtype->type = t->type;
2129 static MonoReflectionType*
2130 ves_icall_MonoGenericClass_GetParentType (MonoReflectionGenericClass *type)
2132 MonoDynamicGenericClass *gclass;
2133 MonoReflectionType *parent = NULL;
2138 MONO_ARCH_SAVE_REGS;
2140 g_assert (type->type.type->data.generic_class->is_dynamic);
2141 gclass = (MonoDynamicGenericClass *) type->type.type->data.generic_class;
2143 domain = mono_object_domain (type);
2144 klass = mono_class_from_mono_type (type->generic_type->type);
2146 if (!klass->generic_class && !klass->generic_container)
2149 if (!strcmp (type->generic_type->object.vtable->klass->name, "TypeBuilder")) {
2150 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *) type->generic_type;
2151 parent = tb->parent;
2152 } else if (klass->wastypebuilder) {
2153 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *) type->generic_type;
2154 parent = tb->parent;
2156 MonoClass *pklass = klass->parent;
2158 parent = mono_type_get_object (domain, &pklass->byval_arg);
2161 if (!parent || (parent->type->type != MONO_TYPE_GENERICINST))
2164 inflated = mono_class_inflate_generic_type (
2165 parent->type, mono_generic_class_get_context ((MonoGenericClass *) gclass));
2167 return mono_type_get_object (domain, inflated);
2171 ves_icall_MonoGenericClass_GetInterfaces (MonoReflectionGenericClass *type)
2173 static MonoClass *System_Reflection_MonoGenericClass;
2174 MonoGenericClass *gclass;
2175 MonoReflectionTypeBuilder *tb = NULL;
2176 MonoClass *klass = NULL;
2181 MONO_ARCH_SAVE_REGS;
2183 if (!System_Reflection_MonoGenericClass) {
2184 System_Reflection_MonoGenericClass = mono_class_from_name (
2185 mono_defaults.corlib, "System.Reflection", "MonoGenericClass");
2186 g_assert (System_Reflection_MonoGenericClass);
2189 domain = mono_object_domain (type);
2191 gclass = type->type.type->data.generic_class;
2192 g_assert (gclass->is_dynamic);
2194 if (!strcmp (type->generic_type->object.vtable->klass->name, "TypeBuilder")) {
2195 tb = (MonoReflectionTypeBuilder *) type->generic_type;
2196 icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
2198 klass = gclass->container_class;
2199 mono_class_init (klass);
2200 icount = klass->interface_count;
2203 res = mono_array_new (domain, System_Reflection_MonoGenericClass, icount);
2205 for (i = 0; i < icount; i++) {
2206 MonoReflectionType *iface;
2210 iface = mono_array_get (tb->interfaces, MonoReflectionType *, i);
2213 it = &klass->interfaces [i]->byval_arg;
2215 it = mono_class_inflate_generic_type (it, mono_generic_class_get_context (gclass));
2217 iface = mono_type_get_object (domain, it);
2218 mono_array_setref (res, i, iface);
2224 static MonoReflectionMethod*
2225 ves_icall_MonoGenericClass_GetCorrespondingInflatedMethod (MonoReflectionGenericClass *type,
2226 MonoReflectionMethod* generic)
2228 MonoGenericClass *gclass;
2229 MonoDynamicGenericClass *dgclass;
2233 MONO_ARCH_SAVE_REGS;
2235 gclass = type->type.type->data.generic_class;
2236 g_assert (gclass->is_dynamic);
2238 dgclass = (MonoDynamicGenericClass *) gclass;
2240 domain = mono_object_domain (type);
2242 for (i = 0; i < dgclass->count_methods; i++)
2243 if (generic->method->token == dgclass->methods [i]->token)
2244 return mono_method_get_object (domain, dgclass->methods [i], NULL);
2249 static MonoReflectionMethod*
2250 ves_icall_MonoGenericClass_GetCorrespondingInflatedConstructor (MonoReflectionGenericClass *type,
2251 MonoReflectionMethod* generic)
2253 MonoGenericClass *gclass;
2254 MonoDynamicGenericClass *dgclass;
2258 MONO_ARCH_SAVE_REGS;
2260 gclass = type->type.type->data.generic_class;
2261 g_assert (gclass->is_dynamic);
2263 dgclass = (MonoDynamicGenericClass *) gclass;
2265 domain = mono_object_domain (type);
2267 for (i = 0; i < dgclass->count_ctors; i++)
2268 if (generic->method->token == dgclass->ctors [i]->token)
2269 return mono_method_get_object (domain, dgclass->ctors [i], NULL);
2275 static MonoReflectionField*
2276 ves_icall_MonoGenericClass_GetCorrespondingInflatedField (MonoReflectionGenericClass *type,
2277 MonoString* generic_name)
2279 MonoGenericClass *gclass;
2280 MonoDynamicGenericClass *dgclass;
2282 MonoClass *refclass;
2283 char *utf8_name = mono_string_to_utf8 (generic_name);
2286 MONO_ARCH_SAVE_REGS;
2288 gclass = type->type.type->data.generic_class;
2289 g_assert (gclass->is_dynamic);
2291 dgclass = (MonoDynamicGenericClass *) gclass;
2293 refclass = mono_class_from_mono_type (type->type.type);
2295 domain = mono_object_domain (type);
2297 for (i = 0; i < dgclass->count_fields; i++)
2298 if (strcmp (utf8_name, dgclass->fields [i].name) == 0) {
2300 return mono_field_get_object (domain, refclass, &dgclass->fields [i]);
2309 static MonoReflectionMethod*
2310 ves_icall_MonoType_GetCorrespondingInflatedMethod (MonoReflectionType *type,
2311 MonoReflectionMethod* generic)
2318 MONO_ARCH_SAVE_REGS;
2320 domain = ((MonoObject *)type)->vtable->domain;
2322 klass = mono_class_from_mono_type (type->type);
2325 while ((method = mono_class_get_methods (klass, &iter))) {
2326 if (method->token == generic->method->token)
2327 return mono_method_get_object (domain, method, klass);
2334 ves_icall_MonoGenericClass_GetMethods (MonoReflectionGenericClass *type,
2335 MonoReflectionType *reflected_type)
2337 MonoGenericClass *gclass;
2338 MonoDynamicGenericClass *dgclass;
2340 MonoClass *refclass;
2344 MONO_ARCH_SAVE_REGS;
2346 gclass = type->type.type->data.generic_class;
2347 g_assert (gclass->is_dynamic);
2348 dgclass = (MonoDynamicGenericClass *) gclass;
2350 refclass = mono_class_from_mono_type (reflected_type->type);
2352 domain = mono_object_domain (type);
2353 res = mono_array_new (domain, mono_defaults.method_info_class, dgclass->count_methods);
2355 for (i = 0; i < dgclass->count_methods; i++)
2356 mono_array_setref (res, i, mono_method_get_object (domain, dgclass->methods [i], refclass));
2362 ves_icall_MonoGenericClass_GetConstructors (MonoReflectionGenericClass *type,
2363 MonoReflectionType *reflected_type)
2365 static MonoClass *System_Reflection_ConstructorInfo;
2366 MonoGenericClass *gclass;
2367 MonoDynamicGenericClass *dgclass;
2369 MonoClass *refclass;
2373 MONO_ARCH_SAVE_REGS;
2375 if (!System_Reflection_ConstructorInfo)
2376 System_Reflection_ConstructorInfo = mono_class_from_name (
2377 mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
2379 gclass = type->type.type->data.generic_class;
2380 g_assert (gclass->is_dynamic);
2381 dgclass = (MonoDynamicGenericClass *) gclass;
2383 refclass = mono_class_from_mono_type (reflected_type->type);
2385 domain = mono_object_domain (type);
2386 res = mono_array_new (domain, System_Reflection_ConstructorInfo, dgclass->count_ctors);
2388 for (i = 0; i < dgclass->count_ctors; i++)
2389 mono_array_setref (res, i, mono_method_get_object (domain, dgclass->ctors [i], refclass));
2395 ves_icall_MonoGenericClass_GetFields (MonoReflectionGenericClass *type,
2396 MonoReflectionType *reflected_type)
2398 MonoGenericClass *gclass;
2399 MonoDynamicGenericClass *dgclass;
2401 MonoClass *refclass;
2405 MONO_ARCH_SAVE_REGS;
2407 gclass = type->type.type->data.generic_class;
2408 g_assert (gclass->is_dynamic);
2409 dgclass = (MonoDynamicGenericClass *) gclass;
2411 refclass = mono_class_from_mono_type (reflected_type->type);
2413 domain = mono_object_domain (type);
2414 res = mono_array_new (domain, mono_defaults.field_info_class, dgclass->count_fields);
2416 for (i = 0; i < dgclass->count_fields; i++)
2417 mono_array_setref (res, i, mono_field_get_object (domain, refclass, &dgclass->fields [i]));
2423 ves_icall_MonoGenericClass_GetProperties (MonoReflectionGenericClass *type,
2424 MonoReflectionType *reflected_type)
2426 static MonoClass *System_Reflection_PropertyInfo;
2427 MonoGenericClass *gclass;
2428 MonoDynamicGenericClass *dgclass;
2430 MonoClass *refclass;
2434 MONO_ARCH_SAVE_REGS;
2436 if (!System_Reflection_PropertyInfo)
2437 System_Reflection_PropertyInfo = mono_class_from_name (
2438 mono_defaults.corlib, "System.Reflection", "PropertyInfo");
2440 gclass = type->type.type->data.generic_class;
2441 g_assert (gclass->is_dynamic);
2442 dgclass = (MonoDynamicGenericClass *) gclass;
2444 refclass = mono_class_from_mono_type (reflected_type->type);
2446 domain = mono_object_domain (type);
2447 res = mono_array_new (domain, System_Reflection_PropertyInfo, dgclass->count_properties);
2449 for (i = 0; i < dgclass->count_properties; i++)
2450 mono_array_setref (res, i, mono_property_get_object (domain, refclass, &dgclass->properties [i]));
2456 ves_icall_MonoGenericClass_GetEvents (MonoReflectionGenericClass *type,
2457 MonoReflectionType *reflected_type)
2459 static MonoClass *System_Reflection_EventInfo;
2460 MonoGenericClass *gclass;
2461 MonoDynamicGenericClass *dgclass;
2463 MonoClass *refclass;
2467 MONO_ARCH_SAVE_REGS;
2469 if (!System_Reflection_EventInfo)
2470 System_Reflection_EventInfo = mono_class_from_name (
2471 mono_defaults.corlib, "System.Reflection", "EventInfo");
2473 gclass = type->type.type->data.generic_class;
2474 g_assert (gclass->is_dynamic);
2475 dgclass = (MonoDynamicGenericClass *) gclass;
2477 refclass = mono_class_from_mono_type (reflected_type->type);
2479 domain = mono_object_domain (type);
2480 res = mono_array_new (domain, System_Reflection_EventInfo, dgclass->count_events);
2482 for (i = 0; i < dgclass->count_events; i++)
2483 mono_array_setref (res, i, mono_event_get_object (domain, refclass, &dgclass->events [i]));
2488 static MonoReflectionMethod *
2489 ves_icall_MonoType_get_DeclaringMethod (MonoReflectionType *type)
2494 MONO_ARCH_SAVE_REGS;
2496 if (type->type->byref || type->type->type != MONO_TYPE_MVAR)
2499 method = type->type->data.generic_param->owner->owner.method;
2501 klass = mono_class_from_mono_type (type->type);
2502 return mono_method_get_object (mono_object_domain (type), method, klass);
2505 static MonoReflectionDllImportAttribute*
2506 ves_icall_MonoMethod_GetDllImportAttribute (MonoMethod *method)
2508 static MonoClass *DllImportAttributeClass = NULL;
2509 MonoDomain *domain = mono_domain_get ();
2510 MonoReflectionDllImportAttribute *attr;
2511 MonoImage *image = method->klass->image;
2512 MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method;
2513 MonoTableInfo *tables = image->tables;
2514 MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
2515 MonoTableInfo *mr = &tables [MONO_TABLE_MODULEREF];
2516 guint32 im_cols [MONO_IMPLMAP_SIZE];
2517 guint32 scope_token;
2518 const char *import = NULL;
2519 const char *scope = NULL;
2522 if (!method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)
2525 if (!DllImportAttributeClass) {
2526 DllImportAttributeClass =
2527 mono_class_from_name (mono_defaults.corlib,
2528 "System.Runtime.InteropServices", "DllImportAttribute");
2529 g_assert (DllImportAttributeClass);
2532 if (method->klass->image->dynamic) {
2533 MonoReflectionMethodAux *method_aux =
2534 g_hash_table_lookup (
2535 ((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
2537 import = method_aux->dllentry;
2538 scope = method_aux->dll;
2542 if (piinfo->implmap_idx) {
2543 mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
2545 piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
2546 import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
2547 scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
2548 scope = mono_metadata_string_heap (image, scope_token);
2551 flags = piinfo->piflags;
2553 attr = (MonoReflectionDllImportAttribute*)mono_object_new (domain, DllImportAttributeClass);
2555 MONO_OBJECT_SETREF (attr, dll, mono_string_new (domain, scope));
2556 MONO_OBJECT_SETREF (attr, entry_point, mono_string_new (domain, import));
2557 attr->call_conv = (flags & 0x700) >> 8;
2558 attr->charset = ((flags & 0x6) >> 1) + 1;
2559 if (attr->charset == 1)
2561 attr->exact_spelling = (flags & 0x1) != 0;
2562 attr->set_last_error = (flags & 0x40) != 0;
2563 attr->best_fit_mapping = (flags & 0x30) == 0x10;
2564 attr->throw_on_unmappable = (flags & 0x3000) == 0x1000;
2565 attr->preserve_sig = FALSE;
2570 static MonoReflectionMethod *
2571 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
2573 MonoGenericContext *context;
2574 MonoMethodInflated *imethod;
2576 MONO_ARCH_SAVE_REGS;
2578 if (!method->method->is_inflated) {
2579 if (mono_method_signature (method->method)->generic_param_count)
2585 imethod = (MonoMethodInflated *) method->method;
2587 /* FIXME: should reflection_info be part of imethod? */
2588 context = mono_method_get_context (method->method);
2589 if (context->gmethod && context->gmethod->reflection_info)
2590 return context->gmethod->reflection_info;
2592 return mono_method_get_object (
2593 mono_object_domain (method), imethod->declaring, NULL);
2597 ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethod *method)
2599 MONO_ARCH_SAVE_REGS;
2601 return mono_method_signature (method->method)->generic_param_count != 0;
2605 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method)
2607 MONO_ARCH_SAVE_REGS;
2609 return !method->method->is_inflated &&
2610 (mono_method_signature (method->method)->generic_param_count != 0);
2614 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
2619 MONO_ARCH_SAVE_REGS;
2621 domain = mono_object_domain (method);
2623 if (method->method->is_inflated) {
2624 MonoGenericMethod *gmethod = mono_method_get_context (method->method)->gmethod;
2627 count = gmethod->inst->type_argc;
2628 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2630 for (i = 0; i < count; i++)
2631 mono_array_setref (res, i, mono_type_get_object (domain, gmethod->inst->type_argv [i]));
2637 count = mono_method_signature (method->method)->generic_param_count;
2638 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2640 for (i = 0; i < count; i++) {
2641 MonoGenericParam *param = &method->method->generic_container->type_params [i];
2642 MonoClass *pklass = mono_class_from_generic_parameter (
2643 param, method->method->klass->image, TRUE);
2644 mono_array_setref (res, i,
2645 mono_type_get_object (domain, &pklass->byval_arg));
2652 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoArray *params)
2655 * Invoke from reflection is supposed to always be a virtual call (the API
2656 * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
2657 * greater flexibility.
2659 MonoMethod *m = mono_get_inflated_method (method->method);
2663 MONO_ARCH_SAVE_REGS;
2665 if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
2667 if (!mono_object_isinst (this, m->klass))
2668 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
2669 m = mono_object_get_virtual_method (this, m);
2670 /* must pass the pointer to the value for valuetype methods */
2671 if (m->klass->valuetype)
2672 obj = mono_object_unbox (this);
2673 } else if (strcmp (m->name, ".ctor") && !m->wrapper_type)
2674 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
2677 pcount = params? mono_array_length (params): 0;
2678 if (pcount != mono_method_signature (m)->param_count)
2679 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
2681 if ((m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) && !strcmp (m->name, ".ctor"))
2682 mono_raise_exception (mono_exception_from_name_msg (mono_defaults.corlib, "System", "MethodAccessException", "Cannot invoke constructor of an abstract class."));
2684 if (m->klass->image->assembly->ref_only)
2685 mono_raise_exception (mono_get_exception_invalid_operation ("It is illegal to invoke a method on a type loaded using the ReflectionOnly api."));
2687 if (m->klass->rank && !strcmp (m->name, ".ctor")) {
2690 guint32 *lower_bounds;
2691 pcount = mono_array_length (params);
2692 lengths = alloca (sizeof (guint32) * pcount);
2693 for (i = 0; i < pcount; ++i)
2694 lengths [i] = *(gint32*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
2696 if (m->klass->rank == pcount) {
2697 /* Only lengths provided. */
2698 lower_bounds = NULL;
2700 g_assert (pcount == (m->klass->rank * 2));
2701 /* lower bounds are first. */
2702 lower_bounds = lengths;
2703 lengths += m->klass->rank;
2706 return (MonoObject*)mono_array_new_full (mono_object_domain (params), m->klass, lengths, lower_bounds);
2708 return mono_runtime_invoke_array (m, obj, params, NULL);
2712 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this, MonoArray *params, MonoArray **outArgs)
2714 MonoDomain *domain = mono_object_domain (method);
2715 MonoMethod *m = method->method;
2716 MonoMethodSignature *sig = mono_method_signature (m);
2717 MonoArray *out_args;
2719 int i, j, outarg_count = 0;
2721 MONO_ARCH_SAVE_REGS;
2723 if (m->klass == mono_defaults.object_class) {
2725 if (!strcmp (m->name, "FieldGetter")) {
2726 MonoClass *k = this->vtable->klass;
2730 /* If this is a proxy, then it must be a CBO */
2731 if (k == mono_defaults.transparent_proxy_class) {
2732 MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
2733 this = tp->rp->unwrapped_server;
2735 k = this->vtable->klass;
2738 name = mono_array_get (params, MonoString *, 1);
2739 str = mono_string_to_utf8 (name);
2742 MonoClassField* field = mono_class_get_field_from_name (k, str);
2744 MonoClass *field_klass = mono_class_from_mono_type (field->type);
2745 if (field_klass->valuetype)
2746 result = mono_value_box (domain, field_klass, (char *)this + field->offset);
2748 result = *((gpointer *)((char *)this + field->offset));
2750 out_args = mono_array_new (domain, mono_defaults.object_class, 1);
2751 *outArgs = out_args;
2752 mono_array_setref (out_args, 0, result);
2760 g_assert_not_reached ();
2762 } else if (!strcmp (m->name, "FieldSetter")) {
2763 MonoClass *k = this->vtable->klass;
2769 /* If this is a proxy, then it must be a CBO */
2770 if (k == mono_defaults.transparent_proxy_class) {
2771 MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
2772 this = tp->rp->unwrapped_server;
2774 k = this->vtable->klass;
2777 name = mono_array_get (params, MonoString *, 1);
2778 str = mono_string_to_utf8 (name);
2781 MonoClassField* field = mono_class_get_field_from_name (k, str);
2783 MonoClass *field_klass = mono_class_from_mono_type (field->type);
2784 MonoObject *val = mono_array_get (params, gpointer, 2);
2786 if (field_klass->valuetype) {
2787 size = mono_type_size (field->type, &align);
2788 memcpy ((char *)this + field->offset,
2789 ((char *)val) + sizeof (MonoObject), size);
2791 *(MonoObject**)((char *)this + field->offset) = val;
2793 out_args = mono_array_new (domain, mono_defaults.object_class, 0);
2794 *outArgs = out_args;
2804 g_assert_not_reached ();
2809 for (i = 0; i < mono_array_length (params); i++) {
2810 if (sig->params [i]->byref)
2814 out_args = mono_array_new (domain, mono_defaults.object_class, outarg_count);
2816 /* handle constructors only for objects already allocated */
2817 if (!strcmp (method->method->name, ".ctor"))
2820 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
2821 g_assert (!method->method->klass->valuetype);
2822 result = mono_runtime_invoke_array (method->method, this, params, NULL);
2824 for (i = 0, j = 0; i < mono_array_length (params); i++) {
2825 if (sig->params [i]->byref) {
2827 arg = mono_array_get (params, gpointer, i);
2828 mono_array_setref (out_args, j, arg);
2833 *outArgs = out_args;
2839 read_enum_value (char *mem, int type)
2843 return *(guint8*)mem;
2845 return *(gint8*)mem;
2847 return *(guint16*)mem;
2849 return *(gint16*)mem;
2851 return *(guint32*)mem;
2853 return *(gint32*)mem;
2855 return *(guint64*)mem;
2857 return *(gint64*)mem;
2859 g_assert_not_reached ();
2865 write_enum_value (char *mem, int type, guint64 value)
2869 case MONO_TYPE_I1: {
2870 guint8 *p = (guint8*)mem;
2875 case MONO_TYPE_I2: {
2876 guint16 *p = (void*)mem;
2881 case MONO_TYPE_I4: {
2882 guint32 *p = (void*)mem;
2887 case MONO_TYPE_I8: {
2888 guint64 *p = (void*)mem;
2893 g_assert_not_reached ();
2899 ves_icall_System_Enum_ToObject (MonoReflectionType *type, MonoObject *obj)
2902 MonoClass *enumc, *objc;
2906 MONO_ARCH_SAVE_REGS;
2908 MONO_CHECK_ARG_NULL (type);
2909 MONO_CHECK_ARG_NULL (obj);
2911 domain = mono_object_domain (type);
2912 enumc = mono_class_from_mono_type (type->type);
2913 objc = obj->vtable->klass;
2915 if (!enumc->enumtype)
2916 mono_raise_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
2917 if (!((objc->enumtype) || (objc->byval_arg.type >= MONO_TYPE_I1 && objc->byval_arg.type <= MONO_TYPE_U8)))
2918 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."));
2920 res = mono_object_new (domain, enumc);
2921 val = read_enum_value ((char *)obj + sizeof (MonoObject), objc->enumtype? objc->enum_basetype->type: objc->byval_arg.type);
2922 write_enum_value ((char *)res + sizeof (MonoObject), enumc->enum_basetype->type, val);
2928 ves_icall_System_Enum_get_value (MonoObject *this)
2936 MONO_ARCH_SAVE_REGS;
2941 g_assert (this->vtable->klass->enumtype);
2943 enumc = mono_class_from_mono_type (this->vtable->klass->enum_basetype);
2944 res = mono_object_new (mono_object_domain (this), enumc);
2945 dst = (char *)res + sizeof (MonoObject);
2946 src = (char *)this + sizeof (MonoObject);
2947 size = mono_class_value_size (enumc, NULL);
2949 memcpy (dst, src, size);
2955 ves_icall_get_enum_info (MonoReflectionType *type, MonoEnumInfo *info)
2957 MonoDomain *domain = mono_object_domain (type);
2958 MonoClass *enumc = mono_class_from_mono_type (type->type);
2959 guint j = 0, nvalues, crow;
2961 MonoClassField *field;
2963 MONO_ARCH_SAVE_REGS;
2965 info->utype = mono_type_get_object (domain, enumc->enum_basetype);
2966 nvalues = mono_class_num_fields (enumc) ? mono_class_num_fields (enumc) - 1 : 0;
2967 info->names = mono_array_new (domain, mono_defaults.string_class, nvalues);
2968 info->values = mono_array_new (domain, enumc, nvalues);
2972 while ((field = mono_class_get_fields (enumc, &iter))) {
2976 if (strcmp ("value__", field->name) == 0)
2978 if (mono_field_is_deleted (field))
2980 mono_array_setref (info->names, j, mono_string_new (domain, field->name));
2983 crow = mono_metadata_get_constant_index (enumc->image, mono_class_get_field_token (field), crow + 1);
2984 field->def_type = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_TYPE);
2985 crow = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_VALUE);
2986 field->data = (gpointer)mono_metadata_blob_heap (enumc->image, crow);
2990 len = mono_metadata_decode_blob_size (p, &p);
2991 switch (enumc->enum_basetype->type) {
2994 mono_array_set (info->values, gchar, j, *p);
2996 case MONO_TYPE_CHAR:
2999 mono_array_set (info->values, gint16, j, read16 (p));
3003 mono_array_set (info->values, gint32, j, read32 (p));
3007 mono_array_set (info->values, gint64, j, read64 (p));
3010 g_error ("Implement type 0x%02x in get_enum_info", enumc->enum_basetype->type);
3017 BFLAGS_IgnoreCase = 1,
3018 BFLAGS_DeclaredOnly = 2,
3019 BFLAGS_Instance = 4,
3021 BFLAGS_Public = 0x10,
3022 BFLAGS_NonPublic = 0x20,
3023 BFLAGS_FlattenHierarchy = 0x40,
3024 BFLAGS_InvokeMethod = 0x100,
3025 BFLAGS_CreateInstance = 0x200,
3026 BFLAGS_GetField = 0x400,
3027 BFLAGS_SetField = 0x800,
3028 BFLAGS_GetProperty = 0x1000,
3029 BFLAGS_SetProperty = 0x2000,
3030 BFLAGS_ExactBinding = 0x10000,
3031 BFLAGS_SuppressChangeType = 0x20000,
3032 BFLAGS_OptionalParamBinding = 0x40000
3035 static MonoReflectionField *
3036 ves_icall_Type_GetField (MonoReflectionType *type, MonoString *name, guint32 bflags)
3039 MonoClass *startklass, *klass;
3041 MonoClassField *field;
3044 int (*compare_func) (const char *s1, const char *s2) = NULL;
3045 domain = ((MonoObject *)type)->vtable->domain;
3046 klass = startklass = mono_class_from_mono_type (type->type);
3048 MONO_ARCH_SAVE_REGS;
3051 mono_raise_exception (mono_get_exception_argument_null ("name"));
3052 if (type->type->byref)
3055 compare_func = (bflags & BFLAGS_IgnoreCase) ? g_strcasecmp : strcmp;
3059 while ((field = mono_class_get_fields (klass, &iter))) {
3061 if (mono_field_is_deleted (field))
3063 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3064 if (bflags & BFLAGS_Public)
3067 if (bflags & BFLAGS_NonPublic)
3073 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
3074 if (bflags & BFLAGS_Static)
3075 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3078 if (bflags & BFLAGS_Instance)
3085 utf8_name = mono_string_to_utf8 (name);
3087 if (compare_func (field->name, utf8_name)) {
3093 return mono_field_get_object (domain, klass, field);
3095 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3102 ves_icall_Type_GetFields_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3105 MonoClass *startklass, *klass, *refklass;
3110 MonoClassField *field;
3112 MONO_ARCH_SAVE_REGS;
3114 domain = ((MonoObject *)type)->vtable->domain;
3115 if (type->type->byref)
3116 return mono_array_new (domain, mono_defaults.field_info_class, 0);
3117 klass = startklass = mono_class_from_mono_type (type->type);
3118 refklass = mono_class_from_mono_type (reftype->type);
3122 res = mono_array_new (domain, mono_defaults.field_info_class, len);
3125 while ((field = mono_class_get_fields (klass, &iter))) {
3127 if (mono_field_is_deleted (field))
3129 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3130 if (bflags & BFLAGS_Public)
3133 if (bflags & BFLAGS_NonPublic) {
3134 /* Serialization currently depends on the old behavior.
3135 * if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE || startklass == klass)*/
3142 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
3143 if (bflags & BFLAGS_Static)
3144 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3147 if (bflags & BFLAGS_Instance)
3153 member = (MonoObject*)mono_field_get_object (domain, refklass, field);
3155 MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, len * 2);
3156 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3160 mono_array_setref (res, i, member);
3163 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3166 MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, i);
3167 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3170 * Better solution for the new GC.
3171 * res->max_length = i;
3178 ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
3181 MonoClass *startklass, *klass, *refklass;
3186 int i, len, match, nslots;
3187 guint32 method_slots_default [8];
3188 guint32 *method_slots;
3189 gchar *mname = NULL;
3190 int (*compare_func) (const char *s1, const char *s2) = NULL;
3192 MONO_ARCH_SAVE_REGS;
3194 domain = ((MonoObject *)type)->vtable->domain;
3195 if (type->type->byref)
3196 return mono_array_new (domain, mono_defaults.method_info_class, 0);
3197 klass = startklass = mono_class_from_mono_type (type->type);
3198 refklass = mono_class_from_mono_type (reftype->type);
3201 mname = mono_string_to_utf8 (name);
3202 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
3205 mono_class_setup_vtable (klass);
3207 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : klass->vtable_size;
3208 if (nslots >= sizeof (method_slots_default) * 8) {
3209 method_slots = g_new0 (guint32, nslots / 32 + 1);
3211 method_slots = method_slots_default;
3212 memset (method_slots, 0, sizeof (method_slots_default));
3216 res = mono_array_new (domain, mono_defaults.method_info_class, len);
3218 mono_class_setup_vtable (klass);
3220 while ((method = mono_class_get_methods (klass, &iter))) {
3222 if (method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
3224 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3225 if (bflags & BFLAGS_Public)
3228 if (bflags & BFLAGS_NonPublic)
3234 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3235 if (bflags & BFLAGS_Static)
3236 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3239 if (bflags & BFLAGS_Instance)
3247 if (compare_func (mname, method->name))
3252 if (method->slot != -1) {
3253 g_assert (method->slot < nslots);
3254 if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
3256 method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
3259 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
3262 MonoArray *new_res = mono_array_new (domain, mono_defaults.method_info_class, len * 2);
3263 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3267 mono_array_setref (res, i, member);
3270 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3274 if (method_slots != method_slots_default)
3275 g_free (method_slots);
3277 MonoArray *new_res = mono_array_new (domain, mono_defaults.method_info_class, i);
3278 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3281 * Better solution for the new GC.
3282 * res->max_length = i;
3289 ves_icall_Type_GetConstructors_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3292 static MonoClass *System_Reflection_ConstructorInfo;
3293 MonoClass *startklass, *klass, *refklass;
3298 gpointer iter = NULL;
3300 MONO_ARCH_SAVE_REGS;
3302 domain = ((MonoObject *)type)->vtable->domain;
3303 if (type->type->byref)
3304 return mono_array_new (domain, mono_defaults.method_info_class, 0);
3305 klass = startklass = mono_class_from_mono_type (type->type);
3306 refklass = mono_class_from_mono_type (reftype->type);
3308 if (!System_Reflection_ConstructorInfo)
3309 System_Reflection_ConstructorInfo = mono_class_from_name (
3310 mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
3314 res = mono_array_new (domain, System_Reflection_ConstructorInfo, len);
3316 while ((method = mono_class_get_methods (klass, &iter))) {
3318 if (strcmp (method->name, ".ctor") && strcmp (method->name, ".cctor"))
3320 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3321 if (bflags & BFLAGS_Public)
3324 if (bflags & BFLAGS_NonPublic)
3330 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3331 if (bflags & BFLAGS_Static)
3332 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3335 if (bflags & BFLAGS_Instance)
3341 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
3344 MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, len * 2);
3345 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3349 mono_array_setref (res, i, member);
3353 MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, i);
3354 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3357 * Better solution for the new GC.
3358 * res->max_length = i;
3365 ves_icall_Type_GetPropertiesByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
3368 static MonoClass *System_Reflection_PropertyInfo;
3369 MonoClass *startklass, *klass;
3373 int i, match, nslots;
3376 guint32 method_slots_default [8];
3377 guint32 *method_slots;
3378 gchar *propname = NULL;
3379 int (*compare_func) (const char *s1, const char *s2) = NULL;
3382 MONO_ARCH_SAVE_REGS;
3384 if (!System_Reflection_PropertyInfo)
3385 System_Reflection_PropertyInfo = mono_class_from_name (
3386 mono_defaults.corlib, "System.Reflection", "PropertyInfo");
3388 domain = ((MonoObject *)type)->vtable->domain;
3389 if (type->type->byref)
3390 return mono_array_new (domain, System_Reflection_PropertyInfo, 0);
3391 klass = startklass = mono_class_from_mono_type (type->type);
3393 propname = mono_string_to_utf8 (name);
3394 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
3397 mono_class_setup_vtable (klass);
3399 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : klass->vtable_size;
3400 if (nslots >= sizeof (method_slots_default) * 8) {
3401 method_slots = g_new0 (guint32, nslots / 32 + 1);
3403 method_slots = method_slots_default;
3404 memset (method_slots, 0, sizeof (method_slots_default));
3408 res = mono_array_new (domain, System_Reflection_PropertyInfo, len);
3410 mono_class_setup_vtable (klass);
3412 while ((prop = mono_class_get_properties (klass, &iter))) {
3418 flags = method->flags;
3421 if ((prop->get && ((prop->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC)) ||
3422 (prop->set && ((prop->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC))) {
3423 if (bflags & BFLAGS_Public)
3426 if (bflags & BFLAGS_NonPublic)
3432 if (flags & METHOD_ATTRIBUTE_STATIC) {
3433 if (bflags & BFLAGS_Static)
3434 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3437 if (bflags & BFLAGS_Instance)
3446 if (compare_func (propname, prop->name))
3450 if (prop->get && prop->get->slot != -1) {
3451 if (method_slots [prop->get->slot >> 5] & (1 << (prop->get->slot & 0x1f)))
3453 method_slots [prop->get->slot >> 5] |= 1 << (prop->get->slot & 0x1f);
3455 if (prop->set && prop->set->slot != -1) {
3456 if (method_slots [prop->set->slot >> 5] & (1 << (prop->set->slot & 0x1f)))
3458 method_slots [prop->set->slot >> 5] |= 1 << (prop->set->slot & 0x1f);
3462 MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, len * 2);
3463 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3467 mono_array_setref (res, i, mono_property_get_object (domain, startklass, prop));
3470 if ((!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent)))
3474 if (method_slots != method_slots_default)
3475 g_free (method_slots);
3477 MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, i);
3478 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3481 * Better solution for the new GC.
3482 * res->max_length = i;
3488 static MonoReflectionEvent *
3489 ves_icall_MonoType_GetEvent (MonoReflectionType *type, MonoString *name, guint32 bflags)
3492 MonoClass *klass, *startklass;
3498 MONO_ARCH_SAVE_REGS;
3500 event_name = mono_string_to_utf8 (name);
3501 if (type->type->byref)
3503 klass = startklass = mono_class_from_mono_type (type->type);
3504 domain = mono_object_domain (type);
3508 while ((event = mono_class_get_events (klass, &iter))) {
3509 if (strcmp (event->name, event_name))
3512 method = event->add;
3514 method = event->remove;
3516 method = event->raise;
3518 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3519 if (!(bflags & BFLAGS_Public))
3522 if (!(bflags & BFLAGS_NonPublic))
3527 if (!(bflags & BFLAGS_NonPublic))
3530 g_free (event_name);
3531 return mono_event_get_object (domain, startklass, event);
3534 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3537 g_free (event_name);
3542 ves_icall_Type_GetEvents_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3545 static MonoClass *System_Reflection_EventInfo;
3546 MonoClass *startklass, *klass;
3553 MONO_ARCH_SAVE_REGS;
3555 if (!System_Reflection_EventInfo)
3556 System_Reflection_EventInfo = mono_class_from_name (
3557 mono_defaults.corlib, "System.Reflection", "EventInfo");
3559 domain = mono_object_domain (type);
3560 if (type->type->byref)
3561 return mono_array_new (domain, System_Reflection_EventInfo, 0);
3562 klass = startklass = mono_class_from_mono_type (type->type);
3566 res = mono_array_new (domain, System_Reflection_EventInfo, len);
3569 while ((event = mono_class_get_events (klass, &iter))) {
3571 method = event->add;
3573 method = event->remove;
3575 method = event->raise;
3577 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3578 if (bflags & BFLAGS_Public)
3581 if (bflags & BFLAGS_NonPublic)
3586 if (bflags & BFLAGS_NonPublic)
3592 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3593 if (bflags & BFLAGS_Static)
3594 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3597 if (bflags & BFLAGS_Instance)
3602 if (bflags & BFLAGS_Instance)
3608 MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, len * 2);
3609 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3613 mono_array_setref (res, i, mono_event_get_object (domain, startklass, event));
3616 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3619 MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, i);
3620 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3623 * Better solution for the new GC.
3624 * res->max_length = i;
3630 static MonoReflectionType *
3631 ves_icall_Type_GetNestedType (MonoReflectionType *type, MonoString *name, guint32 bflags)
3639 MONO_ARCH_SAVE_REGS;
3641 domain = ((MonoObject *)type)->vtable->domain;
3642 if (type->type->byref)
3644 klass = mono_class_from_mono_type (type->type);
3645 str = mono_string_to_utf8 (name);
3649 * If a nested type is generic, return its generic type definition.
3650 * Note that this means that the return value is essentially a
3651 * nested type of the generic type definition of @klass.
3653 * A note in MSDN claims that a generic type definition can have
3654 * nested types that aren't generic. In any case, the container of that
3655 * nested type would be the generic type definition.
3657 if (klass->generic_class)
3658 klass = klass->generic_class->container_class;
3660 for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
3662 nested = tmpn->data;
3663 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
3664 if (bflags & BFLAGS_Public)
3667 if (bflags & BFLAGS_NonPublic)
3672 if (strcmp (nested->name, str) == 0){
3674 return mono_type_get_object (domain, &nested->byval_arg);
3677 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3684 ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags)
3694 MONO_ARCH_SAVE_REGS;
3696 domain = ((MonoObject *)type)->vtable->domain;
3697 if (type->type->byref)
3698 return mono_array_new (domain, mono_defaults.monotype_class, 0);
3699 klass = mono_class_from_mono_type (type->type);
3702 * If a nested type is generic, return its generic type definition.
3703 * Note that this means that the return value is essentially the set
3704 * of nested types of the generic type definition of @klass.
3706 * A note in MSDN claims that a generic type definition can have
3707 * nested types that aren't generic. In any case, the container of that
3708 * nested type would be the generic type definition.
3710 if (klass->generic_class)
3711 klass = klass->generic_class->container_class;
3715 res = mono_array_new (domain, mono_defaults.monotype_class, len);
3716 for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
3718 nested = tmpn->data;
3719 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
3720 if (bflags & BFLAGS_Public)
3723 if (bflags & BFLAGS_NonPublic)
3728 member = (MonoObject*)mono_type_get_object (domain, &nested->byval_arg);
3730 MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, len * 2);
3731 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3735 mono_array_setref (res, i, member);
3739 MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, i);
3740 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3743 * Better solution for the new GC.
3744 * res->max_length = i;
3750 static MonoReflectionType*
3751 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *assembly, MonoReflectionModule *module, MonoString *name, MonoBoolean throwOnError, MonoBoolean ignoreCase)
3754 MonoType *type = NULL;
3755 MonoTypeNameParse info;
3756 gboolean type_resolve;
3758 MONO_ARCH_SAVE_REGS;
3760 /* On MS.NET, this does not fire a TypeResolve event */
3761 type_resolve = TRUE;
3762 str = mono_string_to_utf8 (name);
3763 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
3764 if (!mono_reflection_parse_type (str, &info)) {
3766 g_list_free (info.modifiers);
3767 g_list_free (info.nested);
3768 if (throwOnError) /* uhm: this is a parse error, though... */
3769 mono_raise_exception (mono_get_exception_type_load (name, NULL));
3770 /*g_print ("failed parse\n");*/
3774 if (module != NULL) {
3776 type = mono_reflection_get_type (module->image, &info, ignoreCase, &type_resolve);
3781 if (assembly->assembly->dynamic) {
3782 /* Enumerate all modules */
3783 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
3787 if (abuilder->modules) {
3788 for (i = 0; i < mono_array_length (abuilder->modules); ++i) {
3789 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
3790 type = mono_reflection_get_type (&mb->dynamic_image->image, &info, ignoreCase, &type_resolve);
3796 if (!type && abuilder->loaded_modules) {
3797 for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) {
3798 MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
3799 type = mono_reflection_get_type (mod->image, &info, ignoreCase, &type_resolve);
3806 type = mono_reflection_get_type (assembly->assembly->image, &info, ignoreCase, &type_resolve);
3808 g_list_free (info.modifiers);
3809 g_list_free (info.nested);
3811 MonoException *e = NULL;
3814 e = mono_get_exception_type_load (name, NULL);
3816 mono_loader_clear_error ();
3819 mono_raise_exception (e);
3824 if (type->type == MONO_TYPE_CLASS) {
3825 MonoClass *klass = mono_type_get_class (type);
3826 /* need to report exceptions ? */
3827 if (throwOnError && klass->exception_type) {
3828 /* report SecurityException (or others) that occured when loading the assembly */
3829 MonoException *exc = mono_class_get_exception_for_failure (klass);
3830 mono_loader_clear_error ();
3831 mono_raise_exception (exc);
3832 } else if (klass->exception_type == MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND) {
3837 /* g_print ("got it\n"); */
3838 return mono_type_get_object (mono_object_domain (assembly), type);
3842 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *assembly, MonoBoolean escaped)
3844 MonoDomain *domain = mono_object_domain (assembly);
3845 MonoAssembly *mass = assembly->assembly;
3846 MonoString *res = NULL;
3850 MONO_ARCH_SAVE_REGS;
3852 if (g_path_is_absolute (mass->image->name))
3853 absolute = g_strdup (mass->image->name);
3855 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
3859 for (i = strlen (absolute) - 1; i >= 0; i--)
3860 if (absolute [i] == '\\')
3865 uri = g_filename_to_uri (absolute, NULL, NULL);
3867 uri = g_strconcat ("file://", absolute, NULL);
3871 res = mono_string_new (domain, uri);
3879 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssembly *assembly)
3881 MonoAssembly *mass = assembly->assembly;
3883 MONO_ARCH_SAVE_REGS;
3885 return mass->in_gac;
3888 static MonoReflectionAssembly*
3889 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoString *mname, MonoObject *evidence)
3893 MonoImageOpenStatus status;
3895 MONO_ARCH_SAVE_REGS;
3897 name = mono_string_to_utf8 (mname);
3898 res = mono_assembly_load_with_partial_name (name, &status);
3904 return mono_assembly_get_object (mono_domain_get (), res);
3908 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssembly *assembly)
3910 MonoDomain *domain = mono_object_domain (assembly);
3913 MONO_ARCH_SAVE_REGS;
3915 res = mono_string_new (domain, mono_image_get_filename (assembly->assembly->image));
3921 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssembly *assembly)
3923 MONO_ARCH_SAVE_REGS;
3925 return assembly->assembly->ref_only;
3929 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssembly *assembly)
3931 MonoDomain *domain = mono_object_domain (assembly);
3933 MONO_ARCH_SAVE_REGS;
3935 return mono_string_new (domain, assembly->assembly->image->version);
3938 static MonoReflectionMethod*
3939 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssembly *assembly)
3941 guint32 token = mono_image_get_entry_point (assembly->assembly->image);
3943 MONO_ARCH_SAVE_REGS;
3947 return mono_method_get_object (mono_object_domain (assembly), mono_get_method (assembly->assembly->image, token, NULL), NULL);
3950 static MonoReflectionModule*
3951 ves_icall_System_Reflection_Assembly_get_ManifestModule (MonoReflectionAssembly *assembly)
3953 return mono_module_get_object (mono_object_domain (assembly), assembly->assembly->image);
3957 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssembly *assembly)
3959 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
3960 MonoArray *result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, table->rows);
3964 MONO_ARCH_SAVE_REGS;
3966 for (i = 0; i < table->rows; ++i) {
3967 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_MANIFEST_NAME));
3968 mono_array_setref (result, i, mono_string_new (mono_object_domain (assembly), val));
3974 create_version (MonoDomain *domain, guint32 major, guint32 minor, guint32 build, guint32 revision)
3976 static MonoClass *System_Version = NULL;
3977 static MonoMethod *create_version = NULL;
3981 if (!System_Version) {
3982 System_Version = mono_class_from_name (mono_defaults.corlib, "System", "Version");
3983 g_assert (System_Version);
3986 if (!create_version) {
3987 MonoMethodDesc *desc = mono_method_desc_new (":.ctor(int,int,int,int)", FALSE);
3988 create_version = mono_method_desc_search_in_class (desc, System_Version);
3989 g_assert (create_version);
3990 mono_method_desc_free (desc);
3996 args [3] = &revision;
3997 result = mono_object_new (domain, System_Version);
3998 mono_runtime_invoke (create_version, result, args, NULL);
4004 ves_icall_System_Reflection_Assembly_GetReferencedAssemblies (MonoReflectionAssembly *assembly)
4006 static MonoClass *System_Reflection_AssemblyName;
4008 MonoDomain *domain = mono_object_domain (assembly);
4010 static MonoMethod *create_culture = NULL;
4011 MonoImage *image = assembly->assembly->image;
4014 MONO_ARCH_SAVE_REGS;
4016 if (!System_Reflection_AssemblyName)
4017 System_Reflection_AssemblyName = mono_class_from_name (
4018 mono_defaults.corlib, "System.Reflection", "AssemblyName");
4020 t = &assembly->assembly->image->tables [MONO_TABLE_ASSEMBLYREF];
4023 result = mono_array_new (domain, System_Reflection_AssemblyName, count);
4026 MonoMethodDesc *desc = mono_method_desc_new (
4027 "System.Globalization.CultureInfo:CreateSpecificCulture(string)", TRUE);
4028 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4029 g_assert (create_culture);
4030 mono_method_desc_free (desc);
4033 for (i = 0; i < count; i++) {
4034 MonoReflectionAssemblyName *aname;
4035 guint32 cols [MONO_ASSEMBLYREF_SIZE];
4037 mono_metadata_decode_row (t, i, cols, MONO_ASSEMBLYREF_SIZE);
4039 aname = (MonoReflectionAssemblyName *) mono_object_new (
4040 domain, System_Reflection_AssemblyName);
4042 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_NAME])));
4044 aname->major = cols [MONO_ASSEMBLYREF_MAJOR_VERSION];
4045 aname->minor = cols [MONO_ASSEMBLYREF_MINOR_VERSION];
4046 aname->build = cols [MONO_ASSEMBLYREF_BUILD_NUMBER];
4047 aname->revision = cols [MONO_ASSEMBLYREF_REV_NUMBER];
4048 aname->flags = cols [MONO_ASSEMBLYREF_FLAGS];
4049 aname->versioncompat = 1; /* SameMachine (default) */
4050 aname->hashalg = ASSEMBLY_HASH_SHA1; /* SHA1 (default) */
4051 MONO_OBJECT_SETREF (aname, version, create_version (domain, aname->major, aname->minor, aname->build, aname->revision));
4053 if (create_culture) {
4055 args [0] = mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_CULTURE]));
4056 MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
4059 if (cols [MONO_ASSEMBLYREF_PUBLIC_KEY]) {
4060 const gchar *pkey_ptr = mono_metadata_blob_heap (image, cols [MONO_ASSEMBLYREF_PUBLIC_KEY]);
4061 guint32 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
4063 if ((cols [MONO_ASSEMBLYREF_FLAGS] & ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG)) {
4064 /* public key token isn't copied - the class library will
4065 automatically generate it from the public key if required */
4066 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4067 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
4069 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4070 memcpy (mono_array_addr (aname->keyToken, guint8, 0), pkey_ptr, pkey_len);
4074 /* note: this function doesn't return the codebase on purpose (i.e. it can
4075 be used under partial trust as path information isn't present). */
4077 mono_array_setref (result, i, aname);
4088 foreach_namespace (const char* key, gconstpointer val, NameSpaceInfo *info)
4090 MonoString *name = mono_string_new (mono_object_domain (info->res), key);
4092 mono_array_setref (info->res, info->idx, name);
4097 ves_icall_System_Reflection_Assembly_GetNamespaces (MonoReflectionAssembly *assembly)
4099 MonoImage *img = assembly->assembly->image;
4103 MONO_ARCH_SAVE_REGS;
4105 if (!img->name_cache)
4106 mono_image_init_name_cache (img);
4108 res = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, g_hash_table_size (img->name_cache));
4111 g_hash_table_foreach (img->name_cache, (GHFunc)foreach_namespace, &info);
4116 /* move this in some file in mono/util/ */
4118 g_concat_dir_and_file (const char *dir, const char *file)
4120 g_return_val_if_fail (dir != NULL, NULL);
4121 g_return_val_if_fail (file != NULL, NULL);
4124 * If the directory name doesn't have a / on the end, we need
4125 * to add one so we get a proper path to the file
4127 if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
4128 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
4130 return g_strconcat (dir, file, NULL);
4134 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssembly *assembly, MonoString *name, gint32 *size, MonoReflectionModule **ref_module)
4136 char *n = mono_string_to_utf8 (name);
4137 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4139 guint32 cols [MONO_MANIFEST_SIZE];
4140 guint32 impl, file_idx;
4144 MONO_ARCH_SAVE_REGS;
4146 for (i = 0; i < table->rows; ++i) {
4147 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4148 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4149 if (strcmp (val, n) == 0)
4153 if (i == table->rows)
4156 impl = cols [MONO_MANIFEST_IMPLEMENTATION];
4159 * this code should only be called after obtaining the
4160 * ResourceInfo and handling the other cases.
4162 g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
4163 file_idx = impl >> MONO_IMPLEMENTATION_BITS;
4165 module = mono_image_load_file_for_image (assembly->assembly->image, file_idx);
4170 module = assembly->assembly->image;
4172 *ref_module = mono_module_get_object (mono_domain_get (), module);
4174 return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
4178 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoManifestResourceInfo *info)
4180 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4182 guint32 cols [MONO_MANIFEST_SIZE];
4183 guint32 file_cols [MONO_FILE_SIZE];
4187 MONO_ARCH_SAVE_REGS;
4189 n = mono_string_to_utf8 (name);
4190 for (i = 0; i < table->rows; ++i) {
4191 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4192 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4193 if (strcmp (val, n) == 0)
4197 if (i == table->rows)
4200 if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
4201 info->location = RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST;
4204 switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
4205 case MONO_IMPLEMENTATION_FILE:
4206 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4207 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4208 mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
4209 val = mono_metadata_string_heap (assembly->assembly->image, file_cols [MONO_FILE_NAME]);
4210 MONO_OBJECT_SETREF (info, filename, mono_string_new (mono_object_domain (assembly), val));
4211 if (file_cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA)
4214 info->location = RESOURCE_LOCATION_EMBEDDED;
4217 case MONO_IMPLEMENTATION_ASSEMBLYREF:
4218 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4219 mono_assembly_load_reference (assembly->assembly->image, i - 1);
4220 if (assembly->assembly->image->references [i - 1] == (gpointer)-1) {
4221 char *msg = g_strdup_printf ("Assembly %d referenced from assembly %s not found ", i - 1, assembly->assembly->image->name);
4222 MonoException *ex = mono_get_exception_file_not_found2 (msg, NULL);
4224 mono_raise_exception (ex);
4226 MONO_OBJECT_SETREF (info, assembly, mono_assembly_get_object (mono_domain_get (), assembly->assembly->image->references [i - 1]));
4228 /* Obtain info recursively */
4229 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (info->assembly, name, info);
4230 info->location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
4233 case MONO_IMPLEMENTATION_EXP_TYPE:
4234 g_assert_not_reached ();
4243 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoBoolean resource_modules)
4245 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4246 MonoArray *result = NULL;
4251 MONO_ARCH_SAVE_REGS;
4253 /* check hash if needed */
4255 n = mono_string_to_utf8 (name);
4256 for (i = 0; i < table->rows; ++i) {
4257 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4258 if (strcmp (val, n) == 0) {
4261 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4262 fn = mono_string_new (mono_object_domain (assembly), n);
4264 return (MonoObject*)fn;
4272 for (i = 0; i < table->rows; ++i) {
4273 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA))
4277 result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, count);
4280 for (i = 0; i < table->rows; ++i) {
4281 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4282 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4283 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4284 mono_array_setref (result, count, mono_string_new (mono_object_domain (assembly), n));
4289 return (MonoObject*)result;
4293 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly *assembly)
4295 MonoDomain *domain = mono_domain_get();
4298 int i, j, file_count = 0;
4299 MonoImage **modules;
4300 guint32 module_count, real_module_count;
4301 MonoTableInfo *table;
4303 g_assert (assembly->assembly->image != NULL);
4305 if (assembly->assembly->dynamic) {
4306 MonoReflectionAssemblyBuilder *assemblyb = (MonoReflectionAssemblyBuilder*)assembly;
4308 if (assemblyb->modules)
4309 module_count = mono_array_length (assemblyb->modules);
4312 real_module_count = module_count;
4314 modules = g_new0 (MonoImage*, module_count);
4315 if (assemblyb->modules) {
4316 for (i = 0; i < mono_array_length (assemblyb->modules); ++i) {
4318 mono_array_get (assemblyb->modules, MonoReflectionModuleBuilder*, i)->module.image;
4323 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4324 file_count = table->rows;
4326 modules = assembly->assembly->image->modules;
4327 module_count = assembly->assembly->image->module_count;
4329 real_module_count = 0;
4330 for (i = 0; i < module_count; ++i)
4332 real_module_count ++;
4335 klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "Module");
4336 res = mono_array_new (domain, klass, 1 + real_module_count + file_count);
4338 mono_array_setref (res, 0, mono_module_get_object (domain, assembly->assembly->image));
4340 for (i = 0; i < module_count; ++i)
4342 mono_array_setref (res, j, mono_module_get_object (domain, modules[i]));
4346 for (i = 0; i < file_count; ++i, ++j)
4347 mono_array_setref (res, j, mono_module_file_get_object (domain, assembly->assembly->image, i));
4349 if (assembly->assembly->dynamic)
4355 static MonoReflectionMethod*
4356 ves_icall_GetCurrentMethod (void)
4358 MonoMethod *m = mono_method_get_last_managed ();
4360 MONO_ARCH_SAVE_REGS;
4362 return mono_method_get_object (mono_domain_get (), m, NULL);
4365 static MonoReflectionMethod*
4366 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternal (MonoMethod *method)
4368 return mono_method_get_object (mono_domain_get (), method, NULL);
4371 static MonoReflectionMethodBody*
4372 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod *method)
4374 return mono_method_body_get_object (mono_domain_get (), method);
4377 static MonoReflectionAssembly*
4378 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (void)
4380 MonoMethod *m = mono_method_get_last_managed ();
4382 MONO_ARCH_SAVE_REGS;
4384 return mono_assembly_get_object (mono_domain_get (), m->klass->image->assembly);
4388 static MonoReflectionAssembly*
4389 ves_icall_System_Reflection_Assembly_GetEntryAssembly (void)
4391 MonoDomain* domain = mono_domain_get ();
4393 MONO_ARCH_SAVE_REGS;
4395 if (!domain->entry_assembly)
4398 return mono_assembly_get_object (domain, domain->entry_assembly);
4401 static MonoReflectionAssembly*
4402 ves_icall_System_Reflection_Assembly_GetCallingAssembly (void)
4404 MonoMethod *m = mono_method_get_last_managed ();
4405 MonoMethod *dest = m;
4407 MONO_ARCH_SAVE_REGS;
4409 mono_stack_walk_no_il (get_caller, &dest);
4412 return mono_assembly_get_object (mono_domain_get (), dest->klass->image->assembly);
4416 ves_icall_System_MonoType_getFullName (MonoReflectionType *object, gboolean full_name,
4417 gboolean assembly_qualified)
4419 MonoDomain *domain = mono_object_domain (object);
4420 MonoTypeNameFormat format;
4424 MONO_ARCH_SAVE_REGS;
4426 format = assembly_qualified ?
4427 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
4428 MONO_TYPE_NAME_FORMAT_FULL_NAME;
4430 format = MONO_TYPE_NAME_FORMAT_REFLECTION;
4432 name = mono_type_get_name_full (object->type, format);
4436 if (full_name && (object->type->type == MONO_TYPE_VAR || object->type->type == MONO_TYPE_MVAR))
4439 res = mono_string_new (domain, name);
4446 fill_reflection_assembly_name (MonoDomain *domain, MonoReflectionAssemblyName *aname, MonoAssemblyName *name, const char *absolute, gboolean by_default_version)
4448 static MonoMethod *create_culture = NULL;
4451 const char *pkey_ptr;
4454 MONO_ARCH_SAVE_REGS;
4456 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, name->name));
4457 aname->major = name->major;
4458 aname->minor = name->minor;
4459 aname->build = name->build;
4460 aname->revision = name->revision;
4461 aname->hashalg = name->hash_alg;
4462 if (by_default_version)
4463 MONO_OBJECT_SETREF (aname, version, create_version (domain, name->major, name->minor, name->build, name->revision));
4465 codebase = g_filename_to_uri (absolute, NULL, NULL);
4467 MONO_OBJECT_SETREF (aname, codebase, mono_string_new (domain, codebase));
4471 if (!create_culture) {
4472 MonoMethodDesc *desc = mono_method_desc_new ("System.Globalization.CultureInfo:CreateSpecificCulture(string)", TRUE);
4473 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4474 g_assert (create_culture);
4475 mono_method_desc_free (desc);
4478 if (name->culture) {
4479 args [0] = mono_string_new (domain, name->culture);
4480 MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
4483 if (name->public_key) {
4484 pkey_ptr = (char*)name->public_key;
4485 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
4487 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4488 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
4491 /* MonoAssemblyName keeps the public key token as an hexadecimal string */
4492 if (name->public_key_token [0]) {
4496 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, 8));
4497 p = mono_array_addr (aname->keyToken, char, 0);
4499 for (i = 0, j = 0; i < 8; i++) {
4500 *p = g_ascii_xdigit_value (name->public_key_token [j++]) << 4;
4501 *p |= g_ascii_xdigit_value (name->public_key_token [j++]);
4508 ves_icall_System_Reflection_Assembly_FillName (MonoReflectionAssembly *assembly, MonoReflectionAssemblyName *aname)
4511 MonoAssembly *mass = assembly->assembly;
4513 MONO_ARCH_SAVE_REGS;
4515 if (g_path_is_absolute (mass->image->name)) {
4516 fill_reflection_assembly_name (mono_object_domain (assembly),
4517 aname, &mass->aname, mass->image->name, TRUE);
4520 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4522 fill_reflection_assembly_name (mono_object_domain (assembly),
4523 aname, &mass->aname, absolute, TRUE);
4529 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoString *fname, MonoReflectionAssemblyName *aname)
4532 MonoImageOpenStatus status = MONO_IMAGE_OK;
4535 MonoAssemblyName name;
4537 MONO_ARCH_SAVE_REGS;
4539 filename = mono_string_to_utf8 (fname);
4541 image = mono_image_open (filename, &status);
4547 if (status == MONO_IMAGE_IMAGE_INVALID)
4548 exc = mono_get_exception_bad_image_format2 (NULL, fname);
4550 exc = mono_get_exception_file_not_found2 (NULL, fname);
4551 mono_raise_exception (exc);
4554 res = mono_assembly_fill_assembly_name (image, &name);
4556 mono_image_close (image);
4558 mono_raise_exception (mono_get_exception_argument ("assemblyFile", "The file does not contain a manifest"));
4561 fill_reflection_assembly_name (mono_domain_get (), aname, &name, filename, TRUE);
4564 mono_image_close (image);
4568 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssembly *assembly,
4569 char **minimum, guint32 *minLength, char **optional, guint32 *optLength, char **refused, guint32 *refLength)
4571 MonoBoolean result = FALSE;
4572 MonoDeclSecurityEntry entry;
4574 /* SecurityAction.RequestMinimum */
4575 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQMIN, &entry)) {
4576 *minimum = entry.blob;
4577 *minLength = entry.size;
4580 /* SecurityAction.RequestOptional */
4581 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQOPT, &entry)) {
4582 *optional = entry.blob;
4583 *optLength = entry.size;
4586 /* SecurityAction.RequestRefuse */
4587 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQREFUSE, &entry)) {
4588 *refused = entry.blob;
4589 *refLength = entry.size;
4597 mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoBoolean exportedOnly)
4601 MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
4603 guint32 attrs, visibility;
4605 /* we start the count from 1 because we skip the special type <Module> */
4608 for (i = 1; i < tdef->rows; ++i) {
4609 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
4610 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
4611 if (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)
4615 count = tdef->rows - 1;
4617 res = mono_array_new (domain, mono_defaults.monotype_class, count);
4619 for (i = 1; i < tdef->rows; ++i) {
4620 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
4621 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
4622 if (!exportedOnly || (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)) {
4623 klass = mono_class_get_throw (image, (i + 1) | MONO_TOKEN_TYPE_DEF);
4624 if (mono_loader_get_last_error ())
4625 mono_loader_clear_error ();
4626 mono_array_setref (res, count, mono_type_get_object (domain, &klass->byval_arg));
4635 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly, MonoBoolean exportedOnly)
4637 MonoArray *res = NULL;
4638 MonoImage *image = NULL;
4639 MonoTableInfo *table = NULL;
4644 MONO_ARCH_SAVE_REGS;
4646 domain = mono_object_domain (assembly);
4648 if (assembly->assembly->dynamic) {
4649 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
4650 if (abuilder->modules) {
4651 for (i = 0; i < mono_array_length(abuilder->modules); i++) {
4652 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
4653 MonoArray *append = mb->types;
4654 /* The types array might not be fully filled up */
4655 if (append && mb->num_types > 0) {
4658 len1 = res ? mono_array_length (res) : 0;
4659 len2 = mb->num_types;
4660 new = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4662 mono_array_memcpy_refs (new, 0, res, 0, len1);
4663 mono_array_memcpy_refs (new, len1, append, 0, len2);
4669 * Replace TypeBuilders with the created types to be compatible
4673 for (i = 0; i < mono_array_length (res); ++i) {
4674 MonoReflectionTypeBuilder *tb = mono_array_get (res, MonoReflectionTypeBuilder*, i);
4676 mono_array_setref (res, i, tb->created);
4681 if (abuilder->loaded_modules)
4682 for (i = 0; i < mono_array_length(abuilder->loaded_modules); i++) {
4683 MonoReflectionModule *rm = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
4684 MonoArray *append = mono_module_get_types (domain, rm->image, exportedOnly);
4685 if (append && mono_array_length (append) > 0) {
4688 len1 = res ? mono_array_length (res) : 0;
4689 len2 = mono_array_length (append);
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);
4700 return mono_array_new (domain, mono_defaults.monotype_class, 0);
4702 image = assembly->assembly->image;
4703 table = &image->tables [MONO_TABLE_FILE];
4704 res = mono_module_get_types (domain, image, exportedOnly);
4706 /* Append data from all modules in the assembly */
4707 for (i = 0; i < table->rows; ++i) {
4708 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4709 MonoImage *loaded_image = mono_assembly_load_module (image->assembly, i + 1);
4711 MonoArray *res2 = mono_module_get_types (domain, loaded_image, exportedOnly);
4712 /* Append the new types to the end of the array */
4713 if (mono_array_length (res2) > 0) {
4717 len1 = mono_array_length (res);
4718 len2 = mono_array_length (res2);
4719 res3 = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4720 mono_array_memcpy_refs (res3, 0, res, 0, len1);
4721 mono_array_memcpy_refs (res3, len1, res2, 0, len2);
4728 /* the ReflectionTypeLoadException must have all the types (Types property),
4729 * NULL replacing types which throws an exception. The LoaderException must
4730 * contain all exceptions for NULL items.
4733 len = mono_array_length (res);
4735 for (i = 0; i < len; i++) {
4736 MonoReflectionType *t = mono_array_get (res, gpointer, i);
4737 MonoClass *klass = mono_type_get_class (t->type);
4738 if ((klass != NULL) && klass->exception_type) {
4739 /* keep the class in the list */
4740 list = g_list_append (list, klass);
4741 /* and replace Type with NULL */
4742 mono_array_setref (res, i, NULL);
4748 MonoException *exc = NULL;
4749 MonoArray *exl = NULL;
4750 int length = g_list_length (list);
4752 mono_loader_clear_error ();
4754 exl = mono_array_new (domain, mono_defaults.exception_class, length);
4755 for (i = 0, tmp = list; i < length; i++, tmp = tmp->next) {
4756 MonoException *exc = mono_class_get_exception_for_failure (tmp->data);
4757 mono_array_setref (exl, i, exc);
4762 exc = mono_get_exception_reflection_type_load (res, exl);
4763 mono_loader_clear_error ();
4764 mono_raise_exception (exc);
4771 ves_icall_System_Reflection_AssemblyName_ParseName (MonoReflectionAssemblyName *name, MonoString *assname)
4773 MonoAssemblyName aname;
4774 MonoDomain *domain = mono_object_domain (name);
4776 gboolean is_version_defined;
4778 val = mono_string_to_utf8 (assname);
4779 if (!mono_assembly_name_parse_full (val, &aname, TRUE, &is_version_defined))
4782 fill_reflection_assembly_name (domain, name, &aname, "", is_version_defined);
4784 mono_assembly_name_free (&aname);
4785 g_free ((guint8*) aname.public_key);
4791 static MonoReflectionType*
4792 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModule *module)
4794 MonoDomain *domain = mono_object_domain (module);
4797 MONO_ARCH_SAVE_REGS;
4799 g_assert (module->image);
4801 if (module->image->dynamic && ((MonoDynamicImage*)(module->image))->initial_image)
4802 /* These images do not have a global type */
4805 klass = mono_class_get (module->image, 1 | MONO_TOKEN_TYPE_DEF);
4806 return mono_type_get_object (domain, &klass->byval_arg);
4810 ves_icall_System_Reflection_Module_Close (MonoReflectionModule *module)
4812 /*if (module->image)
4813 mono_image_close (module->image);*/
4817 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModule *module)
4819 MonoDomain *domain = mono_object_domain (module);
4821 MONO_ARCH_SAVE_REGS;
4823 g_assert (module->image);
4824 return mono_string_new (domain, module->image->guid);
4828 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine)
4830 if (image->dynamic) {
4831 MonoDynamicImage *dyn = (MonoDynamicImage*)image;
4832 *pe_kind = dyn->pe_kind;
4833 *machine = dyn->machine;
4836 *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
4837 *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
4842 ves_icall_System_Reflection_Module_get_MDStreamVersion (MonoReflectionModule *module)
4844 MonoImage *image = module->image;
4847 mono_raise_exception (mono_get_exception_not_supported (""));
4849 return (image->md_version_major << 16) | (image->md_version_minor);
4853 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModule *module)
4855 MONO_ARCH_SAVE_REGS;
4858 return mono_array_new (mono_object_domain (module), mono_defaults.monotype_class, 0);
4860 return mono_module_get_types (mono_object_domain (module), module->image, FALSE);
4864 mono_metadata_memberref_is_method (MonoImage *image, guint32 token)
4866 guint32 cols [MONO_MEMBERREF_SIZE];
4868 mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
4869 sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
4870 mono_metadata_decode_blob_size (sig, &sig);
4871 return (*sig != 0x6);
4875 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
4878 int table = mono_metadata_token_table (token);
4879 int index = mono_metadata_token_index (token);
4881 *error = ResolveTokenError_Other;
4883 /* Validate token */
4884 if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) &&
4885 (table != MONO_TABLE_TYPESPEC)) {
4886 *error = ResolveTokenError_BadTable;
4891 return mono_lookup_dynamic_token (image, token);
4893 if ((index <= 0) || (index > image->tables [table].rows)) {
4894 *error = ResolveTokenError_OutOfRange;
4898 klass = mono_class_get (image, token);
4900 return &klass->byval_arg;
4906 ves_icall_System_Reflection_Module_ResolveMethodToken (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_METHOD) && (table != MONO_TABLE_METHODSPEC) &&
4915 (table != MONO_TABLE_MEMBERREF)) {
4916 *error = ResolveTokenError_BadTable;
4921 /* FIXME: validate memberref token type */
4922 return mono_lookup_dynamic_token (image, token);
4924 if ((index <= 0) || (index > image->tables [table].rows)) {
4925 *error = ResolveTokenError_OutOfRange;
4928 if ((table == MONO_TABLE_MEMBERREF) && (!mono_metadata_memberref_is_method (image, token))) {
4929 *error = ResolveTokenError_BadTable;
4933 return mono_get_method (image, token, NULL);
4937 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
4939 int index = mono_metadata_token_index (token);
4941 *error = ResolveTokenError_Other;
4943 /* Validate token */
4944 if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
4945 *error = ResolveTokenError_BadTable;
4950 return mono_lookup_dynamic_token (image, token);
4952 if ((index <= 0) || (index >= image->heap_us.size)) {
4953 *error = ResolveTokenError_OutOfRange;
4957 /* FIXME: What to do if the index points into the middle of a string ? */
4959 return mono_ldstr (mono_domain_get (), image, index);
4962 static MonoClassField*
4963 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
4966 int table = mono_metadata_token_table (token);
4967 int index = mono_metadata_token_index (token);
4969 *error = ResolveTokenError_Other;
4971 /* Validate token */
4972 if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
4973 *error = ResolveTokenError_BadTable;
4978 /* FIXME: validate memberref token type */
4979 return mono_lookup_dynamic_token (image, token);
4981 if ((index <= 0) || (index > image->tables [table].rows)) {
4982 *error = ResolveTokenError_OutOfRange;
4985 if ((table == MONO_TABLE_MEMBERREF) && (mono_metadata_memberref_is_method (image, token))) {
4986 *error = ResolveTokenError_BadTable;
4990 return mono_field_from_token (image, token, &klass, NULL);
4995 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
4997 int table = mono_metadata_token_table (token);
4999 *error = ResolveTokenError_Other;
5002 case MONO_TABLE_TYPEDEF:
5003 case MONO_TABLE_TYPEREF:
5004 case MONO_TABLE_TYPESPEC: {
5005 MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, error);
5007 return (MonoObject*)mono_type_get_object (mono_domain_get (), t);
5011 case MONO_TABLE_METHOD:
5012 case MONO_TABLE_METHODSPEC: {
5013 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, error);
5015 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
5019 case MONO_TABLE_FIELD: {
5020 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, error);
5022 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
5026 case MONO_TABLE_MEMBERREF:
5027 if (mono_metadata_memberref_is_method (image, token)) {
5028 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, error);
5030 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
5035 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, error);
5037 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
5044 *error = ResolveTokenError_BadTable;
5050 static MonoReflectionType*
5051 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
5054 int isbyref = 0, rank;
5055 char *str = mono_string_to_utf8 (smodifiers);
5058 MONO_ARCH_SAVE_REGS;
5060 klass = mono_class_from_mono_type (tb->type.type);
5062 /* logic taken from mono_reflection_parse_type(): keep in sync */
5066 if (isbyref) { /* only one level allowed by the spec */
5073 return mono_type_get_object (mono_object_domain (tb), &klass->this_arg);
5076 klass = mono_ptr_class_get (&klass->byval_arg);
5077 mono_class_init (klass);
5088 else if (*p != '*') { /* '*' means unknown lower bound */
5099 klass = mono_array_class_get (klass, rank);
5100 mono_class_init (klass);
5107 return mono_type_get_object (mono_object_domain (tb), &klass->byval_arg);
5111 ves_icall_Type_IsArrayImpl (MonoReflectionType *t)
5116 MONO_ARCH_SAVE_REGS;
5119 res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
5124 static MonoReflectionType *
5125 ves_icall_Type_make_array_type (MonoReflectionType *type, int rank)
5127 MonoClass *klass, *aklass;
5129 MONO_ARCH_SAVE_REGS;
5131 klass = mono_class_from_mono_type (type->type);
5132 aklass = mono_array_class_get (klass, rank);
5134 return mono_type_get_object (mono_object_domain (type), &aklass->byval_arg);
5137 static MonoReflectionType *
5138 ves_icall_Type_make_byref_type (MonoReflectionType *type)
5142 MONO_ARCH_SAVE_REGS;
5144 klass = mono_class_from_mono_type (type->type);
5146 return mono_type_get_object (mono_object_domain (type), &klass->this_arg);
5149 static MonoReflectionType *
5150 ves_icall_Type_MakePointerType (MonoReflectionType *type)
5154 MONO_ARCH_SAVE_REGS;
5156 pklass = mono_ptr_class_get (type->type);
5158 return mono_type_get_object (mono_object_domain (type), &pklass->byval_arg);
5162 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
5163 MonoReflectionMethod *info)
5165 MonoClass *delegate_class = mono_class_from_mono_type (type->type);
5166 MonoObject *delegate;
5169 MONO_ARCH_SAVE_REGS;
5171 mono_assert (delegate_class->parent == mono_defaults.multicastdelegate_class);
5173 delegate = mono_object_new (mono_object_domain (type), delegate_class);
5175 func = mono_compile_method (info->method);
5177 mono_delegate_ctor (delegate, target, func);
5183 * Magic number to convert a time which is relative to
5184 * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
5186 #define EPOCH_ADJUST ((guint64)62135596800LL)
5189 * Magic number to convert FILETIME base Jan 1, 1601 to DateTime - base Jan, 1, 0001
5191 #define FILETIME_ADJUST ((guint64)504911232000000000LL)
5194 * This returns Now in UTC
5197 ves_icall_System_DateTime_GetNow (void)
5199 #ifdef PLATFORM_WIN32
5203 GetSystemTime (&st);
5204 SystemTimeToFileTime (&st, &ft);
5205 return (gint64) FILETIME_ADJUST + ((((gint64)ft.dwHighDateTime)<<32) | ft.dwLowDateTime);
5207 /* FIXME: put this in io-layer and call it GetLocalTime */
5211 MONO_ARCH_SAVE_REGS;
5213 if (gettimeofday (&tv, NULL) == 0) {
5214 res = (((gint64)tv.tv_sec + EPOCH_ADJUST)* 1000000 + tv.tv_usec)*10;
5217 /* fixme: raise exception */
5222 #ifdef PLATFORM_WIN32
5223 /* convert a SYSTEMTIME which is of the form "last thursday in october" to a real date */
5225 convert_to_absolute_date(SYSTEMTIME *date)
5227 #define IS_LEAP(y) ((y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0))
5228 static int days_in_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5229 static int leap_days_in_month[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5230 /* from the calendar FAQ */
5231 int a = (14 - date->wMonth) / 12;
5232 int y = date->wYear - a;
5233 int m = date->wMonth + 12 * a - 2;
5234 int d = (1 + y + y/4 - y/100 + y/400 + (31*m)/12) % 7;
5236 /* d is now the day of the week for the first of the month (0 == Sunday) */
5238 int day_of_week = date->wDayOfWeek;
5240 /* set day_in_month to the first day in the month which falls on day_of_week */
5241 int day_in_month = 1 + (day_of_week - d);
5242 if (day_in_month <= 0)
5245 /* wDay is 1 for first weekday in month, 2 for 2nd ... 5 means last - so work that out allowing for days in the month */
5246 date->wDay = day_in_month + (date->wDay - 1) * 7;
5247 if (date->wDay > (IS_LEAP(date->wYear) ? leap_days_in_month[date->wMonth - 1] : days_in_month[date->wMonth - 1]))
5252 #ifndef PLATFORM_WIN32
5254 * Return's the offset from GMT of a local time.
5256 * tm is a local time
5257 * t is the same local time as seconds.
5260 gmt_offset(struct tm *tm, time_t t)
5262 #if defined (HAVE_TM_GMTOFF)
5263 return tm->tm_gmtoff;
5268 g.tm_isdst = tm->tm_isdst;
5270 return (int)difftime(t, t2);
5275 * This is heavily based on zdump.c from glibc 2.2.
5277 * * data[0]: start of daylight saving time (in DateTime ticks).
5278 * * data[1]: end of daylight saving time (in DateTime ticks).
5279 * * data[2]: utcoffset (in TimeSpan ticks).
5280 * * data[3]: additional offset when daylight saving (in TimeSpan ticks).
5281 * * name[0]: name of this timezone when not daylight saving.
5282 * * name[1]: name of this timezone when daylight saving.
5284 * FIXME: This only works with "standard" Unix dates (years between 1900 and 2100) while
5285 * the class library allows years between 1 and 9999.
5287 * Returns true on success and zero on failure.
5290 ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year, MonoArray **data, MonoArray **names)
5292 #ifndef PLATFORM_WIN32
5293 MonoDomain *domain = mono_domain_get ();
5294 struct tm start, tt;
5298 int is_daylight = 0, day;
5301 MONO_ARCH_SAVE_REGS;
5303 MONO_CHECK_ARG_NULL (data);
5304 MONO_CHECK_ARG_NULL (names);
5306 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5307 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5310 * no info is better than crashing: we'll need our own tz data
5311 * to make this work properly, anyway. The range is probably
5312 * reduced to 1970 .. 2037 because that is what mktime is
5313 * guaranteed to support (we get into an infinite loop
5317 memset (&start, 0, sizeof (start));
5320 start.tm_year = year-1900;
5322 t = mktime (&start);
5324 if ((year < 1970) || (year > 2037) || (t == -1)) {
5326 tt = *localtime (&t);
5327 strftime (tzone, sizeof (tzone), "%Z", &tt);
5328 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5329 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5333 gmtoff = gmt_offset (&start, t);
5335 /* For each day of the year, calculate the tm_gmtoff. */
5336 for (day = 0; day < 365; day++) {
5339 tt = *localtime (&t);
5341 /* Daylight saving starts or ends here. */
5342 if (gmt_offset (&tt, t) != gmtoff) {
5346 /* Try to find the exact hour when daylight saving starts/ends. */
5350 tt1 = *localtime (&t1);
5351 } while (gmt_offset (&tt1, t1) != gmtoff);
5353 /* Try to find the exact minute when daylight saving starts/ends. */
5356 tt1 = *localtime (&t1);
5357 } while (gmt_offset (&tt1, t1) == gmtoff);
5359 strftime (tzone, sizeof (tzone), "%Z", &tt);
5361 /* Write data, if we're already in daylight saving, we're done. */
5363 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5364 mono_array_set ((*data), gint64, 1, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
5367 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5368 mono_array_set ((*data), gint64, 0, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
5372 /* This is only set once when we enter daylight saving. */
5373 mono_array_set ((*data), gint64, 2, (gint64)gmtoff * 10000000L);
5374 mono_array_set ((*data), gint64, 3, (gint64)(gmt_offset (&tt, t) - gmtoff) * 10000000L);
5376 gmtoff = gmt_offset (&tt, t);
5381 strftime (tzone, sizeof (tzone), "%Z", &tt);
5382 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5383 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5384 mono_array_set ((*data), gint64, 0, 0);
5385 mono_array_set ((*data), gint64, 1, 0);
5386 mono_array_set ((*data), gint64, 2, (gint64) gmtoff * 10000000L);
5387 mono_array_set ((*data), gint64, 3, 0);
5392 MonoDomain *domain = mono_domain_get ();
5393 TIME_ZONE_INFORMATION tz_info;
5398 tz_id = GetTimeZoneInformation (&tz_info);
5399 if (tz_id == TIME_ZONE_ID_INVALID)
5402 MONO_CHECK_ARG_NULL (data);
5403 MONO_CHECK_ARG_NULL (names);
5405 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5406 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5408 for (i = 0; i < 32; ++i)
5409 if (!tz_info.DaylightName [i])
5411 mono_array_setref ((*names), 1, mono_string_new_utf16 (domain, tz_info.DaylightName, i));
5412 for (i = 0; i < 32; ++i)
5413 if (!tz_info.StandardName [i])
5415 mono_array_setref ((*names), 0, mono_string_new_utf16 (domain, tz_info.StandardName, i));
5417 if ((year <= 1601) || (year > 30827)) {
5419 * According to MSDN, the MS time functions can't handle dates outside
5425 /* even if the timezone has no daylight savings it may have Bias (e.g. GMT+13 it seems) */
5426 if (tz_id != TIME_ZONE_ID_UNKNOWN) {
5427 tz_info.StandardDate.wYear = year;
5428 convert_to_absolute_date(&tz_info.StandardDate);
5429 err = SystemTimeToFileTime (&tz_info.StandardDate, &ft);
5431 mono_array_set ((*data), gint64, 1, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
5432 tz_info.DaylightDate.wYear = year;
5433 convert_to_absolute_date(&tz_info.DaylightDate);
5434 err = SystemTimeToFileTime (&tz_info.DaylightDate, &ft);
5436 mono_array_set ((*data), gint64, 0, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
5438 mono_array_set ((*data), gint64, 2, (tz_info.Bias + tz_info.StandardBias) * -600000000LL);
5439 mono_array_set ((*data), gint64, 3, (tz_info.DaylightBias - tz_info.StandardBias) * -600000000LL);
5446 ves_icall_System_Object_obj_address (MonoObject *this)
5448 MONO_ARCH_SAVE_REGS;
5455 static inline gint32
5456 mono_array_get_byte_length (MonoArray *array)
5462 klass = array->obj.vtable->klass;
5464 if (array->bounds == NULL)
5465 length = array->max_length;
5468 for (i = 0; i < klass->rank; ++ i)
5469 length *= array->bounds [i].length;
5472 switch (klass->element_class->byval_arg.type) {
5475 case MONO_TYPE_BOOLEAN:
5479 case MONO_TYPE_CHAR:
5487 return length * sizeof (gpointer);
5498 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array)
5500 MONO_ARCH_SAVE_REGS;
5502 return mono_array_get_byte_length (array);
5506 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx)
5508 MONO_ARCH_SAVE_REGS;
5510 return mono_array_get (array, gint8, idx);
5514 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value)
5516 MONO_ARCH_SAVE_REGS;
5518 mono_array_set (array, gint8, idx, value);
5522 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count)
5524 guint8 *src_buf, *dest_buf;
5526 MONO_ARCH_SAVE_REGS;
5528 /* watch out for integer overflow */
5529 if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count))
5532 src_buf = (guint8 *)src->vector + src_offset;
5533 dest_buf = (guint8 *)dest->vector + dest_offset;
5536 memcpy (dest_buf, src_buf, count);
5538 memmove (dest_buf, src_buf, count); /* Source and dest are the same array */
5544 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this, MonoString *class_name)
5546 MonoDomain *domain = mono_object_domain (this);
5548 MonoRealProxy *rp = ((MonoRealProxy *)this);
5549 MonoTransparentProxy *tp;
5553 MONO_ARCH_SAVE_REGS;
5555 res = mono_object_new (domain, mono_defaults.transparent_proxy_class);
5556 tp = (MonoTransparentProxy*) res;
5558 MONO_OBJECT_SETREF (tp, rp, rp);
5559 type = ((MonoReflectionType *)rp->class_to_proxy)->type;
5560 klass = mono_class_from_mono_type (type);
5562 tp->custom_type_info = (mono_object_isinst (this, mono_defaults.iremotingtypeinfo_class) != NULL);
5563 tp->remote_class = mono_remote_class (domain, class_name, klass);
5565 res->vtable = mono_remote_class_vtable (domain, tp->remote_class, rp);
5569 static MonoReflectionType *
5570 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
5572 return mono_type_get_object (mono_object_domain (tp), &tp->remote_class->proxy_class->byval_arg);
5575 /* System.Environment */
5578 ves_icall_System_Environment_get_MachineName (void)
5580 #if defined (PLATFORM_WIN32)
5585 len = MAX_COMPUTERNAME_LENGTH + 1;
5586 buf = g_new (gunichar2, len);
5589 if (GetComputerName (buf, (PDWORD) &len))
5590 result = mono_string_new_utf16 (mono_domain_get (), buf, len);
5598 if (gethostname (buf, sizeof (buf)) == 0)
5599 result = mono_string_new (mono_domain_get (), buf);
5608 ves_icall_System_Environment_get_Platform (void)
5610 MONO_ARCH_SAVE_REGS;
5612 #if defined (PLATFORM_WIN32)
5622 ves_icall_System_Environment_get_NewLine (void)
5624 MONO_ARCH_SAVE_REGS;
5626 #if defined (PLATFORM_WIN32)
5627 return mono_string_new (mono_domain_get (), "\r\n");
5629 return mono_string_new (mono_domain_get (), "\n");
5634 ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name)
5639 MONO_ARCH_SAVE_REGS;
5644 utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
5645 value = g_getenv (utf8_name);
5652 return mono_string_new (mono_domain_get (), value);
5656 * There is no standard way to get at environ.
5658 #ifndef __MINGW32_VERSION
5666 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
5674 MONO_ARCH_SAVE_REGS;
5677 for (e = environ; *e != 0; ++ e)
5680 domain = mono_domain_get ();
5681 names = mono_array_new (domain, mono_defaults.string_class, n);
5684 for (e = environ; *e != 0; ++ e) {
5685 parts = g_strsplit (*e, "=", 2);
5687 str = mono_string_new (domain, *parts);
5688 mono_array_setref (names, n, str);
5700 * If your platform lacks setenv/unsetenv, you must upgrade your glib.
5702 #if !GLIB_CHECK_VERSION(2,4,0)
5703 #define g_setenv(a,b,c) setenv(a,b,c)
5704 #define g_unsetenv(a) unsetenv(a)
5708 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
5710 #ifdef PLATFORM_WIN32
5711 gunichar2 *utf16_name, *utf16_value;
5713 gchar *utf8_name, *utf8_value;
5716 MONO_ARCH_SAVE_REGS;
5718 #ifdef PLATFORM_WIN32
5719 utf16_name = mono_string_to_utf16 (name);
5720 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
5721 SetEnvironmentVariable (utf16_name, NULL);
5722 g_free (utf16_name);
5726 utf16_value = mono_string_to_utf16 (value);
5728 SetEnvironmentVariable (utf16_name, utf16_value);
5730 g_free (utf16_name);
5731 g_free (utf16_value);
5733 utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
5735 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
5736 g_unsetenv (utf8_name);
5741 utf8_value = mono_string_to_utf8 (value);
5742 g_setenv (utf8_name, utf8_value, TRUE);
5745 g_free (utf8_value);
5750 * Returns: the number of milliseconds elapsed since the system started.
5753 ves_icall_System_Environment_get_TickCount (void)
5755 return GetTickCount ();
5760 ves_icall_System_Environment_Exit (int result)
5762 MONO_ARCH_SAVE_REGS;
5764 mono_runtime_set_shutting_down ();
5766 /* Suspend all managed threads since the runtime is going away */
5767 mono_thread_suspend_all_other_threads ();
5769 mono_runtime_quit ();
5771 /* we may need to do some cleanup here... */
5776 ves_icall_System_Environment_GetGacPath (void)
5778 return mono_string_new (mono_domain_get (), mono_assembly_getrootdir ());
5782 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
5784 #if defined (PLATFORM_WIN32)
5785 #ifndef CSIDL_FLAG_CREATE
5786 #define CSIDL_FLAG_CREATE 0x8000
5789 WCHAR path [MAX_PATH];
5790 /* Create directory if no existing */
5791 if (SUCCEEDED (SHGetFolderPathW (NULL, folder | CSIDL_FLAG_CREATE, NULL, 0, path))) {
5795 return mono_string_new_utf16 (mono_domain_get (), path, len);
5798 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
5800 return mono_string_new (mono_domain_get (), "");
5804 ves_icall_System_Environment_GetLogicalDrives (void)
5806 gunichar2 buf [128], *ptr, *dname;
5808 gint initial_size = 127, size = 128;
5811 MonoString *drivestr;
5812 MonoDomain *domain = mono_domain_get ();
5815 MONO_ARCH_SAVE_REGS;
5820 while (size > initial_size) {
5821 size = GetLogicalDriveStrings (initial_size, ptr);
5822 if (size > initial_size) {
5825 ptr = g_malloc0 ((size + 1) * sizeof (gunichar2));
5826 initial_size = size;
5840 result = mono_array_new (domain, mono_defaults.string_class, ndrives);
5845 while (*u16) { u16++; len ++; }
5846 drivestr = mono_string_new_utf16 (domain, dname, len);
5847 mono_array_setref (result, ndrives++, drivestr);
5858 ves_icall_System_Environment_InternalGetHome (void)
5860 MONO_ARCH_SAVE_REGS;
5862 return mono_string_new (mono_domain_get (), g_get_home_dir ());
5865 static const char *encodings [] = {
5867 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
5868 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
5869 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
5871 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
5872 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
5873 "x_unicode_2_0_utf_7",
5875 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
5876 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
5878 "utf_16", "UTF_16LE", "ucs_2", "unicode",
5881 "unicodefffe", "utf_16be",
5888 * Returns the internal codepage, if the value of "int_code_page" is
5889 * 1 at entry, and we can not compute a suitable code page number,
5890 * returns the code page as a string
5893 ves_icall_System_Text_Encoding_InternalCodePage (gint32 *int_code_page)
5898 char *codepage = NULL;
5900 int want_name = *int_code_page;
5903 *int_code_page = -1;
5904 MONO_ARCH_SAVE_REGS;
5906 g_get_charset (&cset);
5907 c = codepage = strdup (cset);
5908 for (c = codepage; *c; c++){
5909 if (isascii (*c) && isalpha (*c))
5914 /* g_print ("charset: %s\n", cset); */
5916 /* handle some common aliases */
5919 for (i = 0; p != 0; ){
5920 if ((gssize) p < 7){
5922 p = encodings [++i];
5925 if (strcmp (p, codepage) == 0){
5926 *int_code_page = code;
5929 p = encodings [++i];
5932 if (strstr (codepage, "utf_8") != NULL)
5933 *int_code_page |= 0x10000000;
5936 if (want_name && *int_code_page == -1)
5937 return mono_string_new (mono_domain_get (), cset);
5943 ves_icall_System_Environment_get_HasShutdownStarted (void)
5945 if (mono_runtime_is_shutting_down ())
5948 if (mono_domain_is_unloading (mono_domain_get ()))
5955 ves_icall_MonoMethodMessage_InitMessage (MonoMethodMessage *this,
5956 MonoReflectionMethod *method,
5957 MonoArray *out_args)
5959 MONO_ARCH_SAVE_REGS;
5961 mono_message_init (mono_object_domain (this), this, method, out_args);
5965 ves_icall_IsTransparentProxy (MonoObject *proxy)
5967 MONO_ARCH_SAVE_REGS;
5972 if (proxy->vtable->klass == mono_defaults.transparent_proxy_class)
5979 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
5984 MONO_ARCH_SAVE_REGS;
5986 klass = mono_class_from_mono_type (type->type);
5987 vtable = mono_class_vtable (mono_domain_get (), klass);
5989 if (enable) vtable->remote = 1;
5990 else vtable->remote = 0;
5994 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type)
5999 MONO_ARCH_SAVE_REGS;
6001 domain = mono_object_domain (type);
6002 klass = mono_class_from_mono_type (type->type);
6004 if (klass->rank >= 1) {
6005 g_assert (klass->rank == 1);
6006 return (MonoObject *) mono_array_new (domain, klass->element_class, 0);
6008 /* Bypass remoting object creation check */
6009 return mono_object_new_alloc_specific (mono_class_vtable (domain, klass));
6014 ves_icall_System_IO_get_temp_path (void)
6016 MONO_ARCH_SAVE_REGS;
6018 return mono_string_new (mono_domain_get (), g_get_tmp_dir ());
6022 ves_icall_RuntimeMethod_GetFunctionPointer (MonoMethod *method)
6024 MONO_ARCH_SAVE_REGS;
6026 return mono_compile_method (method);
6030 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
6035 MONO_ARCH_SAVE_REGS;
6037 path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
6039 #if defined (PLATFORM_WIN32)
6040 /* Avoid mixing '/' and '\\' */
6043 for (i = strlen (path) - 1; i >= 0; i--)
6044 if (path [i] == '/')
6048 mcpath = mono_string_new (mono_domain_get (), path);
6055 ves_icall_System_Configuration_DefaultConfig_get_bundled_machine_config (void)
6057 const gchar *machine_config;
6059 MONO_ARCH_SAVE_REGS;
6061 machine_config = mono_get_machine_config ();
6063 if (!machine_config)
6066 return mono_string_new (mono_domain_get (), machine_config);
6070 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
6075 MONO_ARCH_SAVE_REGS;
6077 path = g_path_get_dirname (mono_get_config_dir ());
6079 #if defined (PLATFORM_WIN32)
6080 /* Avoid mixing '/' and '\\' */
6083 for (i = strlen (path) - 1; i >= 0; i--)
6084 if (path [i] == '/')
6088 ipath = mono_string_new (mono_domain_get (), path);
6095 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
6097 #if defined (PLATFORM_WIN32)
6098 OutputDebugString (mono_string_chars (message));
6100 g_warning ("WriteWindowsDebugString called and PLATFORM_WIN32 not defined!\n");
6104 /* Only used for value types */
6106 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
6111 MONO_ARCH_SAVE_REGS;
6113 domain = mono_object_domain (type);
6114 klass = mono_class_from_mono_type (type->type);
6116 if (mono_class_is_nullable (klass))
6117 /* No arguments -> null */
6120 return mono_object_new (domain, klass);
6123 static MonoReflectionMethod *
6124 ves_icall_MonoMethod_get_base_definition (MonoReflectionMethod *m)
6126 MonoClass *klass, *parent;
6127 MonoMethod *method = m->method;
6128 MonoMethod *result = NULL;
6130 MONO_ARCH_SAVE_REGS;
6132 if (method->klass == NULL)
6135 if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
6136 MONO_CLASS_IS_INTERFACE (method->klass) ||
6137 method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
6140 klass = method->klass;
6141 if (klass->generic_class)
6142 klass = klass->generic_class->container_class;
6144 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
6145 for (parent = klass->parent; parent != NULL; parent = parent->parent) {
6146 mono_class_setup_vtable (parent);
6147 if (parent->vtable_size <= method->slot)
6152 if (klass == method->klass)
6155 result = klass->vtable [method->slot];
6156 if (result == NULL) {
6157 /* It is an abstract method */
6158 gpointer iter = NULL;
6159 while ((result = mono_class_get_methods (klass, &iter)))
6160 if (result->slot == method->slot)
6167 return mono_method_get_object (mono_domain_get (), result, NULL);
6171 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
6173 MONO_ARCH_SAVE_REGS;
6175 iter->sig = *(MonoMethodSignature**)argsp;
6177 g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
6178 g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
6181 /* FIXME: it's not documented what start is exactly... */
6185 guint32 i, arg_size;
6187 iter->args = argsp + sizeof (gpointer);
6188 #ifndef MONO_ARCH_REGPARMS
6189 for (i = 0; i < iter->sig->sentinelpos; ++i) {
6190 arg_size = mono_type_stack_size (iter->sig->params [i], &align);
6191 iter->args = (char*)iter->args + arg_size;
6195 iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
6197 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
6201 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
6203 guint32 i, arg_size;
6206 MONO_ARCH_SAVE_REGS;
6208 i = iter->sig->sentinelpos + iter->next_arg;
6210 g_assert (i < iter->sig->param_count);
6212 res.type = iter->sig->params [i];
6213 res.klass = mono_class_from_mono_type (res.type);
6214 /* FIXME: endianess issue... */
6215 res.value = iter->args;
6216 arg_size = mono_type_stack_size (res.type, &align);
6217 iter->args = (char*)iter->args + arg_size;
6220 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6226 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
6228 guint32 i, arg_size;
6231 MONO_ARCH_SAVE_REGS;
6233 i = iter->sig->sentinelpos + iter->next_arg;
6235 g_assert (i < iter->sig->param_count);
6237 while (i < iter->sig->param_count) {
6238 if (!mono_metadata_type_equal (type, iter->sig->params [i]))
6240 res.type = iter->sig->params [i];
6241 res.klass = mono_class_from_mono_type (res.type);
6242 /* FIXME: endianess issue... */
6243 res.value = iter->args;
6244 arg_size = mono_type_stack_size (res.type, &align);
6245 iter->args = (char*)iter->args + arg_size;
6247 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6250 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
6259 mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
6262 MONO_ARCH_SAVE_REGS;
6264 i = iter->sig->sentinelpos + iter->next_arg;
6266 g_assert (i < iter->sig->param_count);
6268 return iter->sig->params [i];
6272 mono_TypedReference_ToObject (MonoTypedRef tref)
6274 MONO_ARCH_SAVE_REGS;
6276 if (MONO_TYPE_IS_REFERENCE (tref.type)) {
6277 MonoObject** objp = tref.value;
6281 return mono_value_box (mono_domain_get (), tref.klass, tref.value);
6285 mono_TypedReference_ToObjectInternal (MonoType *type, gpointer value, MonoClass *klass)
6287 MONO_ARCH_SAVE_REGS;
6289 if (MONO_TYPE_IS_REFERENCE (type)) {
6290 MonoObject** objp = value;
6294 return mono_value_box (mono_domain_get (), klass, value);
6298 prelink_method (MonoMethod *method)
6300 const char *exc_class, *exc_arg;
6301 if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
6303 mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
6305 mono_raise_exception(
6306 mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg ) );
6308 /* create the wrapper, too? */
6312 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
6314 MONO_ARCH_SAVE_REGS;
6315 prelink_method (method->method);
6319 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
6321 MonoClass *klass = mono_class_from_mono_type (type->type);
6323 gpointer iter = NULL;
6324 MONO_ARCH_SAVE_REGS;
6326 while ((m = mono_class_get_methods (klass, &iter)))
6330 /* These parameters are "readonly" in corlib/System/Char.cs */
6332 ves_icall_System_Char_GetDataTablePointers (guint8 const **category_data,
6333 guint8 const **numeric_data,
6334 gdouble const **numeric_data_values,
6335 guint16 const **to_lower_data_low,
6336 guint16 const **to_lower_data_high,
6337 guint16 const **to_upper_data_low,
6338 guint16 const **to_upper_data_high)
6340 *category_data = CategoryData;
6341 *numeric_data = NumericData;
6342 *numeric_data_values = NumericDataValues;
6343 *to_lower_data_low = ToLowerDataLow;
6344 *to_lower_data_high = ToLowerDataHigh;
6345 *to_upper_data_low = ToUpperDataLow;
6346 *to_upper_data_high = ToUpperDataHigh;
6350 ves_icall_MonoDebugger_GetMethodToken (MonoReflectionMethod *method)
6352 return method->method->token;
6356 * We eturn NULL for no modifiers so the corlib code can return Type.EmptyTypes
6357 * and avoid useless allocations.
6360 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional)
6364 for (i = 0; i < type->num_mods; ++i) {
6365 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
6370 res = mono_array_new (mono_domain_get (), mono_defaults.systemtype_class, count);
6372 for (i = 0; i < type->num_mods; ++i) {
6373 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
6374 MonoClass *klass = mono_class_get (image, type->modifiers [i].token);
6375 mono_array_setref (res, count, mono_type_get_object (mono_domain_get (), &klass->byval_arg));
6383 param_info_get_type_modifiers (MonoReflectionParameter *param, MonoBoolean optional)
6385 MonoType *type = param->ClassImpl->type;
6386 MonoReflectionMethod *method = (MonoReflectionMethod*)param->MemberImpl;
6387 MonoImage *image = method->method->klass->image;
6388 int pos = param->PositionImpl;
6389 MonoMethodSignature *sig = mono_method_signature (method->method);
6393 type = sig->params [pos];
6395 return type_array_from_modifiers (image, type, optional);
6399 get_property_type (MonoProperty *prop)
6401 MonoMethodSignature *sig;
6403 sig = mono_method_signature (prop->get);
6405 } else if (prop->set) {
6406 sig = mono_method_signature (prop->set);
6407 return sig->params [sig->param_count - 1];
6413 property_info_get_type_modifiers (MonoReflectionProperty *property, MonoBoolean optional)
6415 MonoType *type = get_property_type (property->property);
6416 MonoImage *image = property->klass->image;
6420 return type_array_from_modifiers (image, type, optional);
6424 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
6426 MonoCustomAttrInfo *cinfo;
6429 cinfo = mono_reflection_get_custom_attrs_info (obj);
6432 found = mono_custom_attrs_has_attr (cinfo, mono_class_from_mono_type (attr_type->type));
6434 mono_custom_attrs_free (cinfo);
6439 custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
6441 return mono_reflection_get_custom_attrs_by_type (obj, attr_type ? mono_class_from_mono_type (attr_type->type) : NULL);
6445 GCHandle_CheckCurrentDomain (guint32 gchandle)
6447 return mono_gchandle_is_in_domain (gchandle, mono_domain_get ());
6451 ves_icall_Mono_Runtime_GetDisplayName (void)
6453 static const char display_name_str [] = "Mono " VERSION;
6454 MonoString *display_name = mono_string_new (mono_domain_get (), display_name_str);
6455 return display_name;
6460 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
6461 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
6462 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 62, 128, 128, 128, 63,
6463 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 0, 128, 128,
6464 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
6465 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 128, 128, 128, 128, 128,
6466 128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
6467 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
6471 base64_to_byte_array (gunichar2 *start, gint ilength, MonoBoolean allowWhitespaceOnly)
6476 gunichar2 last, prev_last;
6484 last = prev_last = 0;
6485 for (i = 0; i < ilength; i++) {
6487 if (c >= sizeof (dbase64)) {
6488 exc = mono_exception_from_name_msg (mono_get_corlib (),
6489 "System", "FormatException",
6490 "Invalid character found.");
6491 mono_raise_exception (exc);
6492 } else if (isspace (c)) {
6500 olength = ilength - ignored;
6502 if (allowWhitespaceOnly && olength == 0) {
6503 return mono_array_new (mono_domain_get (), mono_defaults.byte_class, 0);
6506 if ((olength & 3) != 0 || olength <= 0) {
6507 exc = mono_exception_from_name_msg (mono_get_corlib (), "System",
6508 "FormatException", "Invalid length.");
6509 mono_raise_exception (exc);
6512 olength = (olength * 3) / 4;
6516 if (prev_last == '=')
6519 result = mono_array_new (mono_domain_get (), mono_defaults.byte_class, olength);
6520 res_ptr = mono_array_addr (result, guchar, 0);
6521 for (i = 0; i < ilength; ) {
6524 for (k = 0; k < 4 && i < ilength;) {
6530 if (((b [k] = dbase64 [c]) & 0x80) != 0) {
6531 exc = mono_exception_from_name_msg (mono_get_corlib (),
6532 "System", "FormatException",
6533 "Invalid character found.");
6534 mono_raise_exception (exc);
6539 *res_ptr++ = (b [0] << 2) | (b [1] >> 4);
6541 *res_ptr++ = (b [1] << 4) | (b [2] >> 2);
6543 *res_ptr++ = (b [2] << 6) | b [3];
6545 while (i < ilength && isspace (start [i]))
6553 InternalFromBase64String (MonoString *str, MonoBoolean allowWhitespaceOnly)
6555 MONO_ARCH_SAVE_REGS;
6557 return base64_to_byte_array (mono_string_chars (str),
6558 mono_string_length (str), allowWhitespaceOnly);
6562 InternalFromBase64CharArray (MonoArray *input, gint offset, gint length)
6564 MONO_ARCH_SAVE_REGS;
6566 return base64_to_byte_array (mono_array_addr (input, gunichar2, offset),
6570 #define ICALL_TYPE(id,name,first)
6571 #define ICALL(id,name,func) Icall_ ## id,
6574 #include "metadata/icall-def.h"
6580 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
6581 #define ICALL(id,name,func)
6583 #include "metadata/icall-def.h"
6589 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
6590 #define ICALL(id,name,func)
6592 guint16 first_icall;
6595 static const IcallTypeDesc
6596 icall_type_descs [] = {
6597 #include "metadata/icall-def.h"
6601 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
6604 #define ICALL_TYPE(id,name,first)
6607 #ifdef HAVE_ARRAY_ELEM_INIT
6608 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
6609 #define MSGSTRFIELD1(line) str##line
6611 static const struct msgstrtn_t {
6612 #define ICALL(id,name,func)
6614 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
6615 #include "metadata/icall-def.h"
6617 } icall_type_names_str = {
6618 #define ICALL_TYPE(id,name,first) (name),
6619 #include "metadata/icall-def.h"
6622 static const guint16 icall_type_names_idx [] = {
6623 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
6624 #include "metadata/icall-def.h"
6627 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
6629 static const struct msgstr_t {
6631 #define ICALL_TYPE(id,name,first)
6632 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
6633 #include "metadata/icall-def.h"
6635 } icall_names_str = {
6636 #define ICALL(id,name,func) (name),
6637 #include "metadata/icall-def.h"
6640 static const guint16 icall_names_idx [] = {
6641 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
6642 #include "metadata/icall-def.h"
6645 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
6651 #define ICALL_TYPE(id,name,first) name,
6652 #define ICALL(id,name,func)
6653 static const char* const
6654 icall_type_names [] = {
6655 #include "metadata/icall-def.h"
6659 #define icall_type_name_get(id) (icall_type_names [(id)])
6663 #define ICALL_TYPE(id,name,first)
6664 #define ICALL(id,name,func) name,
6665 static const char* const
6667 #include "metadata/icall-def.h"
6670 #define icall_name_get(id) icall_names [(id)]
6672 #endif /* !HAVE_ARRAY_ELEM_INIT */
6676 #define ICALL_TYPE(id,name,first)
6677 #define ICALL(id,name,func) func,
6678 static const gconstpointer
6679 icall_functions [] = {
6680 #include "metadata/icall-def.h"
6684 static GHashTable *icall_hash = NULL;
6685 static GHashTable *jit_icall_hash_name = NULL;
6686 static GHashTable *jit_icall_hash_addr = NULL;
6689 mono_icall_init (void)
6693 /* check that tables are sorted: disable in release */
6696 const char *prev_class = NULL;
6697 const char *prev_method;
6699 for (i = 0; i < Icall_type_num; ++i) {
6700 const IcallTypeDesc *desc;
6703 if (prev_class && strcmp (prev_class, icall_type_name_get (i)) >= 0)
6704 g_print ("class %s should come before class %s\n", icall_type_name_get (i), prev_class);
6705 prev_class = icall_type_name_get (i);
6706 desc = &icall_type_descs [i];
6707 num_icalls = icall_desc_num_icalls (desc);
6708 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
6709 for (j = 0; j < num_icalls; ++j) {
6710 const char *methodn = icall_name_get (desc->first_icall + j);
6711 if (prev_method && strcmp (prev_method, methodn) >= 0)
6712 g_print ("method %s should come before method %s\n", methodn, prev_method);
6713 prev_method = methodn;
6718 icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
6722 mono_icall_cleanup (void)
6724 g_hash_table_destroy (icall_hash);
6725 g_hash_table_destroy (jit_icall_hash_name);
6726 g_hash_table_destroy (jit_icall_hash_addr);
6730 mono_add_internal_call (const char *name, gconstpointer method)
6732 mono_loader_lock ();
6734 g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
6736 mono_loader_unlock ();
6739 #ifdef HAVE_ARRAY_ELEM_INIT
6741 compare_method_imap (const void *key, const void *elem)
6743 const char* method_name = (const char*)&icall_names_str + (*(guint16*)elem);
6744 return strcmp (key, method_name);
6748 find_method_icall (const IcallTypeDesc *imap, const char *name)
6750 const guint16 *nameslot = bsearch (name, icall_names_idx + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names_idx [0]), compare_method_imap);
6753 return (gpointer)icall_functions [(nameslot - &icall_names_idx [0])];
6757 compare_class_imap (const void *key, const void *elem)
6759 const char* class_name = (const char*)&icall_type_names_str + (*(guint16*)elem);
6760 return strcmp (key, class_name);
6763 static const IcallTypeDesc*
6764 find_class_icalls (const char *name)
6766 const guint16 *nameslot = bsearch (name, icall_type_names_idx, Icall_type_num, sizeof (icall_type_names_idx [0]), compare_class_imap);
6769 return &icall_type_descs [nameslot - &icall_type_names_idx [0]];
6774 compare_method_imap (const void *key, const void *elem)
6776 const char** method_name = (const char**)elem;
6777 return strcmp (key, *method_name);
6781 find_method_icall (const IcallTypeDesc *imap, const char *name)
6783 const char **nameslot = bsearch (name, icall_names + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names [0]), compare_method_imap);
6786 return (gpointer)icall_functions [(nameslot - icall_names)];
6790 compare_class_imap (const void *key, const void *elem)
6792 const char** class_name = (const char**)elem;
6793 return strcmp (key, *class_name);
6796 static const IcallTypeDesc*
6797 find_class_icalls (const char *name)
6799 const char **nameslot = bsearch (name, icall_type_names, Icall_type_num, sizeof (icall_type_names [0]), compare_class_imap);
6802 return &icall_type_descs [nameslot - icall_type_names];
6808 * we should probably export this as an helper (handle nested types).
6809 * Returns the number of chars written in buf.
6812 concat_class_name (char *buf, int bufsize, MonoClass *klass)
6814 int nspacelen, cnamelen;
6815 nspacelen = strlen (klass->name_space);
6816 cnamelen = strlen (klass->name);
6817 if (nspacelen + cnamelen + 2 > bufsize)
6820 memcpy (buf, klass->name_space, nspacelen);
6821 buf [nspacelen ++] = '.';
6823 memcpy (buf + nspacelen, klass->name, cnamelen);
6824 buf [nspacelen + cnamelen] = 0;
6825 return nspacelen + cnamelen;
6829 mono_lookup_internal_call (MonoMethod *method)
6834 int typelen = 0, mlen, siglen;
6836 const IcallTypeDesc *imap;
6838 g_assert (method != NULL);
6840 if (method->is_inflated)
6841 method = ((MonoMethodInflated *) method)->declaring;
6843 if (method->klass->nested_in) {
6844 int pos = concat_class_name (mname, sizeof (mname)-2, method->klass->nested_in);
6848 mname [pos++] = '/';
6851 typelen = concat_class_name (mname+pos, sizeof (mname)-pos-1, method->klass);
6857 typelen = concat_class_name (mname, sizeof (mname), method->klass);
6862 imap = find_class_icalls (mname);
6864 mname [typelen] = ':';
6865 mname [typelen + 1] = ':';
6867 mlen = strlen (method->name);
6868 memcpy (mname + typelen + 2, method->name, mlen);
6869 sigstart = mname + typelen + 2 + mlen;
6872 tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
6873 siglen = strlen (tmpsig);
6874 if (typelen + mlen + siglen + 6 > sizeof (mname))
6877 memcpy (sigstart + 1, tmpsig, siglen);
6878 sigstart [siglen + 1] = ')';
6879 sigstart [siglen + 2] = 0;
6882 mono_loader_lock ();
6884 res = g_hash_table_lookup (icall_hash, mname);
6886 mono_loader_unlock ();
6889 /* try without signature */
6891 res = g_hash_table_lookup (icall_hash, mname);
6893 mono_loader_unlock ();
6897 /* it wasn't found in the static call tables */
6899 mono_loader_unlock ();
6902 res = find_method_icall (imap, sigstart - mlen);
6904 mono_loader_unlock ();
6907 /* try _with_ signature */
6909 res = find_method_icall (imap, sigstart - mlen);
6911 mono_loader_unlock ();
6915 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname);
6916 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
6917 g_print ("The out of sync library is: %s\n", method->klass->image->name);
6918 g_print ("\nWhen you update one from cvs you need to update, compile and install\nthe other too.\n");
6919 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");
6920 g_print ("If you see other errors or faults after this message they are probably related\n");
6921 g_print ("and you need to fix your mono install first.\n");
6923 mono_loader_unlock ();
6929 type_from_typename (char *typename)
6931 MonoClass *klass = NULL; /* assignment to shut GCC warning up */
6933 if (!strcmp (typename, "int"))
6934 klass = mono_defaults.int_class;
6935 else if (!strcmp (typename, "ptr"))
6936 klass = mono_defaults.int_class;
6937 else if (!strcmp (typename, "void"))
6938 klass = mono_defaults.void_class;
6939 else if (!strcmp (typename, "int32"))
6940 klass = mono_defaults.int32_class;
6941 else if (!strcmp (typename, "uint32"))
6942 klass = mono_defaults.uint32_class;
6943 else if (!strcmp (typename, "int8"))
6944 klass = mono_defaults.sbyte_class;
6945 else if (!strcmp (typename, "uint8"))
6946 klass = mono_defaults.byte_class;
6947 else if (!strcmp (typename, "int16"))
6948 klass = mono_defaults.int16_class;
6949 else if (!strcmp (typename, "uint16"))
6950 klass = mono_defaults.uint16_class;
6951 else if (!strcmp (typename, "long"))
6952 klass = mono_defaults.int64_class;
6953 else if (!strcmp (typename, "ulong"))
6954 klass = mono_defaults.uint64_class;
6955 else if (!strcmp (typename, "float"))
6956 klass = mono_defaults.single_class;
6957 else if (!strcmp (typename, "double"))
6958 klass = mono_defaults.double_class;
6959 else if (!strcmp (typename, "object"))
6960 klass = mono_defaults.object_class;
6961 else if (!strcmp (typename, "obj"))
6962 klass = mono_defaults.object_class;
6965 g_assert_not_reached ();
6967 return &klass->byval_arg;
6970 MonoMethodSignature*
6971 mono_create_icall_signature (const char *sigstr)
6976 MonoMethodSignature *res;
6978 mono_loader_lock ();
6979 res = g_hash_table_lookup (mono_defaults.corlib->helper_signatures, sigstr);
6981 mono_loader_unlock ();
6985 parts = g_strsplit (sigstr, " ", 256);
6994 res = mono_metadata_signature_alloc (mono_defaults.corlib, len - 1);
6997 #ifdef PLATFORM_WIN32
6999 * Under windows, the default pinvoke calling convention is STDCALL but
7002 res->call_convention = MONO_CALL_C;
7005 res->ret = type_from_typename (parts [0]);
7006 for (i = 1; i < len; ++i) {
7007 res->params [i - 1] = type_from_typename (parts [i]);
7012 g_hash_table_insert (mono_defaults.corlib->helper_signatures, (gpointer)sigstr, res);
7014 mono_loader_unlock ();
7020 mono_find_jit_icall_by_name (const char *name)
7022 MonoJitICallInfo *info;
7023 g_assert (jit_icall_hash_name);
7025 mono_loader_lock ();
7026 info = g_hash_table_lookup (jit_icall_hash_name, name);
7027 mono_loader_unlock ();
7032 mono_find_jit_icall_by_addr (gconstpointer addr)
7034 MonoJitICallInfo *info;
7035 g_assert (jit_icall_hash_addr);
7037 mono_loader_lock ();
7038 info = g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
7039 mono_loader_unlock ();
7045 mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
7047 mono_loader_lock ();
7048 g_hash_table_insert (jit_icall_hash_addr, (gpointer)wrapper, info);
7049 mono_loader_unlock ();
7053 mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
7055 MonoJitICallInfo *info;
7060 mono_loader_lock ();
7062 if (!jit_icall_hash_name) {
7063 jit_icall_hash_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
7064 jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
7067 if (g_hash_table_lookup (jit_icall_hash_name, name)) {
7068 g_warning ("jit icall already defined \"%s\"\n", name);
7069 g_assert_not_reached ();
7072 info = g_new0 (MonoJitICallInfo, 1);
7079 info->wrapper = func;
7081 info->wrapper = NULL;
7084 g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
7085 g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
7087 mono_loader_unlock ();