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);
699 if (array->bounds == NULL)
700 size *= array->max_length;
702 for (i = 0; i < klass->rank; ++i)
703 size *= array->bounds [i].length;
705 memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
707 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
711 guint ## n *data = (guint ## n *) mono_array_addr (array, char, 0); \
713 for (i = 0; i < size; i += n/8, data++) { \
714 tmp = read ## n (data); \
719 /* printf ("Initialize array with elements of %s type\n", klass->element_class->name); */
721 switch (mono_type_get_underlying_type (&klass->element_class->byval_arg)->type) {
741 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData (void)
745 return offsetof (MonoString, chars);
749 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue (MonoObject *obj)
753 if ((obj == NULL) || (! (obj->vtable->klass->valuetype)))
756 return mono_object_clone (obj);
760 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (MonoType *handle)
766 MONO_CHECK_ARG_NULL (handle);
768 klass = mono_class_from_mono_type (handle);
769 MONO_CHECK_ARG (handle, klass);
771 /* This will call the type constructor */
772 if (! (klass->flags & TYPE_ATTRIBUTE_INTERFACE))
773 mono_runtime_class_init (mono_class_vtable (mono_domain_get (), klass));
777 ves_icall_System_Object_MemberwiseClone (MonoObject *this)
781 return mono_object_clone (this);
785 ves_icall_System_ValueType_InternalGetHashCode (MonoObject *this, MonoArray **fields)
788 MonoObject **values = NULL;
792 MonoClassField* field;
797 klass = mono_object_class (this);
799 if (mono_class_num_fields (klass) == 0)
800 return mono_object_hash (this);
803 * Compute the starting value of the hashcode for fields of primitive
804 * types, and return the remaining fields in an array to the managed side.
805 * This way, we can avoid costly reflection operations in managed code.
808 while ((field = mono_class_get_fields (klass, &iter))) {
809 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
811 if (mono_field_is_deleted (field))
813 /* FIXME: Add more types */
814 switch (field->type->type) {
816 result ^= *(gint32*)((guint8*)this + field->offset);
818 case MONO_TYPE_STRING: {
820 s = *(MonoString**)((guint8*)this + field->offset);
822 result ^= mono_string_hash (s);
827 values = g_newa (MonoObject*, mono_class_num_fields (klass));
828 o = mono_field_get_value_object (mono_object_domain (this), field, this);
829 values [count++] = o;
835 *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
836 for (i = 0; i < count; ++i)
837 mono_array_setref (*fields, i, values [i]);
845 ves_icall_System_ValueType_Equals (MonoObject *this, MonoObject *that, MonoArray **fields)
848 MonoObject **values = NULL;
850 MonoClassField* field;
856 MONO_CHECK_ARG_NULL (that);
858 if (this->vtable != that->vtable)
861 klass = mono_object_class (this);
864 * Do the comparison for fields of primitive type and return a result if
865 * possible. Otherwise, return the remaining fields in an array to the
866 * managed side. This way, we can avoid costly reflection operations in
871 while ((field = mono_class_get_fields (klass, &iter))) {
872 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
874 if (mono_field_is_deleted (field))
876 /* FIXME: Add more types */
877 switch (field->type->type) {
879 if (*(gint32*)((guint8*)this + field->offset) != *(gint32*)((guint8*)that + field->offset))
882 case MONO_TYPE_STRING: {
884 guint32 s1len, s2len;
885 s1 = *(MonoString**)((guint8*)this + field->offset);
886 s2 = *(MonoString**)((guint8*)that + field->offset);
889 if ((s1 == NULL) || (s2 == NULL))
891 s1len = mono_string_length (s1);
892 s2len = mono_string_length (s2);
896 if (memcmp (mono_string_chars (s1), mono_string_chars (s2), s1len * sizeof (gunichar2)) != 0)
902 values = g_newa (MonoObject*, mono_class_num_fields (klass) * 2);
903 o = mono_field_get_value_object (mono_object_domain (this), field, this);
904 values [count++] = o;
905 o = mono_field_get_value_object (mono_object_domain (this), field, that);
906 values [count++] = o;
912 *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
913 for (i = 0; i < count; ++i)
914 mono_array_setref (*fields, i, values [i]);
921 static MonoReflectionType *
922 ves_icall_System_Object_GetType (MonoObject *obj)
926 if (obj->vtable->klass != mono_defaults.transparent_proxy_class)
927 return mono_type_get_object (mono_object_domain (obj), &obj->vtable->klass->byval_arg);
929 return mono_type_get_object (mono_object_domain (obj), &((MonoTransparentProxy*)obj)->remote_class->proxy_class->byval_arg);
933 mono_type_type_from_obj (MonoReflectionType *mtype, MonoObject *obj)
937 mtype->type = &obj->vtable->klass->byval_arg;
938 g_assert (mtype->type->type);
942 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj)
946 MONO_CHECK_ARG_NULL (obj);
948 return mono_image_create_token (mb->dynamic_image, obj, TRUE);
952 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder *mb,
953 MonoReflectionMethod *method,
954 MonoArray *opt_param_types)
958 MONO_CHECK_ARG_NULL (method);
960 return mono_image_create_method_token (
961 mb->dynamic_image, (MonoObject *) method, opt_param_types);
965 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder *mb, HANDLE file)
969 mono_image_create_pefile (mb, file);
973 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
977 mono_image_build_metadata (mb);
981 get_caller (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
983 MonoMethod **dest = data;
985 /* skip unmanaged frames */
1000 static MonoReflectionType *
1001 type_from_name (const char *str, MonoBoolean ignoreCase)
1003 MonoType *type = NULL;
1004 MonoAssembly *assembly = NULL;
1005 MonoTypeNameParse info;
1006 char *temp_str = g_strdup (str);
1007 gboolean type_resolve = FALSE;
1009 MONO_ARCH_SAVE_REGS;
1011 /* mono_reflection_parse_type() mangles the string */
1012 if (!mono_reflection_parse_type (temp_str, &info)) {
1013 g_list_free (info.modifiers);
1014 g_list_free (info.nested);
1019 if (info.assembly.name) {
1020 assembly = mono_assembly_load (&info.assembly, NULL, NULL);
1022 MonoMethod *m = mono_method_get_last_managed ();
1023 MonoMethod *dest = m;
1025 mono_stack_walk_no_il (get_caller, &dest);
1030 * FIXME: mono_method_get_last_managed() sometimes returns NULL, thus
1031 * causing ves_icall_System_Reflection_Assembly_GetCallingAssembly()
1032 * to crash. This only seems to happen in some strange remoting
1033 * scenarios and I was unable to figure out what's happening there.
1034 * Dec 10, 2005 - Martin.
1038 assembly = dest->klass->image->assembly;
1040 g_warning (G_STRLOC);
1045 type = mono_reflection_get_type (assembly->image, &info, ignoreCase, &type_resolve);
1047 if (!info.assembly.name && !type) /* try mscorlib */
1048 type = mono_reflection_get_type (NULL, &info, ignoreCase, &type_resolve);
1050 g_list_free (info.modifiers);
1051 g_list_free (info.nested);
1057 return mono_type_get_object (mono_domain_get (), type);
1061 MonoReflectionType *
1062 mono_type_get (const char *str)
1064 char *copy = g_strdup (str);
1065 MonoReflectionType *type = type_from_name (copy, FALSE);
1072 static MonoReflectionType*
1073 ves_icall_type_from_name (MonoString *name,
1074 MonoBoolean throwOnError,
1075 MonoBoolean ignoreCase)
1077 char *str = mono_string_to_utf8 (name);
1078 MonoReflectionType *type;
1080 type = type_from_name (str, ignoreCase);
1084 mono_raise_exception (mono_get_exception_type_load (name, NULL));
1091 static MonoReflectionType*
1092 ves_icall_type_from_handle (MonoType *handle)
1094 MonoDomain *domain = mono_domain_get ();
1095 MonoClass *klass = mono_class_from_mono_type (handle);
1097 MONO_ARCH_SAVE_REGS;
1099 mono_class_init (klass);
1100 return mono_type_get_object (domain, handle);
1104 ves_icall_type_Equals (MonoReflectionType *type, MonoReflectionType *c)
1106 MONO_ARCH_SAVE_REGS;
1108 if (c && type->type && c->type)
1109 return mono_metadata_type_equal (type->type, c->type);
1114 /* System.TypeCode */
1133 TYPECODE_STRING = 18
1137 ves_icall_type_GetTypeCodeInternal (MonoReflectionType *type)
1139 int t = type->type->type;
1141 MONO_ARCH_SAVE_REGS;
1143 if (type->type->byref)
1144 return TYPECODE_OBJECT;
1148 case MONO_TYPE_VOID:
1149 return TYPECODE_OBJECT;
1150 case MONO_TYPE_BOOLEAN:
1151 return TYPECODE_BOOLEAN;
1153 return TYPECODE_BYTE;
1155 return TYPECODE_SBYTE;
1157 return TYPECODE_UINT16;
1159 return TYPECODE_INT16;
1160 case MONO_TYPE_CHAR:
1161 return TYPECODE_CHAR;
1165 return TYPECODE_OBJECT;
1167 return TYPECODE_UINT32;
1169 return TYPECODE_INT32;
1171 return TYPECODE_UINT64;
1173 return TYPECODE_INT64;
1175 return TYPECODE_SINGLE;
1177 return TYPECODE_DOUBLE;
1178 case MONO_TYPE_VALUETYPE:
1179 if (type->type->data.klass->enumtype) {
1180 t = type->type->data.klass->enum_basetype->type;
1183 MonoClass *k = type->type->data.klass;
1184 if (strcmp (k->name_space, "System") == 0) {
1185 if (strcmp (k->name, "Decimal") == 0)
1186 return TYPECODE_DECIMAL;
1187 else if (strcmp (k->name, "DateTime") == 0)
1188 return TYPECODE_DATETIME;
1191 return TYPECODE_OBJECT;
1192 case MONO_TYPE_STRING:
1193 return TYPECODE_STRING;
1194 case MONO_TYPE_SZARRAY:
1195 case MONO_TYPE_ARRAY:
1196 case MONO_TYPE_OBJECT:
1198 case MONO_TYPE_MVAR:
1199 case MONO_TYPE_TYPEDBYREF:
1200 return TYPECODE_OBJECT;
1201 case MONO_TYPE_CLASS:
1203 MonoClass *k = type->type->data.klass;
1204 if (strcmp (k->name_space, "System") == 0) {
1205 if (strcmp (k->name, "DBNull") == 0)
1206 return TYPECODE_DBNULL;
1209 return TYPECODE_OBJECT;
1210 case MONO_TYPE_GENERICINST:
1211 return TYPECODE_OBJECT;
1213 g_error ("type 0x%02x not handled in GetTypeCode()", t);
1219 ves_icall_type_is_subtype_of (MonoReflectionType *type, MonoReflectionType *c, MonoBoolean check_interfaces)
1225 MONO_ARCH_SAVE_REGS;
1227 g_assert (type != NULL);
1229 domain = ((MonoObject *)type)->vtable->domain;
1231 if (!c) /* FIXME: dont know what do do here */
1234 klass = mono_class_from_mono_type (type->type);
1235 klassc = mono_class_from_mono_type (c->type);
1237 if (type->type->byref)
1238 return klassc == mono_defaults.object_class;
1240 return mono_class_is_subclass_of (klass, klassc, check_interfaces);
1244 ves_icall_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType *c)
1250 MONO_ARCH_SAVE_REGS;
1252 g_assert (type != NULL);
1254 domain = ((MonoObject *)type)->vtable->domain;
1256 klass = mono_class_from_mono_type (type->type);
1257 klassc = mono_class_from_mono_type (c->type);
1259 if (type->type->byref && !c->type->byref)
1262 return mono_class_is_assignable_from (klass, klassc);
1266 ves_icall_type_IsInstanceOfType (MonoReflectionType *type, MonoObject *obj)
1268 MonoClass *klass = mono_class_from_mono_type (type->type);
1269 return mono_object_isinst (obj, klass) != NULL;
1273 ves_icall_get_attributes (MonoReflectionType *type)
1275 MonoClass *klass = mono_class_from_mono_type (type->type);
1277 MONO_ARCH_SAVE_REGS;
1279 return klass->flags;
1282 static MonoReflectionMarshal*
1283 ves_icall_System_Reflection_FieldInfo_GetUnmanagedMarshal (MonoReflectionField *field)
1285 MonoClass *klass = field->field->parent;
1286 MonoMarshalType *info;
1289 if (klass->generic_container ||
1290 (klass->generic_class && klass->generic_class->inst->is_open))
1293 info = mono_marshal_load_type_info (klass);
1295 for (i = 0; i < info->num_fields; ++i) {
1296 if (info->fields [i].field == field->field) {
1297 if (!info->fields [i].mspec)
1300 return mono_reflection_marshal_from_marshal_spec (field->object.vtable->domain, klass, info->fields [i].mspec);
1307 static MonoReflectionField*
1308 ves_icall_System_Reflection_FieldInfo_internal_from_handle (MonoClassField *handle)
1310 MONO_ARCH_SAVE_REGS;
1314 return mono_field_get_object (mono_domain_get (), handle->parent, handle);
1318 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
1320 MonoDomain *domain = mono_domain_get ();
1321 MonoMethodSignature* sig;
1322 MONO_ARCH_SAVE_REGS;
1324 if (method->is_inflated)
1325 method = mono_get_inflated_method (method);
1327 sig = mono_method_signature (method);
1329 info->parent = mono_type_get_object (domain, &method->klass->byval_arg);
1330 info->ret = mono_type_get_object (domain, sig->ret);
1331 info->attrs = method->flags;
1332 info->implattrs = method->iflags;
1333 if (sig->call_convention == MONO_CALL_DEFAULT)
1336 if (sig->call_convention == MONO_CALL_VARARG)
1341 info->callconv |= (sig->hasthis << 5) | (sig->explicit_this << 6);
1345 ves_icall_get_parameter_info (MonoMethod *method)
1347 MonoDomain *domain = mono_domain_get ();
1349 MONO_ARCH_SAVE_REGS;
1351 if (method->is_inflated)
1352 method = mono_get_inflated_method (method);
1354 return mono_param_get_objects (domain, method);
1357 static MonoReflectionMarshal*
1358 ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod *method)
1360 MonoDomain *domain = mono_domain_get ();
1361 MonoReflectionMarshal* res = NULL;
1362 MonoMarshalSpec **mspecs;
1365 MONO_ARCH_SAVE_REGS;
1367 if (method->is_inflated)
1368 method = mono_get_inflated_method (method);
1370 mspecs = g_new (MonoMarshalSpec*, mono_method_signature (method)->param_count + 1);
1371 mono_method_get_marshal_info (method, mspecs);
1374 res = mono_reflection_marshal_from_marshal_spec (domain, method->klass, mspecs [0]);
1376 for (i = mono_method_signature (method)->param_count; i >= 0; i--)
1378 mono_metadata_free_marshal_spec (mspecs [i]);
1385 ves_icall_MonoField_GetFieldOffset (MonoReflectionField *field)
1387 return field->field->offset - sizeof (MonoObject);
1390 static MonoReflectionType*
1391 ves_icall_MonoField_GetParentType (MonoReflectionField *field, MonoBoolean declaring)
1394 MONO_ARCH_SAVE_REGS;
1396 parent = declaring? field->field->parent: field->klass;
1398 return mono_type_get_object (mono_object_domain (field), &parent->byval_arg);
1402 ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj)
1405 MonoClassField *cf = field->field;
1409 MonoDomain *domain = mono_object_domain (field);
1411 gboolean is_static = FALSE;
1412 gboolean is_ref = FALSE;
1414 MONO_ARCH_SAVE_REGS;
1416 if (field->klass->image->assembly->ref_only)
1417 mono_raise_exception (mono_get_exception_invalid_operation (
1418 "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
1420 mono_class_init (field->klass);
1422 t = mono_type_get_underlying_type (cf->type);
1424 case MONO_TYPE_STRING:
1425 case MONO_TYPE_OBJECT:
1426 case MONO_TYPE_CLASS:
1427 case MONO_TYPE_ARRAY:
1428 case MONO_TYPE_SZARRAY:
1433 case MONO_TYPE_BOOLEAN:
1436 case MONO_TYPE_CHAR:
1445 case MONO_TYPE_VALUETYPE:
1448 case MONO_TYPE_GENERICINST:
1449 if (mono_type_generic_inst_is_valuetype (t)) {
1456 g_error ("type 0x%x not handled in "
1457 "ves_icall_Monofield_GetValue", t->type);
1462 if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) {
1464 vtable = mono_class_vtable (domain, cf->parent);
1465 if (!vtable->initialized && !(cf->type->attrs & FIELD_ATTRIBUTE_LITERAL))
1466 mono_runtime_class_init (vtable);
1471 mono_field_static_get_value (vtable, cf, &o);
1473 mono_field_get_value (obj, cf, &o);
1478 if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) {
1479 MonoClass *nklass = mono_class_from_mono_type (cf->type);
1482 /* Convert the Nullable structure into a boxed vtype */
1484 buf = (guint8*)vtable->data + cf->offset;
1486 buf = (guint8*)obj + cf->offset;
1488 return mono_nullable_box (buf, nklass);
1491 /* boxed value type */
1492 klass = mono_class_from_mono_type (cf->type);
1493 o = mono_object_new (domain, klass);
1494 v = ((gchar *) o) + sizeof (MonoObject);
1496 mono_field_static_get_value (vtable, cf, v);
1498 mono_field_get_value (obj, cf, v);
1505 ves_icall_FieldInfo_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value)
1507 MonoClassField *cf = field->field;
1510 MONO_ARCH_SAVE_REGS;
1512 if (field->klass->image->assembly->ref_only)
1513 mono_raise_exception (mono_get_exception_invalid_operation (
1514 "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
1516 v = (gchar *) value;
1517 if (!cf->type->byref) {
1518 switch (cf->type->type) {
1521 case MONO_TYPE_BOOLEAN:
1524 case MONO_TYPE_CHAR:
1533 case MONO_TYPE_VALUETYPE:
1535 v += sizeof (MonoObject);
1537 case MONO_TYPE_STRING:
1538 case MONO_TYPE_OBJECT:
1539 case MONO_TYPE_CLASS:
1540 case MONO_TYPE_ARRAY:
1541 case MONO_TYPE_SZARRAY:
1544 case MONO_TYPE_GENERICINST: {
1545 MonoGenericClass *gclass = cf->type->data.generic_class;
1546 g_assert (!gclass->inst->is_open);
1548 if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) {
1549 MonoClass *nklass = mono_class_from_mono_type (cf->type);
1553 * Convert the boxed vtype into a Nullable structure.
1554 * This is complicated by the fact that Nullables have
1555 * a variable structure.
1557 /* Allocate using alloca so it gets GC tracking */
1558 buf = alloca (nklass->instance_size);
1560 mono_nullable_init (buf, value, nklass);
1565 if (gclass->container_class->valuetype && (v != NULL))
1566 v += sizeof (MonoObject);
1570 g_error ("type 0x%x not handled in "
1571 "ves_icall_FieldInfo_SetValueInternal", cf->type->type);
1576 if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) {
1577 MonoVTable *vtable = mono_class_vtable (mono_object_domain (field), cf->parent);
1578 if (!vtable->initialized)
1579 mono_runtime_class_init (vtable);
1580 mono_field_static_set_value (vtable, cf, v);
1582 mono_field_set_value (obj, cf, v);
1586 static MonoReflectionType*
1587 ves_icall_MonoGenericMethod_get_ReflectedType (MonoReflectionGenericMethod *rmethod)
1589 MonoMethod *method = mono_get_inflated_method (rmethod->method.method);
1591 return mono_type_get_object (mono_object_domain (rmethod), &method->klass->byval_arg);
1594 /* From MonoProperty.cs */
1596 PInfo_Attributes = 1,
1597 PInfo_GetMethod = 1 << 1,
1598 PInfo_SetMethod = 1 << 2,
1599 PInfo_ReflectedType = 1 << 3,
1600 PInfo_DeclaringType = 1 << 4,
1605 ves_icall_get_property_info (MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
1607 MonoDomain *domain = mono_object_domain (property);
1609 MONO_ARCH_SAVE_REGS;
1611 if ((req_info & PInfo_ReflectedType) != 0)
1612 info->parent = mono_type_get_object (domain, &property->klass->byval_arg);
1613 else if ((req_info & PInfo_DeclaringType) != 0)
1614 info->parent = mono_type_get_object (domain, &property->property->parent->byval_arg);
1616 if ((req_info & PInfo_Name) != 0)
1617 info->name = mono_string_new (domain, property->property->name);
1619 if ((req_info & PInfo_Attributes) != 0)
1620 info->attrs = property->property->attrs;
1622 if ((req_info & PInfo_GetMethod) != 0)
1623 info->get = property->property->get ?
1624 mono_method_get_object (domain, property->property->get, NULL): NULL;
1626 if ((req_info & PInfo_SetMethod) != 0)
1627 info->set = property->property->set ?
1628 mono_method_get_object (domain, property->property->set, NULL): NULL;
1630 * There may be other methods defined for properties, though, it seems they are not exposed
1631 * in the reflection API
1636 ves_icall_get_event_info (MonoReflectionEvent *event, MonoEventInfo *info)
1638 MonoDomain *domain = mono_object_domain (event);
1640 MONO_ARCH_SAVE_REGS;
1642 info->reflected_type = mono_type_get_object (domain, &event->klass->byval_arg);
1643 info->declaring_type = mono_type_get_object (domain, &event->event->parent->byval_arg);
1645 info->name = mono_string_new (domain, event->event->name);
1646 info->attrs = event->event->attrs;
1647 info->add_method = event->event->add ? mono_method_get_object (domain, event->event->add, NULL): NULL;
1648 info->remove_method = event->event->remove ? mono_method_get_object (domain, event->event->remove, NULL): NULL;
1649 info->raise_method = event->event->raise ? mono_method_get_object (domain, event->event->raise, NULL): NULL;
1651 if (event->event->other) {
1653 while (event->event->other [n])
1655 info->other_methods = mono_array_new (domain, mono_defaults.method_info_class, n);
1657 for (i = 0; i < n; i++)
1658 mono_array_setref (info->other_methods, i, mono_method_get_object (domain, event->event->other [i], NULL));
1663 ves_icall_Type_GetInterfaces (MonoReflectionType* type)
1665 MonoDomain *domain = mono_object_domain (type);
1667 GPtrArray *ifaces = NULL;
1669 MonoClass *class = mono_class_from_mono_type (type->type);
1672 MonoGenericContext *context = NULL;
1674 MONO_ARCH_SAVE_REGS;
1676 /* open generic-instance classes can share their interface_id */
1677 if (class->generic_class && class->generic_class->inst->is_open) {
1678 context = class->generic_class->context;
1679 class = class->generic_class->container_class;
1682 mono_class_setup_vtable (class);
1684 slots = mono_bitset_new (class->max_interface_id + 1, 0);
1686 for (parent = class; parent; parent = parent->parent) {
1687 GPtrArray *tmp_ifaces = mono_class_get_implemented_interfaces (parent);
1689 for (i = 0; i < tmp_ifaces->len; ++i) {
1690 MonoClass *ic = g_ptr_array_index (tmp_ifaces, i);
1692 if (mono_bitset_test (slots, ic->interface_id))
1695 mono_bitset_set (slots, ic->interface_id);
1697 ifaces = g_ptr_array_new ();
1698 g_ptr_array_add (ifaces, ic);
1700 g_ptr_array_free (tmp_ifaces, TRUE);
1703 mono_bitset_free (slots);
1706 return mono_array_new (domain, mono_defaults.monotype_class, 0);
1708 intf = mono_array_new (domain, mono_defaults.monotype_class, ifaces->len);
1709 for (i = 0; i < ifaces->len; ++i) {
1710 MonoClass *ic = g_ptr_array_index (ifaces, i);
1711 MonoType *ret = &ic->byval_arg;
1712 if (context && ic->generic_class && ic->generic_class->inst->is_open)
1713 ret = mono_class_inflate_generic_type (ret, context);
1715 mono_array_setref (intf, i, mono_type_get_object (domain, ret));
1717 g_ptr_array_free (ifaces, TRUE);
1723 ves_icall_Type_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType *iface, MonoArray **targets, MonoArray **methods)
1725 MonoClass *class = mono_class_from_mono_type (type->type);
1726 MonoClass *iclass = mono_class_from_mono_type (iface->type);
1727 MonoReflectionMethod *member;
1730 int i = 0, len, ioffset;
1733 MONO_ARCH_SAVE_REGS;
1735 mono_class_setup_vtable (class);
1737 /* type doesn't implement iface: the exception is thrown in managed code */
1738 if ((iclass->interface_id > class->max_interface_id) || !class->interface_offsets [iclass->interface_id])
1741 len = mono_class_num_methods (iclass);
1742 ioffset = class->interface_offsets [iclass->interface_id];
1743 domain = mono_object_domain (type);
1744 *targets = mono_array_new (domain, mono_defaults.method_info_class, len);
1745 *methods = mono_array_new (domain, mono_defaults.method_info_class, len);
1748 while ((method = mono_class_get_methods (iclass, &iter))) {
1749 member = mono_method_get_object (domain, method, iclass);
1750 mono_array_setref (*methods, i, member);
1751 member = mono_method_get_object (domain, class->vtable [i + ioffset], class);
1752 mono_array_setref (*targets, i, member);
1759 ves_icall_Type_GetPacking (MonoReflectionType *type, guint32 *packing, guint32 *size)
1761 MonoClass *klass = mono_class_from_mono_type (type->type);
1763 g_assert (!klass->image->dynamic);
1765 mono_metadata_packing_from_typedef (klass->image, klass->type_token, packing, size);
1768 static MonoReflectionType*
1769 ves_icall_MonoType_GetElementType (MonoReflectionType *type)
1771 MonoClass *class = mono_class_from_mono_type (type->type);
1773 MONO_ARCH_SAVE_REGS;
1775 // GelElementType should only return a type for:
1776 // Array Pointer PassedByRef
1777 if (type->type->byref)
1778 return mono_type_get_object (mono_object_domain (type), &class->byval_arg);
1779 if (class->enumtype && class->enum_basetype) /* types that are modifierd typebuilkders may not have enum_basetype set */
1780 return mono_type_get_object (mono_object_domain (type), class->enum_basetype);
1781 else if (class->element_class && MONO_CLASS_IS_ARRAY (class))
1782 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
1783 else if (class->element_class && type->type->type == MONO_TYPE_PTR)
1784 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
1789 static MonoReflectionType*
1790 ves_icall_get_type_parent (MonoReflectionType *type)
1792 MonoClass *class = mono_class_from_mono_type (type->type);
1794 MONO_ARCH_SAVE_REGS;
1796 return class->parent ? mono_type_get_object (mono_object_domain (type), &class->parent->byval_arg): NULL;
1800 ves_icall_type_ispointer (MonoReflectionType *type)
1802 MONO_ARCH_SAVE_REGS;
1804 return type->type->type == MONO_TYPE_PTR;
1808 ves_icall_type_isprimitive (MonoReflectionType *type)
1810 MONO_ARCH_SAVE_REGS;
1812 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)));
1816 ves_icall_type_isbyref (MonoReflectionType *type)
1818 MONO_ARCH_SAVE_REGS;
1820 return type->type->byref;
1824 ves_icall_type_iscomobject (MonoReflectionType *type)
1826 MonoClass *klass = mono_class_from_mono_type (type->type);
1827 MONO_ARCH_SAVE_REGS;
1829 return (klass && klass->is_com_object);
1832 static MonoReflectionModule*
1833 ves_icall_MonoType_get_Module (MonoReflectionType *type)
1835 MonoClass *class = mono_class_from_mono_type (type->type);
1837 MONO_ARCH_SAVE_REGS;
1839 return mono_module_get_object (mono_object_domain (type), class->image);
1842 static MonoReflectionAssembly*
1843 ves_icall_MonoType_get_Assembly (MonoReflectionType *type)
1845 MonoDomain *domain = mono_domain_get ();
1846 MonoClass *class = mono_class_from_mono_type (type->type);
1848 MONO_ARCH_SAVE_REGS;
1850 return mono_assembly_get_object (domain, class->image->assembly);
1853 static MonoReflectionType*
1854 ves_icall_MonoType_get_DeclaringType (MonoReflectionType *type)
1856 MonoDomain *domain = mono_domain_get ();
1859 MONO_ARCH_SAVE_REGS;
1861 if (type->type->byref)
1863 if (type->type->type == MONO_TYPE_VAR)
1864 class = type->type->data.generic_param->owner->klass;
1865 else if (type->type->type == MONO_TYPE_MVAR)
1866 class = type->type->data.generic_param->method->klass;
1868 class = mono_class_from_mono_type (type->type)->nested_in;
1870 return class ? mono_type_get_object (domain, &class->byval_arg) : NULL;
1873 static MonoReflectionType*
1874 ves_icall_MonoType_get_UnderlyingSystemType (MonoReflectionType *type)
1876 MonoDomain *domain = mono_domain_get ();
1877 MonoClass *class = mono_class_from_mono_type (type->type);
1879 MONO_ARCH_SAVE_REGS;
1881 if (class->enumtype && class->enum_basetype) /* types that are modified typebuilders may not have enum_basetype set */
1882 return mono_type_get_object (domain, class->enum_basetype);
1883 else if (class->element_class)
1884 return mono_type_get_object (domain, &class->element_class->byval_arg);
1890 ves_icall_MonoType_get_Name (MonoReflectionType *type)
1892 MonoDomain *domain = mono_domain_get ();
1893 MonoClass *class = mono_class_from_mono_type (type->type);
1895 MONO_ARCH_SAVE_REGS;
1897 if (type->type->byref) {
1898 char *n = g_strdup_printf ("%s&", class->name);
1899 MonoString *res = mono_string_new (domain, n);
1905 return mono_string_new (domain, class->name);
1910 ves_icall_MonoType_get_Namespace (MonoReflectionType *type)
1912 MonoDomain *domain = mono_domain_get ();
1913 MonoClass *class = mono_class_from_mono_type (type->type);
1915 MONO_ARCH_SAVE_REGS;
1917 while (class->nested_in)
1918 class = class->nested_in;
1920 if (class->name_space [0] == '\0')
1923 return mono_string_new (domain, class->name_space);
1927 ves_icall_MonoType_GetArrayRank (MonoReflectionType *type)
1929 MonoClass *class = mono_class_from_mono_type (type->type);
1931 MONO_ARCH_SAVE_REGS;
1937 ves_icall_MonoType_GetGenericArguments (MonoReflectionType *type)
1940 MonoClass *klass, *pklass;
1942 MONO_ARCH_SAVE_REGS;
1944 klass = mono_class_from_mono_type (type->type);
1946 if (klass->generic_container) {
1947 MonoGenericContainer *container = klass->generic_container;
1948 res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, container->type_argc);
1949 for (i = 0; i < container->type_argc; ++i) {
1950 pklass = mono_class_from_generic_parameter (&container->type_params [i], klass->image, FALSE);
1951 mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), &pklass->byval_arg));
1953 } else if (klass->generic_class) {
1954 MonoGenericInst *inst = klass->generic_class->inst;
1955 res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, inst->type_argc);
1956 for (i = 0; i < inst->type_argc; ++i)
1957 mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), inst->type_argv [i]));
1959 res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, 0);
1965 ves_icall_Type_get_IsGenericTypeDefinition (MonoReflectionType *type)
1968 MONO_ARCH_SAVE_REGS;
1970 if (type->type->byref)
1973 klass = mono_class_from_mono_type (type->type);
1975 return klass->generic_container != NULL;
1978 static MonoReflectionType*
1979 ves_icall_Type_GetGenericTypeDefinition_impl (MonoReflectionType *type)
1982 MONO_ARCH_SAVE_REGS;
1984 if (type->type->byref)
1987 klass = mono_class_from_mono_type (type->type);
1988 if (klass->generic_container) {
1989 return type; /* check this one */
1991 if (klass->generic_class) {
1992 MonoClass *generic_class = klass->generic_class->container_class;
1994 if (generic_class->wastypebuilder && generic_class->reflection_info)
1995 return generic_class->reflection_info;
1997 return mono_type_get_object (mono_object_domain (type), &generic_class->byval_arg);
2002 static MonoReflectionType*
2003 ves_icall_Type_MakeGenericType (MonoReflectionType *type, MonoArray *type_array)
2005 MonoType *geninst, **types;
2008 MONO_ARCH_SAVE_REGS;
2010 count = mono_array_length (type_array);
2011 types = g_new0 (MonoType *, count);
2013 for (i = 0; i < count; i++) {
2014 MonoReflectionType *t = mono_array_get (type_array, gpointer, i);
2015 types [i] = t->type;
2018 geninst = mono_reflection_bind_generic_parameters (type, count, types);
2023 return mono_type_get_object (mono_object_domain (type), geninst);
2027 ves_icall_Type_get_IsGenericInstance (MonoReflectionType *type)
2030 MONO_ARCH_SAVE_REGS;
2032 if (type->type->byref)
2035 klass = mono_class_from_mono_type (type->type);
2036 return klass->generic_class != NULL;
2040 ves_icall_Type_get_IsGenericType (MonoReflectionType *type)
2043 MONO_ARCH_SAVE_REGS;
2045 if (type->type->byref)
2048 klass = mono_class_from_mono_type (type->type);
2049 return klass->generic_class != NULL || klass->generic_container != NULL;
2053 ves_icall_Type_GetGenericParameterPosition (MonoReflectionType *type)
2055 MONO_ARCH_SAVE_REGS;
2057 if (is_generic_parameter (type->type))
2058 return type->type->data.generic_param->num;
2062 static GenericParameterAttributes
2063 ves_icall_Type_GetGenericParameterAttributes (MonoReflectionType *type)
2065 MONO_ARCH_SAVE_REGS;
2066 g_assert (is_generic_parameter (type->type));
2067 return type->type->data.generic_param->flags;
2071 ves_icall_Type_GetGenericParameterConstraints (MonoReflectionType *type)
2073 MonoGenericParam *param;
2079 MONO_ARCH_SAVE_REGS;
2081 domain = mono_object_domain (type);
2082 param = type->type->data.generic_param;
2083 for (count = 0, ptr = param->constraints; ptr && *ptr; ptr++, count++)
2086 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2087 for (i = 0; i < count; i++)
2088 mono_array_setref (res, i, mono_type_get_object (domain, ¶m->constraints [i]->byval_arg));
2095 ves_icall_MonoType_get_IsGenericParameter (MonoReflectionType *type)
2097 MONO_ARCH_SAVE_REGS;
2098 return is_generic_parameter (type->type);
2102 ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder *tb)
2104 MONO_ARCH_SAVE_REGS;
2105 return is_generic_parameter (tb->type.type);
2109 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
2110 MonoReflectionType *t)
2112 enumtype->type = t->type;
2115 static MonoReflectionType*
2116 ves_icall_MonoGenericClass_GetParentType (MonoReflectionGenericClass *type)
2118 MonoDynamicGenericClass *gclass;
2119 MonoReflectionType *parent = NULL;
2124 MONO_ARCH_SAVE_REGS;
2126 g_assert (type->type.type->data.generic_class->is_dynamic);
2127 gclass = (MonoDynamicGenericClass *) type->type.type->data.generic_class;
2129 domain = mono_object_domain (type);
2130 klass = mono_class_from_mono_type (type->generic_type->type);
2132 if (!klass->generic_class && !klass->generic_container)
2135 if (!strcmp (type->generic_type->object.vtable->klass->name, "TypeBuilder")) {
2136 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *) type->generic_type;
2137 parent = tb->parent;
2138 } else if (klass->wastypebuilder) {
2139 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *) type->generic_type;
2140 parent = tb->parent;
2142 MonoClass *pklass = klass->parent;
2144 parent = mono_type_get_object (domain, &pklass->byval_arg);
2147 if (!parent || (parent->type->type != MONO_TYPE_GENERICINST))
2150 inflated = mono_class_inflate_generic_type (
2151 parent->type, gclass->generic_class.generic_class.context);
2153 return mono_type_get_object (domain, inflated);
2157 ves_icall_MonoGenericClass_GetInterfaces (MonoReflectionGenericClass *type)
2159 static MonoClass *System_Reflection_MonoGenericClass;
2160 MonoDynamicGenericClass *gclass;
2161 MonoReflectionTypeBuilder *tb = NULL;
2162 MonoClass *klass = NULL;
2167 MONO_ARCH_SAVE_REGS;
2169 if (!System_Reflection_MonoGenericClass) {
2170 System_Reflection_MonoGenericClass = mono_class_from_name (
2171 mono_defaults.corlib, "System.Reflection", "MonoGenericClass");
2172 g_assert (System_Reflection_MonoGenericClass);
2175 domain = mono_object_domain (type);
2177 g_assert (type->type.type->data.generic_class->is_dynamic);
2178 gclass = (MonoDynamicGenericClass *) type->type.type->data.generic_class;
2180 if (!strcmp (type->generic_type->object.vtable->klass->name, "TypeBuilder")) {
2181 tb = (MonoReflectionTypeBuilder *) type->generic_type;
2182 icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
2184 klass = gclass->generic_class.generic_class.container_class;
2185 mono_class_init (klass);
2186 icount = klass->interface_count;
2189 res = mono_array_new (domain, System_Reflection_MonoGenericClass, icount);
2191 for (i = 0; i < icount; i++) {
2192 MonoReflectionType *iface;
2196 iface = mono_array_get (tb->interfaces, MonoReflectionType *, i);
2199 it = &klass->interfaces [i]->byval_arg;
2201 it = mono_class_inflate_generic_type (
2202 it, gclass->generic_class.generic_class.context);
2204 iface = mono_type_get_object (domain, it);
2205 mono_array_setref (res, i, iface);
2211 static MonoReflectionMethod*
2212 ves_icall_MonoGenericClass_GetCorrespondingInflatedMethod (MonoReflectionGenericClass *type,
2213 MonoReflectionMethod* generic)
2215 MonoGenericClass *gclass;
2216 MonoDynamicGenericClass *dgclass;
2220 MONO_ARCH_SAVE_REGS;
2222 gclass = type->type.type->data.generic_class;
2223 g_assert (gclass->is_dynamic);
2225 dgclass = (MonoDynamicGenericClass *) gclass;
2227 domain = mono_object_domain (type);
2229 for (i = 0; i < dgclass->count_methods; i++)
2230 if (generic->method->token == dgclass->methods [i]->token)
2231 return mono_method_get_object (domain, dgclass->methods [i], NULL);
2236 static MonoReflectionMethod*
2237 ves_icall_MonoGenericClass_GetCorrespondingInflatedConstructor (MonoReflectionGenericClass *type,
2238 MonoReflectionMethod* generic)
2240 MonoGenericClass *gclass;
2241 MonoDynamicGenericClass *dgclass;
2245 MONO_ARCH_SAVE_REGS;
2247 gclass = type->type.type->data.generic_class;
2248 g_assert (gclass->is_dynamic);
2250 dgclass = (MonoDynamicGenericClass *) gclass;
2252 domain = mono_object_domain (type);
2254 for (i = 0; i < dgclass->count_ctors; i++)
2255 if (generic->method->token == dgclass->ctors [i]->token)
2256 return mono_method_get_object (domain, dgclass->ctors [i], NULL);
2262 static MonoReflectionField*
2263 ves_icall_MonoGenericClass_GetCorrespondingInflatedField (MonoReflectionGenericClass *type,
2264 MonoString* generic_name)
2266 MonoGenericClass *gclass;
2267 MonoDynamicGenericClass *dgclass;
2269 MonoClass *refclass;
2270 char *utf8_name = mono_string_to_utf8 (generic_name);
2273 MONO_ARCH_SAVE_REGS;
2275 gclass = type->type.type->data.generic_class;
2276 g_assert (gclass->is_dynamic);
2278 dgclass = (MonoDynamicGenericClass *) gclass;
2280 refclass = mono_class_from_mono_type (type->type.type);
2282 domain = mono_object_domain (type);
2284 for (i = 0; i < dgclass->count_fields; i++)
2285 if (strcmp (utf8_name, dgclass->fields [i].name) == 0) {
2287 return mono_field_get_object (domain, refclass, &dgclass->fields [i]);
2296 static MonoReflectionMethod*
2297 ves_icall_MonoType_GetCorrespondingInflatedMethod (MonoReflectionType *type,
2298 MonoReflectionMethod* generic)
2305 MONO_ARCH_SAVE_REGS;
2307 domain = ((MonoObject *)type)->vtable->domain;
2309 klass = mono_class_from_mono_type (type->type);
2312 while ((method = mono_class_get_methods (klass, &iter))) {
2313 if (method->token == generic->method->token)
2314 return mono_method_get_object (domain, method, klass);
2321 ves_icall_MonoGenericClass_GetMethods (MonoReflectionGenericClass *type,
2322 MonoReflectionType *reflected_type)
2324 MonoGenericClass *gclass;
2325 MonoDynamicGenericClass *dgclass;
2327 MonoClass *refclass;
2331 MONO_ARCH_SAVE_REGS;
2333 gclass = type->type.type->data.generic_class;
2334 g_assert (gclass->is_dynamic);
2335 dgclass = (MonoDynamicGenericClass *) gclass;
2337 refclass = mono_class_from_mono_type (reflected_type->type);
2339 domain = mono_object_domain (type);
2340 res = mono_array_new (domain, mono_defaults.method_info_class, dgclass->count_methods);
2342 for (i = 0; i < dgclass->count_methods; i++)
2343 mono_array_setref (res, i, mono_method_get_object (domain, dgclass->methods [i], refclass));
2349 ves_icall_MonoGenericClass_GetConstructors (MonoReflectionGenericClass *type,
2350 MonoReflectionType *reflected_type)
2352 static MonoClass *System_Reflection_ConstructorInfo;
2353 MonoGenericClass *gclass;
2354 MonoDynamicGenericClass *dgclass;
2356 MonoClass *refclass;
2360 MONO_ARCH_SAVE_REGS;
2362 if (!System_Reflection_ConstructorInfo)
2363 System_Reflection_ConstructorInfo = mono_class_from_name (
2364 mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
2366 gclass = type->type.type->data.generic_class;
2367 g_assert (gclass->is_dynamic);
2368 dgclass = (MonoDynamicGenericClass *) gclass;
2370 refclass = mono_class_from_mono_type (reflected_type->type);
2372 domain = mono_object_domain (type);
2373 res = mono_array_new (domain, System_Reflection_ConstructorInfo, dgclass->count_ctors);
2375 for (i = 0; i < dgclass->count_ctors; i++)
2376 mono_array_setref (res, i, mono_method_get_object (domain, dgclass->ctors [i], refclass));
2382 ves_icall_MonoGenericClass_GetFields (MonoReflectionGenericClass *type,
2383 MonoReflectionType *reflected_type)
2385 MonoGenericClass *gclass;
2386 MonoDynamicGenericClass *dgclass;
2388 MonoClass *refclass;
2392 MONO_ARCH_SAVE_REGS;
2394 gclass = type->type.type->data.generic_class;
2395 g_assert (gclass->is_dynamic);
2396 dgclass = (MonoDynamicGenericClass *) gclass;
2398 refclass = mono_class_from_mono_type (reflected_type->type);
2400 domain = mono_object_domain (type);
2401 res = mono_array_new (domain, mono_defaults.field_info_class, dgclass->count_fields);
2403 for (i = 0; i < dgclass->count_fields; i++)
2404 mono_array_setref (res, i, mono_field_get_object (domain, refclass, &dgclass->fields [i]));
2410 ves_icall_MonoGenericClass_GetProperties (MonoReflectionGenericClass *type,
2411 MonoReflectionType *reflected_type)
2413 static MonoClass *System_Reflection_PropertyInfo;
2414 MonoGenericClass *gclass;
2415 MonoDynamicGenericClass *dgclass;
2417 MonoClass *refclass;
2421 MONO_ARCH_SAVE_REGS;
2423 if (!System_Reflection_PropertyInfo)
2424 System_Reflection_PropertyInfo = mono_class_from_name (
2425 mono_defaults.corlib, "System.Reflection", "PropertyInfo");
2427 gclass = type->type.type->data.generic_class;
2428 g_assert (gclass->is_dynamic);
2429 dgclass = (MonoDynamicGenericClass *) gclass;
2431 refclass = mono_class_from_mono_type (reflected_type->type);
2433 domain = mono_object_domain (type);
2434 res = mono_array_new (domain, System_Reflection_PropertyInfo, dgclass->count_properties);
2436 for (i = 0; i < dgclass->count_properties; i++)
2437 mono_array_setref (res, i, mono_property_get_object (domain, refclass, &dgclass->properties [i]));
2443 ves_icall_MonoGenericClass_GetEvents (MonoReflectionGenericClass *type,
2444 MonoReflectionType *reflected_type)
2446 static MonoClass *System_Reflection_EventInfo;
2447 MonoGenericClass *gclass;
2448 MonoDynamicGenericClass *dgclass;
2450 MonoClass *refclass;
2454 MONO_ARCH_SAVE_REGS;
2456 if (!System_Reflection_EventInfo)
2457 System_Reflection_EventInfo = mono_class_from_name (
2458 mono_defaults.corlib, "System.Reflection", "EventInfo");
2460 gclass = type->type.type->data.generic_class;
2461 g_assert (gclass->is_dynamic);
2462 dgclass = (MonoDynamicGenericClass *) gclass;
2464 refclass = mono_class_from_mono_type (reflected_type->type);
2466 domain = mono_object_domain (type);
2467 res = mono_array_new (domain, System_Reflection_EventInfo, dgclass->count_events);
2469 for (i = 0; i < dgclass->count_events; i++)
2470 mono_array_setref (res, i, mono_event_get_object (domain, refclass, &dgclass->events [i]));
2475 static MonoReflectionMethod *
2476 ves_icall_MonoType_get_DeclaringMethod (MonoReflectionType *type)
2481 MONO_ARCH_SAVE_REGS;
2483 if (type->type->byref || type->type->type != MONO_TYPE_MVAR)
2486 method = type->type->data.generic_param->method;
2488 klass = mono_class_from_mono_type (type->type);
2489 return mono_method_get_object (mono_object_domain (type), method, klass);
2492 static MonoReflectionDllImportAttribute*
2493 ves_icall_MonoMethod_GetDllImportAttribute (MonoMethod *method)
2495 static MonoClass *DllImportAttributeClass = NULL;
2496 MonoDomain *domain = mono_domain_get ();
2497 MonoReflectionDllImportAttribute *attr;
2498 MonoImage *image = method->klass->image;
2499 MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method;
2500 MonoTableInfo *tables = image->tables;
2501 MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
2502 MonoTableInfo *mr = &tables [MONO_TABLE_MODULEREF];
2503 guint32 im_cols [MONO_IMPLMAP_SIZE];
2504 guint32 scope_token;
2505 const char *import = NULL;
2506 const char *scope = NULL;
2509 if (!method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)
2512 if (!DllImportAttributeClass) {
2513 DllImportAttributeClass =
2514 mono_class_from_name (mono_defaults.corlib,
2515 "System.Runtime.InteropServices", "DllImportAttribute");
2516 g_assert (DllImportAttributeClass);
2519 if (method->klass->image->dynamic) {
2520 MonoReflectionMethodAux *method_aux =
2521 g_hash_table_lookup (
2522 ((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
2524 import = method_aux->dllentry;
2525 scope = method_aux->dll;
2529 if (piinfo->implmap_idx) {
2530 mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
2532 piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
2533 import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
2534 scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
2535 scope = mono_metadata_string_heap (image, scope_token);
2538 flags = piinfo->piflags;
2540 attr = (MonoReflectionDllImportAttribute*)mono_object_new (domain, DllImportAttributeClass);
2542 MONO_OBJECT_SETREF (attr, dll, mono_string_new (domain, scope));
2543 MONO_OBJECT_SETREF (attr, entry_point, mono_string_new (domain, import));
2544 attr->call_conv = (flags & 0x700) >> 8;
2545 attr->charset = ((flags & 0x6) >> 1) + 1;
2546 if (attr->charset == 1)
2548 attr->exact_spelling = (flags & 0x1) != 0;
2549 attr->set_last_error = (flags & 0x40) != 0;
2550 attr->best_fit_mapping = (flags & 0x30) == 0x10;
2551 attr->throw_on_unmappable = (flags & 0x3000) == 0x1000;
2552 attr->preserve_sig = FALSE;
2557 static MonoReflectionMethod *
2558 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
2560 MonoMethodInflated *imethod;
2562 MONO_ARCH_SAVE_REGS;
2564 if (!method->method->is_inflated) {
2565 if (mono_method_signature (method->method)->generic_param_count)
2571 imethod = (MonoMethodInflated *) method->method;
2572 if (imethod->context->gmethod && imethod->context->gmethod->reflection_info)
2573 return imethod->context->gmethod->reflection_info;
2575 return mono_method_get_object (
2576 mono_object_domain (method), imethod->declaring, NULL);
2580 ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethod *method)
2582 MONO_ARCH_SAVE_REGS;
2584 return mono_method_signature (method->method)->generic_param_count != 0;
2588 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method)
2590 MONO_ARCH_SAVE_REGS;
2592 return !method->method->is_inflated &&
2593 (mono_method_signature (method->method)->generic_param_count != 0);
2597 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
2602 MONO_ARCH_SAVE_REGS;
2604 domain = mono_object_domain (method);
2606 if (method->method->is_inflated) {
2607 MonoMethodInflated *imethod = (MonoMethodInflated *) method->method;
2608 MonoGenericMethod *gmethod = imethod->context->gmethod;
2611 count = gmethod->inst->type_argc;
2612 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2614 for (i = 0; i < count; i++)
2615 mono_array_setref (res, i, mono_type_get_object (domain, gmethod->inst->type_argv [i]));
2621 count = mono_method_signature (method->method)->generic_param_count;
2622 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2624 for (i = 0; i < count; i++) {
2625 MonoGenericParam *param = &method->method->generic_container->type_params [i];
2626 MonoClass *pklass = mono_class_from_generic_parameter (
2627 param, method->method->klass->image, TRUE);
2628 mono_array_setref (res, i,
2629 mono_type_get_object (domain, &pklass->byval_arg));
2636 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoArray *params)
2639 * Invoke from reflection is supposed to always be a virtual call (the API
2640 * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
2641 * greater flexibility.
2643 MonoMethod *m = mono_get_inflated_method (method->method);
2647 MONO_ARCH_SAVE_REGS;
2649 if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
2651 if (!mono_object_isinst (this, m->klass))
2652 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
2653 m = mono_object_get_virtual_method (this, m);
2654 /* must pass the pointer to the value for valuetype methods */
2655 if (m->klass->valuetype)
2656 obj = mono_object_unbox (this);
2657 } else if (strcmp (m->name, ".ctor") && !m->wrapper_type)
2658 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
2661 pcount = params? mono_array_length (params): 0;
2662 if (pcount != mono_method_signature (m)->param_count)
2663 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
2665 if ((m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) && !strcmp (m->name, ".ctor"))
2666 mono_raise_exception (mono_exception_from_name_msg (mono_defaults.corlib, "System", "MethodAccessException", "Cannot invoke constructor of an abstract class."));
2668 if (m->klass->image->assembly->ref_only)
2669 mono_raise_exception (mono_get_exception_invalid_operation ("It is illegal to invoke a method on a type loaded using the ReflectionOnly api."));
2671 if (m->klass->rank && !strcmp (m->name, ".ctor")) {
2674 guint32 *lower_bounds;
2675 pcount = mono_array_length (params);
2676 lengths = alloca (sizeof (guint32) * pcount);
2677 for (i = 0; i < pcount; ++i)
2678 lengths [i] = *(gint32*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
2680 if (m->klass->rank == pcount) {
2681 /* Only lengths provided. */
2682 lower_bounds = NULL;
2684 g_assert (pcount == (m->klass->rank * 2));
2685 /* lower bounds are first. */
2686 lower_bounds = lengths;
2687 lengths += m->klass->rank;
2690 return (MonoObject*)mono_array_new_full (mono_object_domain (params), m->klass, lengths, lower_bounds);
2692 return mono_runtime_invoke_array (m, obj, params, NULL);
2696 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this, MonoArray *params, MonoArray **outArgs)
2698 MonoDomain *domain = mono_object_domain (method);
2699 MonoMethod *m = method->method;
2700 MonoMethodSignature *sig = mono_method_signature (m);
2701 MonoArray *out_args;
2703 int i, j, outarg_count = 0;
2705 MONO_ARCH_SAVE_REGS;
2707 if (m->klass == mono_defaults.object_class) {
2709 if (!strcmp (m->name, "FieldGetter")) {
2710 MonoClass *k = this->vtable->klass;
2714 /* If this is a proxy, then it must be a CBO */
2715 if (k == mono_defaults.transparent_proxy_class) {
2716 MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
2717 this = tp->rp->unwrapped_server;
2719 k = this->vtable->klass;
2722 name = mono_array_get (params, MonoString *, 1);
2723 str = mono_string_to_utf8 (name);
2726 MonoClassField* field = mono_class_get_field_from_name (k, str);
2728 MonoClass *field_klass = mono_class_from_mono_type (field->type);
2729 if (field_klass->valuetype)
2730 result = mono_value_box (domain, field_klass, (char *)this + field->offset);
2732 result = *((gpointer *)((char *)this + field->offset));
2734 out_args = mono_array_new (domain, mono_defaults.object_class, 1);
2735 *outArgs = out_args;
2736 mono_array_setref (out_args, 0, result);
2744 g_assert_not_reached ();
2746 } else if (!strcmp (m->name, "FieldSetter")) {
2747 MonoClass *k = this->vtable->klass;
2753 /* If this is a proxy, then it must be a CBO */
2754 if (k == mono_defaults.transparent_proxy_class) {
2755 MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
2756 this = tp->rp->unwrapped_server;
2758 k = this->vtable->klass;
2761 name = mono_array_get (params, MonoString *, 1);
2762 str = mono_string_to_utf8 (name);
2765 MonoClassField* field = mono_class_get_field_from_name (k, str);
2767 MonoClass *field_klass = mono_class_from_mono_type (field->type);
2768 MonoObject *val = mono_array_get (params, gpointer, 2);
2770 if (field_klass->valuetype) {
2771 size = mono_type_size (field->type, &align);
2772 memcpy ((char *)this + field->offset,
2773 ((char *)val) + sizeof (MonoObject), size);
2775 *(MonoObject**)((char *)this + field->offset) = val;
2777 out_args = mono_array_new (domain, mono_defaults.object_class, 0);
2778 *outArgs = out_args;
2788 g_assert_not_reached ();
2793 for (i = 0; i < mono_array_length (params); i++) {
2794 if (sig->params [i]->byref)
2798 out_args = mono_array_new (domain, mono_defaults.object_class, outarg_count);
2800 /* handle constructors only for objects already allocated */
2801 if (!strcmp (method->method->name, ".ctor"))
2804 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
2805 g_assert (!method->method->klass->valuetype);
2806 result = mono_runtime_invoke_array (method->method, this, params, NULL);
2808 for (i = 0, j = 0; i < mono_array_length (params); i++) {
2809 if (sig->params [i]->byref) {
2811 arg = mono_array_get (params, gpointer, i);
2812 mono_array_setref (out_args, j, arg);
2817 *outArgs = out_args;
2823 read_enum_value (char *mem, int type)
2827 return *(guint8*)mem;
2829 return *(gint8*)mem;
2831 return *(guint16*)mem;
2833 return *(gint16*)mem;
2835 return *(guint32*)mem;
2837 return *(gint32*)mem;
2839 return *(guint64*)mem;
2841 return *(gint64*)mem;
2843 g_assert_not_reached ();
2849 write_enum_value (char *mem, int type, guint64 value)
2853 case MONO_TYPE_I1: {
2854 guint8 *p = (guint8*)mem;
2859 case MONO_TYPE_I2: {
2860 guint16 *p = (void*)mem;
2865 case MONO_TYPE_I4: {
2866 guint32 *p = (void*)mem;
2871 case MONO_TYPE_I8: {
2872 guint64 *p = (void*)mem;
2877 g_assert_not_reached ();
2883 ves_icall_System_Enum_ToObject (MonoReflectionType *type, MonoObject *obj)
2886 MonoClass *enumc, *objc;
2890 MONO_ARCH_SAVE_REGS;
2892 MONO_CHECK_ARG_NULL (type);
2893 MONO_CHECK_ARG_NULL (obj);
2895 domain = mono_object_domain (type);
2896 enumc = mono_class_from_mono_type (type->type);
2897 objc = obj->vtable->klass;
2899 if (!enumc->enumtype)
2900 mono_raise_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
2901 if (!((objc->enumtype) || (objc->byval_arg.type >= MONO_TYPE_I1 && objc->byval_arg.type <= MONO_TYPE_U8)))
2902 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."));
2904 res = mono_object_new (domain, enumc);
2905 val = read_enum_value ((char *)obj + sizeof (MonoObject), objc->enumtype? objc->enum_basetype->type: objc->byval_arg.type);
2906 write_enum_value ((char *)res + sizeof (MonoObject), enumc->enum_basetype->type, val);
2912 ves_icall_System_Enum_get_value (MonoObject *this)
2920 MONO_ARCH_SAVE_REGS;
2925 g_assert (this->vtable->klass->enumtype);
2927 enumc = mono_class_from_mono_type (this->vtable->klass->enum_basetype);
2928 res = mono_object_new (mono_object_domain (this), enumc);
2929 dst = (char *)res + sizeof (MonoObject);
2930 src = (char *)this + sizeof (MonoObject);
2931 size = mono_class_value_size (enumc, NULL);
2933 memcpy (dst, src, size);
2939 ves_icall_get_enum_info (MonoReflectionType *type, MonoEnumInfo *info)
2941 MonoDomain *domain = mono_object_domain (type);
2942 MonoClass *enumc = mono_class_from_mono_type (type->type);
2943 guint j = 0, nvalues, crow;
2945 MonoClassField *field;
2947 MONO_ARCH_SAVE_REGS;
2949 info->utype = mono_type_get_object (domain, enumc->enum_basetype);
2950 nvalues = mono_class_num_fields (enumc) ? mono_class_num_fields (enumc) - 1 : 0;
2951 info->names = mono_array_new (domain, mono_defaults.string_class, nvalues);
2952 info->values = mono_array_new (domain, enumc, nvalues);
2956 while ((field = mono_class_get_fields (enumc, &iter))) {
2960 if (strcmp ("value__", field->name) == 0)
2962 if (mono_field_is_deleted (field))
2964 mono_array_setref (info->names, j, mono_string_new (domain, field->name));
2967 crow = mono_metadata_get_constant_index (enumc->image, mono_class_get_field_token (field), crow + 1);
2968 field->def_type = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_TYPE);
2969 crow = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_VALUE);
2970 field->data = (gpointer)mono_metadata_blob_heap (enumc->image, crow);
2974 len = mono_metadata_decode_blob_size (p, &p);
2975 switch (enumc->enum_basetype->type) {
2978 mono_array_set (info->values, gchar, j, *p);
2980 case MONO_TYPE_CHAR:
2983 mono_array_set (info->values, gint16, j, read16 (p));
2987 mono_array_set (info->values, gint32, j, read32 (p));
2991 mono_array_set (info->values, gint64, j, read64 (p));
2994 g_error ("Implement type 0x%02x in get_enum_info", enumc->enum_basetype->type);
3001 BFLAGS_IgnoreCase = 1,
3002 BFLAGS_DeclaredOnly = 2,
3003 BFLAGS_Instance = 4,
3005 BFLAGS_Public = 0x10,
3006 BFLAGS_NonPublic = 0x20,
3007 BFLAGS_FlattenHierarchy = 0x40,
3008 BFLAGS_InvokeMethod = 0x100,
3009 BFLAGS_CreateInstance = 0x200,
3010 BFLAGS_GetField = 0x400,
3011 BFLAGS_SetField = 0x800,
3012 BFLAGS_GetProperty = 0x1000,
3013 BFLAGS_SetProperty = 0x2000,
3014 BFLAGS_ExactBinding = 0x10000,
3015 BFLAGS_SuppressChangeType = 0x20000,
3016 BFLAGS_OptionalParamBinding = 0x40000
3019 static MonoReflectionField *
3020 ves_icall_Type_GetField (MonoReflectionType *type, MonoString *name, guint32 bflags)
3023 MonoClass *startklass, *klass;
3025 MonoClassField *field;
3028 int (*compare_func) (const char *s1, const char *s2) = NULL;
3029 domain = ((MonoObject *)type)->vtable->domain;
3030 klass = startklass = mono_class_from_mono_type (type->type);
3032 MONO_ARCH_SAVE_REGS;
3035 mono_raise_exception (mono_get_exception_argument_null ("name"));
3036 if (type->type->byref)
3039 compare_func = (bflags & BFLAGS_IgnoreCase) ? g_strcasecmp : strcmp;
3043 while ((field = mono_class_get_fields (klass, &iter))) {
3045 if (mono_field_is_deleted (field))
3047 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3048 if (bflags & BFLAGS_Public)
3051 if (bflags & BFLAGS_NonPublic)
3057 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
3058 if (bflags & BFLAGS_Static)
3059 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3062 if (bflags & BFLAGS_Instance)
3069 utf8_name = mono_string_to_utf8 (name);
3071 if (compare_func (field->name, utf8_name)) {
3077 return mono_field_get_object (domain, klass, field);
3079 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3086 ves_icall_Type_GetFields_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3089 MonoClass *startklass, *klass, *refklass;
3094 MonoClassField *field;
3096 MONO_ARCH_SAVE_REGS;
3098 domain = ((MonoObject *)type)->vtable->domain;
3099 if (type->type->byref)
3100 return mono_array_new (domain, mono_defaults.field_info_class, 0);
3101 klass = startklass = mono_class_from_mono_type (type->type);
3102 refklass = mono_class_from_mono_type (reftype->type);
3106 res = mono_array_new (domain, mono_defaults.field_info_class, len);
3109 while ((field = mono_class_get_fields (klass, &iter))) {
3111 if (mono_field_is_deleted (field))
3113 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3114 if (bflags & BFLAGS_Public)
3117 if (bflags & BFLAGS_NonPublic) {
3118 /* Serialization currently depends on the old behavior.
3119 * if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE || startklass == klass)*/
3126 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
3127 if (bflags & BFLAGS_Static)
3128 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3131 if (bflags & BFLAGS_Instance)
3137 member = (MonoObject*)mono_field_get_object (domain, refklass, field);
3139 MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, len * 2);
3140 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3144 mono_array_setref (res, i, member);
3147 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3150 MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, i);
3151 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3154 * Better solution for the new GC.
3155 * res->max_length = i;
3162 ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
3165 MonoClass *startklass, *klass, *refklass;
3170 int i, len, match, nslots;
3171 guint32 method_slots_default [8];
3172 guint32 *method_slots;
3173 gchar *mname = NULL;
3174 int (*compare_func) (const char *s1, const char *s2) = NULL;
3176 MONO_ARCH_SAVE_REGS;
3178 domain = ((MonoObject *)type)->vtable->domain;
3179 if (type->type->byref)
3180 return mono_array_new (domain, mono_defaults.method_info_class, 0);
3181 klass = startklass = mono_class_from_mono_type (type->type);
3182 refklass = mono_class_from_mono_type (reftype->type);
3185 mname = mono_string_to_utf8 (name);
3186 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
3189 mono_class_setup_vtable (klass);
3191 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : klass->vtable_size;
3192 if (nslots >= sizeof (method_slots_default) * 8) {
3193 method_slots = g_new0 (guint32, nslots / 32 + 1);
3195 method_slots = method_slots_default;
3196 memset (method_slots, 0, sizeof (method_slots_default));
3200 res = mono_array_new (domain, mono_defaults.method_info_class, len);
3202 mono_class_setup_vtable (klass);
3204 while ((method = mono_class_get_methods (klass, &iter))) {
3206 if (method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
3208 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3209 if (bflags & BFLAGS_Public)
3212 if (bflags & BFLAGS_NonPublic)
3218 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3219 if (bflags & BFLAGS_Static)
3220 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3223 if (bflags & BFLAGS_Instance)
3231 if (compare_func (mname, method->name))
3236 if (method->slot != -1) {
3237 g_assert (method->slot < nslots);
3238 if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
3240 method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
3243 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
3246 MonoArray *new_res = mono_array_new (domain, mono_defaults.method_info_class, len * 2);
3247 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3251 mono_array_setref (res, i, member);
3254 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3258 if (method_slots != method_slots_default)
3259 g_free (method_slots);
3261 MonoArray *new_res = mono_array_new (domain, mono_defaults.method_info_class, i);
3262 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3265 * Better solution for the new GC.
3266 * res->max_length = i;
3273 ves_icall_Type_GetConstructors_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3276 static MonoClass *System_Reflection_ConstructorInfo;
3277 MonoClass *startklass, *klass, *refklass;
3282 gpointer iter = NULL;
3284 MONO_ARCH_SAVE_REGS;
3286 domain = ((MonoObject *)type)->vtable->domain;
3287 if (type->type->byref)
3288 return mono_array_new (domain, mono_defaults.method_info_class, 0);
3289 klass = startklass = mono_class_from_mono_type (type->type);
3290 refklass = mono_class_from_mono_type (reftype->type);
3292 if (!System_Reflection_ConstructorInfo)
3293 System_Reflection_ConstructorInfo = mono_class_from_name (
3294 mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
3298 res = mono_array_new (domain, System_Reflection_ConstructorInfo, len);
3300 while ((method = mono_class_get_methods (klass, &iter))) {
3302 if (strcmp (method->name, ".ctor") && strcmp (method->name, ".cctor"))
3304 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3305 if (bflags & BFLAGS_Public)
3308 if (bflags & BFLAGS_NonPublic)
3314 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3315 if (bflags & BFLAGS_Static)
3316 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3319 if (bflags & BFLAGS_Instance)
3325 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
3328 MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, len * 2);
3329 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3333 mono_array_setref (res, i, member);
3337 MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, i);
3338 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3341 * Better solution for the new GC.
3342 * res->max_length = i;
3349 ves_icall_Type_GetPropertiesByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
3352 static MonoClass *System_Reflection_PropertyInfo;
3353 MonoClass *startklass, *klass;
3357 int i, match, nslots;
3360 guint32 method_slots_default [8];
3361 guint32 *method_slots;
3362 gchar *propname = NULL;
3363 int (*compare_func) (const char *s1, const char *s2) = NULL;
3366 MONO_ARCH_SAVE_REGS;
3368 if (!System_Reflection_PropertyInfo)
3369 System_Reflection_PropertyInfo = mono_class_from_name (
3370 mono_defaults.corlib, "System.Reflection", "PropertyInfo");
3372 domain = ((MonoObject *)type)->vtable->domain;
3373 if (type->type->byref)
3374 return mono_array_new (domain, System_Reflection_PropertyInfo, 0);
3375 klass = startklass = mono_class_from_mono_type (type->type);
3377 propname = mono_string_to_utf8 (name);
3378 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
3381 mono_class_setup_vtable (klass);
3383 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : klass->vtable_size;
3384 if (nslots >= sizeof (method_slots_default) * 8) {
3385 method_slots = g_new0 (guint32, nslots / 32 + 1);
3387 method_slots = method_slots_default;
3388 memset (method_slots, 0, sizeof (method_slots_default));
3392 res = mono_array_new (domain, System_Reflection_PropertyInfo, len);
3394 mono_class_setup_vtable (klass);
3396 while ((prop = mono_class_get_properties (klass, &iter))) {
3402 flags = method->flags;
3405 if ((prop->get && ((prop->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC)) ||
3406 (prop->set && ((prop->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC))) {
3407 if (bflags & BFLAGS_Public)
3410 if (bflags & BFLAGS_NonPublic)
3416 if (flags & METHOD_ATTRIBUTE_STATIC) {
3417 if (bflags & BFLAGS_Static)
3418 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3421 if (bflags & BFLAGS_Instance)
3430 if (compare_func (propname, prop->name))
3434 if (prop->get && prop->get->slot != -1) {
3435 if (method_slots [prop->get->slot >> 5] & (1 << (prop->get->slot & 0x1f)))
3437 method_slots [prop->get->slot >> 5] |= 1 << (prop->get->slot & 0x1f);
3439 if (prop->set && prop->set->slot != -1) {
3440 if (method_slots [prop->set->slot >> 5] & (1 << (prop->set->slot & 0x1f)))
3442 method_slots [prop->set->slot >> 5] |= 1 << (prop->set->slot & 0x1f);
3446 MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, len * 2);
3447 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3451 mono_array_setref (res, i, mono_property_get_object (domain, startklass, prop));
3454 if ((!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent)))
3458 if (method_slots != method_slots_default)
3459 g_free (method_slots);
3461 MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, i);
3462 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3465 * Better solution for the new GC.
3466 * res->max_length = i;
3472 static MonoReflectionEvent *
3473 ves_icall_MonoType_GetEvent (MonoReflectionType *type, MonoString *name, guint32 bflags)
3476 MonoClass *klass, *startklass;
3482 MONO_ARCH_SAVE_REGS;
3484 event_name = mono_string_to_utf8 (name);
3485 if (type->type->byref)
3487 klass = startklass = mono_class_from_mono_type (type->type);
3488 domain = mono_object_domain (type);
3492 while ((event = mono_class_get_events (klass, &iter))) {
3493 if (strcmp (event->name, event_name))
3496 method = event->add;
3498 method = event->remove;
3500 method = event->raise;
3502 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3503 if (!(bflags & BFLAGS_Public))
3506 if (!(bflags & BFLAGS_NonPublic))
3511 if (!(bflags & BFLAGS_NonPublic))
3514 g_free (event_name);
3515 return mono_event_get_object (domain, startklass, event);
3518 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3521 g_free (event_name);
3526 ves_icall_Type_GetEvents_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3529 static MonoClass *System_Reflection_EventInfo;
3530 MonoClass *startklass, *klass;
3537 MONO_ARCH_SAVE_REGS;
3539 if (!System_Reflection_EventInfo)
3540 System_Reflection_EventInfo = mono_class_from_name (
3541 mono_defaults.corlib, "System.Reflection", "EventInfo");
3543 domain = mono_object_domain (type);
3544 if (type->type->byref)
3545 return mono_array_new (domain, System_Reflection_EventInfo, 0);
3546 klass = startklass = mono_class_from_mono_type (type->type);
3550 res = mono_array_new (domain, System_Reflection_EventInfo, len);
3553 while ((event = mono_class_get_events (klass, &iter))) {
3555 method = event->add;
3557 method = event->remove;
3559 method = event->raise;
3561 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3562 if (bflags & BFLAGS_Public)
3565 if (bflags & BFLAGS_NonPublic)
3570 if (bflags & BFLAGS_NonPublic)
3576 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3577 if (bflags & BFLAGS_Static)
3578 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3581 if (bflags & BFLAGS_Instance)
3586 if (bflags & BFLAGS_Instance)
3592 MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, len * 2);
3593 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3597 mono_array_setref (res, i, mono_event_get_object (domain, startklass, event));
3600 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3603 MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, i);
3604 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3607 * Better solution for the new GC.
3608 * res->max_length = i;
3614 static MonoReflectionType *
3615 ves_icall_Type_GetNestedType (MonoReflectionType *type, MonoString *name, guint32 bflags)
3623 MONO_ARCH_SAVE_REGS;
3625 domain = ((MonoObject *)type)->vtable->domain;
3626 if (type->type->byref)
3628 klass = mono_class_from_mono_type (type->type);
3629 str = mono_string_to_utf8 (name);
3633 * If a nested type is generic, return its generic type definition.
3634 * Note that this means that the return value is essentially a
3635 * nested type of the generic type definition of @klass.
3637 * A note in MSDN claims that a generic type definition can have
3638 * nested types that aren't generic. In any case, the container of that
3639 * nested type would be the generic type definition.
3641 if (klass->generic_class)
3642 klass = klass->generic_class->container_class;
3644 for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
3646 nested = tmpn->data;
3647 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
3648 if (bflags & BFLAGS_Public)
3651 if (bflags & BFLAGS_NonPublic)
3656 if (strcmp (nested->name, str) == 0){
3658 return mono_type_get_object (domain, &nested->byval_arg);
3661 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3668 ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags)
3678 MONO_ARCH_SAVE_REGS;
3680 domain = ((MonoObject *)type)->vtable->domain;
3681 if (type->type->byref)
3682 return mono_array_new (domain, mono_defaults.monotype_class, 0);
3683 klass = mono_class_from_mono_type (type->type);
3686 * If a nested type is generic, return its generic type definition.
3687 * Note that this means that the return value is essentially the set
3688 * of nested types of the generic type definition of @klass.
3690 * A note in MSDN claims that a generic type definition can have
3691 * nested types that aren't generic. In any case, the container of that
3692 * nested type would be the generic type definition.
3694 if (klass->generic_class)
3695 klass = klass->generic_class->container_class;
3699 res = mono_array_new (domain, mono_defaults.monotype_class, len);
3700 for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
3702 nested = tmpn->data;
3703 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
3704 if (bflags & BFLAGS_Public)
3707 if (bflags & BFLAGS_NonPublic)
3712 member = (MonoObject*)mono_type_get_object (domain, &nested->byval_arg);
3714 MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, len * 2);
3715 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3719 mono_array_setref (res, i, member);
3723 MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, i);
3724 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3727 * Better solution for the new GC.
3728 * res->max_length = i;
3734 static MonoReflectionType*
3735 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *assembly, MonoReflectionModule *module, MonoString *name, MonoBoolean throwOnError, MonoBoolean ignoreCase)
3738 MonoType *type = NULL;
3739 MonoTypeNameParse info;
3740 gboolean type_resolve;
3742 MONO_ARCH_SAVE_REGS;
3744 /* On MS.NET, this does not fire a TypeResolve event */
3745 type_resolve = TRUE;
3746 str = mono_string_to_utf8 (name);
3747 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
3748 if (!mono_reflection_parse_type (str, &info)) {
3750 g_list_free (info.modifiers);
3751 g_list_free (info.nested);
3752 if (throwOnError) /* uhm: this is a parse error, though... */
3753 mono_raise_exception (mono_get_exception_type_load (name, NULL));
3754 /*g_print ("failed parse\n");*/
3758 if (module != NULL) {
3760 type = mono_reflection_get_type (module->image, &info, ignoreCase, &type_resolve);
3765 if (assembly->assembly->dynamic) {
3766 /* Enumerate all modules */
3767 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
3771 if (abuilder->modules) {
3772 for (i = 0; i < mono_array_length (abuilder->modules); ++i) {
3773 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
3774 type = mono_reflection_get_type (&mb->dynamic_image->image, &info, ignoreCase, &type_resolve);
3780 if (!type && abuilder->loaded_modules) {
3781 for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) {
3782 MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
3783 type = mono_reflection_get_type (mod->image, &info, ignoreCase, &type_resolve);
3790 type = mono_reflection_get_type (assembly->assembly->image, &info, ignoreCase, &type_resolve);
3792 g_list_free (info.modifiers);
3793 g_list_free (info.nested);
3796 mono_raise_exception (mono_get_exception_type_load (name, NULL));
3797 /* g_print ("failed find\n"); */
3801 if (type->type == MONO_TYPE_CLASS) {
3802 MonoClass *klass = mono_type_get_class (type);
3803 /* need to report exceptions ? */
3804 if (throwOnError && klass->exception_type) {
3805 /* report SecurityException (or others) that occured when loading the assembly */
3806 MonoException *exc = mono_class_get_exception_for_failure (klass);
3807 mono_raise_exception (exc);
3808 } else if (klass->exception_type == MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND) {
3813 /* g_print ("got it\n"); */
3814 return mono_type_get_object (mono_object_domain (assembly), type);
3818 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *assembly, MonoBoolean escaped)
3820 MonoDomain *domain = mono_object_domain (assembly);
3821 MonoAssembly *mass = assembly->assembly;
3822 MonoString *res = NULL;
3826 MONO_ARCH_SAVE_REGS;
3828 if (g_path_is_absolute (mass->image->name))
3829 absolute = g_strdup (mass->image->name);
3831 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
3835 for (i = strlen (absolute) - 1; i >= 0; i--)
3836 if (absolute [i] == '\\')
3841 uri = g_filename_to_uri (absolute, NULL, NULL);
3843 uri = g_strconcat ("file://", absolute, NULL);
3847 res = mono_string_new (domain, uri);
3855 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssembly *assembly)
3857 MonoAssembly *mass = assembly->assembly;
3859 MONO_ARCH_SAVE_REGS;
3861 return mass->in_gac;
3864 static MonoReflectionAssembly*
3865 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoString *mname, MonoObject *evidence)
3869 MonoImageOpenStatus status;
3871 MONO_ARCH_SAVE_REGS;
3873 name = mono_string_to_utf8 (mname);
3874 res = mono_assembly_load_with_partial_name (name, &status);
3880 return mono_assembly_get_object (mono_domain_get (), res);
3884 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssembly *assembly)
3886 MonoDomain *domain = mono_object_domain (assembly);
3889 MONO_ARCH_SAVE_REGS;
3891 res = mono_string_new (domain, mono_image_get_filename (assembly->assembly->image));
3897 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssembly *assembly)
3899 MONO_ARCH_SAVE_REGS;
3901 return assembly->assembly->ref_only;
3905 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssembly *assembly)
3907 MonoDomain *domain = mono_object_domain (assembly);
3909 MONO_ARCH_SAVE_REGS;
3911 return mono_string_new (domain, assembly->assembly->image->version);
3914 static MonoReflectionMethod*
3915 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssembly *assembly)
3917 guint32 token = mono_image_get_entry_point (assembly->assembly->image);
3919 MONO_ARCH_SAVE_REGS;
3923 return mono_method_get_object (mono_object_domain (assembly), mono_get_method (assembly->assembly->image, token, NULL), NULL);
3926 static MonoReflectionModule*
3927 ves_icall_System_Reflection_Assembly_get_ManifestModule (MonoReflectionAssembly *assembly)
3929 return mono_module_get_object (mono_object_domain (assembly), assembly->assembly->image);
3933 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssembly *assembly)
3935 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
3936 MonoArray *result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, table->rows);
3940 MONO_ARCH_SAVE_REGS;
3942 for (i = 0; i < table->rows; ++i) {
3943 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_MANIFEST_NAME));
3944 mono_array_setref (result, i, mono_string_new (mono_object_domain (assembly), val));
3950 create_version (MonoDomain *domain, guint32 major, guint32 minor, guint32 build, guint32 revision)
3952 static MonoClass *System_Version = NULL;
3953 static MonoMethod *create_version = NULL;
3957 if (!System_Version) {
3958 System_Version = mono_class_from_name (mono_defaults.corlib, "System", "Version");
3959 g_assert (System_Version);
3962 if (!create_version) {
3963 MonoMethodDesc *desc = mono_method_desc_new (":.ctor(int,int,int,int)", FALSE);
3964 create_version = mono_method_desc_search_in_class (desc, System_Version);
3965 g_assert (create_version);
3966 mono_method_desc_free (desc);
3972 args [3] = &revision;
3973 result = mono_object_new (domain, System_Version);
3974 mono_runtime_invoke (create_version, result, args, NULL);
3980 ves_icall_System_Reflection_Assembly_GetReferencedAssemblies (MonoReflectionAssembly *assembly)
3982 static MonoClass *System_Reflection_AssemblyName;
3984 MonoDomain *domain = mono_object_domain (assembly);
3986 static MonoMethod *create_culture = NULL;
3987 MonoImage *image = assembly->assembly->image;
3990 MONO_ARCH_SAVE_REGS;
3992 if (!System_Reflection_AssemblyName)
3993 System_Reflection_AssemblyName = mono_class_from_name (
3994 mono_defaults.corlib, "System.Reflection", "AssemblyName");
3996 t = &assembly->assembly->image->tables [MONO_TABLE_ASSEMBLYREF];
3999 result = mono_array_new (domain, System_Reflection_AssemblyName, count);
4002 MonoMethodDesc *desc = mono_method_desc_new (
4003 "System.Globalization.CultureInfo:CreateSpecificCulture(string)", TRUE);
4004 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4005 g_assert (create_culture);
4006 mono_method_desc_free (desc);
4009 for (i = 0; i < count; i++) {
4010 MonoReflectionAssemblyName *aname;
4011 guint32 cols [MONO_ASSEMBLYREF_SIZE];
4013 mono_metadata_decode_row (t, i, cols, MONO_ASSEMBLYREF_SIZE);
4015 aname = (MonoReflectionAssemblyName *) mono_object_new (
4016 domain, System_Reflection_AssemblyName);
4018 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_NAME])));
4020 aname->major = cols [MONO_ASSEMBLYREF_MAJOR_VERSION];
4021 aname->minor = cols [MONO_ASSEMBLYREF_MINOR_VERSION];
4022 aname->build = cols [MONO_ASSEMBLYREF_BUILD_NUMBER];
4023 aname->revision = cols [MONO_ASSEMBLYREF_REV_NUMBER];
4024 aname->flags = cols [MONO_ASSEMBLYREF_FLAGS];
4025 aname->versioncompat = 1; /* SameMachine (default) */
4026 aname->hashalg = ASSEMBLY_HASH_SHA1; /* SHA1 (default) */
4027 MONO_OBJECT_SETREF (aname, version, create_version (domain, aname->major, aname->minor, aname->build, aname->revision));
4029 if (create_culture) {
4031 args [0] = mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_CULTURE]));
4032 MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
4035 if (cols [MONO_ASSEMBLYREF_PUBLIC_KEY]) {
4036 const gchar *pkey_ptr = mono_metadata_blob_heap (image, cols [MONO_ASSEMBLYREF_PUBLIC_KEY]);
4037 guint32 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
4039 if ((cols [MONO_ASSEMBLYREF_FLAGS] & ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG)) {
4040 /* public key token isn't copied - the class library will
4041 automatically generate it from the public key if required */
4042 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4043 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
4045 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4046 memcpy (mono_array_addr (aname->keyToken, guint8, 0), pkey_ptr, pkey_len);
4050 /* note: this function doesn't return the codebase on purpose (i.e. it can
4051 be used under partial trust as path information isn't present). */
4053 mono_array_setref (result, i, aname);
4064 foreach_namespace (const char* key, gconstpointer val, NameSpaceInfo *info)
4066 MonoString *name = mono_string_new (mono_object_domain (info->res), key);
4068 mono_array_setref (info->res, info->idx, name);
4073 ves_icall_System_Reflection_Assembly_GetNamespaces (MonoReflectionAssembly *assembly)
4075 MonoImage *img = assembly->assembly->image;
4079 MONO_ARCH_SAVE_REGS;
4081 if (!img->name_cache)
4082 mono_image_init_name_cache (img);
4084 res = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, g_hash_table_size (img->name_cache));
4087 g_hash_table_foreach (img->name_cache, (GHFunc)foreach_namespace, &info);
4092 /* move this in some file in mono/util/ */
4094 g_concat_dir_and_file (const char *dir, const char *file)
4096 g_return_val_if_fail (dir != NULL, NULL);
4097 g_return_val_if_fail (file != NULL, NULL);
4100 * If the directory name doesn't have a / on the end, we need
4101 * to add one so we get a proper path to the file
4103 if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
4104 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
4106 return g_strconcat (dir, file, NULL);
4110 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssembly *assembly, MonoString *name, gint32 *size, MonoReflectionModule **ref_module)
4112 char *n = mono_string_to_utf8 (name);
4113 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4115 guint32 cols [MONO_MANIFEST_SIZE];
4116 guint32 impl, file_idx;
4120 MONO_ARCH_SAVE_REGS;
4122 for (i = 0; i < table->rows; ++i) {
4123 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4124 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4125 if (strcmp (val, n) == 0)
4129 if (i == table->rows)
4132 impl = cols [MONO_MANIFEST_IMPLEMENTATION];
4135 * this code should only be called after obtaining the
4136 * ResourceInfo and handling the other cases.
4138 g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
4139 file_idx = impl >> MONO_IMPLEMENTATION_BITS;
4141 module = mono_image_load_file_for_image (assembly->assembly->image, file_idx);
4146 module = assembly->assembly->image;
4148 *ref_module = mono_module_get_object (mono_domain_get (), module);
4150 return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
4154 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoManifestResourceInfo *info)
4156 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4158 guint32 cols [MONO_MANIFEST_SIZE];
4159 guint32 file_cols [MONO_FILE_SIZE];
4163 MONO_ARCH_SAVE_REGS;
4165 n = mono_string_to_utf8 (name);
4166 for (i = 0; i < table->rows; ++i) {
4167 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4168 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4169 if (strcmp (val, n) == 0)
4173 if (i == table->rows)
4176 if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
4177 info->location = RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST;
4180 switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
4181 case MONO_IMPLEMENTATION_FILE:
4182 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4183 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4184 mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
4185 val = mono_metadata_string_heap (assembly->assembly->image, file_cols [MONO_FILE_NAME]);
4186 MONO_OBJECT_SETREF (info, filename, mono_string_new (mono_object_domain (assembly), val));
4187 if (file_cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA)
4190 info->location = RESOURCE_LOCATION_EMBEDDED;
4193 case MONO_IMPLEMENTATION_ASSEMBLYREF:
4194 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4195 mono_assembly_load_reference (assembly->assembly->image, i - 1);
4196 if (assembly->assembly->image->references [i - 1] == (gpointer)-1) {
4197 char *msg = g_strdup_printf ("Assembly %d referenced from assembly %s not found ", i - 1, assembly->assembly->image->name);
4198 MonoException *ex = mono_get_exception_file_not_found2 (msg, NULL);
4200 mono_raise_exception (ex);
4202 MONO_OBJECT_SETREF (info, assembly, mono_assembly_get_object (mono_domain_get (), assembly->assembly->image->references [i - 1]));
4204 /* Obtain info recursively */
4205 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (info->assembly, name, info);
4206 info->location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
4209 case MONO_IMPLEMENTATION_EXP_TYPE:
4210 g_assert_not_reached ();
4219 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoBoolean resource_modules)
4221 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4222 MonoArray *result = NULL;
4227 MONO_ARCH_SAVE_REGS;
4229 /* check hash if needed */
4231 n = mono_string_to_utf8 (name);
4232 for (i = 0; i < table->rows; ++i) {
4233 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4234 if (strcmp (val, n) == 0) {
4237 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4238 fn = mono_string_new (mono_object_domain (assembly), n);
4240 return (MonoObject*)fn;
4248 for (i = 0; i < table->rows; ++i) {
4249 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA))
4253 result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, count);
4256 for (i = 0; i < table->rows; ++i) {
4257 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4258 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4259 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4260 mono_array_setref (result, count, mono_string_new (mono_object_domain (assembly), n));
4265 return (MonoObject*)result;
4269 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly *assembly)
4271 MonoDomain *domain = mono_domain_get();
4274 int i, j, file_count = 0;
4275 MonoImage **modules;
4276 guint32 module_count, real_module_count;
4277 MonoTableInfo *table;
4279 g_assert (assembly->assembly->image != NULL);
4281 if (assembly->assembly->dynamic) {
4282 MonoReflectionAssemblyBuilder *assemblyb = (MonoReflectionAssemblyBuilder*)assembly;
4284 if (assemblyb->modules)
4285 module_count = mono_array_length (assemblyb->modules);
4288 real_module_count = module_count;
4290 modules = g_new0 (MonoImage*, module_count);
4291 if (assemblyb->modules) {
4292 for (i = 0; i < mono_array_length (assemblyb->modules); ++i) {
4294 mono_array_get (assemblyb->modules, MonoReflectionModuleBuilder*, i)->module.image;
4299 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4300 file_count = table->rows;
4302 modules = assembly->assembly->image->modules;
4303 module_count = assembly->assembly->image->module_count;
4305 real_module_count = 0;
4306 for (i = 0; i < module_count; ++i)
4308 real_module_count ++;
4311 klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "Module");
4312 res = mono_array_new (domain, klass, 1 + real_module_count + file_count);
4314 mono_array_setref (res, 0, mono_module_get_object (domain, assembly->assembly->image));
4316 for (i = 0; i < module_count; ++i)
4318 mono_array_setref (res, j, mono_module_get_object (domain, modules[i]));
4322 for (i = 0; i < file_count; ++i, ++j)
4323 mono_array_setref (res, j, mono_module_file_get_object (domain, assembly->assembly->image, i));
4325 if (assembly->assembly->dynamic)
4331 static MonoReflectionMethod*
4332 ves_icall_GetCurrentMethod (void)
4334 MonoMethod *m = mono_method_get_last_managed ();
4336 MONO_ARCH_SAVE_REGS;
4338 return mono_method_get_object (mono_domain_get (), m, NULL);
4341 static MonoReflectionMethod*
4342 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternal (MonoMethod *method)
4344 return mono_method_get_object (mono_domain_get (), method, NULL);
4347 static MonoReflectionMethodBody*
4348 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod *method)
4350 return mono_method_body_get_object (mono_domain_get (), method);
4353 static MonoReflectionAssembly*
4354 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (void)
4356 MonoMethod *m = mono_method_get_last_managed ();
4358 MONO_ARCH_SAVE_REGS;
4360 return mono_assembly_get_object (mono_domain_get (), m->klass->image->assembly);
4364 static MonoReflectionAssembly*
4365 ves_icall_System_Reflection_Assembly_GetEntryAssembly (void)
4367 MonoDomain* domain = mono_domain_get ();
4369 MONO_ARCH_SAVE_REGS;
4371 if (!domain->entry_assembly)
4374 return mono_assembly_get_object (domain, domain->entry_assembly);
4377 static MonoReflectionAssembly*
4378 ves_icall_System_Reflection_Assembly_GetCallingAssembly (void)
4380 MonoMethod *m = mono_method_get_last_managed ();
4381 MonoMethod *dest = m;
4383 MONO_ARCH_SAVE_REGS;
4385 mono_stack_walk_no_il (get_caller, &dest);
4388 return mono_assembly_get_object (mono_domain_get (), dest->klass->image->assembly);
4392 ves_icall_System_MonoType_getFullName (MonoReflectionType *object, gboolean full_name,
4393 gboolean assembly_qualified)
4395 MonoDomain *domain = mono_object_domain (object);
4396 MonoTypeNameFormat format;
4400 MONO_ARCH_SAVE_REGS;
4402 format = assembly_qualified ?
4403 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
4404 MONO_TYPE_NAME_FORMAT_FULL_NAME;
4406 format = MONO_TYPE_NAME_FORMAT_REFLECTION;
4408 name = mono_type_get_name_full (object->type, format);
4412 if (full_name && (object->type->type == MONO_TYPE_VAR || object->type->type == MONO_TYPE_MVAR))
4415 res = mono_string_new (domain, name);
4422 fill_reflection_assembly_name (MonoDomain *domain, MonoReflectionAssemblyName *aname, MonoAssemblyName *name, const char *absolute, gboolean by_default_version)
4424 static MonoMethod *create_culture = NULL;
4427 const char *pkey_ptr;
4430 MONO_ARCH_SAVE_REGS;
4432 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, name->name));
4433 aname->major = name->major;
4434 aname->minor = name->minor;
4435 aname->build = name->build;
4436 aname->revision = name->revision;
4437 aname->hashalg = name->hash_alg;
4438 if (by_default_version)
4439 MONO_OBJECT_SETREF (aname, version, create_version (domain, name->major, name->minor, name->build, name->revision));
4441 codebase = g_filename_to_uri (absolute, NULL, NULL);
4443 MONO_OBJECT_SETREF (aname, codebase, mono_string_new (domain, codebase));
4447 if (!create_culture) {
4448 MonoMethodDesc *desc = mono_method_desc_new ("System.Globalization.CultureInfo:CreateSpecificCulture(string)", TRUE);
4449 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4450 g_assert (create_culture);
4451 mono_method_desc_free (desc);
4454 if (name->culture) {
4455 args [0] = mono_string_new (domain, name->culture);
4456 MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
4459 if (name->public_key) {
4460 pkey_ptr = (char*)name->public_key;
4461 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
4463 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4464 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
4467 /* MonoAssemblyName keeps the public key token as an hexadecimal string */
4468 if (name->public_key_token [0]) {
4472 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, 8));
4473 p = mono_array_addr (aname->keyToken, char, 0);
4475 for (i = 0, j = 0; i < 8; i++) {
4476 *p = g_ascii_xdigit_value (name->public_key_token [j++]) << 4;
4477 *p |= g_ascii_xdigit_value (name->public_key_token [j++]);
4484 ves_icall_System_Reflection_Assembly_FillName (MonoReflectionAssembly *assembly, MonoReflectionAssemblyName *aname)
4487 MonoAssembly *mass = assembly->assembly;
4489 MONO_ARCH_SAVE_REGS;
4491 if (g_path_is_absolute (mass->image->name)) {
4492 fill_reflection_assembly_name (mono_object_domain (assembly),
4493 aname, &mass->aname, mass->image->name, TRUE);
4496 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4498 fill_reflection_assembly_name (mono_object_domain (assembly),
4499 aname, &mass->aname, absolute, TRUE);
4505 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoString *fname, MonoReflectionAssemblyName *aname)
4508 MonoImageOpenStatus status = MONO_IMAGE_OK;
4511 MonoAssemblyName name;
4513 MONO_ARCH_SAVE_REGS;
4515 filename = mono_string_to_utf8 (fname);
4517 image = mono_image_open (filename, &status);
4523 if (status == MONO_IMAGE_IMAGE_INVALID)
4524 exc = mono_get_exception_bad_image_format2 (NULL, fname);
4526 exc = mono_get_exception_file_not_found2 (NULL, fname);
4527 mono_raise_exception (exc);
4530 res = mono_assembly_fill_assembly_name (image, &name);
4532 mono_image_close (image);
4534 mono_raise_exception (mono_get_exception_argument ("assemblyFile", "The file does not contain a manifest"));
4537 fill_reflection_assembly_name (mono_domain_get (), aname, &name, filename, TRUE);
4540 mono_image_close (image);
4544 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssembly *assembly,
4545 char **minimum, guint32 *minLength, char **optional, guint32 *optLength, char **refused, guint32 *refLength)
4547 MonoBoolean result = FALSE;
4548 MonoDeclSecurityEntry entry;
4550 /* SecurityAction.RequestMinimum */
4551 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQMIN, &entry)) {
4552 *minimum = entry.blob;
4553 *minLength = entry.size;
4556 /* SecurityAction.RequestOptional */
4557 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQOPT, &entry)) {
4558 *optional = entry.blob;
4559 *optLength = entry.size;
4562 /* SecurityAction.RequestRefuse */
4563 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQREFUSE, &entry)) {
4564 *refused = entry.blob;
4565 *refLength = entry.size;
4573 mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoBoolean exportedOnly)
4577 MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
4579 guint32 attrs, visibility;
4581 /* we start the count from 1 because we skip the special type <Module> */
4584 for (i = 1; i < tdef->rows; ++i) {
4585 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
4586 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
4587 if (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)
4591 count = tdef->rows - 1;
4593 res = mono_array_new (domain, mono_defaults.monotype_class, count);
4595 for (i = 1; i < tdef->rows; ++i) {
4596 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
4597 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
4598 if (!exportedOnly || (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)) {
4599 klass = mono_class_get_throw (image, (i + 1) | MONO_TOKEN_TYPE_DEF);
4600 if (mono_loader_get_last_error ())
4601 mono_loader_clear_error ();
4602 mono_array_setref (res, count, mono_type_get_object (domain, &klass->byval_arg));
4611 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly, MonoBoolean exportedOnly)
4613 MonoArray *res = NULL;
4614 MonoImage *image = NULL;
4615 MonoTableInfo *table = NULL;
4620 MONO_ARCH_SAVE_REGS;
4622 domain = mono_object_domain (assembly);
4624 if (assembly->assembly->dynamic) {
4625 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
4626 if (abuilder->modules) {
4627 for (i = 0; i < mono_array_length(abuilder->modules); i++) {
4628 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
4629 MonoArray *append = mb->types;
4630 /* The types array might not be fully filled up */
4631 if (append && mb->num_types > 0) {
4634 len1 = res ? mono_array_length (res) : 0;
4635 len2 = mb->num_types;
4636 new = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4638 mono_array_memcpy_refs (new, 0, res, 0, len1);
4639 mono_array_memcpy_refs (new, len1, append, 0, len2);
4645 * Replace TypeBuilders with the created types to be compatible
4649 for (i = 0; i < mono_array_length (res); ++i) {
4650 MonoReflectionTypeBuilder *tb = mono_array_get (res, MonoReflectionTypeBuilder*, i);
4652 mono_array_setref (res, i, tb->created);
4657 if (abuilder->loaded_modules)
4658 for (i = 0; i < mono_array_length(abuilder->loaded_modules); i++) {
4659 MonoReflectionModule *rm = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
4660 MonoArray *append = mono_module_get_types (domain, rm->image, exportedOnly);
4661 if (append && mono_array_length (append) > 0) {
4664 len1 = res ? mono_array_length (res) : 0;
4665 len2 = mono_array_length (append);
4666 new = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4668 mono_array_memcpy_refs (new, 0, res, 0, len1);
4669 mono_array_memcpy_refs (new, len1, append, 0, len2);
4676 return mono_array_new (domain, mono_defaults.monotype_class, 0);
4678 image = assembly->assembly->image;
4679 table = &image->tables [MONO_TABLE_FILE];
4680 res = mono_module_get_types (domain, image, exportedOnly);
4682 /* Append data from all modules in the assembly */
4683 for (i = 0; i < table->rows; ++i) {
4684 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4685 MonoImage *loaded_image = mono_assembly_load_module (image->assembly, i + 1);
4687 MonoArray *res2 = mono_module_get_types (domain, loaded_image, exportedOnly);
4688 /* Append the new types to the end of the array */
4689 if (mono_array_length (res2) > 0) {
4693 len1 = mono_array_length (res);
4694 len2 = mono_array_length (res2);
4695 res3 = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4696 mono_array_memcpy_refs (res3, 0, res, 0, len1);
4697 mono_array_memcpy_refs (res3, len1, res2, 0, len2);
4704 /* the ReflectionTypeLoadException must have all the types (Types property),
4705 * NULL replacing types which throws an exception. The LoaderException must
4706 * contain all exceptions for NULL items.
4709 len = mono_array_length (res);
4711 for (i = 0; i < len; i++) {
4712 MonoReflectionType *t = mono_array_get (res, gpointer, i);
4713 MonoClass *klass = mono_type_get_class (t->type);
4714 if ((klass != NULL) && klass->exception_type) {
4715 /* keep the class in the list */
4716 list = g_list_append (list, klass);
4717 /* and replace Type with NULL */
4718 mono_array_setref (res, i, NULL);
4724 MonoException *exc = NULL;
4725 MonoArray *exl = NULL;
4726 int length = g_list_length (list);
4728 mono_loader_clear_error ();
4730 exl = mono_array_new (domain, mono_defaults.exception_class, length);
4731 for (i = 0, tmp = list; i < length; i++, tmp = tmp->next) {
4732 MonoException *exc = mono_class_get_exception_for_failure (tmp->data);
4733 mono_array_setref (exl, i, exc);
4738 exc = mono_get_exception_reflection_type_load (res, exl);
4739 mono_raise_exception (exc);
4746 ves_icall_System_Reflection_AssemblyName_ParseName (MonoReflectionAssemblyName *name, MonoString *assname)
4748 MonoAssemblyName aname;
4749 MonoDomain *domain = mono_object_domain (name);
4751 gboolean is_version_defined;
4753 val = mono_string_to_utf8 (assname);
4754 if (!mono_assembly_name_parse_full (val, &aname, TRUE, &is_version_defined))
4757 fill_reflection_assembly_name (domain, name, &aname, "", is_version_defined);
4759 mono_assembly_name_free (&aname);
4760 g_free ((guint8*) aname.public_key);
4766 static MonoReflectionType*
4767 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModule *module)
4769 MonoDomain *domain = mono_object_domain (module);
4772 MONO_ARCH_SAVE_REGS;
4774 g_assert (module->image);
4776 if (module->image->dynamic && ((MonoDynamicImage*)(module->image))->initial_image)
4777 /* These images do not have a global type */
4780 klass = mono_class_get (module->image, 1 | MONO_TOKEN_TYPE_DEF);
4781 return mono_type_get_object (domain, &klass->byval_arg);
4785 ves_icall_System_Reflection_Module_Close (MonoReflectionModule *module)
4787 /*if (module->image)
4788 mono_image_close (module->image);*/
4792 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModule *module)
4794 MonoDomain *domain = mono_object_domain (module);
4796 MONO_ARCH_SAVE_REGS;
4798 g_assert (module->image);
4799 return mono_string_new (domain, module->image->guid);
4803 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine)
4805 if (image->dynamic) {
4806 MonoDynamicImage *dyn = (MonoDynamicImage*)image;
4807 *pe_kind = dyn->pe_kind;
4808 *machine = dyn->machine;
4811 *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
4812 *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
4817 ves_icall_System_Reflection_Module_get_MDStreamVersion (MonoReflectionModule *module)
4819 MonoImage *image = module->image;
4822 mono_raise_exception (mono_get_exception_not_supported (""));
4824 return (image->md_version_major << 16) | (image->md_version_minor);
4828 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModule *module)
4830 MONO_ARCH_SAVE_REGS;
4833 return mono_array_new (mono_object_domain (module), mono_defaults.monotype_class, 0);
4835 return mono_module_get_types (mono_object_domain (module), module->image, FALSE);
4839 mono_metadata_memberref_is_method (MonoImage *image, guint32 token)
4841 guint32 cols [MONO_MEMBERREF_SIZE];
4843 mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
4844 sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
4845 mono_metadata_decode_blob_size (sig, &sig);
4846 return (*sig != 0x6);
4850 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
4853 int table = mono_metadata_token_table (token);
4854 int index = mono_metadata_token_index (token);
4856 *error = ResolveTokenError_Other;
4858 /* Validate token */
4859 if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) &&
4860 (table != MONO_TABLE_TYPESPEC)) {
4861 *error = ResolveTokenError_BadTable;
4866 return mono_lookup_dynamic_token (image, token);
4868 if ((index <= 0) || (index > image->tables [table].rows)) {
4869 *error = ResolveTokenError_OutOfRange;
4873 klass = mono_class_get (image, token);
4875 return &klass->byval_arg;
4881 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
4883 int table = mono_metadata_token_table (token);
4884 int index = mono_metadata_token_index (token);
4886 *error = ResolveTokenError_Other;
4888 /* Validate token */
4889 if ((table != MONO_TABLE_METHOD) && (table != MONO_TABLE_METHODSPEC) &&
4890 (table != MONO_TABLE_MEMBERREF)) {
4891 *error = ResolveTokenError_BadTable;
4896 /* FIXME: validate memberref token type */
4897 return mono_lookup_dynamic_token (image, token);
4899 if ((index <= 0) || (index > image->tables [table].rows)) {
4900 *error = ResolveTokenError_OutOfRange;
4903 if ((table == MONO_TABLE_MEMBERREF) && (!mono_metadata_memberref_is_method (image, token))) {
4904 *error = ResolveTokenError_BadTable;
4908 return mono_get_method (image, token, NULL);
4912 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
4914 int index = mono_metadata_token_index (token);
4916 *error = ResolveTokenError_Other;
4918 /* Validate token */
4919 if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
4920 *error = ResolveTokenError_BadTable;
4925 return mono_lookup_dynamic_token (image, token);
4927 if ((index <= 0) || (index >= image->heap_us.size)) {
4928 *error = ResolveTokenError_OutOfRange;
4932 /* FIXME: What to do if the index points into the middle of a string ? */
4934 return mono_ldstr (mono_domain_get (), image, index);
4937 static MonoClassField*
4938 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
4941 int table = mono_metadata_token_table (token);
4942 int index = mono_metadata_token_index (token);
4944 *error = ResolveTokenError_Other;
4946 /* Validate token */
4947 if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
4948 *error = ResolveTokenError_BadTable;
4953 /* FIXME: validate memberref token type */
4954 return mono_lookup_dynamic_token (image, token);
4956 if ((index <= 0) || (index > image->tables [table].rows)) {
4957 *error = ResolveTokenError_OutOfRange;
4960 if ((table == MONO_TABLE_MEMBERREF) && (mono_metadata_memberref_is_method (image, token))) {
4961 *error = ResolveTokenError_BadTable;
4965 return mono_field_from_token (image, token, &klass, NULL);
4970 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
4972 int table = mono_metadata_token_table (token);
4974 *error = ResolveTokenError_Other;
4977 case MONO_TABLE_TYPEDEF:
4978 case MONO_TABLE_TYPEREF:
4979 case MONO_TABLE_TYPESPEC: {
4980 MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, error);
4982 return (MonoObject*)mono_type_get_object (mono_domain_get (), t);
4986 case MONO_TABLE_METHOD:
4987 case MONO_TABLE_METHODSPEC: {
4988 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, error);
4990 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
4994 case MONO_TABLE_FIELD: {
4995 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, error);
4997 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
5001 case MONO_TABLE_MEMBERREF:
5002 if (mono_metadata_memberref_is_method (image, token)) {
5003 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, error);
5005 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
5010 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, error);
5012 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
5019 *error = ResolveTokenError_BadTable;
5025 static MonoReflectionType*
5026 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
5029 int isbyref = 0, rank;
5030 char *str = mono_string_to_utf8 (smodifiers);
5033 MONO_ARCH_SAVE_REGS;
5035 klass = mono_class_from_mono_type (tb->type.type);
5037 /* logic taken from mono_reflection_parse_type(): keep in sync */
5041 if (isbyref) { /* only one level allowed by the spec */
5048 return mono_type_get_object (mono_object_domain (tb), &klass->this_arg);
5051 klass = mono_ptr_class_get (&klass->byval_arg);
5052 mono_class_init (klass);
5063 else if (*p != '*') { /* '*' means unknown lower bound */
5074 klass = mono_array_class_get (klass, rank);
5075 mono_class_init (klass);
5082 return mono_type_get_object (mono_object_domain (tb), &klass->byval_arg);
5086 ves_icall_Type_IsArrayImpl (MonoReflectionType *t)
5091 MONO_ARCH_SAVE_REGS;
5094 res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
5099 static MonoReflectionType *
5100 ves_icall_Type_make_array_type (MonoReflectionType *type, int rank)
5102 MonoClass *klass, *aklass;
5104 MONO_ARCH_SAVE_REGS;
5106 klass = mono_class_from_mono_type (type->type);
5107 aklass = mono_array_class_get (klass, rank);
5109 return mono_type_get_object (mono_object_domain (type), &aklass->byval_arg);
5112 static MonoReflectionType *
5113 ves_icall_Type_make_byref_type (MonoReflectionType *type)
5117 MONO_ARCH_SAVE_REGS;
5119 klass = mono_class_from_mono_type (type->type);
5121 return mono_type_get_object (mono_object_domain (type), &klass->this_arg);
5124 static MonoReflectionType *
5125 ves_icall_Type_MakePointerType (MonoReflectionType *type)
5129 MONO_ARCH_SAVE_REGS;
5131 pklass = mono_ptr_class_get (type->type);
5133 return mono_type_get_object (mono_object_domain (type), &pklass->byval_arg);
5137 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
5138 MonoReflectionMethod *info)
5140 MonoClass *delegate_class = mono_class_from_mono_type (type->type);
5141 MonoObject *delegate;
5144 MONO_ARCH_SAVE_REGS;
5146 mono_assert (delegate_class->parent == mono_defaults.multicastdelegate_class);
5148 delegate = mono_object_new (mono_object_domain (type), delegate_class);
5150 func = mono_compile_method (info->method);
5152 mono_delegate_ctor (delegate, target, func);
5158 * Magic number to convert a time which is relative to
5159 * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
5161 #define EPOCH_ADJUST ((guint64)62135596800LL)
5164 * Magic number to convert FILETIME base Jan 1, 1601 to DateTime - base Jan, 1, 0001
5166 #define FILETIME_ADJUST ((guint64)504911232000000000LL)
5169 * This returns Now in UTC
5172 ves_icall_System_DateTime_GetNow (void)
5174 #ifdef PLATFORM_WIN32
5178 GetSystemTime (&st);
5179 SystemTimeToFileTime (&st, &ft);
5180 return (gint64) FILETIME_ADJUST + ((((gint64)ft.dwHighDateTime)<<32) | ft.dwLowDateTime);
5182 /* FIXME: put this in io-layer and call it GetLocalTime */
5186 MONO_ARCH_SAVE_REGS;
5188 if (gettimeofday (&tv, NULL) == 0) {
5189 res = (((gint64)tv.tv_sec + EPOCH_ADJUST)* 1000000 + tv.tv_usec)*10;
5192 /* fixme: raise exception */
5197 #ifdef PLATFORM_WIN32
5198 /* convert a SYSTEMTIME which is of the form "last thursday in october" to a real date */
5200 convert_to_absolute_date(SYSTEMTIME *date)
5202 #define IS_LEAP(y) ((y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0))
5203 static int days_in_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5204 static int leap_days_in_month[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5205 /* from the calendar FAQ */
5206 int a = (14 - date->wMonth) / 12;
5207 int y = date->wYear - a;
5208 int m = date->wMonth + 12 * a - 2;
5209 int d = (1 + y + y/4 - y/100 + y/400 + (31*m)/12) % 7;
5211 /* d is now the day of the week for the first of the month (0 == Sunday) */
5213 int day_of_week = date->wDayOfWeek;
5215 /* set day_in_month to the first day in the month which falls on day_of_week */
5216 int day_in_month = 1 + (day_of_week - d);
5217 if (day_in_month <= 0)
5220 /* wDay is 1 for first weekday in month, 2 for 2nd ... 5 means last - so work that out allowing for days in the month */
5221 date->wDay = day_in_month + (date->wDay - 1) * 7;
5222 if (date->wDay > (IS_LEAP(date->wYear) ? leap_days_in_month[date->wMonth - 1] : days_in_month[date->wMonth - 1]))
5227 #ifndef PLATFORM_WIN32
5229 * Return's the offset from GMT of a local time.
5231 * tm is a local time
5232 * t is the same local time as seconds.
5235 gmt_offset(struct tm *tm, time_t t)
5237 #if defined (HAVE_TM_GMTOFF)
5238 return tm->tm_gmtoff;
5243 g.tm_isdst = tm->tm_isdst;
5245 return (int)difftime(t, t2);
5250 * This is heavily based on zdump.c from glibc 2.2.
5252 * * data[0]: start of daylight saving time (in DateTime ticks).
5253 * * data[1]: end of daylight saving time (in DateTime ticks).
5254 * * data[2]: utcoffset (in TimeSpan ticks).
5255 * * data[3]: additional offset when daylight saving (in TimeSpan ticks).
5256 * * name[0]: name of this timezone when not daylight saving.
5257 * * name[1]: name of this timezone when daylight saving.
5259 * FIXME: This only works with "standard" Unix dates (years between 1900 and 2100) while
5260 * the class library allows years between 1 and 9999.
5262 * Returns true on success and zero on failure.
5265 ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year, MonoArray **data, MonoArray **names)
5267 #ifndef PLATFORM_WIN32
5268 MonoDomain *domain = mono_domain_get ();
5269 struct tm start, tt;
5273 int is_daylight = 0, day;
5276 MONO_ARCH_SAVE_REGS;
5278 MONO_CHECK_ARG_NULL (data);
5279 MONO_CHECK_ARG_NULL (names);
5281 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5282 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5285 * no info is better than crashing: we'll need our own tz data
5286 * to make this work properly, anyway. The range is probably
5287 * reduced to 1970 .. 2037 because that is what mktime is
5288 * guaranteed to support (we get into an infinite loop
5292 memset (&start, 0, sizeof (start));
5295 start.tm_year = year-1900;
5297 t = mktime (&start);
5299 if ((year < 1970) || (year > 2037) || (t == -1)) {
5301 tt = *localtime (&t);
5302 strftime (tzone, sizeof (tzone), "%Z", &tt);
5303 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5304 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5308 gmtoff = gmt_offset (&start, t);
5310 /* For each day of the year, calculate the tm_gmtoff. */
5311 for (day = 0; day < 365; day++) {
5314 tt = *localtime (&t);
5316 /* Daylight saving starts or ends here. */
5317 if (gmt_offset (&tt, t) != gmtoff) {
5321 /* Try to find the exact hour when daylight saving starts/ends. */
5325 tt1 = *localtime (&t1);
5326 } while (gmt_offset (&tt1, t1) != gmtoff);
5328 /* Try to find the exact minute when daylight saving starts/ends. */
5331 tt1 = *localtime (&t1);
5332 } while (gmt_offset (&tt1, t1) == gmtoff);
5334 strftime (tzone, sizeof (tzone), "%Z", &tt);
5336 /* Write data, if we're already in daylight saving, we're done. */
5338 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5339 mono_array_set ((*data), gint64, 1, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
5342 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5343 mono_array_set ((*data), gint64, 0, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
5347 /* This is only set once when we enter daylight saving. */
5348 mono_array_set ((*data), gint64, 2, (gint64)gmtoff * 10000000L);
5349 mono_array_set ((*data), gint64, 3, (gint64)(gmt_offset (&tt, t) - gmtoff) * 10000000L);
5351 gmtoff = gmt_offset (&tt, t);
5356 strftime (tzone, sizeof (tzone), "%Z", &tt);
5357 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5358 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5359 mono_array_set ((*data), gint64, 0, 0);
5360 mono_array_set ((*data), gint64, 1, 0);
5361 mono_array_set ((*data), gint64, 2, (gint64) gmtoff * 10000000L);
5362 mono_array_set ((*data), gint64, 3, 0);
5367 MonoDomain *domain = mono_domain_get ();
5368 TIME_ZONE_INFORMATION tz_info;
5373 tz_id = GetTimeZoneInformation (&tz_info);
5374 if (tz_id == TIME_ZONE_ID_INVALID)
5377 MONO_CHECK_ARG_NULL (data);
5378 MONO_CHECK_ARG_NULL (names);
5380 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5381 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5383 for (i = 0; i < 32; ++i)
5384 if (!tz_info.DaylightName [i])
5386 mono_array_setref ((*names), 1, mono_string_new_utf16 (domain, tz_info.DaylightName, i));
5387 for (i = 0; i < 32; ++i)
5388 if (!tz_info.StandardName [i])
5390 mono_array_setref ((*names), 0, mono_string_new_utf16 (domain, tz_info.StandardName, i));
5392 if ((year <= 1601) || (year > 30827)) {
5394 * According to MSDN, the MS time functions can't handle dates outside
5400 /* even if the timezone has no daylight savings it may have Bias (e.g. GMT+13 it seems) */
5401 if (tz_id != TIME_ZONE_ID_UNKNOWN) {
5402 tz_info.StandardDate.wYear = year;
5403 convert_to_absolute_date(&tz_info.StandardDate);
5404 err = SystemTimeToFileTime (&tz_info.StandardDate, &ft);
5406 mono_array_set ((*data), gint64, 1, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
5407 tz_info.DaylightDate.wYear = year;
5408 convert_to_absolute_date(&tz_info.DaylightDate);
5409 err = SystemTimeToFileTime (&tz_info.DaylightDate, &ft);
5411 mono_array_set ((*data), gint64, 0, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
5413 mono_array_set ((*data), gint64, 2, (tz_info.Bias + tz_info.StandardBias) * -600000000LL);
5414 mono_array_set ((*data), gint64, 3, (tz_info.DaylightBias - tz_info.StandardBias) * -600000000LL);
5421 ves_icall_System_Object_obj_address (MonoObject *this)
5423 MONO_ARCH_SAVE_REGS;
5430 static inline gint32
5431 mono_array_get_byte_length (MonoArray *array)
5437 klass = array->obj.vtable->klass;
5439 if (array->bounds == NULL)
5440 length = array->max_length;
5443 for (i = 0; i < klass->rank; ++ i)
5444 length *= array->bounds [i].length;
5447 switch (klass->element_class->byval_arg.type) {
5450 case MONO_TYPE_BOOLEAN:
5454 case MONO_TYPE_CHAR:
5462 return length * sizeof (gpointer);
5473 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array)
5475 MONO_ARCH_SAVE_REGS;
5477 return mono_array_get_byte_length (array);
5481 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx)
5483 MONO_ARCH_SAVE_REGS;
5485 return mono_array_get (array, gint8, idx);
5489 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value)
5491 MONO_ARCH_SAVE_REGS;
5493 mono_array_set (array, gint8, idx, value);
5497 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count)
5499 guint8 *src_buf, *dest_buf;
5501 MONO_ARCH_SAVE_REGS;
5503 /* watch out for integer overflow */
5504 if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count))
5507 src_buf = (guint8 *)src->vector + src_offset;
5508 dest_buf = (guint8 *)dest->vector + dest_offset;
5511 memcpy (dest_buf, src_buf, count);
5513 memmove (dest_buf, src_buf, count); /* Source and dest are the same array */
5519 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this, MonoString *class_name)
5521 MonoDomain *domain = mono_object_domain (this);
5523 MonoRealProxy *rp = ((MonoRealProxy *)this);
5524 MonoTransparentProxy *tp;
5528 MONO_ARCH_SAVE_REGS;
5530 res = mono_object_new (domain, mono_defaults.transparent_proxy_class);
5531 tp = (MonoTransparentProxy*) res;
5533 MONO_OBJECT_SETREF (tp, rp, rp);
5534 type = ((MonoReflectionType *)rp->class_to_proxy)->type;
5535 klass = mono_class_from_mono_type (type);
5537 tp->custom_type_info = (mono_object_isinst (this, mono_defaults.iremotingtypeinfo_class) != NULL);
5538 tp->remote_class = mono_remote_class (domain, class_name, klass);
5540 res->vtable = mono_remote_class_vtable (domain, tp->remote_class, rp);
5544 static MonoReflectionType *
5545 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
5547 return mono_type_get_object (mono_object_domain (tp), &tp->remote_class->proxy_class->byval_arg);
5550 /* System.Environment */
5553 ves_icall_System_Environment_get_MachineName (void)
5555 #if defined (PLATFORM_WIN32)
5560 len = MAX_COMPUTERNAME_LENGTH + 1;
5561 buf = g_new (gunichar2, len);
5564 if (GetComputerName (buf, (PDWORD) &len))
5565 result = mono_string_new_utf16 (mono_domain_get (), buf, len);
5573 if (gethostname (buf, sizeof (buf)) == 0)
5574 result = mono_string_new (mono_domain_get (), buf);
5583 ves_icall_System_Environment_get_Platform (void)
5585 MONO_ARCH_SAVE_REGS;
5587 #if defined (PLATFORM_WIN32)
5597 ves_icall_System_Environment_get_NewLine (void)
5599 MONO_ARCH_SAVE_REGS;
5601 #if defined (PLATFORM_WIN32)
5602 return mono_string_new (mono_domain_get (), "\r\n");
5604 return mono_string_new (mono_domain_get (), "\n");
5609 ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name)
5614 MONO_ARCH_SAVE_REGS;
5619 utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
5620 value = g_getenv (utf8_name);
5627 return mono_string_new (mono_domain_get (), value);
5631 * There is no standard way to get at environ.
5639 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
5647 MONO_ARCH_SAVE_REGS;
5650 for (e = environ; *e != 0; ++ e)
5653 domain = mono_domain_get ();
5654 names = mono_array_new (domain, mono_defaults.string_class, n);
5657 for (e = environ; *e != 0; ++ e) {
5658 parts = g_strsplit (*e, "=", 2);
5660 str = mono_string_new (domain, *parts);
5661 mono_array_setref (names, n, str);
5673 * If your platform lacks setenv/unsetenv, you must upgrade your glib.
5675 #if !GLIB_CHECK_VERSION(2,4,0)
5676 #define g_setenv(a,b,c) setenv(a,b,c)
5677 #define g_unsetenv(a) unsetenv(a)
5681 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
5683 #ifdef PLATFORM_WIN32
5684 gunichar2 *utf16_name, *utf16_value;
5686 gchar *utf8_name, *utf8_value;
5689 MONO_ARCH_SAVE_REGS;
5691 #ifdef PLATFORM_WIN32
5692 utf16_name = mono_string_to_utf16 (name);
5693 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
5694 SetEnvironmentVariable (utf16_name, NULL);
5695 g_free (utf16_name);
5699 utf16_value = mono_string_to_utf16 (value);
5701 SetEnvironmentVariable (utf16_name, utf16_value);
5703 g_free (utf16_name);
5704 g_free (utf16_value);
5706 utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
5708 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
5709 g_unsetenv (utf8_name);
5714 utf8_value = mono_string_to_utf8 (value);
5715 g_setenv (utf8_name, utf8_value, TRUE);
5718 g_free (utf8_value);
5723 * Returns: the number of milliseconds elapsed since the system started.
5726 ves_icall_System_Environment_get_TickCount (void)
5728 return GetTickCount ();
5733 ves_icall_System_Environment_Exit (int result)
5735 MONO_ARCH_SAVE_REGS;
5737 mono_runtime_set_shutting_down ();
5739 /* Suspend all managed threads since the runtime is going away */
5740 mono_thread_suspend_all_other_threads ();
5742 mono_runtime_quit ();
5744 /* we may need to do some cleanup here... */
5749 ves_icall_System_Environment_GetGacPath (void)
5751 return mono_string_new (mono_domain_get (), mono_assembly_getrootdir ());
5755 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
5757 #if defined (PLATFORM_WIN32)
5758 #ifndef CSIDL_FLAG_CREATE
5759 #define CSIDL_FLAG_CREATE 0x8000
5762 WCHAR path [MAX_PATH];
5763 /* Create directory if no existing */
5764 if (SUCCEEDED (SHGetFolderPathW (NULL, folder | CSIDL_FLAG_CREATE, NULL, 0, path))) {
5768 return mono_string_new_utf16 (mono_domain_get (), path, len);
5771 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
5773 return mono_string_new (mono_domain_get (), "");
5777 ves_icall_System_Environment_GetLogicalDrives (void)
5779 gunichar2 buf [128], *ptr, *dname;
5781 gint initial_size = 127, size = 128;
5784 MonoString *drivestr;
5785 MonoDomain *domain = mono_domain_get ();
5788 MONO_ARCH_SAVE_REGS;
5793 while (size > initial_size) {
5794 size = GetLogicalDriveStrings (initial_size, ptr);
5795 if (size > initial_size) {
5798 ptr = g_malloc0 ((size + 1) * sizeof (gunichar2));
5799 initial_size = size;
5813 result = mono_array_new (domain, mono_defaults.string_class, ndrives);
5818 while (*u16) { u16++; len ++; }
5819 drivestr = mono_string_new_utf16 (domain, dname, len);
5820 mono_array_setref (result, ndrives++, drivestr);
5831 ves_icall_System_Environment_InternalGetHome (void)
5833 MONO_ARCH_SAVE_REGS;
5835 return mono_string_new (mono_domain_get (), g_get_home_dir ());
5838 static const char *encodings [] = {
5840 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
5841 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
5842 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
5844 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
5845 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
5846 "x_unicode_2_0_utf_7",
5848 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
5849 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
5851 "utf_16", "UTF_16LE", "ucs_2", "unicode",
5854 "unicodefffe", "utf_16be",
5861 * Returns the internal codepage, if the value of "int_code_page" is
5862 * 1 at entry, and we can not compute a suitable code page number,
5863 * returns the code page as a string
5866 ves_icall_System_Text_Encoding_InternalCodePage (gint32 *int_code_page)
5871 char *codepage = NULL;
5873 int want_name = *int_code_page;
5876 *int_code_page = -1;
5877 MONO_ARCH_SAVE_REGS;
5879 g_get_charset (&cset);
5880 c = codepage = strdup (cset);
5881 for (c = codepage; *c; c++){
5882 if (isascii (*c) && isalpha (*c))
5887 /* g_print ("charset: %s\n", cset); */
5889 /* handle some common aliases */
5892 for (i = 0; p != 0; ){
5893 if ((gssize) p < 7){
5895 p = encodings [++i];
5898 if (strcmp (p, codepage) == 0){
5899 *int_code_page = code;
5902 p = encodings [++i];
5905 if (strstr (codepage, "utf_8") != NULL)
5906 *int_code_page |= 0x10000000;
5909 if (want_name && *int_code_page == -1)
5910 return mono_string_new (mono_domain_get (), cset);
5916 ves_icall_System_Environment_get_HasShutdownStarted (void)
5918 if (mono_runtime_is_shutting_down ())
5921 if (mono_domain_is_unloading (mono_domain_get ()))
5928 ves_icall_MonoMethodMessage_InitMessage (MonoMethodMessage *this,
5929 MonoReflectionMethod *method,
5930 MonoArray *out_args)
5932 MONO_ARCH_SAVE_REGS;
5934 mono_message_init (mono_object_domain (this), this, method, out_args);
5938 ves_icall_IsTransparentProxy (MonoObject *proxy)
5940 MONO_ARCH_SAVE_REGS;
5945 if (proxy->vtable->klass == mono_defaults.transparent_proxy_class)
5952 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
5957 MONO_ARCH_SAVE_REGS;
5959 klass = mono_class_from_mono_type (type->type);
5960 vtable = mono_class_vtable (mono_domain_get (), klass);
5962 if (enable) vtable->remote = 1;
5963 else vtable->remote = 0;
5967 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type)
5972 MONO_ARCH_SAVE_REGS;
5974 domain = mono_object_domain (type);
5975 klass = mono_class_from_mono_type (type->type);
5977 if (klass->rank >= 1) {
5978 g_assert (klass->rank == 1);
5979 return (MonoObject *) mono_array_new (domain, klass->element_class, 0);
5981 /* Bypass remoting object creation check */
5982 return mono_object_new_alloc_specific (mono_class_vtable (domain, klass));
5987 ves_icall_System_IO_get_temp_path (void)
5989 MONO_ARCH_SAVE_REGS;
5991 return mono_string_new (mono_domain_get (), g_get_tmp_dir ());
5995 ves_icall_RuntimeMethod_GetFunctionPointer (MonoMethod *method)
5997 MONO_ARCH_SAVE_REGS;
5999 return mono_compile_method (method);
6003 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
6008 MONO_ARCH_SAVE_REGS;
6010 path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
6012 #if defined (PLATFORM_WIN32)
6013 /* Avoid mixing '/' and '\\' */
6016 for (i = strlen (path) - 1; i >= 0; i--)
6017 if (path [i] == '/')
6021 mcpath = mono_string_new (mono_domain_get (), path);
6028 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
6033 MONO_ARCH_SAVE_REGS;
6035 path = g_path_get_dirname (mono_get_config_dir ());
6037 #if defined (PLATFORM_WIN32)
6038 /* Avoid mixing '/' and '\\' */
6041 for (i = strlen (path) - 1; i >= 0; i--)
6042 if (path [i] == '/')
6046 ipath = mono_string_new (mono_domain_get (), path);
6053 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
6055 #if defined (PLATFORM_WIN32)
6056 OutputDebugString (mono_string_chars (message));
6058 g_warning ("WriteWindowsDebugString called and PLATFORM_WIN32 not defined!\n");
6062 /* Only used for value types */
6064 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
6069 MONO_ARCH_SAVE_REGS;
6071 domain = mono_object_domain (type);
6072 klass = mono_class_from_mono_type (type->type);
6074 if (mono_class_is_nullable (klass))
6075 /* No arguments -> null */
6078 return mono_object_new (domain, klass);
6081 static MonoReflectionMethod *
6082 ves_icall_MonoMethod_get_base_definition (MonoReflectionMethod *m)
6084 MonoClass *klass, *parent;
6085 MonoMethod *method = m->method;
6086 MonoMethod *result = NULL;
6088 MONO_ARCH_SAVE_REGS;
6090 if (method->klass == NULL)
6093 if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
6094 MONO_CLASS_IS_INTERFACE (method->klass) ||
6095 method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
6098 klass = method->klass;
6099 if (klass->generic_class)
6100 klass = klass->generic_class->container_class;
6102 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
6103 for (parent = klass->parent; parent != NULL; parent = parent->parent) {
6104 mono_class_setup_vtable (parent);
6105 if (parent->vtable_size <= method->slot)
6110 if (klass == method->klass)
6113 result = klass->vtable [method->slot];
6114 if (result == NULL) {
6115 /* It is an abstract method */
6116 gpointer iter = NULL;
6117 while ((result = mono_class_get_methods (klass, &iter)))
6118 if (result->slot == method->slot)
6125 return mono_method_get_object (mono_domain_get (), result, NULL);
6129 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
6131 MONO_ARCH_SAVE_REGS;
6133 iter->sig = *(MonoMethodSignature**)argsp;
6135 g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
6136 g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
6139 /* FIXME: it's not documented what start is exactly... */
6143 guint32 i, arg_size;
6145 iter->args = argsp + sizeof (gpointer);
6146 #ifndef MONO_ARCH_REGPARMS
6147 for (i = 0; i < iter->sig->sentinelpos; ++i) {
6148 arg_size = mono_type_stack_size (iter->sig->params [i], &align);
6149 iter->args = (char*)iter->args + arg_size;
6153 iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
6155 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
6159 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
6161 guint32 i, arg_size;
6164 MONO_ARCH_SAVE_REGS;
6166 i = iter->sig->sentinelpos + iter->next_arg;
6168 g_assert (i < iter->sig->param_count);
6170 res.type = iter->sig->params [i];
6171 res.klass = mono_class_from_mono_type (res.type);
6172 /* FIXME: endianess issue... */
6173 res.value = iter->args;
6174 arg_size = mono_type_stack_size (res.type, &align);
6175 iter->args = (char*)iter->args + arg_size;
6178 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6184 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
6186 guint32 i, arg_size;
6189 MONO_ARCH_SAVE_REGS;
6191 i = iter->sig->sentinelpos + iter->next_arg;
6193 g_assert (i < iter->sig->param_count);
6195 while (i < iter->sig->param_count) {
6196 if (!mono_metadata_type_equal (type, iter->sig->params [i]))
6198 res.type = iter->sig->params [i];
6199 res.klass = mono_class_from_mono_type (res.type);
6200 /* FIXME: endianess issue... */
6201 res.value = iter->args;
6202 arg_size = mono_type_stack_size (res.type, &align);
6203 iter->args = (char*)iter->args + arg_size;
6205 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6208 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
6217 mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
6220 MONO_ARCH_SAVE_REGS;
6222 i = iter->sig->sentinelpos + iter->next_arg;
6224 g_assert (i < iter->sig->param_count);
6226 return iter->sig->params [i];
6230 mono_TypedReference_ToObject (MonoTypedRef tref)
6232 MONO_ARCH_SAVE_REGS;
6234 if (MONO_TYPE_IS_REFERENCE (tref.type)) {
6235 MonoObject** objp = tref.value;
6239 return mono_value_box (mono_domain_get (), tref.klass, tref.value);
6243 mono_TypedReference_ToObjectInternal (MonoType *type, gpointer value, MonoClass *klass)
6245 MONO_ARCH_SAVE_REGS;
6247 if (MONO_TYPE_IS_REFERENCE (type)) {
6248 MonoObject** objp = value;
6252 return mono_value_box (mono_domain_get (), klass, value);
6256 prelink_method (MonoMethod *method)
6258 const char *exc_class, *exc_arg;
6259 if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
6261 mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
6263 mono_raise_exception(
6264 mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg ) );
6266 /* create the wrapper, too? */
6270 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
6272 MONO_ARCH_SAVE_REGS;
6273 prelink_method (method->method);
6277 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
6279 MonoClass *klass = mono_class_from_mono_type (type->type);
6281 gpointer iter = NULL;
6282 MONO_ARCH_SAVE_REGS;
6284 while ((m = mono_class_get_methods (klass, &iter)))
6288 /* These parameters are "readonly" in corlib/System/Char.cs */
6290 ves_icall_System_Char_GetDataTablePointers (guint8 const **category_data,
6291 guint8 const **numeric_data,
6292 gdouble const **numeric_data_values,
6293 guint16 const **to_lower_data_low,
6294 guint16 const **to_lower_data_high,
6295 guint16 const **to_upper_data_low,
6296 guint16 const **to_upper_data_high)
6298 *category_data = CategoryData;
6299 *numeric_data = NumericData;
6300 *numeric_data_values = NumericDataValues;
6301 *to_lower_data_low = ToLowerDataLow;
6302 *to_lower_data_high = ToLowerDataHigh;
6303 *to_upper_data_low = ToUpperDataLow;
6304 *to_upper_data_high = ToUpperDataHigh;
6308 ves_icall_MonoDebugger_GetMethodToken (MonoReflectionMethod *method)
6310 return method->method->token;
6314 * We eturn NULL for no modifiers so the corlib code can return Type.EmptyTypes
6315 * and avoid useless allocations.
6318 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional)
6322 for (i = 0; i < type->num_mods; ++i) {
6323 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
6328 res = mono_array_new (mono_domain_get (), mono_defaults.systemtype_class, count);
6330 for (i = 0; i < type->num_mods; ++i) {
6331 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
6332 MonoClass *klass = mono_class_get (image, type->modifiers [i].token);
6333 mono_array_setref (res, count, mono_type_get_object (mono_domain_get (), &klass->byval_arg));
6341 param_info_get_type_modifiers (MonoReflectionParameter *param, MonoBoolean optional)
6343 MonoType *type = param->ClassImpl->type;
6344 MonoReflectionMethod *method = (MonoReflectionMethod*)param->MemberImpl;
6345 MonoImage *image = method->method->klass->image;
6346 int pos = param->PositionImpl;
6347 MonoMethodSignature *sig = mono_method_signature (method->method);
6351 type = sig->params [pos];
6353 return type_array_from_modifiers (image, type, optional);
6357 get_property_type (MonoProperty *prop)
6359 MonoMethodSignature *sig;
6361 sig = mono_method_signature (prop->get);
6363 } else if (prop->set) {
6364 sig = mono_method_signature (prop->set);
6365 return sig->params [sig->param_count - 1];
6371 property_info_get_type_modifiers (MonoReflectionProperty *property, MonoBoolean optional)
6373 MonoType *type = get_property_type (property->property);
6374 MonoImage *image = property->klass->image;
6378 return type_array_from_modifiers (image, type, optional);
6382 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
6384 MonoCustomAttrInfo *cinfo;
6387 cinfo = mono_reflection_get_custom_attrs_info (obj);
6390 found = mono_custom_attrs_has_attr (cinfo, mono_class_from_mono_type (attr_type->type));
6392 mono_custom_attrs_free (cinfo);
6397 custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
6399 return mono_reflection_get_custom_attrs_by_type (obj, attr_type ? mono_class_from_mono_type (attr_type->type) : NULL);
6403 GCHandle_CheckCurrentDomain (guint32 gchandle)
6405 return mono_gchandle_is_in_domain (gchandle, mono_domain_get ());
6409 ves_icall_Mono_Runtime_GetDisplayName (void)
6411 static const char display_name_str [] = "Mono " VERSION;
6412 MonoString *display_name = mono_string_new (mono_domain_get (), display_name_str);
6413 return display_name;
6418 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
6419 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
6420 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 62, 128, 128, 128, 63,
6421 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 0, 128, 128,
6422 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
6423 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 128, 128, 128, 128, 128,
6424 128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
6425 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
6429 base64_to_byte_array (gunichar2 *start, gint ilength, MonoBoolean allowWhitespaceOnly)
6434 gunichar2 last, prev_last;
6442 last = prev_last = 0;
6443 for (i = 0; i < ilength; i++) {
6445 if (c >= sizeof (dbase64)) {
6446 exc = mono_exception_from_name_msg (mono_get_corlib (),
6447 "System", "FormatException",
6448 "Invalid character found.");
6449 mono_raise_exception (exc);
6450 } else if (isspace (c)) {
6458 olength = ilength - ignored;
6460 if (allowWhitespaceOnly && olength == 0) {
6461 return mono_array_new (mono_domain_get (), mono_defaults.byte_class, 0);
6464 if ((olength & 3) != 0 || olength <= 0) {
6465 exc = mono_exception_from_name_msg (mono_get_corlib (), "System",
6466 "FormatException", "Invalid length.");
6467 mono_raise_exception (exc);
6470 olength = (olength * 3) / 4;
6474 if (prev_last == '=')
6477 result = mono_array_new (mono_domain_get (), mono_defaults.byte_class, olength);
6478 res_ptr = mono_array_addr (result, guchar, 0);
6479 for (i = 0; i < ilength; ) {
6482 for (k = 0; k < 4 && i < ilength;) {
6488 if (((b [k] = dbase64 [c]) & 0x80) != 0) {
6489 exc = mono_exception_from_name_msg (mono_get_corlib (),
6490 "System", "FormatException",
6491 "Invalid character found.");
6492 mono_raise_exception (exc);
6497 *res_ptr++ = (b [0] << 2) | (b [1] >> 4);
6499 *res_ptr++ = (b [1] << 4) | (b [2] >> 2);
6501 *res_ptr++ = (b [2] << 6) | b [3];
6503 while (i < ilength && isspace (start [i]))
6511 InternalFromBase64String (MonoString *str, MonoBoolean allowWhitespaceOnly)
6513 MONO_ARCH_SAVE_REGS;
6515 return base64_to_byte_array (mono_string_chars (str),
6516 mono_string_length (str), allowWhitespaceOnly);
6520 InternalFromBase64CharArray (MonoArray *input, gint offset, gint length)
6522 MONO_ARCH_SAVE_REGS;
6524 return base64_to_byte_array (mono_array_addr (input, gunichar2, offset),
6528 #define ICALL_TYPE(id,name,first)
6529 #define ICALL(id,name,func) Icall_ ## id,
6532 #include "metadata/icall-def.h"
6538 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
6539 #define ICALL(id,name,func)
6541 #include "metadata/icall-def.h"
6547 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
6548 #define ICALL(id,name,func)
6550 guint16 first_icall;
6553 static const IcallTypeDesc
6554 icall_type_descs [] = {
6555 #include "metadata/icall-def.h"
6559 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
6562 #define ICALL_TYPE(id,name,first)
6565 #ifdef HAVE_ARRAY_ELEM_INIT
6566 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
6567 #define MSGSTRFIELD1(line) str##line
6569 static const struct msgstrtn_t {
6570 #define ICALL(id,name,func)
6572 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
6573 #include "metadata/icall-def.h"
6575 } icall_type_names_str = {
6576 #define ICALL_TYPE(id,name,first) (name),
6577 #include "metadata/icall-def.h"
6580 static const guint16 icall_type_names_idx [] = {
6581 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
6582 #include "metadata/icall-def.h"
6585 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
6587 static const struct msgstr_t {
6589 #define ICALL_TYPE(id,name,first)
6590 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
6591 #include "metadata/icall-def.h"
6593 } icall_names_str = {
6594 #define ICALL(id,name,func) (name),
6595 #include "metadata/icall-def.h"
6598 static const guint16 icall_names_idx [] = {
6599 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
6600 #include "metadata/icall-def.h"
6603 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
6609 #define ICALL_TYPE(id,name,first) name,
6610 #define ICALL(id,name,func)
6611 static const char* const
6612 icall_type_names [] = {
6613 #include "metadata/icall-def.h"
6617 #define icall_type_name_get(id) (icall_type_names [(id)])
6621 #define ICALL_TYPE(id,name,first)
6622 #define ICALL(id,name,func) name,
6623 static const char* const
6625 #include "metadata/icall-def.h"
6628 #define icall_name_get(id) icall_names [(id)]
6630 #endif /* !HAVE_ARRAY_ELEM_INIT */
6634 #define ICALL_TYPE(id,name,first)
6635 #define ICALL(id,name,func) func,
6636 static const gconstpointer
6637 icall_functions [] = {
6638 #include "metadata/icall-def.h"
6642 static GHashTable *icall_hash = NULL;
6643 static GHashTable *jit_icall_hash_name = NULL;
6644 static GHashTable *jit_icall_hash_addr = NULL;
6647 mono_icall_init (void)
6651 /* check that tables are sorted: disable in release */
6654 const char *prev_class = NULL;
6655 const char *prev_method;
6657 for (i = 0; i < Icall_type_num; ++i) {
6658 const IcallTypeDesc *desc;
6661 if (prev_class && strcmp (prev_class, icall_type_name_get (i)) >= 0)
6662 g_print ("class %s should come before class %s\n", icall_type_name_get (i), prev_class);
6663 prev_class = icall_type_name_get (i);
6664 desc = &icall_type_descs [i];
6665 num_icalls = icall_desc_num_icalls (desc);
6666 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
6667 for (j = 0; j < num_icalls; ++j) {
6668 const char *methodn = icall_name_get (desc->first_icall + j);
6669 if (prev_method && strcmp (prev_method, methodn) >= 0)
6670 g_print ("method %s should come before method %s\n", methodn, prev_method);
6671 prev_method = methodn;
6676 icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
6680 mono_icall_cleanup (void)
6682 g_hash_table_destroy (icall_hash);
6683 g_hash_table_destroy (jit_icall_hash_name);
6684 g_hash_table_destroy (jit_icall_hash_addr);
6688 mono_add_internal_call (const char *name, gconstpointer method)
6690 mono_loader_lock ();
6692 g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
6694 mono_loader_unlock ();
6697 #ifdef HAVE_ARRAY_ELEM_INIT
6699 compare_method_imap (const void *key, const void *elem)
6701 const char* method_name = (const char*)&icall_names_str + (*(guint16*)elem);
6702 return strcmp (key, method_name);
6706 find_method_icall (const IcallTypeDesc *imap, const char *name)
6708 const guint16 *nameslot = bsearch (name, icall_names_idx + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names_idx [0]), compare_method_imap);
6711 return (gpointer)icall_functions [(nameslot - &icall_names_idx [0])];
6715 compare_class_imap (const void *key, const void *elem)
6717 const char* class_name = (const char*)&icall_type_names_str + (*(guint16*)elem);
6718 return strcmp (key, class_name);
6721 static const IcallTypeDesc*
6722 find_class_icalls (const char *name)
6724 const guint16 *nameslot = bsearch (name, icall_type_names_idx, Icall_type_num, sizeof (icall_type_names_idx [0]), compare_class_imap);
6727 return &icall_type_descs [nameslot - &icall_type_names_idx [0]];
6732 compare_method_imap (const void *key, const void *elem)
6734 const char** method_name = (const char**)elem;
6735 return strcmp (key, *method_name);
6739 find_method_icall (const IcallTypeDesc *imap, const char *name)
6741 const char **nameslot = bsearch (name, icall_names + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names [0]), compare_method_imap);
6744 return (gpointer)icall_functions [(nameslot - icall_names)];
6748 compare_class_imap (const void *key, const void *elem)
6750 const char** class_name = (const char**)elem;
6751 return strcmp (key, *class_name);
6754 static const IcallTypeDesc*
6755 find_class_icalls (const char *name)
6757 const char **nameslot = bsearch (name, icall_type_names, Icall_type_num, sizeof (icall_type_names [0]), compare_class_imap);
6760 return &icall_type_descs [nameslot - icall_type_names];
6766 * we should probably export this as an helper (handle nested types).
6767 * Returns the number of chars written in buf.
6770 concat_class_name (char *buf, int bufsize, MonoClass *klass)
6772 int nspacelen, cnamelen;
6773 nspacelen = strlen (klass->name_space);
6774 cnamelen = strlen (klass->name);
6775 if (nspacelen + cnamelen + 2 > bufsize)
6778 memcpy (buf, klass->name_space, nspacelen);
6779 buf [nspacelen ++] = '.';
6781 memcpy (buf + nspacelen, klass->name, cnamelen);
6782 buf [nspacelen + cnamelen] = 0;
6783 return nspacelen + cnamelen;
6787 mono_lookup_internal_call (MonoMethod *method)
6792 int typelen = 0, mlen, siglen;
6794 const IcallTypeDesc *imap;
6796 g_assert (method != NULL);
6798 if (method->is_inflated)
6799 method = ((MonoMethodInflated *) method)->declaring;
6801 if (method->klass->nested_in) {
6802 int pos = concat_class_name (mname, sizeof (mname)-2, method->klass->nested_in);
6806 mname [pos++] = '/';
6809 typelen = concat_class_name (mname+pos, sizeof (mname)-pos-1, method->klass);
6815 typelen = concat_class_name (mname, sizeof (mname), method->klass);
6820 imap = find_class_icalls (mname);
6822 mname [typelen] = ':';
6823 mname [typelen + 1] = ':';
6825 mlen = strlen (method->name);
6826 memcpy (mname + typelen + 2, method->name, mlen);
6827 sigstart = mname + typelen + 2 + mlen;
6830 tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
6831 siglen = strlen (tmpsig);
6832 if (typelen + mlen + siglen + 6 > sizeof (mname))
6835 memcpy (sigstart + 1, tmpsig, siglen);
6836 sigstart [siglen + 1] = ')';
6837 sigstart [siglen + 2] = 0;
6840 mono_loader_lock ();
6842 res = g_hash_table_lookup (icall_hash, mname);
6844 mono_loader_unlock ();
6847 /* try without signature */
6849 res = g_hash_table_lookup (icall_hash, mname);
6851 mono_loader_unlock ();
6855 /* it wasn't found in the static call tables */
6857 mono_loader_unlock ();
6860 res = find_method_icall (imap, sigstart - mlen);
6862 mono_loader_unlock ();
6865 /* try _with_ signature */
6867 res = find_method_icall (imap, sigstart - mlen);
6869 mono_loader_unlock ();
6873 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname);
6874 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
6875 g_print ("The out of sync library is: %s\n", method->klass->image->name);
6876 g_print ("\nWhen you update one from cvs you need to update, compile and install\nthe other too.\n");
6877 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");
6878 g_print ("If you see other errors or faults after this message they are probably related\n");
6879 g_print ("and you need to fix your mono install first.\n");
6881 mono_loader_unlock ();
6887 type_from_typename (char *typename)
6889 MonoClass *klass = NULL; /* assignment to shut GCC warning up */
6891 if (!strcmp (typename, "int"))
6892 klass = mono_defaults.int_class;
6893 else if (!strcmp (typename, "ptr"))
6894 klass = mono_defaults.int_class;
6895 else if (!strcmp (typename, "void"))
6896 klass = mono_defaults.void_class;
6897 else if (!strcmp (typename, "int32"))
6898 klass = mono_defaults.int32_class;
6899 else if (!strcmp (typename, "uint32"))
6900 klass = mono_defaults.uint32_class;
6901 else if (!strcmp (typename, "int8"))
6902 klass = mono_defaults.sbyte_class;
6903 else if (!strcmp (typename, "uint8"))
6904 klass = mono_defaults.byte_class;
6905 else if (!strcmp (typename, "int16"))
6906 klass = mono_defaults.int16_class;
6907 else if (!strcmp (typename, "uint16"))
6908 klass = mono_defaults.uint16_class;
6909 else if (!strcmp (typename, "long"))
6910 klass = mono_defaults.int64_class;
6911 else if (!strcmp (typename, "ulong"))
6912 klass = mono_defaults.uint64_class;
6913 else if (!strcmp (typename, "float"))
6914 klass = mono_defaults.single_class;
6915 else if (!strcmp (typename, "double"))
6916 klass = mono_defaults.double_class;
6917 else if (!strcmp (typename, "object"))
6918 klass = mono_defaults.object_class;
6919 else if (!strcmp (typename, "obj"))
6920 klass = mono_defaults.object_class;
6923 g_assert_not_reached ();
6925 return &klass->byval_arg;
6928 MonoMethodSignature*
6929 mono_create_icall_signature (const char *sigstr)
6934 MonoMethodSignature *res;
6936 mono_loader_lock ();
6937 res = g_hash_table_lookup (mono_defaults.corlib->helper_signatures, sigstr);
6939 mono_loader_unlock ();
6943 parts = g_strsplit (sigstr, " ", 256);
6952 res = mono_metadata_signature_alloc (mono_defaults.corlib, len - 1);
6955 #ifdef PLATFORM_WIN32
6957 * Under windows, the default pinvoke calling convention is STDCALL but
6960 res->call_convention = MONO_CALL_C;
6963 res->ret = type_from_typename (parts [0]);
6964 for (i = 1; i < len; ++i) {
6965 res->params [i - 1] = type_from_typename (parts [i]);
6970 g_hash_table_insert (mono_defaults.corlib->helper_signatures, (gpointer)sigstr, res);
6972 mono_loader_unlock ();
6978 mono_find_jit_icall_by_name (const char *name)
6980 MonoJitICallInfo *info;
6981 g_assert (jit_icall_hash_name);
6983 mono_loader_lock ();
6984 info = g_hash_table_lookup (jit_icall_hash_name, name);
6985 mono_loader_unlock ();
6990 mono_find_jit_icall_by_addr (gconstpointer addr)
6992 MonoJitICallInfo *info;
6993 g_assert (jit_icall_hash_addr);
6995 mono_loader_lock ();
6996 info = g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
6997 mono_loader_unlock ();
7003 mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
7005 mono_loader_lock ();
7006 g_hash_table_insert (jit_icall_hash_addr, (gpointer)wrapper, info);
7007 mono_loader_unlock ();
7011 mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
7013 MonoJitICallInfo *info;
7018 mono_loader_lock ();
7020 if (!jit_icall_hash_name) {
7021 jit_icall_hash_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
7022 jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
7025 if (g_hash_table_lookup (jit_icall_hash_name, name)) {
7026 g_warning ("jit icall already defined \"%s\"\n", name);
7027 g_assert_not_reached ();
7030 info = g_new0 (MonoJitICallInfo, 1);
7037 info->wrapper = func;
7039 info->wrapper = NULL;
7042 g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
7043 g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
7045 mono_loader_unlock ();