5 * Dietmar Maurer (dietmar@ximian.com)
6 * Paolo Molaro (lupus@ximian.com)
7 * Patrik Torstensson (patrik.torstensson@labs2.com)
9 * (C) 2001 Ximian, Inc.
19 #if defined (PLATFORM_WIN32)
23 #include <mono/metadata/object.h>
24 #include <mono/metadata/threads.h>
25 #include <mono/metadata/threads-types.h>
26 #include <mono/metadata/threadpool.h>
27 #include <mono/metadata/monitor.h>
28 #include <mono/metadata/reflection.h>
29 #include <mono/metadata/assembly.h>
30 #include <mono/metadata/tabledefs.h>
31 #include <mono/metadata/exception.h>
32 #include <mono/metadata/file-io.h>
33 #include <mono/metadata/console-io.h>
34 #include <mono/metadata/socket-io.h>
35 #include <mono/metadata/mono-endian.h>
36 #include <mono/metadata/tokentype.h>
37 #include <mono/metadata/domain-internals.h>
38 #include <mono/metadata/metadata-internals.h>
39 #include <mono/metadata/class-internals.h>
40 #include <mono/metadata/marshal.h>
41 #include <mono/metadata/gc-internal.h>
42 #include <mono/metadata/mono-gc.h>
43 #include <mono/metadata/rand.h>
44 #include <mono/metadata/sysmath.h>
45 #include <mono/metadata/string-icalls.h>
46 #include <mono/metadata/debug-helpers.h>
47 #include <mono/metadata/process.h>
48 #include <mono/metadata/environment.h>
49 #include <mono/metadata/profiler-private.h>
50 #include <mono/metadata/locales.h>
51 #include <mono/metadata/filewatcher.h>
52 #include <mono/metadata/char-conversions.h>
53 #include <mono/metadata/security.h>
54 #include <mono/metadata/mono-config.h>
55 #include <mono/metadata/cil-coff.h>
56 #include <mono/metadata/security-manager.h>
57 #include <mono/io-layer/io-layer.h>
58 #include <mono/utils/strtod.h>
59 #include <mono/utils/monobitset.h>
61 #if defined (PLATFORM_WIN32)
67 static MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void);
70 static inline MonoBoolean
71 is_generic_parameter (MonoType *type)
73 return !type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR);
77 * We expect a pointer to a char, not a string
80 mono_double_ParseImpl (char *ptr, double *result)
89 *result = strtod (ptr, &endptr);
92 *result = bsd_strtod (ptr, &endptr);
95 if (!*ptr || (endptr && *endptr))
102 mono_class_get_throw (MonoImage *image, guint32 type_token)
104 MonoClass *class = mono_class_get (image, type_token);
105 MonoLoaderError *error;
111 error = mono_loader_get_last_error ();
112 g_assert (error != NULL);
114 ex = mono_loader_error_prepare_exception (error);
115 mono_raise_exception (ex);
120 ves_icall_System_Array_GetValueImpl (MonoObject *this, guint32 pos)
129 ao = (MonoArray *)this;
130 ac = (MonoClass *)ao->obj.vtable->klass;
132 esize = mono_array_element_size (ac);
133 ea = (gpointer*)((char*)ao->vector + (pos * esize));
135 if (ac->element_class->valuetype)
136 return mono_value_box (this->vtable->domain, ac->element_class, ea);
142 ves_icall_System_Array_GetValue (MonoObject *this, MonoObject *idxs)
150 MONO_CHECK_ARG_NULL (idxs);
152 io = (MonoArray *)idxs;
153 ic = (MonoClass *)io->obj.vtable->klass;
155 ao = (MonoArray *)this;
156 ac = (MonoClass *)ao->obj.vtable->klass;
158 g_assert (ic->rank == 1);
159 if (io->bounds != NULL || io->max_length != ac->rank)
160 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
162 ind = (gint32 *)io->vector;
164 if (ao->bounds == NULL) {
165 if (*ind < 0 || *ind >= ao->max_length)
166 mono_raise_exception (mono_get_exception_index_out_of_range ());
168 return ves_icall_System_Array_GetValueImpl (this, *ind);
171 for (i = 0; i < ac->rank; i++)
172 if ((ind [i] < ao->bounds [i].lower_bound) ||
173 (ind [i] >= ao->bounds [i].length + ao->bounds [i].lower_bound))
174 mono_raise_exception (mono_get_exception_index_out_of_range ());
176 pos = ind [0] - ao->bounds [0].lower_bound;
177 for (i = 1; i < ac->rank; i++)
178 pos = pos*ao->bounds [i].length + ind [i] -
179 ao->bounds [i].lower_bound;
181 return ves_icall_System_Array_GetValueImpl (this, pos);
185 ves_icall_System_Array_SetValueImpl (MonoArray *this, MonoObject *value, guint32 pos)
187 MonoClass *ac, *vc, *ec;
199 vc = value->vtable->klass;
203 ac = this->obj.vtable->klass;
204 ec = ac->element_class;
206 esize = mono_array_element_size (ac);
207 ea = (gpointer*)((char*)this->vector + (pos * esize));
208 va = (gpointer*)((char*)value + sizeof (MonoObject));
211 memset (ea, 0, esize);
215 #define NO_WIDENING_CONVERSION G_STMT_START{\
216 mono_raise_exception (mono_get_exception_argument ( \
217 "value", "not a widening conversion")); \
220 #define CHECK_WIDENING_CONVERSION(extra) G_STMT_START{\
221 if (esize < vsize + (extra)) \
222 mono_raise_exception (mono_get_exception_argument ( \
223 "value", "not a widening conversion")); \
226 #define INVALID_CAST G_STMT_START{\
227 mono_raise_exception (mono_get_exception_invalid_cast ()); \
230 /* Check element (destination) type. */
231 switch (ec->byval_arg.type) {
232 case MONO_TYPE_STRING:
233 switch (vc->byval_arg.type) {
234 case MONO_TYPE_STRING:
240 case MONO_TYPE_BOOLEAN:
241 switch (vc->byval_arg.type) {
242 case MONO_TYPE_BOOLEAN:
255 NO_WIDENING_CONVERSION;
262 if (!ec->valuetype) {
263 if (!mono_object_isinst (value, ec))
265 *ea = (gpointer)value;
269 if (mono_object_isinst (value, ec)) {
270 memcpy (ea, (char *)value + sizeof (MonoObject), esize);
277 vsize = mono_class_instance_size (vc) - sizeof (MonoObject);
279 et = ec->byval_arg.type;
280 if (et == MONO_TYPE_VALUETYPE && ec->byval_arg.data.klass->enumtype)
281 et = ec->byval_arg.data.klass->enum_basetype->type;
283 vt = vc->byval_arg.type;
284 if (vt == MONO_TYPE_VALUETYPE && vc->byval_arg.data.klass->enumtype)
285 vt = vc->byval_arg.data.klass->enum_basetype->type;
287 #define ASSIGN_UNSIGNED(etype) G_STMT_START{\
293 case MONO_TYPE_CHAR: \
294 CHECK_WIDENING_CONVERSION(0); \
295 *(etype *) ea = (etype) u64; \
297 /* You can't assign a signed value to an unsigned array. */ \
302 /* You can't assign a floating point number to an integer array. */ \
305 NO_WIDENING_CONVERSION; \
309 #define ASSIGN_SIGNED(etype) G_STMT_START{\
315 CHECK_WIDENING_CONVERSION(0); \
316 *(etype *) ea = (etype) i64; \
318 /* You can assign an unsigned value to a signed array if the array's */ \
319 /* element size is larger than the value size. */ \
324 case MONO_TYPE_CHAR: \
325 CHECK_WIDENING_CONVERSION(1); \
326 *(etype *) ea = (etype) u64; \
328 /* You can't assign a floating point number to an integer array. */ \
331 NO_WIDENING_CONVERSION; \
335 #define ASSIGN_REAL(etype) G_STMT_START{\
339 CHECK_WIDENING_CONVERSION(0); \
340 *(etype *) ea = (etype) r64; \
342 /* All integer values fit into a floating point array, so we don't */ \
343 /* need to CHECK_WIDENING_CONVERSION here. */ \
348 *(etype *) ea = (etype) i64; \
354 case MONO_TYPE_CHAR: \
355 *(etype *) ea = (etype) u64; \
362 u64 = *(guint8 *) va;
365 u64 = *(guint16 *) va;
368 u64 = *(guint32 *) va;
371 u64 = *(guint64 *) va;
377 i64 = *(gint16 *) va;
380 i64 = *(gint32 *) va;
383 i64 = *(gint64 *) va;
386 r64 = *(gfloat *) va;
389 r64 = *(gdouble *) va;
392 u64 = *(guint16 *) va;
394 case MONO_TYPE_BOOLEAN:
395 /* Boolean is only compatible with itself. */
408 NO_WIDENING_CONVERSION;
415 /* If we can't do a direct copy, let's try a widening conversion. */
418 ASSIGN_UNSIGNED (guint16);
420 ASSIGN_UNSIGNED (guint8);
422 ASSIGN_UNSIGNED (guint16);
424 ASSIGN_UNSIGNED (guint32);
426 ASSIGN_UNSIGNED (guint64);
428 ASSIGN_SIGNED (gint8);
430 ASSIGN_SIGNED (gint16);
432 ASSIGN_SIGNED (gint32);
434 ASSIGN_SIGNED (gint64);
436 ASSIGN_REAL (gfloat);
438 ASSIGN_REAL (gdouble);
442 /* Not reached, INVALID_CAST does not return. Just to avoid a compiler warning ... */
446 #undef NO_WIDENING_CONVERSION
447 #undef CHECK_WIDENING_CONVERSION
448 #undef ASSIGN_UNSIGNED
454 ves_icall_System_Array_SetValue (MonoArray *this, MonoObject *value,
462 MONO_CHECK_ARG_NULL (idxs);
464 ic = idxs->obj.vtable->klass;
465 ac = this->obj.vtable->klass;
467 g_assert (ic->rank == 1);
468 if (idxs->bounds != NULL || idxs->max_length != ac->rank)
469 mono_raise_exception (mono_get_exception_argument (NULL, NULL));
471 ind = (gint32 *)idxs->vector;
473 if (this->bounds == NULL) {
474 if (*ind < 0 || *ind >= this->max_length)
475 mono_raise_exception (mono_get_exception_index_out_of_range ());
477 ves_icall_System_Array_SetValueImpl (this, value, *ind);
481 for (i = 0; i < ac->rank; i++)
482 if ((ind [i] < this->bounds [i].lower_bound) ||
483 (ind [i] >= this->bounds [i].length + this->bounds [i].lower_bound))
484 mono_raise_exception (mono_get_exception_index_out_of_range ());
486 pos = ind [0] - this->bounds [0].lower_bound;
487 for (i = 1; i < ac->rank; i++)
488 pos = pos * this->bounds [i].length + ind [i] -
489 this->bounds [i].lower_bound;
491 ves_icall_System_Array_SetValueImpl (this, value, pos);
495 ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
500 gboolean bounded = FALSE;
504 MONO_CHECK_ARG_NULL (type);
505 MONO_CHECK_ARG_NULL (lengths);
507 MONO_CHECK_ARG (lengths, mono_array_length (lengths) > 0);
509 MONO_CHECK_ARG (bounds, mono_array_length (lengths) == mono_array_length (bounds));
511 for (i = 0; i < mono_array_length (lengths); i++)
512 if (mono_array_get (lengths, gint32, i) < 0)
513 mono_raise_exception (mono_get_exception_argument_out_of_range (NULL));
515 if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint32, 0) != 0))
516 /* vectors are not the same as one dimensional arrays with no-zero bounds */
521 aklass = mono_bounded_array_class_get (mono_class_from_mono_type (type->type), mono_array_length (lengths), bounded);
523 sizes = alloca (aklass->rank * sizeof(guint32) * 2);
524 for (i = 0; i < aklass->rank; ++i) {
525 sizes [i] = mono_array_get (lengths, guint32, i);
527 sizes [i + aklass->rank] = mono_array_get (bounds, guint32, i);
529 sizes [i + aklass->rank] = 0;
532 array = mono_array_new_full (mono_object_domain (type), aklass, sizes, sizes + aklass->rank);
538 ves_icall_System_Array_GetRank (MonoObject *this)
542 return this->vtable->klass->rank;
546 ves_icall_System_Array_GetLength (MonoArray *this, gint32 dimension)
548 gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
552 if ((dimension < 0) || (dimension >= rank))
553 mono_raise_exception (mono_get_exception_index_out_of_range ());
555 if (this->bounds == NULL)
556 return this->max_length;
558 return this->bounds [dimension].length;
562 ves_icall_System_Array_GetLowerBound (MonoArray *this, gint32 dimension)
564 gint32 rank = ((MonoObject *)this)->vtable->klass->rank;
568 if ((dimension < 0) || (dimension >= rank))
569 mono_raise_exception (mono_get_exception_index_out_of_range ());
571 if (this->bounds == NULL)
574 return this->bounds [dimension].lower_bound;
578 ves_icall_System_Array_ClearInternal (MonoArray *arr, int idx, int length)
580 int sz = mono_array_element_size (mono_object_class (arr));
581 memset (mono_array_addr_with_size (arr, sz, idx), 0, length * sz);
585 ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* dest, int dest_idx, int length)
590 MonoClass *src_class;
591 MonoClass *dest_class;
596 if (source->obj.vtable->klass->rank != dest->obj.vtable->klass->rank)
599 if (source->bounds || dest->bounds)
602 if ((dest_idx + length > mono_array_length (dest)) ||
603 (source_idx + length > mono_array_length (source)))
606 src_class = source->obj.vtable->klass->element_class;
607 dest_class = dest->obj.vtable->klass->element_class;
610 * Handle common cases.
613 /* Case1: object[] -> valuetype[] (ArrayList::ToArray) */
614 if (src_class == mono_defaults.object_class && dest_class->valuetype) {
615 int has_refs = dest_class->has_references;
616 for (i = source_idx; i < source_idx + length; ++i) {
617 MonoObject *elem = mono_array_get (source, MonoObject*, i);
618 if (elem && !mono_object_isinst (elem, dest_class))
622 element_size = mono_array_element_size (dest->obj.vtable->klass);
623 memset (mono_array_addr_with_size (dest, element_size, dest_idx), 0, element_size * length);
624 for (i = 0; i < length; ++i) {
625 MonoObject *elem = mono_array_get (source, MonoObject*, source_idx + i);
626 void *addr = mono_array_addr_with_size (dest, element_size, dest_idx + i);
630 mono_value_copy (addr, (char *)elem + sizeof (MonoObject), dest_class);
632 memcpy (addr, (char *)elem + sizeof (MonoObject), element_size);
637 /* Check if we're copying a char[] <==> (u)short[] */
638 if (src_class != dest_class) {
639 if (dest_class->valuetype || dest_class->enumtype || src_class->valuetype || src_class->enumtype)
642 if (mono_class_is_subclass_of (src_class, dest_class, FALSE))
644 /* Case2: object[] -> reftype[] (ArrayList::ToArray) */
645 else if (mono_class_is_subclass_of (dest_class, src_class, FALSE))
646 for (i = source_idx; i < source_idx + length; ++i) {
647 MonoObject *elem = mono_array_get (source, MonoObject*, i);
648 if (elem && !mono_object_isinst (elem, dest_class))
655 if (dest_class->valuetype) {
656 element_size = mono_array_element_size (source->obj.vtable->klass);
657 source_addr = mono_array_addr_with_size (source, element_size, source_idx);
658 if (dest_class->has_references) {
659 mono_value_copy_array (dest, dest_idx, source_addr, length);
661 dest_addr = mono_array_addr_with_size (dest, element_size, dest_idx);
662 memmove (dest_addr, source_addr, element_size * length);
665 mono_array_memcpy_refs (dest, dest_idx, source, source_idx, length);
672 ves_icall_System_Array_GetGenericValueImpl (MonoObject *this, guint32 pos, gpointer value)
681 ao = (MonoArray *)this;
682 ac = (MonoClass *)ao->obj.vtable->klass;
684 esize = mono_array_element_size (ac);
685 ea = (gpointer*)((char*)ao->vector + (pos * esize));
687 memcpy (value, ea, esize);
691 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoArray *array, MonoClassField *field_handle)
693 MonoClass *klass = array->obj.vtable->klass;
694 guint32 size = mono_array_element_size (klass);
696 size *= array->max_length;
698 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
700 guint ## n *data = (guint ## n *) mono_array_addr (array, char, 0); \
701 guint ## n *src = (guint ## n *) field_handle->data; \
702 guint ## n *end = (guint ## n *)((char*)src + size); \
704 for (; src < end; data++, src++) { \
705 *data = read ## n (src); \
709 /* printf ("Initialize array with elements of %s type\n", klass->element_class->name); */
711 switch (mono_type_get_underlying_type (&klass->element_class->byval_arg)->type) {
728 memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
732 memcpy (mono_array_addr (array, char, 0), field_handle->data, size);
734 if (klass->element_class->byval_arg.type == MONO_TYPE_R8) {
737 double *data = (double*)mono_array_addr (array, double, 0);
739 for (i = 0; i < size; i++, data++) {
749 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData (void)
753 return offsetof (MonoString, chars);
757 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue (MonoObject *obj)
761 if ((obj == NULL) || (! (obj->vtable->klass->valuetype)))
764 return mono_object_clone (obj);
768 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (MonoType *handle)
774 MONO_CHECK_ARG_NULL (handle);
776 klass = mono_class_from_mono_type (handle);
777 MONO_CHECK_ARG (handle, klass);
779 /* This will call the type constructor */
780 if (! (klass->flags & TYPE_ATTRIBUTE_INTERFACE))
781 mono_runtime_class_init (mono_class_vtable (mono_domain_get (), klass));
785 ves_icall_System_Object_MemberwiseClone (MonoObject *this)
789 return mono_object_clone (this);
793 ves_icall_System_ValueType_InternalGetHashCode (MonoObject *this, MonoArray **fields)
796 MonoObject **values = NULL;
800 MonoClassField* field;
805 klass = mono_object_class (this);
807 if (mono_class_num_fields (klass) == 0)
808 return mono_object_hash (this);
811 * Compute the starting value of the hashcode for fields of primitive
812 * types, and return the remaining fields in an array to the managed side.
813 * This way, we can avoid costly reflection operations in managed code.
816 while ((field = mono_class_get_fields (klass, &iter))) {
817 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
819 if (mono_field_is_deleted (field))
821 /* FIXME: Add more types */
822 switch (field->type->type) {
824 result ^= *(gint32*)((guint8*)this + field->offset);
826 case MONO_TYPE_STRING: {
828 s = *(MonoString**)((guint8*)this + field->offset);
830 result ^= mono_string_hash (s);
835 values = g_newa (MonoObject*, mono_class_num_fields (klass));
836 o = mono_field_get_value_object (mono_object_domain (this), field, this);
837 values [count++] = o;
843 *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
844 for (i = 0; i < count; ++i)
845 mono_array_setref (*fields, i, values [i]);
853 ves_icall_System_ValueType_Equals (MonoObject *this, MonoObject *that, MonoArray **fields)
856 MonoObject **values = NULL;
858 MonoClassField* field;
864 MONO_CHECK_ARG_NULL (that);
866 if (this->vtable != that->vtable)
869 klass = mono_object_class (this);
872 * Do the comparison for fields of primitive type and return a result if
873 * possible. Otherwise, return the remaining fields in an array to the
874 * managed side. This way, we can avoid costly reflection operations in
879 while ((field = mono_class_get_fields (klass, &iter))) {
880 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
882 if (mono_field_is_deleted (field))
884 /* FIXME: Add more types */
885 switch (field->type->type) {
887 if (*(gint32*)((guint8*)this + field->offset) != *(gint32*)((guint8*)that + field->offset))
890 case MONO_TYPE_STRING: {
892 guint32 s1len, s2len;
893 s1 = *(MonoString**)((guint8*)this + field->offset);
894 s2 = *(MonoString**)((guint8*)that + field->offset);
897 if ((s1 == NULL) || (s2 == NULL))
899 s1len = mono_string_length (s1);
900 s2len = mono_string_length (s2);
904 if (memcmp (mono_string_chars (s1), mono_string_chars (s2), s1len * sizeof (gunichar2)) != 0)
910 values = g_newa (MonoObject*, mono_class_num_fields (klass) * 2);
911 o = mono_field_get_value_object (mono_object_domain (this), field, this);
912 values [count++] = o;
913 o = mono_field_get_value_object (mono_object_domain (this), field, that);
914 values [count++] = o;
920 *fields = mono_array_new (mono_domain_get (), mono_defaults.object_class, count);
921 for (i = 0; i < count; ++i)
922 mono_array_setref (*fields, i, values [i]);
929 static MonoReflectionType *
930 ves_icall_System_Object_GetType (MonoObject *obj)
934 if (obj->vtable->klass != mono_defaults.transparent_proxy_class)
935 return mono_type_get_object (mono_object_domain (obj), &obj->vtable->klass->byval_arg);
937 return mono_type_get_object (mono_object_domain (obj), &((MonoTransparentProxy*)obj)->remote_class->proxy_class->byval_arg);
941 mono_type_type_from_obj (MonoReflectionType *mtype, MonoObject *obj)
945 mtype->type = &obj->vtable->klass->byval_arg;
946 g_assert (mtype->type->type);
950 ves_icall_ModuleBuilder_getToken (MonoReflectionModuleBuilder *mb, MonoObject *obj)
954 MONO_CHECK_ARG_NULL (obj);
956 return mono_image_create_token (mb->dynamic_image, obj, TRUE);
960 ves_icall_ModuleBuilder_getMethodToken (MonoReflectionModuleBuilder *mb,
961 MonoReflectionMethod *method,
962 MonoArray *opt_param_types)
966 MONO_CHECK_ARG_NULL (method);
968 return mono_image_create_method_token (
969 mb->dynamic_image, (MonoObject *) method, opt_param_types);
973 ves_icall_ModuleBuilder_WriteToFile (MonoReflectionModuleBuilder *mb, HANDLE file)
977 mono_image_create_pefile (mb, file);
981 ves_icall_ModuleBuilder_build_metadata (MonoReflectionModuleBuilder *mb)
985 mono_image_build_metadata (mb);
989 get_caller (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
991 MonoMethod **dest = data;
993 /* skip unmanaged frames */
1008 static MonoReflectionType *
1009 type_from_name (const char *str, MonoBoolean ignoreCase)
1011 MonoType *type = NULL;
1012 MonoAssembly *assembly = NULL;
1013 MonoTypeNameParse info;
1014 char *temp_str = g_strdup (str);
1015 gboolean type_resolve = FALSE;
1017 MONO_ARCH_SAVE_REGS;
1019 /* mono_reflection_parse_type() mangles the string */
1020 if (!mono_reflection_parse_type (temp_str, &info)) {
1021 g_list_free (info.modifiers);
1022 g_list_free (info.nested);
1027 if (info.assembly.name) {
1028 assembly = mono_assembly_load (&info.assembly, NULL, NULL);
1030 MonoMethod *m = mono_method_get_last_managed ();
1031 MonoMethod *dest = m;
1033 mono_stack_walk_no_il (get_caller, &dest);
1038 * FIXME: mono_method_get_last_managed() sometimes returns NULL, thus
1039 * causing ves_icall_System_Reflection_Assembly_GetCallingAssembly()
1040 * to crash. This only seems to happen in some strange remoting
1041 * scenarios and I was unable to figure out what's happening there.
1042 * Dec 10, 2005 - Martin.
1046 assembly = dest->klass->image->assembly;
1048 g_warning (G_STRLOC);
1053 type = mono_reflection_get_type (assembly->image, &info, ignoreCase, &type_resolve);
1055 if (!info.assembly.name && !type) /* try mscorlib */
1056 type = mono_reflection_get_type (NULL, &info, ignoreCase, &type_resolve);
1058 g_list_free (info.modifiers);
1059 g_list_free (info.nested);
1065 return mono_type_get_object (mono_domain_get (), type);
1069 MonoReflectionType *
1070 mono_type_get (const char *str)
1072 char *copy = g_strdup (str);
1073 MonoReflectionType *type = type_from_name (copy, FALSE);
1080 static MonoReflectionType*
1081 ves_icall_type_from_name (MonoString *name,
1082 MonoBoolean throwOnError,
1083 MonoBoolean ignoreCase)
1085 char *str = mono_string_to_utf8 (name);
1086 MonoReflectionType *type;
1088 type = type_from_name (str, ignoreCase);
1091 MonoException *e = NULL;
1094 e = mono_get_exception_type_load (name, NULL);
1096 mono_loader_clear_error ();
1098 mono_raise_exception (e);
1105 static MonoReflectionType*
1106 ves_icall_type_from_handle (MonoType *handle)
1108 MonoDomain *domain = mono_domain_get ();
1109 MonoClass *klass = mono_class_from_mono_type (handle);
1111 MONO_ARCH_SAVE_REGS;
1113 mono_class_init (klass);
1114 return mono_type_get_object (domain, handle);
1118 ves_icall_System_Type_EqualsInternal (MonoReflectionType *type, MonoReflectionType *c)
1120 MONO_ARCH_SAVE_REGS;
1122 if (c && type->type && c->type)
1123 return mono_metadata_type_equal (type->type, c->type);
1128 /* System.TypeCode */
1147 TYPECODE_STRING = 18
1151 ves_icall_type_GetTypeCodeInternal (MonoReflectionType *type)
1153 int t = type->type->type;
1155 MONO_ARCH_SAVE_REGS;
1157 if (type->type->byref)
1158 return TYPECODE_OBJECT;
1162 case MONO_TYPE_VOID:
1163 return TYPECODE_OBJECT;
1164 case MONO_TYPE_BOOLEAN:
1165 return TYPECODE_BOOLEAN;
1167 return TYPECODE_BYTE;
1169 return TYPECODE_SBYTE;
1171 return TYPECODE_UINT16;
1173 return TYPECODE_INT16;
1174 case MONO_TYPE_CHAR:
1175 return TYPECODE_CHAR;
1179 return TYPECODE_OBJECT;
1181 return TYPECODE_UINT32;
1183 return TYPECODE_INT32;
1185 return TYPECODE_UINT64;
1187 return TYPECODE_INT64;
1189 return TYPECODE_SINGLE;
1191 return TYPECODE_DOUBLE;
1192 case MONO_TYPE_VALUETYPE:
1193 if (type->type->data.klass->enumtype) {
1194 t = type->type->data.klass->enum_basetype->type;
1197 MonoClass *k = type->type->data.klass;
1198 if (strcmp (k->name_space, "System") == 0) {
1199 if (strcmp (k->name, "Decimal") == 0)
1200 return TYPECODE_DECIMAL;
1201 else if (strcmp (k->name, "DateTime") == 0)
1202 return TYPECODE_DATETIME;
1205 return TYPECODE_OBJECT;
1206 case MONO_TYPE_STRING:
1207 return TYPECODE_STRING;
1208 case MONO_TYPE_SZARRAY:
1209 case MONO_TYPE_ARRAY:
1210 case MONO_TYPE_OBJECT:
1212 case MONO_TYPE_MVAR:
1213 case MONO_TYPE_TYPEDBYREF:
1214 return TYPECODE_OBJECT;
1215 case MONO_TYPE_CLASS:
1217 MonoClass *k = type->type->data.klass;
1218 if (strcmp (k->name_space, "System") == 0) {
1219 if (strcmp (k->name, "DBNull") == 0)
1220 return TYPECODE_DBNULL;
1223 return TYPECODE_OBJECT;
1224 case MONO_TYPE_GENERICINST:
1225 return TYPECODE_OBJECT;
1227 g_error ("type 0x%02x not handled in GetTypeCode()", t);
1233 ves_icall_type_is_subtype_of (MonoReflectionType *type, MonoReflectionType *c, MonoBoolean check_interfaces)
1239 MONO_ARCH_SAVE_REGS;
1241 g_assert (type != NULL);
1243 domain = ((MonoObject *)type)->vtable->domain;
1245 if (!c) /* FIXME: dont know what do do here */
1248 klass = mono_class_from_mono_type (type->type);
1249 klassc = mono_class_from_mono_type (c->type);
1251 if (type->type->byref)
1252 return klassc == mono_defaults.object_class;
1254 return mono_class_is_subclass_of (klass, klassc, check_interfaces);
1258 ves_icall_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType *c)
1264 MONO_ARCH_SAVE_REGS;
1266 g_assert (type != NULL);
1268 domain = ((MonoObject *)type)->vtable->domain;
1270 klass = mono_class_from_mono_type (type->type);
1271 klassc = mono_class_from_mono_type (c->type);
1273 if (type->type->byref && !c->type->byref)
1276 return mono_class_is_assignable_from (klass, klassc);
1280 ves_icall_type_IsInstanceOfType (MonoReflectionType *type, MonoObject *obj)
1282 MonoClass *klass = mono_class_from_mono_type (type->type);
1283 return mono_object_isinst (obj, klass) != NULL;
1287 ves_icall_get_attributes (MonoReflectionType *type)
1289 MonoClass *klass = mono_class_from_mono_type (type->type);
1291 MONO_ARCH_SAVE_REGS;
1293 return klass->flags;
1296 static MonoReflectionMarshal*
1297 ves_icall_System_Reflection_FieldInfo_GetUnmanagedMarshal (MonoReflectionField *field)
1299 MonoClass *klass = field->field->parent;
1300 MonoMarshalType *info;
1303 if (klass->generic_container ||
1304 (klass->generic_class && klass->generic_class->inst->is_open))
1307 info = mono_marshal_load_type_info (klass);
1309 for (i = 0; i < info->num_fields; ++i) {
1310 if (info->fields [i].field == field->field) {
1311 if (!info->fields [i].mspec)
1314 return mono_reflection_marshal_from_marshal_spec (field->object.vtable->domain, klass, info->fields [i].mspec);
1321 static MonoReflectionField*
1322 ves_icall_System_Reflection_FieldInfo_internal_from_handle (MonoClassField *handle)
1324 MONO_ARCH_SAVE_REGS;
1328 return mono_field_get_object (mono_domain_get (), handle->parent, handle);
1332 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
1334 MonoDomain *domain = mono_domain_get ();
1335 MonoMethodSignature* sig;
1336 MONO_ARCH_SAVE_REGS;
1338 if (method->is_inflated)
1339 method = mono_get_inflated_method (method);
1341 sig = mono_method_signature (method);
1343 info->parent = mono_type_get_object (domain, &method->klass->byval_arg);
1344 info->ret = mono_type_get_object (domain, sig->ret);
1345 info->attrs = method->flags;
1346 info->implattrs = method->iflags;
1347 if (sig->call_convention == MONO_CALL_DEFAULT)
1350 if (sig->call_convention == MONO_CALL_VARARG)
1355 info->callconv |= (sig->hasthis << 5) | (sig->explicit_this << 6);
1359 ves_icall_get_parameter_info (MonoMethod *method)
1361 MonoDomain *domain = mono_domain_get ();
1363 MONO_ARCH_SAVE_REGS;
1365 if (method->is_inflated)
1366 method = mono_get_inflated_method (method);
1368 return mono_param_get_objects (domain, method);
1371 static MonoReflectionMarshal*
1372 ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod *method)
1374 MonoDomain *domain = mono_domain_get ();
1375 MonoReflectionMarshal* res = NULL;
1376 MonoMarshalSpec **mspecs;
1379 MONO_ARCH_SAVE_REGS;
1381 if (method->is_inflated)
1382 method = mono_get_inflated_method (method);
1384 mspecs = g_new (MonoMarshalSpec*, mono_method_signature (method)->param_count + 1);
1385 mono_method_get_marshal_info (method, mspecs);
1388 res = mono_reflection_marshal_from_marshal_spec (domain, method->klass, mspecs [0]);
1390 for (i = mono_method_signature (method)->param_count; i >= 0; i--)
1392 mono_metadata_free_marshal_spec (mspecs [i]);
1399 ves_icall_MonoField_GetFieldOffset (MonoReflectionField *field)
1401 return field->field->offset - sizeof (MonoObject);
1404 static MonoReflectionType*
1405 ves_icall_MonoField_GetParentType (MonoReflectionField *field, MonoBoolean declaring)
1408 MONO_ARCH_SAVE_REGS;
1410 parent = declaring? field->field->parent: field->klass;
1412 return mono_type_get_object (mono_object_domain (field), &parent->byval_arg);
1416 ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj)
1419 MonoClassField *cf = field->field;
1423 MonoDomain *domain = mono_object_domain (field);
1425 gboolean is_static = FALSE;
1426 gboolean is_ref = FALSE;
1428 MONO_ARCH_SAVE_REGS;
1430 if (field->klass->image->assembly->ref_only)
1431 mono_raise_exception (mono_get_exception_invalid_operation (
1432 "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
1434 mono_class_init (field->klass);
1436 t = mono_type_get_underlying_type (cf->type);
1438 case MONO_TYPE_STRING:
1439 case MONO_TYPE_OBJECT:
1440 case MONO_TYPE_CLASS:
1441 case MONO_TYPE_ARRAY:
1442 case MONO_TYPE_SZARRAY:
1447 case MONO_TYPE_BOOLEAN:
1450 case MONO_TYPE_CHAR:
1459 case MONO_TYPE_VALUETYPE:
1462 case MONO_TYPE_GENERICINST:
1463 if (mono_type_generic_inst_is_valuetype (t)) {
1470 g_error ("type 0x%x not handled in "
1471 "ves_icall_Monofield_GetValue", t->type);
1476 if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) {
1478 vtable = mono_class_vtable (domain, cf->parent);
1479 if (!vtable->initialized && !(cf->type->attrs & FIELD_ATTRIBUTE_LITERAL))
1480 mono_runtime_class_init (vtable);
1485 mono_field_static_get_value (vtable, cf, &o);
1487 mono_field_get_value (obj, cf, &o);
1492 if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) {
1493 MonoClass *nklass = mono_class_from_mono_type (cf->type);
1496 /* Convert the Nullable structure into a boxed vtype */
1498 buf = (guint8*)vtable->data + cf->offset;
1500 buf = (guint8*)obj + cf->offset;
1502 return mono_nullable_box (buf, nklass);
1505 /* boxed value type */
1506 klass = mono_class_from_mono_type (cf->type);
1507 o = mono_object_new (domain, klass);
1508 v = ((gchar *) o) + sizeof (MonoObject);
1510 mono_field_static_get_value (vtable, cf, v);
1512 mono_field_get_value (obj, cf, v);
1519 ves_icall_FieldInfo_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value)
1521 MonoClassField *cf = field->field;
1524 MONO_ARCH_SAVE_REGS;
1526 if (field->klass->image->assembly->ref_only)
1527 mono_raise_exception (mono_get_exception_invalid_operation (
1528 "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
1530 v = (gchar *) value;
1531 if (!cf->type->byref) {
1532 switch (cf->type->type) {
1535 case MONO_TYPE_BOOLEAN:
1538 case MONO_TYPE_CHAR:
1547 case MONO_TYPE_VALUETYPE:
1549 v += sizeof (MonoObject);
1551 case MONO_TYPE_STRING:
1552 case MONO_TYPE_OBJECT:
1553 case MONO_TYPE_CLASS:
1554 case MONO_TYPE_ARRAY:
1555 case MONO_TYPE_SZARRAY:
1558 case MONO_TYPE_GENERICINST: {
1559 MonoGenericClass *gclass = cf->type->data.generic_class;
1560 g_assert (!gclass->inst->is_open);
1562 if (mono_class_is_nullable (mono_class_from_mono_type (cf->type))) {
1563 MonoClass *nklass = mono_class_from_mono_type (cf->type);
1567 * Convert the boxed vtype into a Nullable structure.
1568 * This is complicated by the fact that Nullables have
1569 * a variable structure.
1571 /* Allocate using alloca so it gets GC tracking */
1572 buf = alloca (nklass->instance_size);
1574 mono_nullable_init (buf, value, nklass);
1579 if (gclass->container_class->valuetype && (v != NULL))
1580 v += sizeof (MonoObject);
1584 g_error ("type 0x%x not handled in "
1585 "ves_icall_FieldInfo_SetValueInternal", cf->type->type);
1590 if (cf->type->attrs & FIELD_ATTRIBUTE_STATIC) {
1591 MonoVTable *vtable = mono_class_vtable (mono_object_domain (field), cf->parent);
1592 if (!vtable->initialized)
1593 mono_runtime_class_init (vtable);
1594 mono_field_static_set_value (vtable, cf, v);
1596 mono_field_set_value (obj, cf, v);
1600 static MonoReflectionType*
1601 ves_icall_MonoGenericMethod_get_ReflectedType (MonoReflectionGenericMethod *rmethod)
1603 MonoMethod *method = mono_get_inflated_method (rmethod->method.method);
1605 return mono_type_get_object (mono_object_domain (rmethod), &method->klass->byval_arg);
1608 /* From MonoProperty.cs */
1610 PInfo_Attributes = 1,
1611 PInfo_GetMethod = 1 << 1,
1612 PInfo_SetMethod = 1 << 2,
1613 PInfo_ReflectedType = 1 << 3,
1614 PInfo_DeclaringType = 1 << 4,
1619 ves_icall_get_property_info (MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
1621 MonoDomain *domain = mono_object_domain (property);
1623 MONO_ARCH_SAVE_REGS;
1625 if ((req_info & PInfo_ReflectedType) != 0)
1626 info->parent = mono_type_get_object (domain, &property->klass->byval_arg);
1627 else if ((req_info & PInfo_DeclaringType) != 0)
1628 info->parent = mono_type_get_object (domain, &property->property->parent->byval_arg);
1630 if ((req_info & PInfo_Name) != 0)
1631 info->name = mono_string_new (domain, property->property->name);
1633 if ((req_info & PInfo_Attributes) != 0)
1634 info->attrs = property->property->attrs;
1636 if ((req_info & PInfo_GetMethod) != 0)
1637 info->get = property->property->get ?
1638 mono_method_get_object (domain, property->property->get, NULL): NULL;
1640 if ((req_info & PInfo_SetMethod) != 0)
1641 info->set = property->property->set ?
1642 mono_method_get_object (domain, property->property->set, NULL): NULL;
1644 * There may be other methods defined for properties, though, it seems they are not exposed
1645 * in the reflection API
1650 ves_icall_get_event_info (MonoReflectionEvent *event, MonoEventInfo *info)
1652 MonoDomain *domain = mono_object_domain (event);
1654 MONO_ARCH_SAVE_REGS;
1656 info->reflected_type = mono_type_get_object (domain, &event->klass->byval_arg);
1657 info->declaring_type = mono_type_get_object (domain, &event->event->parent->byval_arg);
1659 info->name = mono_string_new (domain, event->event->name);
1660 info->attrs = event->event->attrs;
1661 info->add_method = event->event->add ? mono_method_get_object (domain, event->event->add, NULL): NULL;
1662 info->remove_method = event->event->remove ? mono_method_get_object (domain, event->event->remove, NULL): NULL;
1663 info->raise_method = event->event->raise ? mono_method_get_object (domain, event->event->raise, NULL): NULL;
1665 if (event->event->other) {
1667 while (event->event->other [n])
1669 info->other_methods = mono_array_new (domain, mono_defaults.method_info_class, n);
1671 for (i = 0; i < n; i++)
1672 mono_array_setref (info->other_methods, i, mono_method_get_object (domain, event->event->other [i], NULL));
1677 ves_icall_Type_GetInterfaces (MonoReflectionType* type)
1679 MonoDomain *domain = mono_object_domain (type);
1681 GPtrArray *ifaces = NULL;
1683 MonoClass *class = mono_class_from_mono_type (type->type);
1686 MonoGenericContext *context = NULL;
1688 MONO_ARCH_SAVE_REGS;
1690 /* open generic-instance classes can share their interface_id */
1691 if (class->generic_class && class->generic_class->inst->is_open) {
1692 context = mono_class_get_context (class);
1693 class = class->generic_class->container_class;
1696 mono_class_setup_vtable (class);
1698 slots = mono_bitset_new (class->max_interface_id + 1, 0);
1700 for (parent = class; parent; parent = parent->parent) {
1701 GPtrArray *tmp_ifaces = mono_class_get_implemented_interfaces (parent);
1703 for (i = 0; i < tmp_ifaces->len; ++i) {
1704 MonoClass *ic = g_ptr_array_index (tmp_ifaces, i);
1706 if (mono_bitset_test (slots, ic->interface_id))
1709 mono_bitset_set (slots, ic->interface_id);
1711 ifaces = g_ptr_array_new ();
1712 g_ptr_array_add (ifaces, ic);
1714 g_ptr_array_free (tmp_ifaces, TRUE);
1717 mono_bitset_free (slots);
1720 return mono_array_new (domain, mono_defaults.monotype_class, 0);
1722 intf = mono_array_new (domain, mono_defaults.monotype_class, ifaces->len);
1723 for (i = 0; i < ifaces->len; ++i) {
1724 MonoClass *ic = g_ptr_array_index (ifaces, i);
1725 MonoType *ret = &ic->byval_arg;
1726 if (context && ic->generic_class && ic->generic_class->inst->is_open)
1727 ret = mono_class_inflate_generic_type (ret, context);
1729 mono_array_setref (intf, i, mono_type_get_object (domain, ret));
1731 g_ptr_array_free (ifaces, TRUE);
1737 ves_icall_Type_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType *iface, MonoArray **targets, MonoArray **methods)
1739 MonoClass *class = mono_class_from_mono_type (type->type);
1740 MonoClass *iclass = mono_class_from_mono_type (iface->type);
1741 MonoReflectionMethod *member;
1744 int i = 0, len, ioffset;
1747 MONO_ARCH_SAVE_REGS;
1749 mono_class_setup_vtable (class);
1751 /* type doesn't implement iface: the exception is thrown in managed code */
1752 if ((iclass->interface_id > class->max_interface_id) || !class->interface_offsets [iclass->interface_id])
1755 len = mono_class_num_methods (iclass);
1756 ioffset = class->interface_offsets [iclass->interface_id];
1757 domain = mono_object_domain (type);
1758 *targets = mono_array_new (domain, mono_defaults.method_info_class, len);
1759 *methods = mono_array_new (domain, mono_defaults.method_info_class, len);
1762 while ((method = mono_class_get_methods (iclass, &iter))) {
1763 member = mono_method_get_object (domain, method, iclass);
1764 mono_array_setref (*methods, i, member);
1765 member = mono_method_get_object (domain, class->vtable [i + ioffset], class);
1766 mono_array_setref (*targets, i, member);
1773 ves_icall_Type_GetPacking (MonoReflectionType *type, guint32 *packing, guint32 *size)
1775 MonoClass *klass = mono_class_from_mono_type (type->type);
1777 g_assert (!klass->image->dynamic);
1779 mono_metadata_packing_from_typedef (klass->image, klass->type_token, packing, size);
1782 static MonoReflectionType*
1783 ves_icall_MonoType_GetElementType (MonoReflectionType *type)
1785 MonoClass *class = mono_class_from_mono_type (type->type);
1787 MONO_ARCH_SAVE_REGS;
1789 // GetElementType should only return a type for:
1790 // Array Pointer PassedByRef
1791 if (type->type->byref)
1792 return mono_type_get_object (mono_object_domain (type), &class->byval_arg);
1793 else if (class->element_class && MONO_CLASS_IS_ARRAY (class))
1794 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
1795 else if (class->element_class && type->type->type == MONO_TYPE_PTR)
1796 return mono_type_get_object (mono_object_domain (type), &class->element_class->byval_arg);
1801 static MonoReflectionType*
1802 ves_icall_get_type_parent (MonoReflectionType *type)
1804 MonoClass *class = mono_class_from_mono_type (type->type);
1806 MONO_ARCH_SAVE_REGS;
1808 return class->parent ? mono_type_get_object (mono_object_domain (type), &class->parent->byval_arg): NULL;
1812 ves_icall_type_ispointer (MonoReflectionType *type)
1814 MONO_ARCH_SAVE_REGS;
1816 return type->type->type == MONO_TYPE_PTR;
1820 ves_icall_type_isprimitive (MonoReflectionType *type)
1822 MONO_ARCH_SAVE_REGS;
1824 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)));
1828 ves_icall_type_isbyref (MonoReflectionType *type)
1830 MONO_ARCH_SAVE_REGS;
1832 return type->type->byref;
1836 ves_icall_type_iscomobject (MonoReflectionType *type)
1838 MonoClass *klass = mono_class_from_mono_type (type->type);
1839 MONO_ARCH_SAVE_REGS;
1841 return (klass && klass->is_com_object);
1844 static MonoReflectionModule*
1845 ves_icall_MonoType_get_Module (MonoReflectionType *type)
1847 MonoClass *class = mono_class_from_mono_type (type->type);
1849 MONO_ARCH_SAVE_REGS;
1851 return mono_module_get_object (mono_object_domain (type), class->image);
1854 static MonoReflectionAssembly*
1855 ves_icall_MonoType_get_Assembly (MonoReflectionType *type)
1857 MonoDomain *domain = mono_domain_get ();
1858 MonoClass *class = mono_class_from_mono_type (type->type);
1860 MONO_ARCH_SAVE_REGS;
1862 return mono_assembly_get_object (domain, class->image->assembly);
1865 static MonoReflectionType*
1866 ves_icall_MonoType_get_DeclaringType (MonoReflectionType *type)
1868 MonoDomain *domain = mono_domain_get ();
1871 MONO_ARCH_SAVE_REGS;
1873 if (type->type->byref)
1875 if (type->type->type == MONO_TYPE_VAR)
1876 class = type->type->data.generic_param->owner->owner.klass;
1877 else if (type->type->type == MONO_TYPE_MVAR)
1878 class = type->type->data.generic_param->owner->owner.method->klass;
1880 class = mono_class_from_mono_type (type->type)->nested_in;
1882 return class ? mono_type_get_object (domain, &class->byval_arg) : NULL;
1885 static MonoReflectionType*
1886 ves_icall_MonoType_get_UnderlyingSystemType (MonoReflectionType *type)
1888 MonoDomain *domain = mono_domain_get ();
1889 MonoClass *class = mono_class_from_mono_type (type->type);
1891 MONO_ARCH_SAVE_REGS;
1893 if (class->enumtype && class->enum_basetype) /* types that are modified typebuilders may not have enum_basetype set */
1894 return mono_type_get_object (domain, class->enum_basetype);
1895 else if (class->element_class)
1896 return mono_type_get_object (domain, &class->element_class->byval_arg);
1902 ves_icall_MonoType_get_Name (MonoReflectionType *type)
1904 MonoDomain *domain = mono_domain_get ();
1905 MonoClass *class = mono_class_from_mono_type (type->type);
1907 MONO_ARCH_SAVE_REGS;
1909 if (type->type->byref) {
1910 char *n = g_strdup_printf ("%s&", class->name);
1911 MonoString *res = mono_string_new (domain, n);
1917 return mono_string_new (domain, class->name);
1922 ves_icall_MonoType_get_Namespace (MonoReflectionType *type)
1924 MonoDomain *domain = mono_domain_get ();
1925 MonoClass *class = mono_class_from_mono_type (type->type);
1927 MONO_ARCH_SAVE_REGS;
1929 while (class->nested_in)
1930 class = class->nested_in;
1932 if (class->name_space [0] == '\0')
1935 return mono_string_new (domain, class->name_space);
1939 ves_icall_MonoType_GetArrayRank (MonoReflectionType *type)
1941 MonoClass *class = mono_class_from_mono_type (type->type);
1943 MONO_ARCH_SAVE_REGS;
1949 ves_icall_MonoType_GetGenericArguments (MonoReflectionType *type)
1952 MonoClass *klass, *pklass;
1954 MONO_ARCH_SAVE_REGS;
1956 klass = mono_class_from_mono_type (type->type);
1958 if (klass->generic_container) {
1959 MonoGenericContainer *container = klass->generic_container;
1960 res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, container->type_argc);
1961 for (i = 0; i < container->type_argc; ++i) {
1962 pklass = mono_class_from_generic_parameter (&container->type_params [i], klass->image, FALSE);
1963 mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), &pklass->byval_arg));
1965 } else if (klass->generic_class) {
1966 MonoGenericInst *inst = klass->generic_class->inst;
1967 res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, inst->type_argc);
1968 for (i = 0; i < inst->type_argc; ++i)
1969 mono_array_setref (res, i, mono_type_get_object (mono_object_domain (type), inst->type_argv [i]));
1971 res = mono_array_new (mono_object_domain (type), mono_defaults.monotype_class, 0);
1977 ves_icall_Type_get_IsGenericTypeDefinition (MonoReflectionType *type)
1980 MONO_ARCH_SAVE_REGS;
1982 if (type->type->byref)
1985 klass = mono_class_from_mono_type (type->type);
1987 return klass->generic_container != NULL;
1990 static MonoReflectionType*
1991 ves_icall_Type_GetGenericTypeDefinition_impl (MonoReflectionType *type)
1994 MONO_ARCH_SAVE_REGS;
1996 if (type->type->byref)
1999 klass = mono_class_from_mono_type (type->type);
2000 if (klass->generic_container) {
2001 return type; /* check this one */
2003 if (klass->generic_class) {
2004 MonoClass *generic_class = klass->generic_class->container_class;
2006 if (generic_class->wastypebuilder && generic_class->reflection_info)
2007 return generic_class->reflection_info;
2009 return mono_type_get_object (mono_object_domain (type), &generic_class->byval_arg);
2014 static MonoReflectionType*
2015 ves_icall_Type_MakeGenericType (MonoReflectionType *type, MonoArray *type_array)
2017 MonoType *geninst, **types;
2020 MONO_ARCH_SAVE_REGS;
2022 count = mono_array_length (type_array);
2023 types = g_new0 (MonoType *, count);
2025 for (i = 0; i < count; i++) {
2026 MonoReflectionType *t = mono_array_get (type_array, gpointer, i);
2027 types [i] = t->type;
2030 geninst = mono_reflection_bind_generic_parameters (type, count, types);
2035 return mono_type_get_object (mono_object_domain (type), geninst);
2039 ves_icall_Type_get_IsGenericInstance (MonoReflectionType *type)
2042 MONO_ARCH_SAVE_REGS;
2044 if (type->type->byref)
2047 klass = mono_class_from_mono_type (type->type);
2048 return klass->generic_class != NULL;
2052 ves_icall_Type_get_IsGenericType (MonoReflectionType *type)
2055 MONO_ARCH_SAVE_REGS;
2057 if (type->type->byref)
2060 klass = mono_class_from_mono_type (type->type);
2061 return klass->generic_class != NULL || klass->generic_container != NULL;
2065 ves_icall_Type_GetGenericParameterPosition (MonoReflectionType *type)
2067 MONO_ARCH_SAVE_REGS;
2069 if (is_generic_parameter (type->type))
2070 return type->type->data.generic_param->num;
2074 static GenericParameterAttributes
2075 ves_icall_Type_GetGenericParameterAttributes (MonoReflectionType *type)
2077 MONO_ARCH_SAVE_REGS;
2078 g_assert (is_generic_parameter (type->type));
2079 return type->type->data.generic_param->flags;
2083 ves_icall_Type_GetGenericParameterConstraints (MonoReflectionType *type)
2085 MonoGenericParam *param;
2091 MONO_ARCH_SAVE_REGS;
2093 domain = mono_object_domain (type);
2094 param = type->type->data.generic_param;
2095 for (count = 0, ptr = param->constraints; ptr && *ptr; ptr++, count++)
2098 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2099 for (i = 0; i < count; i++)
2100 mono_array_setref (res, i, mono_type_get_object (domain, ¶m->constraints [i]->byval_arg));
2107 ves_icall_MonoType_get_IsGenericParameter (MonoReflectionType *type)
2109 MONO_ARCH_SAVE_REGS;
2110 return is_generic_parameter (type->type);
2114 ves_icall_TypeBuilder_get_IsGenericParameter (MonoReflectionTypeBuilder *tb)
2116 MONO_ARCH_SAVE_REGS;
2117 return is_generic_parameter (tb->type.type);
2121 ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
2122 MonoReflectionType *t)
2124 enumtype->type = t->type;
2127 static MonoReflectionType*
2128 ves_icall_MonoGenericClass_GetParentType (MonoReflectionGenericClass *type)
2130 MonoDynamicGenericClass *gclass;
2131 MonoReflectionType *parent = NULL;
2136 MONO_ARCH_SAVE_REGS;
2138 g_assert (type->type.type->data.generic_class->is_dynamic);
2139 gclass = (MonoDynamicGenericClass *) type->type.type->data.generic_class;
2141 domain = mono_object_domain (type);
2142 klass = mono_class_from_mono_type (type->generic_type->type);
2144 if (!klass->generic_class && !klass->generic_container)
2147 if (!strcmp (type->generic_type->object.vtable->klass->name, "TypeBuilder")) {
2148 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *) type->generic_type;
2149 parent = tb->parent;
2150 } else if (klass->wastypebuilder) {
2151 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *) type->generic_type;
2152 parent = tb->parent;
2154 MonoClass *pklass = klass->parent;
2156 parent = mono_type_get_object (domain, &pklass->byval_arg);
2159 if (!parent || (parent->type->type != MONO_TYPE_GENERICINST))
2162 inflated = mono_class_inflate_generic_type (
2163 parent->type, mono_generic_class_get_context ((MonoGenericClass *) gclass));
2165 return mono_type_get_object (domain, inflated);
2169 ves_icall_MonoGenericClass_GetInterfaces (MonoReflectionGenericClass *type)
2171 static MonoClass *System_Reflection_MonoGenericClass;
2172 MonoGenericClass *gclass;
2173 MonoReflectionTypeBuilder *tb = NULL;
2174 MonoClass *klass = NULL;
2179 MONO_ARCH_SAVE_REGS;
2181 if (!System_Reflection_MonoGenericClass) {
2182 System_Reflection_MonoGenericClass = mono_class_from_name (
2183 mono_defaults.corlib, "System.Reflection", "MonoGenericClass");
2184 g_assert (System_Reflection_MonoGenericClass);
2187 domain = mono_object_domain (type);
2189 gclass = type->type.type->data.generic_class;
2190 g_assert (gclass->is_dynamic);
2192 if (!strcmp (type->generic_type->object.vtable->klass->name, "TypeBuilder")) {
2193 tb = (MonoReflectionTypeBuilder *) type->generic_type;
2194 icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
2196 klass = gclass->container_class;
2197 mono_class_init (klass);
2198 icount = klass->interface_count;
2201 res = mono_array_new (domain, System_Reflection_MonoGenericClass, icount);
2203 for (i = 0; i < icount; i++) {
2204 MonoReflectionType *iface;
2208 iface = mono_array_get (tb->interfaces, MonoReflectionType *, i);
2211 it = &klass->interfaces [i]->byval_arg;
2213 it = mono_class_inflate_generic_type (it, mono_generic_class_get_context (gclass));
2215 iface = mono_type_get_object (domain, it);
2216 mono_array_setref (res, i, iface);
2222 static MonoReflectionMethod*
2223 ves_icall_MonoGenericClass_GetCorrespondingInflatedMethod (MonoReflectionGenericClass *type,
2224 MonoReflectionMethod* generic)
2226 MonoGenericClass *gclass;
2227 MonoDynamicGenericClass *dgclass;
2231 MONO_ARCH_SAVE_REGS;
2233 gclass = type->type.type->data.generic_class;
2234 g_assert (gclass->is_dynamic);
2236 dgclass = (MonoDynamicGenericClass *) gclass;
2238 domain = mono_object_domain (type);
2240 for (i = 0; i < dgclass->count_methods; i++)
2241 if (generic->method->token == dgclass->methods [i]->token)
2242 return mono_method_get_object (domain, dgclass->methods [i], NULL);
2247 static MonoReflectionMethod*
2248 ves_icall_MonoGenericClass_GetCorrespondingInflatedConstructor (MonoReflectionGenericClass *type,
2249 MonoReflectionMethod* generic)
2251 MonoGenericClass *gclass;
2252 MonoDynamicGenericClass *dgclass;
2256 MONO_ARCH_SAVE_REGS;
2258 gclass = type->type.type->data.generic_class;
2259 g_assert (gclass->is_dynamic);
2261 dgclass = (MonoDynamicGenericClass *) gclass;
2263 domain = mono_object_domain (type);
2265 for (i = 0; i < dgclass->count_ctors; i++)
2266 if (generic->method->token == dgclass->ctors [i]->token)
2267 return mono_method_get_object (domain, dgclass->ctors [i], NULL);
2273 static MonoReflectionField*
2274 ves_icall_MonoGenericClass_GetCorrespondingInflatedField (MonoReflectionGenericClass *type,
2275 MonoString* generic_name)
2277 MonoGenericClass *gclass;
2278 MonoDynamicGenericClass *dgclass;
2280 MonoClass *refclass;
2281 char *utf8_name = mono_string_to_utf8 (generic_name);
2284 MONO_ARCH_SAVE_REGS;
2286 gclass = type->type.type->data.generic_class;
2287 g_assert (gclass->is_dynamic);
2289 dgclass = (MonoDynamicGenericClass *) gclass;
2291 refclass = mono_class_from_mono_type (type->type.type);
2293 domain = mono_object_domain (type);
2295 for (i = 0; i < dgclass->count_fields; i++)
2296 if (strcmp (utf8_name, dgclass->fields [i].name) == 0) {
2298 return mono_field_get_object (domain, refclass, &dgclass->fields [i]);
2307 static MonoReflectionMethod*
2308 ves_icall_MonoType_GetCorrespondingInflatedMethod (MonoReflectionType *type,
2309 MonoReflectionMethod* generic)
2316 MONO_ARCH_SAVE_REGS;
2318 domain = ((MonoObject *)type)->vtable->domain;
2320 klass = mono_class_from_mono_type (type->type);
2323 while ((method = mono_class_get_methods (klass, &iter))) {
2324 if (method->token == generic->method->token)
2325 return mono_method_get_object (domain, method, klass);
2332 ves_icall_MonoGenericClass_GetMethods (MonoReflectionGenericClass *type,
2333 MonoReflectionType *reflected_type)
2335 MonoGenericClass *gclass;
2336 MonoDynamicGenericClass *dgclass;
2338 MonoClass *refclass;
2342 MONO_ARCH_SAVE_REGS;
2344 gclass = type->type.type->data.generic_class;
2345 g_assert (gclass->is_dynamic);
2346 dgclass = (MonoDynamicGenericClass *) gclass;
2348 refclass = mono_class_from_mono_type (reflected_type->type);
2350 domain = mono_object_domain (type);
2351 res = mono_array_new (domain, mono_defaults.method_info_class, dgclass->count_methods);
2353 for (i = 0; i < dgclass->count_methods; i++)
2354 mono_array_setref (res, i, mono_method_get_object (domain, dgclass->methods [i], refclass));
2360 ves_icall_MonoGenericClass_GetConstructors (MonoReflectionGenericClass *type,
2361 MonoReflectionType *reflected_type)
2363 static MonoClass *System_Reflection_ConstructorInfo;
2364 MonoGenericClass *gclass;
2365 MonoDynamicGenericClass *dgclass;
2367 MonoClass *refclass;
2371 MONO_ARCH_SAVE_REGS;
2373 if (!System_Reflection_ConstructorInfo)
2374 System_Reflection_ConstructorInfo = mono_class_from_name (
2375 mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
2377 gclass = type->type.type->data.generic_class;
2378 g_assert (gclass->is_dynamic);
2379 dgclass = (MonoDynamicGenericClass *) gclass;
2381 refclass = mono_class_from_mono_type (reflected_type->type);
2383 domain = mono_object_domain (type);
2384 res = mono_array_new (domain, System_Reflection_ConstructorInfo, dgclass->count_ctors);
2386 for (i = 0; i < dgclass->count_ctors; i++)
2387 mono_array_setref (res, i, mono_method_get_object (domain, dgclass->ctors [i], refclass));
2393 ves_icall_MonoGenericClass_GetFields (MonoReflectionGenericClass *type,
2394 MonoReflectionType *reflected_type)
2396 MonoGenericClass *gclass;
2397 MonoDynamicGenericClass *dgclass;
2399 MonoClass *refclass;
2403 MONO_ARCH_SAVE_REGS;
2405 gclass = type->type.type->data.generic_class;
2406 g_assert (gclass->is_dynamic);
2407 dgclass = (MonoDynamicGenericClass *) gclass;
2409 refclass = mono_class_from_mono_type (reflected_type->type);
2411 domain = mono_object_domain (type);
2412 res = mono_array_new (domain, mono_defaults.field_info_class, dgclass->count_fields);
2414 for (i = 0; i < dgclass->count_fields; i++)
2415 mono_array_setref (res, i, mono_field_get_object (domain, refclass, &dgclass->fields [i]));
2421 ves_icall_MonoGenericClass_GetProperties (MonoReflectionGenericClass *type,
2422 MonoReflectionType *reflected_type)
2424 static MonoClass *System_Reflection_PropertyInfo;
2425 MonoGenericClass *gclass;
2426 MonoDynamicGenericClass *dgclass;
2428 MonoClass *refclass;
2432 MONO_ARCH_SAVE_REGS;
2434 if (!System_Reflection_PropertyInfo)
2435 System_Reflection_PropertyInfo = mono_class_from_name (
2436 mono_defaults.corlib, "System.Reflection", "PropertyInfo");
2438 gclass = type->type.type->data.generic_class;
2439 g_assert (gclass->is_dynamic);
2440 dgclass = (MonoDynamicGenericClass *) gclass;
2442 refclass = mono_class_from_mono_type (reflected_type->type);
2444 domain = mono_object_domain (type);
2445 res = mono_array_new (domain, System_Reflection_PropertyInfo, dgclass->count_properties);
2447 for (i = 0; i < dgclass->count_properties; i++)
2448 mono_array_setref (res, i, mono_property_get_object (domain, refclass, &dgclass->properties [i]));
2454 ves_icall_MonoGenericClass_GetEvents (MonoReflectionGenericClass *type,
2455 MonoReflectionType *reflected_type)
2457 static MonoClass *System_Reflection_EventInfo;
2458 MonoGenericClass *gclass;
2459 MonoDynamicGenericClass *dgclass;
2461 MonoClass *refclass;
2465 MONO_ARCH_SAVE_REGS;
2467 if (!System_Reflection_EventInfo)
2468 System_Reflection_EventInfo = mono_class_from_name (
2469 mono_defaults.corlib, "System.Reflection", "EventInfo");
2471 gclass = type->type.type->data.generic_class;
2472 g_assert (gclass->is_dynamic);
2473 dgclass = (MonoDynamicGenericClass *) gclass;
2475 refclass = mono_class_from_mono_type (reflected_type->type);
2477 domain = mono_object_domain (type);
2478 res = mono_array_new (domain, System_Reflection_EventInfo, dgclass->count_events);
2480 for (i = 0; i < dgclass->count_events; i++)
2481 mono_array_setref (res, i, mono_event_get_object (domain, refclass, &dgclass->events [i]));
2486 static MonoReflectionMethod *
2487 ves_icall_MonoType_get_DeclaringMethod (MonoReflectionType *type)
2492 MONO_ARCH_SAVE_REGS;
2494 if (type->type->byref || type->type->type != MONO_TYPE_MVAR)
2497 method = type->type->data.generic_param->owner->owner.method;
2499 klass = mono_class_from_mono_type (type->type);
2500 return mono_method_get_object (mono_object_domain (type), method, klass);
2503 static MonoReflectionDllImportAttribute*
2504 ves_icall_MonoMethod_GetDllImportAttribute (MonoMethod *method)
2506 static MonoClass *DllImportAttributeClass = NULL;
2507 MonoDomain *domain = mono_domain_get ();
2508 MonoReflectionDllImportAttribute *attr;
2509 MonoImage *image = method->klass->image;
2510 MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method;
2511 MonoTableInfo *tables = image->tables;
2512 MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
2513 MonoTableInfo *mr = &tables [MONO_TABLE_MODULEREF];
2514 guint32 im_cols [MONO_IMPLMAP_SIZE];
2515 guint32 scope_token;
2516 const char *import = NULL;
2517 const char *scope = NULL;
2520 if (!method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)
2523 if (!DllImportAttributeClass) {
2524 DllImportAttributeClass =
2525 mono_class_from_name (mono_defaults.corlib,
2526 "System.Runtime.InteropServices", "DllImportAttribute");
2527 g_assert (DllImportAttributeClass);
2530 if (method->klass->image->dynamic) {
2531 MonoReflectionMethodAux *method_aux =
2532 g_hash_table_lookup (
2533 ((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
2535 import = method_aux->dllentry;
2536 scope = method_aux->dll;
2540 if (piinfo->implmap_idx) {
2541 mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
2543 piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
2544 import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
2545 scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
2546 scope = mono_metadata_string_heap (image, scope_token);
2549 flags = piinfo->piflags;
2551 attr = (MonoReflectionDllImportAttribute*)mono_object_new (domain, DllImportAttributeClass);
2553 MONO_OBJECT_SETREF (attr, dll, mono_string_new (domain, scope));
2554 MONO_OBJECT_SETREF (attr, entry_point, mono_string_new (domain, import));
2555 attr->call_conv = (flags & 0x700) >> 8;
2556 attr->charset = ((flags & 0x6) >> 1) + 1;
2557 if (attr->charset == 1)
2559 attr->exact_spelling = (flags & 0x1) != 0;
2560 attr->set_last_error = (flags & 0x40) != 0;
2561 attr->best_fit_mapping = (flags & 0x30) == 0x10;
2562 attr->throw_on_unmappable = (flags & 0x3000) == 0x1000;
2563 attr->preserve_sig = FALSE;
2568 static MonoReflectionMethod *
2569 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
2571 MonoGenericContext *context;
2572 MonoMethodInflated *imethod;
2574 MONO_ARCH_SAVE_REGS;
2576 if (!method->method->is_inflated) {
2577 if (mono_method_signature (method->method)->generic_param_count)
2583 imethod = (MonoMethodInflated *) method->method;
2585 /* FIXME: should reflection_info be part of imethod? */
2586 context = mono_method_get_context (method->method);
2587 if (context->gmethod && context->gmethod->reflection_info)
2588 return context->gmethod->reflection_info;
2590 return mono_method_get_object (
2591 mono_object_domain (method), imethod->declaring, NULL);
2595 ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethod *method)
2597 MONO_ARCH_SAVE_REGS;
2599 return mono_method_signature (method->method)->generic_param_count != 0;
2603 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method)
2605 MONO_ARCH_SAVE_REGS;
2607 return !method->method->is_inflated &&
2608 (mono_method_signature (method->method)->generic_param_count != 0);
2612 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
2617 MONO_ARCH_SAVE_REGS;
2619 domain = mono_object_domain (method);
2621 if (method->method->is_inflated) {
2622 MonoGenericMethod *gmethod = mono_method_get_context (method->method)->gmethod;
2625 count = gmethod->inst->type_argc;
2626 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2628 for (i = 0; i < count; i++)
2629 mono_array_setref (res, i, mono_type_get_object (domain, gmethod->inst->type_argv [i]));
2635 count = mono_method_signature (method->method)->generic_param_count;
2636 res = mono_array_new (domain, mono_defaults.monotype_class, count);
2638 for (i = 0; i < count; i++) {
2639 MonoGenericParam *param = &method->method->generic_container->type_params [i];
2640 MonoClass *pklass = mono_class_from_generic_parameter (
2641 param, method->method->klass->image, TRUE);
2642 mono_array_setref (res, i,
2643 mono_type_get_object (domain, &pklass->byval_arg));
2650 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this, MonoArray *params)
2653 * Invoke from reflection is supposed to always be a virtual call (the API
2654 * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
2655 * greater flexibility.
2657 MonoMethod *m = mono_get_inflated_method (method->method);
2661 MONO_ARCH_SAVE_REGS;
2663 if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
2665 if (!mono_object_isinst (this, m->klass))
2666 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
2667 m = mono_object_get_virtual_method (this, m);
2668 /* must pass the pointer to the value for valuetype methods */
2669 if (m->klass->valuetype)
2670 obj = mono_object_unbox (this);
2671 } else if (strcmp (m->name, ".ctor") && !m->wrapper_type)
2672 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetException"));
2675 pcount = params? mono_array_length (params): 0;
2676 if (pcount != mono_method_signature (m)->param_count)
2677 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
2679 if ((m->klass->flags & TYPE_ATTRIBUTE_ABSTRACT) && !strcmp (m->name, ".ctor"))
2680 mono_raise_exception (mono_exception_from_name_msg (mono_defaults.corlib, "System", "MethodAccessException", "Cannot invoke constructor of an abstract class."));
2682 if (m->klass->image->assembly->ref_only)
2683 mono_raise_exception (mono_get_exception_invalid_operation ("It is illegal to invoke a method on a type loaded using the ReflectionOnly api."));
2685 if (m->klass->rank && !strcmp (m->name, ".ctor")) {
2688 guint32 *lower_bounds;
2689 pcount = mono_array_length (params);
2690 lengths = alloca (sizeof (guint32) * pcount);
2691 for (i = 0; i < pcount; ++i)
2692 lengths [i] = *(gint32*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
2694 if (m->klass->rank == pcount) {
2695 /* Only lengths provided. */
2696 lower_bounds = NULL;
2698 g_assert (pcount == (m->klass->rank * 2));
2699 /* lower bounds are first. */
2700 lower_bounds = lengths;
2701 lengths += m->klass->rank;
2704 return (MonoObject*)mono_array_new_full (mono_object_domain (params), m->klass, lengths, lower_bounds);
2706 return mono_runtime_invoke_array (m, obj, params, NULL);
2710 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this, MonoArray *params, MonoArray **outArgs)
2712 MonoDomain *domain = mono_object_domain (method);
2713 MonoMethod *m = method->method;
2714 MonoMethodSignature *sig = mono_method_signature (m);
2715 MonoArray *out_args;
2717 int i, j, outarg_count = 0;
2719 MONO_ARCH_SAVE_REGS;
2721 if (m->klass == mono_defaults.object_class) {
2723 if (!strcmp (m->name, "FieldGetter")) {
2724 MonoClass *k = this->vtable->klass;
2728 /* If this is a proxy, then it must be a CBO */
2729 if (k == mono_defaults.transparent_proxy_class) {
2730 MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
2731 this = tp->rp->unwrapped_server;
2733 k = this->vtable->klass;
2736 name = mono_array_get (params, MonoString *, 1);
2737 str = mono_string_to_utf8 (name);
2740 MonoClassField* field = mono_class_get_field_from_name (k, str);
2742 MonoClass *field_klass = mono_class_from_mono_type (field->type);
2743 if (field_klass->valuetype)
2744 result = mono_value_box (domain, field_klass, (char *)this + field->offset);
2746 result = *((gpointer *)((char *)this + field->offset));
2748 out_args = mono_array_new (domain, mono_defaults.object_class, 1);
2749 *outArgs = out_args;
2750 mono_array_setref (out_args, 0, result);
2758 g_assert_not_reached ();
2760 } else if (!strcmp (m->name, "FieldSetter")) {
2761 MonoClass *k = this->vtable->klass;
2767 /* If this is a proxy, then it must be a CBO */
2768 if (k == mono_defaults.transparent_proxy_class) {
2769 MonoTransparentProxy *tp = (MonoTransparentProxy*) this;
2770 this = tp->rp->unwrapped_server;
2772 k = this->vtable->klass;
2775 name = mono_array_get (params, MonoString *, 1);
2776 str = mono_string_to_utf8 (name);
2779 MonoClassField* field = mono_class_get_field_from_name (k, str);
2781 MonoClass *field_klass = mono_class_from_mono_type (field->type);
2782 MonoObject *val = mono_array_get (params, gpointer, 2);
2784 if (field_klass->valuetype) {
2785 size = mono_type_size (field->type, &align);
2786 memcpy ((char *)this + field->offset,
2787 ((char *)val) + sizeof (MonoObject), size);
2789 *(MonoObject**)((char *)this + field->offset) = val;
2791 out_args = mono_array_new (domain, mono_defaults.object_class, 0);
2792 *outArgs = out_args;
2802 g_assert_not_reached ();
2807 for (i = 0; i < mono_array_length (params); i++) {
2808 if (sig->params [i]->byref)
2812 out_args = mono_array_new (domain, mono_defaults.object_class, outarg_count);
2814 /* handle constructors only for objects already allocated */
2815 if (!strcmp (method->method->name, ".ctor"))
2818 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
2819 g_assert (!method->method->klass->valuetype);
2820 result = mono_runtime_invoke_array (method->method, this, params, NULL);
2822 for (i = 0, j = 0; i < mono_array_length (params); i++) {
2823 if (sig->params [i]->byref) {
2825 arg = mono_array_get (params, gpointer, i);
2826 mono_array_setref (out_args, j, arg);
2831 *outArgs = out_args;
2837 read_enum_value (char *mem, int type)
2841 return *(guint8*)mem;
2843 return *(gint8*)mem;
2845 return *(guint16*)mem;
2847 return *(gint16*)mem;
2849 return *(guint32*)mem;
2851 return *(gint32*)mem;
2853 return *(guint64*)mem;
2855 return *(gint64*)mem;
2857 g_assert_not_reached ();
2863 write_enum_value (char *mem, int type, guint64 value)
2867 case MONO_TYPE_I1: {
2868 guint8 *p = (guint8*)mem;
2873 case MONO_TYPE_I2: {
2874 guint16 *p = (void*)mem;
2879 case MONO_TYPE_I4: {
2880 guint32 *p = (void*)mem;
2885 case MONO_TYPE_I8: {
2886 guint64 *p = (void*)mem;
2891 g_assert_not_reached ();
2897 ves_icall_System_Enum_ToObject (MonoReflectionType *type, MonoObject *obj)
2900 MonoClass *enumc, *objc;
2904 MONO_ARCH_SAVE_REGS;
2906 MONO_CHECK_ARG_NULL (type);
2907 MONO_CHECK_ARG_NULL (obj);
2909 domain = mono_object_domain (type);
2910 enumc = mono_class_from_mono_type (type->type);
2911 objc = obj->vtable->klass;
2913 if (!enumc->enumtype)
2914 mono_raise_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
2915 if (!((objc->enumtype) || (objc->byval_arg.type >= MONO_TYPE_I1 && objc->byval_arg.type <= MONO_TYPE_U8)))
2916 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."));
2918 res = mono_object_new (domain, enumc);
2919 val = read_enum_value ((char *)obj + sizeof (MonoObject), objc->enumtype? objc->enum_basetype->type: objc->byval_arg.type);
2920 write_enum_value ((char *)res + sizeof (MonoObject), enumc->enum_basetype->type, val);
2926 ves_icall_System_Enum_get_value (MonoObject *this)
2934 MONO_ARCH_SAVE_REGS;
2939 g_assert (this->vtable->klass->enumtype);
2941 enumc = mono_class_from_mono_type (this->vtable->klass->enum_basetype);
2942 res = mono_object_new (mono_object_domain (this), enumc);
2943 dst = (char *)res + sizeof (MonoObject);
2944 src = (char *)this + sizeof (MonoObject);
2945 size = mono_class_value_size (enumc, NULL);
2947 memcpy (dst, src, size);
2953 ves_icall_get_enum_info (MonoReflectionType *type, MonoEnumInfo *info)
2955 MonoDomain *domain = mono_object_domain (type);
2956 MonoClass *enumc = mono_class_from_mono_type (type->type);
2957 guint j = 0, nvalues, crow;
2959 MonoClassField *field;
2961 MONO_ARCH_SAVE_REGS;
2963 info->utype = mono_type_get_object (domain, enumc->enum_basetype);
2964 nvalues = mono_class_num_fields (enumc) ? mono_class_num_fields (enumc) - 1 : 0;
2965 info->names = mono_array_new (domain, mono_defaults.string_class, nvalues);
2966 info->values = mono_array_new (domain, enumc, nvalues);
2970 while ((field = mono_class_get_fields (enumc, &iter))) {
2974 if (strcmp ("value__", field->name) == 0)
2976 if (mono_field_is_deleted (field))
2978 mono_array_setref (info->names, j, mono_string_new (domain, field->name));
2981 crow = mono_metadata_get_constant_index (enumc->image, mono_class_get_field_token (field), crow + 1);
2982 field->def_type = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_TYPE);
2983 crow = mono_metadata_decode_row_col (&enumc->image->tables [MONO_TABLE_CONSTANT], crow-1, MONO_CONSTANT_VALUE);
2984 field->data = (gpointer)mono_metadata_blob_heap (enumc->image, crow);
2988 len = mono_metadata_decode_blob_size (p, &p);
2989 switch (enumc->enum_basetype->type) {
2992 mono_array_set (info->values, gchar, j, *p);
2994 case MONO_TYPE_CHAR:
2997 mono_array_set (info->values, gint16, j, read16 (p));
3001 mono_array_set (info->values, gint32, j, read32 (p));
3005 mono_array_set (info->values, gint64, j, read64 (p));
3008 g_error ("Implement type 0x%02x in get_enum_info", enumc->enum_basetype->type);
3015 BFLAGS_IgnoreCase = 1,
3016 BFLAGS_DeclaredOnly = 2,
3017 BFLAGS_Instance = 4,
3019 BFLAGS_Public = 0x10,
3020 BFLAGS_NonPublic = 0x20,
3021 BFLAGS_FlattenHierarchy = 0x40,
3022 BFLAGS_InvokeMethod = 0x100,
3023 BFLAGS_CreateInstance = 0x200,
3024 BFLAGS_GetField = 0x400,
3025 BFLAGS_SetField = 0x800,
3026 BFLAGS_GetProperty = 0x1000,
3027 BFLAGS_SetProperty = 0x2000,
3028 BFLAGS_ExactBinding = 0x10000,
3029 BFLAGS_SuppressChangeType = 0x20000,
3030 BFLAGS_OptionalParamBinding = 0x40000
3033 static MonoReflectionField *
3034 ves_icall_Type_GetField (MonoReflectionType *type, MonoString *name, guint32 bflags)
3037 MonoClass *startklass, *klass;
3039 MonoClassField *field;
3042 int (*compare_func) (const char *s1, const char *s2) = NULL;
3043 domain = ((MonoObject *)type)->vtable->domain;
3044 klass = startklass = mono_class_from_mono_type (type->type);
3046 MONO_ARCH_SAVE_REGS;
3049 mono_raise_exception (mono_get_exception_argument_null ("name"));
3050 if (type->type->byref)
3053 compare_func = (bflags & BFLAGS_IgnoreCase) ? g_strcasecmp : strcmp;
3057 while ((field = mono_class_get_fields (klass, &iter))) {
3059 if (mono_field_is_deleted (field))
3061 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3062 if (bflags & BFLAGS_Public)
3065 if (bflags & BFLAGS_NonPublic)
3071 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
3072 if (bflags & BFLAGS_Static)
3073 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3076 if (bflags & BFLAGS_Instance)
3083 utf8_name = mono_string_to_utf8 (name);
3085 if (compare_func (field->name, utf8_name)) {
3091 return mono_field_get_object (domain, klass, field);
3093 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3100 ves_icall_Type_GetFields_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3103 MonoClass *startklass, *klass, *refklass;
3108 MonoClassField *field;
3110 MONO_ARCH_SAVE_REGS;
3112 domain = ((MonoObject *)type)->vtable->domain;
3113 if (type->type->byref)
3114 return mono_array_new (domain, mono_defaults.field_info_class, 0);
3115 klass = startklass = mono_class_from_mono_type (type->type);
3116 refklass = mono_class_from_mono_type (reftype->type);
3120 res = mono_array_new (domain, mono_defaults.field_info_class, len);
3123 while ((field = mono_class_get_fields (klass, &iter))) {
3125 if (mono_field_is_deleted (field))
3127 if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3128 if (bflags & BFLAGS_Public)
3131 if (bflags & BFLAGS_NonPublic) {
3132 /* Serialization currently depends on the old behavior.
3133 * if ((field->type->attrs & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE || startklass == klass)*/
3140 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
3141 if (bflags & BFLAGS_Static)
3142 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3145 if (bflags & BFLAGS_Instance)
3151 member = (MonoObject*)mono_field_get_object (domain, refklass, field);
3153 MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, len * 2);
3154 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3158 mono_array_setref (res, i, member);
3161 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3164 MonoArray *new_res = mono_array_new (domain, mono_defaults.field_info_class, i);
3165 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3168 * Better solution for the new GC.
3169 * res->max_length = i;
3176 ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
3179 MonoClass *startklass, *klass, *refklass;
3184 int i, len, match, nslots;
3185 guint32 method_slots_default [8];
3186 guint32 *method_slots;
3187 gchar *mname = NULL;
3188 int (*compare_func) (const char *s1, const char *s2) = NULL;
3190 MONO_ARCH_SAVE_REGS;
3192 domain = ((MonoObject *)type)->vtable->domain;
3193 if (type->type->byref)
3194 return mono_array_new (domain, mono_defaults.method_info_class, 0);
3195 klass = startklass = mono_class_from_mono_type (type->type);
3196 refklass = mono_class_from_mono_type (reftype->type);
3199 mname = mono_string_to_utf8 (name);
3200 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
3203 mono_class_setup_vtable (klass);
3205 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : klass->vtable_size;
3206 if (nslots >= sizeof (method_slots_default) * 8) {
3207 method_slots = g_new0 (guint32, nslots / 32 + 1);
3209 method_slots = method_slots_default;
3210 memset (method_slots, 0, sizeof (method_slots_default));
3214 res = mono_array_new (domain, mono_defaults.method_info_class, len);
3216 mono_class_setup_vtable (klass);
3218 while ((method = mono_class_get_methods (klass, &iter))) {
3220 if (method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
3222 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3223 if (bflags & BFLAGS_Public)
3226 if (bflags & BFLAGS_NonPublic)
3232 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3233 if (bflags & BFLAGS_Static)
3234 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3237 if (bflags & BFLAGS_Instance)
3245 if (compare_func (mname, method->name))
3250 if (method->slot != -1) {
3251 g_assert (method->slot < nslots);
3252 if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
3254 method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
3257 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
3260 MonoArray *new_res = mono_array_new (domain, mono_defaults.method_info_class, len * 2);
3261 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3265 mono_array_setref (res, i, member);
3268 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3272 if (method_slots != method_slots_default)
3273 g_free (method_slots);
3275 MonoArray *new_res = mono_array_new (domain, mono_defaults.method_info_class, i);
3276 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3279 * Better solution for the new GC.
3280 * res->max_length = i;
3287 ves_icall_Type_GetConstructors_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3290 static MonoClass *System_Reflection_ConstructorInfo;
3291 MonoClass *startklass, *klass, *refklass;
3296 gpointer iter = NULL;
3298 MONO_ARCH_SAVE_REGS;
3300 domain = ((MonoObject *)type)->vtable->domain;
3301 if (type->type->byref)
3302 return mono_array_new (domain, mono_defaults.method_info_class, 0);
3303 klass = startklass = mono_class_from_mono_type (type->type);
3304 refklass = mono_class_from_mono_type (reftype->type);
3306 if (!System_Reflection_ConstructorInfo)
3307 System_Reflection_ConstructorInfo = mono_class_from_name (
3308 mono_defaults.corlib, "System.Reflection", "ConstructorInfo");
3312 res = mono_array_new (domain, System_Reflection_ConstructorInfo, len);
3314 while ((method = mono_class_get_methods (klass, &iter))) {
3316 if (strcmp (method->name, ".ctor") && strcmp (method->name, ".cctor"))
3318 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3319 if (bflags & BFLAGS_Public)
3322 if (bflags & BFLAGS_NonPublic)
3328 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3329 if (bflags & BFLAGS_Static)
3330 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3333 if (bflags & BFLAGS_Instance)
3339 member = (MonoObject*)mono_method_get_object (domain, method, refklass);
3342 MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, len * 2);
3343 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3347 mono_array_setref (res, i, member);
3351 MonoArray *new_res = mono_array_new (domain, System_Reflection_ConstructorInfo, i);
3352 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3355 * Better solution for the new GC.
3356 * res->max_length = i;
3363 ves_icall_Type_GetPropertiesByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
3366 static MonoClass *System_Reflection_PropertyInfo;
3367 MonoClass *startklass, *klass;
3371 int i, match, nslots;
3374 guint32 method_slots_default [8];
3375 guint32 *method_slots;
3376 gchar *propname = NULL;
3377 int (*compare_func) (const char *s1, const char *s2) = NULL;
3380 MONO_ARCH_SAVE_REGS;
3382 if (!System_Reflection_PropertyInfo)
3383 System_Reflection_PropertyInfo = mono_class_from_name (
3384 mono_defaults.corlib, "System.Reflection", "PropertyInfo");
3386 domain = ((MonoObject *)type)->vtable->domain;
3387 if (type->type->byref)
3388 return mono_array_new (domain, System_Reflection_PropertyInfo, 0);
3389 klass = startklass = mono_class_from_mono_type (type->type);
3391 propname = mono_string_to_utf8 (name);
3392 compare_func = (ignore_case) ? g_strcasecmp : strcmp;
3395 mono_class_setup_vtable (klass);
3397 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : klass->vtable_size;
3398 if (nslots >= sizeof (method_slots_default) * 8) {
3399 method_slots = g_new0 (guint32, nslots / 32 + 1);
3401 method_slots = method_slots_default;
3402 memset (method_slots, 0, sizeof (method_slots_default));
3406 res = mono_array_new (domain, System_Reflection_PropertyInfo, len);
3408 mono_class_setup_vtable (klass);
3410 while ((prop = mono_class_get_properties (klass, &iter))) {
3416 flags = method->flags;
3419 if ((prop->get && ((prop->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC)) ||
3420 (prop->set && ((prop->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC))) {
3421 if (bflags & BFLAGS_Public)
3424 if (bflags & BFLAGS_NonPublic)
3430 if (flags & METHOD_ATTRIBUTE_STATIC) {
3431 if (bflags & BFLAGS_Static)
3432 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3435 if (bflags & BFLAGS_Instance)
3444 if (compare_func (propname, prop->name))
3448 if (prop->get && prop->get->slot != -1) {
3449 if (method_slots [prop->get->slot >> 5] & (1 << (prop->get->slot & 0x1f)))
3451 method_slots [prop->get->slot >> 5] |= 1 << (prop->get->slot & 0x1f);
3453 if (prop->set && prop->set->slot != -1) {
3454 if (method_slots [prop->set->slot >> 5] & (1 << (prop->set->slot & 0x1f)))
3456 method_slots [prop->set->slot >> 5] |= 1 << (prop->set->slot & 0x1f);
3460 MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, len * 2);
3461 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3465 mono_array_setref (res, i, mono_property_get_object (domain, startklass, prop));
3468 if ((!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent)))
3472 if (method_slots != method_slots_default)
3473 g_free (method_slots);
3475 MonoArray *new_res = mono_array_new (domain, System_Reflection_PropertyInfo, i);
3476 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3479 * Better solution for the new GC.
3480 * res->max_length = i;
3486 static MonoReflectionEvent *
3487 ves_icall_MonoType_GetEvent (MonoReflectionType *type, MonoString *name, guint32 bflags)
3490 MonoClass *klass, *startklass;
3496 MONO_ARCH_SAVE_REGS;
3498 event_name = mono_string_to_utf8 (name);
3499 if (type->type->byref)
3501 klass = startklass = mono_class_from_mono_type (type->type);
3502 domain = mono_object_domain (type);
3506 while ((event = mono_class_get_events (klass, &iter))) {
3507 if (strcmp (event->name, event_name))
3510 method = event->add;
3512 method = event->remove;
3514 method = event->raise;
3516 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3517 if (!(bflags & BFLAGS_Public))
3520 if (!(bflags & BFLAGS_NonPublic))
3525 if (!(bflags & BFLAGS_NonPublic))
3528 g_free (event_name);
3529 return mono_event_get_object (domain, startklass, event);
3532 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3535 g_free (event_name);
3540 ves_icall_Type_GetEvents_internal (MonoReflectionType *type, guint32 bflags, MonoReflectionType *reftype)
3543 static MonoClass *System_Reflection_EventInfo;
3544 MonoClass *startklass, *klass;
3551 MONO_ARCH_SAVE_REGS;
3553 if (!System_Reflection_EventInfo)
3554 System_Reflection_EventInfo = mono_class_from_name (
3555 mono_defaults.corlib, "System.Reflection", "EventInfo");
3557 domain = mono_object_domain (type);
3558 if (type->type->byref)
3559 return mono_array_new (domain, System_Reflection_EventInfo, 0);
3560 klass = startklass = mono_class_from_mono_type (type->type);
3564 res = mono_array_new (domain, System_Reflection_EventInfo, len);
3567 while ((event = mono_class_get_events (klass, &iter))) {
3569 method = event->add;
3571 method = event->remove;
3573 method = event->raise;
3575 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3576 if (bflags & BFLAGS_Public)
3579 if (bflags & BFLAGS_NonPublic)
3584 if (bflags & BFLAGS_NonPublic)
3590 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3591 if (bflags & BFLAGS_Static)
3592 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3595 if (bflags & BFLAGS_Instance)
3600 if (bflags & BFLAGS_Instance)
3606 MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, len * 2);
3607 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3611 mono_array_setref (res, i, mono_event_get_object (domain, startklass, event));
3614 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3617 MonoArray *new_res = mono_array_new (domain, System_Reflection_EventInfo, i);
3618 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3621 * Better solution for the new GC.
3622 * res->max_length = i;
3628 static MonoReflectionType *
3629 ves_icall_Type_GetNestedType (MonoReflectionType *type, MonoString *name, guint32 bflags)
3637 MONO_ARCH_SAVE_REGS;
3639 domain = ((MonoObject *)type)->vtable->domain;
3640 if (type->type->byref)
3642 klass = mono_class_from_mono_type (type->type);
3643 str = mono_string_to_utf8 (name);
3647 * If a nested type is generic, return its generic type definition.
3648 * Note that this means that the return value is essentially a
3649 * nested type of the generic type definition of @klass.
3651 * A note in MSDN claims that a generic type definition can have
3652 * nested types that aren't generic. In any case, the container of that
3653 * nested type would be the generic type definition.
3655 if (klass->generic_class)
3656 klass = klass->generic_class->container_class;
3658 for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
3660 nested = tmpn->data;
3661 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
3662 if (bflags & BFLAGS_Public)
3665 if (bflags & BFLAGS_NonPublic)
3670 if (strcmp (nested->name, str) == 0){
3672 return mono_type_get_object (domain, &nested->byval_arg);
3675 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3682 ves_icall_Type_GetNestedTypes (MonoReflectionType *type, guint32 bflags)
3692 MONO_ARCH_SAVE_REGS;
3694 domain = ((MonoObject *)type)->vtable->domain;
3695 if (type->type->byref)
3696 return mono_array_new (domain, mono_defaults.monotype_class, 0);
3697 klass = mono_class_from_mono_type (type->type);
3700 * If a nested type is generic, return its generic type definition.
3701 * Note that this means that the return value is essentially the set
3702 * of nested types of the generic type definition of @klass.
3704 * A note in MSDN claims that a generic type definition can have
3705 * nested types that aren't generic. In any case, the container of that
3706 * nested type would be the generic type definition.
3708 if (klass->generic_class)
3709 klass = klass->generic_class->container_class;
3713 res = mono_array_new (domain, mono_defaults.monotype_class, len);
3714 for (tmpn = klass->nested_classes; tmpn; tmpn = tmpn->next) {
3716 nested = tmpn->data;
3717 if ((nested->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
3718 if (bflags & BFLAGS_Public)
3721 if (bflags & BFLAGS_NonPublic)
3726 member = (MonoObject*)mono_type_get_object (domain, &nested->byval_arg);
3728 MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, len * 2);
3729 mono_array_memcpy_refs (new_res, 0, res, 0, len);
3733 mono_array_setref (res, i, member);
3737 MonoArray *new_res = mono_array_new (domain, mono_defaults.monotype_class, i);
3738 mono_array_memcpy_refs (new_res, 0, res, 0, i);
3741 * Better solution for the new GC.
3742 * res->max_length = i;
3748 static MonoReflectionType*
3749 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *assembly, MonoReflectionModule *module, MonoString *name, MonoBoolean throwOnError, MonoBoolean ignoreCase)
3752 MonoType *type = NULL;
3753 MonoTypeNameParse info;
3754 gboolean type_resolve;
3756 MONO_ARCH_SAVE_REGS;
3758 /* On MS.NET, this does not fire a TypeResolve event */
3759 type_resolve = TRUE;
3760 str = mono_string_to_utf8 (name);
3761 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
3762 if (!mono_reflection_parse_type (str, &info)) {
3764 g_list_free (info.modifiers);
3765 g_list_free (info.nested);
3766 if (throwOnError) /* uhm: this is a parse error, though... */
3767 mono_raise_exception (mono_get_exception_type_load (name, NULL));
3768 /*g_print ("failed parse\n");*/
3772 if (module != NULL) {
3774 type = mono_reflection_get_type (module->image, &info, ignoreCase, &type_resolve);
3779 if (assembly->assembly->dynamic) {
3780 /* Enumerate all modules */
3781 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
3785 if (abuilder->modules) {
3786 for (i = 0; i < mono_array_length (abuilder->modules); ++i) {
3787 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
3788 type = mono_reflection_get_type (&mb->dynamic_image->image, &info, ignoreCase, &type_resolve);
3794 if (!type && abuilder->loaded_modules) {
3795 for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) {
3796 MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
3797 type = mono_reflection_get_type (mod->image, &info, ignoreCase, &type_resolve);
3804 type = mono_reflection_get_type (assembly->assembly->image, &info, ignoreCase, &type_resolve);
3806 g_list_free (info.modifiers);
3807 g_list_free (info.nested);
3809 MonoException *e = NULL;
3812 e = mono_get_exception_type_load (name, NULL);
3814 mono_loader_clear_error ();
3817 mono_raise_exception (e);
3822 if (type->type == MONO_TYPE_CLASS) {
3823 MonoClass *klass = mono_type_get_class (type);
3824 /* need to report exceptions ? */
3825 if (throwOnError && klass->exception_type) {
3826 /* report SecurityException (or others) that occured when loading the assembly */
3827 MonoException *exc = mono_class_get_exception_for_failure (klass);
3828 mono_loader_clear_error ();
3829 mono_raise_exception (exc);
3830 } else if (klass->exception_type == MONO_EXCEPTION_SECURITY_INHERITANCEDEMAND) {
3835 /* g_print ("got it\n"); */
3836 return mono_type_get_object (mono_object_domain (assembly), type);
3840 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *assembly, MonoBoolean escaped)
3842 MonoDomain *domain = mono_object_domain (assembly);
3843 MonoAssembly *mass = assembly->assembly;
3844 MonoString *res = NULL;
3848 MONO_ARCH_SAVE_REGS;
3850 if (g_path_is_absolute (mass->image->name))
3851 absolute = g_strdup (mass->image->name);
3853 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
3857 for (i = strlen (absolute) - 1; i >= 0; i--)
3858 if (absolute [i] == '\\')
3863 uri = g_filename_to_uri (absolute, NULL, NULL);
3865 uri = g_strconcat ("file://", absolute, NULL);
3869 res = mono_string_new (domain, uri);
3877 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssembly *assembly)
3879 MonoAssembly *mass = assembly->assembly;
3881 MONO_ARCH_SAVE_REGS;
3883 return mass->in_gac;
3886 static MonoReflectionAssembly*
3887 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoString *mname, MonoObject *evidence)
3891 MonoImageOpenStatus status;
3893 MONO_ARCH_SAVE_REGS;
3895 name = mono_string_to_utf8 (mname);
3896 res = mono_assembly_load_with_partial_name (name, &status);
3902 return mono_assembly_get_object (mono_domain_get (), res);
3906 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssembly *assembly)
3908 MonoDomain *domain = mono_object_domain (assembly);
3911 MONO_ARCH_SAVE_REGS;
3913 res = mono_string_new (domain, mono_image_get_filename (assembly->assembly->image));
3919 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssembly *assembly)
3921 MONO_ARCH_SAVE_REGS;
3923 return assembly->assembly->ref_only;
3927 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssembly *assembly)
3929 MonoDomain *domain = mono_object_domain (assembly);
3931 MONO_ARCH_SAVE_REGS;
3933 return mono_string_new (domain, assembly->assembly->image->version);
3936 static MonoReflectionMethod*
3937 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssembly *assembly)
3939 guint32 token = mono_image_get_entry_point (assembly->assembly->image);
3941 MONO_ARCH_SAVE_REGS;
3945 return mono_method_get_object (mono_object_domain (assembly), mono_get_method (assembly->assembly->image, token, NULL), NULL);
3948 static MonoReflectionModule*
3949 ves_icall_System_Reflection_Assembly_get_ManifestModule (MonoReflectionAssembly *assembly)
3951 return mono_module_get_object (mono_object_domain (assembly), assembly->assembly->image);
3955 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssembly *assembly)
3957 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
3958 MonoArray *result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, table->rows);
3962 MONO_ARCH_SAVE_REGS;
3964 for (i = 0; i < table->rows; ++i) {
3965 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_MANIFEST_NAME));
3966 mono_array_setref (result, i, mono_string_new (mono_object_domain (assembly), val));
3972 create_version (MonoDomain *domain, guint32 major, guint32 minor, guint32 build, guint32 revision)
3974 static MonoClass *System_Version = NULL;
3975 static MonoMethod *create_version = NULL;
3979 if (!System_Version) {
3980 System_Version = mono_class_from_name (mono_defaults.corlib, "System", "Version");
3981 g_assert (System_Version);
3984 if (!create_version) {
3985 MonoMethodDesc *desc = mono_method_desc_new (":.ctor(int,int,int,int)", FALSE);
3986 create_version = mono_method_desc_search_in_class (desc, System_Version);
3987 g_assert (create_version);
3988 mono_method_desc_free (desc);
3994 args [3] = &revision;
3995 result = mono_object_new (domain, System_Version);
3996 mono_runtime_invoke (create_version, result, args, NULL);
4002 ves_icall_System_Reflection_Assembly_GetReferencedAssemblies (MonoReflectionAssembly *assembly)
4004 static MonoClass *System_Reflection_AssemblyName;
4006 MonoDomain *domain = mono_object_domain (assembly);
4008 static MonoMethod *create_culture = NULL;
4009 MonoImage *image = assembly->assembly->image;
4012 MONO_ARCH_SAVE_REGS;
4014 if (!System_Reflection_AssemblyName)
4015 System_Reflection_AssemblyName = mono_class_from_name (
4016 mono_defaults.corlib, "System.Reflection", "AssemblyName");
4018 t = &assembly->assembly->image->tables [MONO_TABLE_ASSEMBLYREF];
4021 result = mono_array_new (domain, System_Reflection_AssemblyName, count);
4024 MonoMethodDesc *desc = mono_method_desc_new (
4025 "System.Globalization.CultureInfo:CreateSpecificCulture(string)", TRUE);
4026 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4027 g_assert (create_culture);
4028 mono_method_desc_free (desc);
4031 for (i = 0; i < count; i++) {
4032 MonoReflectionAssemblyName *aname;
4033 guint32 cols [MONO_ASSEMBLYREF_SIZE];
4035 mono_metadata_decode_row (t, i, cols, MONO_ASSEMBLYREF_SIZE);
4037 aname = (MonoReflectionAssemblyName *) mono_object_new (
4038 domain, System_Reflection_AssemblyName);
4040 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_NAME])));
4042 aname->major = cols [MONO_ASSEMBLYREF_MAJOR_VERSION];
4043 aname->minor = cols [MONO_ASSEMBLYREF_MINOR_VERSION];
4044 aname->build = cols [MONO_ASSEMBLYREF_BUILD_NUMBER];
4045 aname->revision = cols [MONO_ASSEMBLYREF_REV_NUMBER];
4046 aname->flags = cols [MONO_ASSEMBLYREF_FLAGS];
4047 aname->versioncompat = 1; /* SameMachine (default) */
4048 aname->hashalg = ASSEMBLY_HASH_SHA1; /* SHA1 (default) */
4049 MONO_OBJECT_SETREF (aname, version, create_version (domain, aname->major, aname->minor, aname->build, aname->revision));
4051 if (create_culture) {
4053 args [0] = mono_string_new (domain, mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_CULTURE]));
4054 MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
4057 if (cols [MONO_ASSEMBLYREF_PUBLIC_KEY]) {
4058 const gchar *pkey_ptr = mono_metadata_blob_heap (image, cols [MONO_ASSEMBLYREF_PUBLIC_KEY]);
4059 guint32 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
4061 if ((cols [MONO_ASSEMBLYREF_FLAGS] & ASSEMBLYREF_FULL_PUBLIC_KEY_FLAG)) {
4062 /* public key token isn't copied - the class library will
4063 automatically generate it from the public key if required */
4064 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4065 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
4067 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4068 memcpy (mono_array_addr (aname->keyToken, guint8, 0), pkey_ptr, pkey_len);
4072 /* note: this function doesn't return the codebase on purpose (i.e. it can
4073 be used under partial trust as path information isn't present). */
4075 mono_array_setref (result, i, aname);
4086 foreach_namespace (const char* key, gconstpointer val, NameSpaceInfo *info)
4088 MonoString *name = mono_string_new (mono_object_domain (info->res), key);
4090 mono_array_setref (info->res, info->idx, name);
4095 ves_icall_System_Reflection_Assembly_GetNamespaces (MonoReflectionAssembly *assembly)
4097 MonoImage *img = assembly->assembly->image;
4101 MONO_ARCH_SAVE_REGS;
4103 if (!img->name_cache)
4104 mono_image_init_name_cache (img);
4106 res = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, g_hash_table_size (img->name_cache));
4109 g_hash_table_foreach (img->name_cache, (GHFunc)foreach_namespace, &info);
4114 /* move this in some file in mono/util/ */
4116 g_concat_dir_and_file (const char *dir, const char *file)
4118 g_return_val_if_fail (dir != NULL, NULL);
4119 g_return_val_if_fail (file != NULL, NULL);
4122 * If the directory name doesn't have a / on the end, we need
4123 * to add one so we get a proper path to the file
4125 if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
4126 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
4128 return g_strconcat (dir, file, NULL);
4132 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssembly *assembly, MonoString *name, gint32 *size, MonoReflectionModule **ref_module)
4134 char *n = mono_string_to_utf8 (name);
4135 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4137 guint32 cols [MONO_MANIFEST_SIZE];
4138 guint32 impl, file_idx;
4142 MONO_ARCH_SAVE_REGS;
4144 for (i = 0; i < table->rows; ++i) {
4145 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4146 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4147 if (strcmp (val, n) == 0)
4151 if (i == table->rows)
4154 impl = cols [MONO_MANIFEST_IMPLEMENTATION];
4157 * this code should only be called after obtaining the
4158 * ResourceInfo and handling the other cases.
4160 g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
4161 file_idx = impl >> MONO_IMPLEMENTATION_BITS;
4163 module = mono_image_load_file_for_image (assembly->assembly->image, file_idx);
4168 module = assembly->assembly->image;
4170 *ref_module = mono_module_get_object (mono_domain_get (), module);
4172 return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
4176 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoManifestResourceInfo *info)
4178 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4180 guint32 cols [MONO_MANIFEST_SIZE];
4181 guint32 file_cols [MONO_FILE_SIZE];
4185 MONO_ARCH_SAVE_REGS;
4187 n = mono_string_to_utf8 (name);
4188 for (i = 0; i < table->rows; ++i) {
4189 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4190 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4191 if (strcmp (val, n) == 0)
4195 if (i == table->rows)
4198 if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
4199 info->location = RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST;
4202 switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
4203 case MONO_IMPLEMENTATION_FILE:
4204 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4205 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4206 mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
4207 val = mono_metadata_string_heap (assembly->assembly->image, file_cols [MONO_FILE_NAME]);
4208 MONO_OBJECT_SETREF (info, filename, mono_string_new (mono_object_domain (assembly), val));
4209 if (file_cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA)
4212 info->location = RESOURCE_LOCATION_EMBEDDED;
4215 case MONO_IMPLEMENTATION_ASSEMBLYREF:
4216 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4217 mono_assembly_load_reference (assembly->assembly->image, i - 1);
4218 if (assembly->assembly->image->references [i - 1] == (gpointer)-1) {
4219 char *msg = g_strdup_printf ("Assembly %d referenced from assembly %s not found ", i - 1, assembly->assembly->image->name);
4220 MonoException *ex = mono_get_exception_file_not_found2 (msg, NULL);
4222 mono_raise_exception (ex);
4224 MONO_OBJECT_SETREF (info, assembly, mono_assembly_get_object (mono_domain_get (), assembly->assembly->image->references [i - 1]));
4226 /* Obtain info recursively */
4227 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (info->assembly, name, info);
4228 info->location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
4231 case MONO_IMPLEMENTATION_EXP_TYPE:
4232 g_assert_not_reached ();
4241 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoBoolean resource_modules)
4243 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4244 MonoArray *result = NULL;
4249 MONO_ARCH_SAVE_REGS;
4251 /* check hash if needed */
4253 n = mono_string_to_utf8 (name);
4254 for (i = 0; i < table->rows; ++i) {
4255 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4256 if (strcmp (val, n) == 0) {
4259 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4260 fn = mono_string_new (mono_object_domain (assembly), n);
4262 return (MonoObject*)fn;
4270 for (i = 0; i < table->rows; ++i) {
4271 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA))
4275 result = mono_array_new (mono_object_domain (assembly), mono_defaults.string_class, count);
4278 for (i = 0; i < table->rows; ++i) {
4279 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4280 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4281 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4282 mono_array_setref (result, count, mono_string_new (mono_object_domain (assembly), n));
4287 return (MonoObject*)result;
4291 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly *assembly)
4293 MonoDomain *domain = mono_domain_get();
4296 int i, j, file_count = 0;
4297 MonoImage **modules;
4298 guint32 module_count, real_module_count;
4299 MonoTableInfo *table;
4301 g_assert (assembly->assembly->image != NULL);
4303 if (assembly->assembly->dynamic) {
4304 MonoReflectionAssemblyBuilder *assemblyb = (MonoReflectionAssemblyBuilder*)assembly;
4306 if (assemblyb->modules)
4307 module_count = mono_array_length (assemblyb->modules);
4310 real_module_count = module_count;
4312 modules = g_new0 (MonoImage*, module_count);
4313 if (assemblyb->modules) {
4314 for (i = 0; i < mono_array_length (assemblyb->modules); ++i) {
4316 mono_array_get (assemblyb->modules, MonoReflectionModuleBuilder*, i)->module.image;
4321 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4322 file_count = table->rows;
4324 modules = assembly->assembly->image->modules;
4325 module_count = assembly->assembly->image->module_count;
4327 real_module_count = 0;
4328 for (i = 0; i < module_count; ++i)
4330 real_module_count ++;
4333 klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "Module");
4334 res = mono_array_new (domain, klass, 1 + real_module_count + file_count);
4336 mono_array_setref (res, 0, mono_module_get_object (domain, assembly->assembly->image));
4338 for (i = 0; i < module_count; ++i)
4340 mono_array_setref (res, j, mono_module_get_object (domain, modules[i]));
4344 for (i = 0; i < file_count; ++i, ++j)
4345 mono_array_setref (res, j, mono_module_file_get_object (domain, assembly->assembly->image, i));
4347 if (assembly->assembly->dynamic)
4353 static MonoReflectionMethod*
4354 ves_icall_GetCurrentMethod (void)
4356 MonoMethod *m = mono_method_get_last_managed ();
4358 MONO_ARCH_SAVE_REGS;
4360 return mono_method_get_object (mono_domain_get (), m, NULL);
4363 static MonoReflectionMethod*
4364 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternal (MonoMethod *method)
4366 return mono_method_get_object (mono_domain_get (), method, NULL);
4369 static MonoReflectionMethodBody*
4370 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod *method)
4372 return mono_method_body_get_object (mono_domain_get (), method);
4375 static MonoReflectionAssembly*
4376 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (void)
4378 MonoMethod *m = mono_method_get_last_managed ();
4380 MONO_ARCH_SAVE_REGS;
4382 return mono_assembly_get_object (mono_domain_get (), m->klass->image->assembly);
4386 static MonoReflectionAssembly*
4387 ves_icall_System_Reflection_Assembly_GetEntryAssembly (void)
4389 MonoDomain* domain = mono_domain_get ();
4391 MONO_ARCH_SAVE_REGS;
4393 if (!domain->entry_assembly)
4396 return mono_assembly_get_object (domain, domain->entry_assembly);
4399 static MonoReflectionAssembly*
4400 ves_icall_System_Reflection_Assembly_GetCallingAssembly (void)
4402 MonoMethod *m = mono_method_get_last_managed ();
4403 MonoMethod *dest = m;
4405 MONO_ARCH_SAVE_REGS;
4407 mono_stack_walk_no_il (get_caller, &dest);
4410 return mono_assembly_get_object (mono_domain_get (), dest->klass->image->assembly);
4414 ves_icall_System_MonoType_getFullName (MonoReflectionType *object, gboolean full_name,
4415 gboolean assembly_qualified)
4417 MonoDomain *domain = mono_object_domain (object);
4418 MonoTypeNameFormat format;
4422 MONO_ARCH_SAVE_REGS;
4424 format = assembly_qualified ?
4425 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
4426 MONO_TYPE_NAME_FORMAT_FULL_NAME;
4428 format = MONO_TYPE_NAME_FORMAT_REFLECTION;
4430 name = mono_type_get_name_full (object->type, format);
4434 if (full_name && (object->type->type == MONO_TYPE_VAR || object->type->type == MONO_TYPE_MVAR))
4437 res = mono_string_new (domain, name);
4444 fill_reflection_assembly_name (MonoDomain *domain, MonoReflectionAssemblyName *aname, MonoAssemblyName *name, const char *absolute, gboolean by_default_version)
4446 static MonoMethod *create_culture = NULL;
4449 const char *pkey_ptr;
4452 MONO_ARCH_SAVE_REGS;
4454 MONO_OBJECT_SETREF (aname, name, mono_string_new (domain, name->name));
4455 aname->major = name->major;
4456 aname->minor = name->minor;
4457 aname->build = name->build;
4458 aname->revision = name->revision;
4459 aname->hashalg = name->hash_alg;
4460 if (by_default_version)
4461 MONO_OBJECT_SETREF (aname, version, create_version (domain, name->major, name->minor, name->build, name->revision));
4463 codebase = g_filename_to_uri (absolute, NULL, NULL);
4465 MONO_OBJECT_SETREF (aname, codebase, mono_string_new (domain, codebase));
4469 if (!create_culture) {
4470 MonoMethodDesc *desc = mono_method_desc_new ("System.Globalization.CultureInfo:CreateSpecificCulture(string)", TRUE);
4471 create_culture = mono_method_desc_search_in_image (desc, mono_defaults.corlib);
4472 g_assert (create_culture);
4473 mono_method_desc_free (desc);
4476 if (name->culture) {
4477 args [0] = mono_string_new (domain, name->culture);
4478 MONO_OBJECT_SETREF (aname, cultureInfo, mono_runtime_invoke (create_culture, NULL, args, NULL));
4481 if (name->public_key) {
4482 pkey_ptr = (char*)name->public_key;
4483 pkey_len = mono_metadata_decode_blob_size (pkey_ptr, &pkey_ptr);
4485 MONO_OBJECT_SETREF (aname, publicKey, mono_array_new (domain, mono_defaults.byte_class, pkey_len));
4486 memcpy (mono_array_addr (aname->publicKey, guint8, 0), pkey_ptr, pkey_len);
4489 /* MonoAssemblyName keeps the public key token as an hexadecimal string */
4490 if (name->public_key_token [0]) {
4494 MONO_OBJECT_SETREF (aname, keyToken, mono_array_new (domain, mono_defaults.byte_class, 8));
4495 p = mono_array_addr (aname->keyToken, char, 0);
4497 for (i = 0, j = 0; i < 8; i++) {
4498 *p = g_ascii_xdigit_value (name->public_key_token [j++]) << 4;
4499 *p |= g_ascii_xdigit_value (name->public_key_token [j++]);
4506 ves_icall_System_Reflection_Assembly_FillName (MonoReflectionAssembly *assembly, MonoReflectionAssemblyName *aname)
4509 MonoAssembly *mass = assembly->assembly;
4511 MONO_ARCH_SAVE_REGS;
4513 if (g_path_is_absolute (mass->image->name)) {
4514 fill_reflection_assembly_name (mono_object_domain (assembly),
4515 aname, &mass->aname, mass->image->name, TRUE);
4518 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4520 fill_reflection_assembly_name (mono_object_domain (assembly),
4521 aname, &mass->aname, absolute, TRUE);
4527 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoString *fname, MonoReflectionAssemblyName *aname)
4530 MonoImageOpenStatus status = MONO_IMAGE_OK;
4533 MonoAssemblyName name;
4535 MONO_ARCH_SAVE_REGS;
4537 filename = mono_string_to_utf8 (fname);
4539 image = mono_image_open (filename, &status);
4545 if (status == MONO_IMAGE_IMAGE_INVALID)
4546 exc = mono_get_exception_bad_image_format2 (NULL, fname);
4548 exc = mono_get_exception_file_not_found2 (NULL, fname);
4549 mono_raise_exception (exc);
4552 res = mono_assembly_fill_assembly_name (image, &name);
4554 mono_image_close (image);
4556 mono_raise_exception (mono_get_exception_argument ("assemblyFile", "The file does not contain a manifest"));
4559 fill_reflection_assembly_name (mono_domain_get (), aname, &name, filename, TRUE);
4562 mono_image_close (image);
4566 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssembly *assembly,
4567 char **minimum, guint32 *minLength, char **optional, guint32 *optLength, char **refused, guint32 *refLength)
4569 MonoBoolean result = FALSE;
4570 MonoDeclSecurityEntry entry;
4572 /* SecurityAction.RequestMinimum */
4573 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQMIN, &entry)) {
4574 *minimum = entry.blob;
4575 *minLength = entry.size;
4578 /* SecurityAction.RequestOptional */
4579 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQOPT, &entry)) {
4580 *optional = entry.blob;
4581 *optLength = entry.size;
4584 /* SecurityAction.RequestRefuse */
4585 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQREFUSE, &entry)) {
4586 *refused = entry.blob;
4587 *refLength = entry.size;
4595 mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoBoolean exportedOnly)
4599 MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
4601 guint32 attrs, visibility;
4603 /* we start the count from 1 because we skip the special type <Module> */
4606 for (i = 1; i < tdef->rows; ++i) {
4607 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
4608 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
4609 if (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)
4613 count = tdef->rows - 1;
4615 res = mono_array_new (domain, mono_defaults.monotype_class, count);
4617 for (i = 1; i < tdef->rows; ++i) {
4618 attrs = mono_metadata_decode_row_col (tdef, i, MONO_TYPEDEF_FLAGS);
4619 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
4620 if (!exportedOnly || (visibility == TYPE_ATTRIBUTE_PUBLIC || visibility == TYPE_ATTRIBUTE_NESTED_PUBLIC)) {
4621 klass = mono_class_get_throw (image, (i + 1) | MONO_TOKEN_TYPE_DEF);
4622 if (mono_loader_get_last_error ())
4623 mono_loader_clear_error ();
4624 mono_array_setref (res, count, mono_type_get_object (domain, &klass->byval_arg));
4633 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly, MonoBoolean exportedOnly)
4635 MonoArray *res = NULL;
4636 MonoImage *image = NULL;
4637 MonoTableInfo *table = NULL;
4642 MONO_ARCH_SAVE_REGS;
4644 domain = mono_object_domain (assembly);
4646 if (assembly->assembly->dynamic) {
4647 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
4648 if (abuilder->modules) {
4649 for (i = 0; i < mono_array_length(abuilder->modules); i++) {
4650 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
4651 MonoArray *append = mb->types;
4652 /* The types array might not be fully filled up */
4653 if (append && mb->num_types > 0) {
4656 len1 = res ? mono_array_length (res) : 0;
4657 len2 = mb->num_types;
4658 new = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4660 mono_array_memcpy_refs (new, 0, res, 0, len1);
4661 mono_array_memcpy_refs (new, len1, append, 0, len2);
4667 * Replace TypeBuilders with the created types to be compatible
4671 for (i = 0; i < mono_array_length (res); ++i) {
4672 MonoReflectionTypeBuilder *tb = mono_array_get (res, MonoReflectionTypeBuilder*, i);
4674 mono_array_setref (res, i, tb->created);
4679 if (abuilder->loaded_modules)
4680 for (i = 0; i < mono_array_length(abuilder->loaded_modules); i++) {
4681 MonoReflectionModule *rm = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
4682 MonoArray *append = mono_module_get_types (domain, rm->image, exportedOnly);
4683 if (append && mono_array_length (append) > 0) {
4686 len1 = res ? mono_array_length (res) : 0;
4687 len2 = mono_array_length (append);
4688 new = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4690 mono_array_memcpy_refs (new, 0, res, 0, len1);
4691 mono_array_memcpy_refs (new, len1, append, 0, len2);
4698 return mono_array_new (domain, mono_defaults.monotype_class, 0);
4700 image = assembly->assembly->image;
4701 table = &image->tables [MONO_TABLE_FILE];
4702 res = mono_module_get_types (domain, image, exportedOnly);
4704 /* Append data from all modules in the assembly */
4705 for (i = 0; i < table->rows; ++i) {
4706 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4707 MonoImage *loaded_image = mono_assembly_load_module (image->assembly, i + 1);
4709 MonoArray *res2 = mono_module_get_types (domain, loaded_image, exportedOnly);
4710 /* Append the new types to the end of the array */
4711 if (mono_array_length (res2) > 0) {
4715 len1 = mono_array_length (res);
4716 len2 = mono_array_length (res2);
4717 res3 = mono_array_new (domain, mono_defaults.monotype_class, len1 + len2);
4718 mono_array_memcpy_refs (res3, 0, res, 0, len1);
4719 mono_array_memcpy_refs (res3, len1, res2, 0, len2);
4726 /* the ReflectionTypeLoadException must have all the types (Types property),
4727 * NULL replacing types which throws an exception. The LoaderException must
4728 * contain all exceptions for NULL items.
4731 len = mono_array_length (res);
4733 for (i = 0; i < len; i++) {
4734 MonoReflectionType *t = mono_array_get (res, gpointer, i);
4735 MonoClass *klass = mono_type_get_class (t->type);
4736 if ((klass != NULL) && klass->exception_type) {
4737 /* keep the class in the list */
4738 list = g_list_append (list, klass);
4739 /* and replace Type with NULL */
4740 mono_array_setref (res, i, NULL);
4746 MonoException *exc = NULL;
4747 MonoArray *exl = NULL;
4748 int length = g_list_length (list);
4750 mono_loader_clear_error ();
4752 exl = mono_array_new (domain, mono_defaults.exception_class, length);
4753 for (i = 0, tmp = list; i < length; i++, tmp = tmp->next) {
4754 MonoException *exc = mono_class_get_exception_for_failure (tmp->data);
4755 mono_array_setref (exl, i, exc);
4760 exc = mono_get_exception_reflection_type_load (res, exl);
4761 mono_loader_clear_error ();
4762 mono_raise_exception (exc);
4769 ves_icall_System_Reflection_AssemblyName_ParseName (MonoReflectionAssemblyName *name, MonoString *assname)
4771 MonoAssemblyName aname;
4772 MonoDomain *domain = mono_object_domain (name);
4774 gboolean is_version_defined;
4776 val = mono_string_to_utf8 (assname);
4777 if (!mono_assembly_name_parse_full (val, &aname, TRUE, &is_version_defined))
4780 fill_reflection_assembly_name (domain, name, &aname, "", is_version_defined);
4782 mono_assembly_name_free (&aname);
4783 g_free ((guint8*) aname.public_key);
4789 static MonoReflectionType*
4790 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModule *module)
4792 MonoDomain *domain = mono_object_domain (module);
4795 MONO_ARCH_SAVE_REGS;
4797 g_assert (module->image);
4799 if (module->image->dynamic && ((MonoDynamicImage*)(module->image))->initial_image)
4800 /* These images do not have a global type */
4803 klass = mono_class_get (module->image, 1 | MONO_TOKEN_TYPE_DEF);
4804 return mono_type_get_object (domain, &klass->byval_arg);
4808 ves_icall_System_Reflection_Module_Close (MonoReflectionModule *module)
4810 /*if (module->image)
4811 mono_image_close (module->image);*/
4815 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModule *module)
4817 MonoDomain *domain = mono_object_domain (module);
4819 MONO_ARCH_SAVE_REGS;
4821 g_assert (module->image);
4822 return mono_string_new (domain, module->image->guid);
4826 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine)
4828 if (image->dynamic) {
4829 MonoDynamicImage *dyn = (MonoDynamicImage*)image;
4830 *pe_kind = dyn->pe_kind;
4831 *machine = dyn->machine;
4834 *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
4835 *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
4840 ves_icall_System_Reflection_Module_get_MDStreamVersion (MonoReflectionModule *module)
4842 MonoImage *image = module->image;
4845 mono_raise_exception (mono_get_exception_not_supported (""));
4847 return (image->md_version_major << 16) | (image->md_version_minor);
4851 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModule *module)
4853 MONO_ARCH_SAVE_REGS;
4856 return mono_array_new (mono_object_domain (module), mono_defaults.monotype_class, 0);
4858 return mono_module_get_types (mono_object_domain (module), module->image, FALSE);
4862 mono_metadata_memberref_is_method (MonoImage *image, guint32 token)
4864 guint32 cols [MONO_MEMBERREF_SIZE];
4866 mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
4867 sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
4868 mono_metadata_decode_blob_size (sig, &sig);
4869 return (*sig != 0x6);
4873 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
4876 int table = mono_metadata_token_table (token);
4877 int index = mono_metadata_token_index (token);
4879 *error = ResolveTokenError_Other;
4881 /* Validate token */
4882 if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) &&
4883 (table != MONO_TABLE_TYPESPEC)) {
4884 *error = ResolveTokenError_BadTable;
4889 return mono_lookup_dynamic_token (image, token);
4891 if ((index <= 0) || (index > image->tables [table].rows)) {
4892 *error = ResolveTokenError_OutOfRange;
4896 klass = mono_class_get (image, token);
4898 return &klass->byval_arg;
4904 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
4906 int table = mono_metadata_token_table (token);
4907 int index = mono_metadata_token_index (token);
4909 *error = ResolveTokenError_Other;
4911 /* Validate token */
4912 if ((table != MONO_TABLE_METHOD) && (table != MONO_TABLE_METHODSPEC) &&
4913 (table != MONO_TABLE_MEMBERREF)) {
4914 *error = ResolveTokenError_BadTable;
4919 /* FIXME: validate memberref token type */
4920 return mono_lookup_dynamic_token (image, token);
4922 if ((index <= 0) || (index > image->tables [table].rows)) {
4923 *error = ResolveTokenError_OutOfRange;
4926 if ((table == MONO_TABLE_MEMBERREF) && (!mono_metadata_memberref_is_method (image, token))) {
4927 *error = ResolveTokenError_BadTable;
4931 return mono_get_method (image, token, NULL);
4935 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
4937 int index = mono_metadata_token_index (token);
4939 *error = ResolveTokenError_Other;
4941 /* Validate token */
4942 if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
4943 *error = ResolveTokenError_BadTable;
4948 return mono_lookup_dynamic_token (image, token);
4950 if ((index <= 0) || (index >= image->heap_us.size)) {
4951 *error = ResolveTokenError_OutOfRange;
4955 /* FIXME: What to do if the index points into the middle of a string ? */
4957 return mono_ldstr (mono_domain_get (), image, index);
4960 static MonoClassField*
4961 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
4964 int table = mono_metadata_token_table (token);
4965 int index = mono_metadata_token_index (token);
4967 *error = ResolveTokenError_Other;
4969 /* Validate token */
4970 if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
4971 *error = ResolveTokenError_BadTable;
4976 /* FIXME: validate memberref token type */
4977 return mono_lookup_dynamic_token (image, token);
4979 if ((index <= 0) || (index > image->tables [table].rows)) {
4980 *error = ResolveTokenError_OutOfRange;
4983 if ((table == MONO_TABLE_MEMBERREF) && (mono_metadata_memberref_is_method (image, token))) {
4984 *error = ResolveTokenError_BadTable;
4988 return mono_field_from_token (image, token, &klass, NULL);
4993 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
4995 int table = mono_metadata_token_table (token);
4997 *error = ResolveTokenError_Other;
5000 case MONO_TABLE_TYPEDEF:
5001 case MONO_TABLE_TYPEREF:
5002 case MONO_TABLE_TYPESPEC: {
5003 MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, error);
5005 return (MonoObject*)mono_type_get_object (mono_domain_get (), t);
5009 case MONO_TABLE_METHOD:
5010 case MONO_TABLE_METHODSPEC: {
5011 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, error);
5013 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
5017 case MONO_TABLE_FIELD: {
5018 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, error);
5020 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
5024 case MONO_TABLE_MEMBERREF:
5025 if (mono_metadata_memberref_is_method (image, token)) {
5026 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, error);
5028 return (MonoObject*)mono_method_get_object (mono_domain_get (), m, m->klass);
5033 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, error);
5035 return (MonoObject*)mono_field_get_object (mono_domain_get (), f->parent, f);
5042 *error = ResolveTokenError_BadTable;
5048 static MonoReflectionType*
5049 ves_icall_ModuleBuilder_create_modified_type (MonoReflectionTypeBuilder *tb, MonoString *smodifiers)
5052 int isbyref = 0, rank;
5053 char *str = mono_string_to_utf8 (smodifiers);
5056 MONO_ARCH_SAVE_REGS;
5058 klass = mono_class_from_mono_type (tb->type.type);
5060 /* logic taken from mono_reflection_parse_type(): keep in sync */
5064 if (isbyref) { /* only one level allowed by the spec */
5071 return mono_type_get_object (mono_object_domain (tb), &klass->this_arg);
5074 klass = mono_ptr_class_get (&klass->byval_arg);
5075 mono_class_init (klass);
5086 else if (*p != '*') { /* '*' means unknown lower bound */
5097 klass = mono_array_class_get (klass, rank);
5098 mono_class_init (klass);
5105 return mono_type_get_object (mono_object_domain (tb), &klass->byval_arg);
5109 ves_icall_Type_IsArrayImpl (MonoReflectionType *t)
5114 MONO_ARCH_SAVE_REGS;
5117 res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
5122 static MonoReflectionType *
5123 ves_icall_Type_make_array_type (MonoReflectionType *type, int rank)
5125 MonoClass *klass, *aklass;
5127 MONO_ARCH_SAVE_REGS;
5129 klass = mono_class_from_mono_type (type->type);
5130 aklass = mono_array_class_get (klass, rank);
5132 return mono_type_get_object (mono_object_domain (type), &aklass->byval_arg);
5135 static MonoReflectionType *
5136 ves_icall_Type_make_byref_type (MonoReflectionType *type)
5140 MONO_ARCH_SAVE_REGS;
5142 klass = mono_class_from_mono_type (type->type);
5144 return mono_type_get_object (mono_object_domain (type), &klass->this_arg);
5147 static MonoReflectionType *
5148 ves_icall_Type_MakePointerType (MonoReflectionType *type)
5152 MONO_ARCH_SAVE_REGS;
5154 pklass = mono_ptr_class_get (type->type);
5156 return mono_type_get_object (mono_object_domain (type), &pklass->byval_arg);
5160 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
5161 MonoReflectionMethod *info)
5163 MonoClass *delegate_class = mono_class_from_mono_type (type->type);
5164 MonoObject *delegate;
5167 MONO_ARCH_SAVE_REGS;
5169 mono_assert (delegate_class->parent == mono_defaults.multicastdelegate_class);
5171 delegate = mono_object_new (mono_object_domain (type), delegate_class);
5173 func = mono_compile_method (info->method);
5175 mono_delegate_ctor (delegate, target, func);
5181 * Magic number to convert a time which is relative to
5182 * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
5184 #define EPOCH_ADJUST ((guint64)62135596800LL)
5187 * Magic number to convert FILETIME base Jan 1, 1601 to DateTime - base Jan, 1, 0001
5189 #define FILETIME_ADJUST ((guint64)504911232000000000LL)
5192 * This returns Now in UTC
5195 ves_icall_System_DateTime_GetNow (void)
5197 #ifdef PLATFORM_WIN32
5201 GetSystemTime (&st);
5202 SystemTimeToFileTime (&st, &ft);
5203 return (gint64) FILETIME_ADJUST + ((((gint64)ft.dwHighDateTime)<<32) | ft.dwLowDateTime);
5205 /* FIXME: put this in io-layer and call it GetLocalTime */
5209 MONO_ARCH_SAVE_REGS;
5211 if (gettimeofday (&tv, NULL) == 0) {
5212 res = (((gint64)tv.tv_sec + EPOCH_ADJUST)* 1000000 + tv.tv_usec)*10;
5215 /* fixme: raise exception */
5220 #ifdef PLATFORM_WIN32
5221 /* convert a SYSTEMTIME which is of the form "last thursday in october" to a real date */
5223 convert_to_absolute_date(SYSTEMTIME *date)
5225 #define IS_LEAP(y) ((y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0))
5226 static int days_in_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5227 static int leap_days_in_month[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
5228 /* from the calendar FAQ */
5229 int a = (14 - date->wMonth) / 12;
5230 int y = date->wYear - a;
5231 int m = date->wMonth + 12 * a - 2;
5232 int d = (1 + y + y/4 - y/100 + y/400 + (31*m)/12) % 7;
5234 /* d is now the day of the week for the first of the month (0 == Sunday) */
5236 int day_of_week = date->wDayOfWeek;
5238 /* set day_in_month to the first day in the month which falls on day_of_week */
5239 int day_in_month = 1 + (day_of_week - d);
5240 if (day_in_month <= 0)
5243 /* wDay is 1 for first weekday in month, 2 for 2nd ... 5 means last - so work that out allowing for days in the month */
5244 date->wDay = day_in_month + (date->wDay - 1) * 7;
5245 if (date->wDay > (IS_LEAP(date->wYear) ? leap_days_in_month[date->wMonth - 1] : days_in_month[date->wMonth - 1]))
5250 #ifndef PLATFORM_WIN32
5252 * Return's the offset from GMT of a local time.
5254 * tm is a local time
5255 * t is the same local time as seconds.
5258 gmt_offset(struct tm *tm, time_t t)
5260 #if defined (HAVE_TM_GMTOFF)
5261 return tm->tm_gmtoff;
5266 g.tm_isdst = tm->tm_isdst;
5268 return (int)difftime(t, t2);
5273 * This is heavily based on zdump.c from glibc 2.2.
5275 * * data[0]: start of daylight saving time (in DateTime ticks).
5276 * * data[1]: end of daylight saving time (in DateTime ticks).
5277 * * data[2]: utcoffset (in TimeSpan ticks).
5278 * * data[3]: additional offset when daylight saving (in TimeSpan ticks).
5279 * * name[0]: name of this timezone when not daylight saving.
5280 * * name[1]: name of this timezone when daylight saving.
5282 * FIXME: This only works with "standard" Unix dates (years between 1900 and 2100) while
5283 * the class library allows years between 1 and 9999.
5285 * Returns true on success and zero on failure.
5288 ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year, MonoArray **data, MonoArray **names)
5290 #ifndef PLATFORM_WIN32
5291 MonoDomain *domain = mono_domain_get ();
5292 struct tm start, tt;
5296 int is_daylight = 0, day;
5299 MONO_ARCH_SAVE_REGS;
5301 MONO_CHECK_ARG_NULL (data);
5302 MONO_CHECK_ARG_NULL (names);
5304 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5305 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5308 * no info is better than crashing: we'll need our own tz data
5309 * to make this work properly, anyway. The range is probably
5310 * reduced to 1970 .. 2037 because that is what mktime is
5311 * guaranteed to support (we get into an infinite loop
5315 memset (&start, 0, sizeof (start));
5318 start.tm_year = year-1900;
5320 t = mktime (&start);
5322 if ((year < 1970) || (year > 2037) || (t == -1)) {
5324 tt = *localtime (&t);
5325 strftime (tzone, sizeof (tzone), "%Z", &tt);
5326 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5327 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5331 gmtoff = gmt_offset (&start, t);
5333 /* For each day of the year, calculate the tm_gmtoff. */
5334 for (day = 0; day < 365; day++) {
5337 tt = *localtime (&t);
5339 /* Daylight saving starts or ends here. */
5340 if (gmt_offset (&tt, t) != gmtoff) {
5344 /* Try to find the exact hour when daylight saving starts/ends. */
5348 tt1 = *localtime (&t1);
5349 } while (gmt_offset (&tt1, t1) != gmtoff);
5351 /* Try to find the exact minute when daylight saving starts/ends. */
5354 tt1 = *localtime (&t1);
5355 } while (gmt_offset (&tt1, t1) == gmtoff);
5357 strftime (tzone, sizeof (tzone), "%Z", &tt);
5359 /* Write data, if we're already in daylight saving, we're done. */
5361 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5362 mono_array_set ((*data), gint64, 1, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
5365 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5366 mono_array_set ((*data), gint64, 0, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
5370 /* This is only set once when we enter daylight saving. */
5371 mono_array_set ((*data), gint64, 2, (gint64)gmtoff * 10000000L);
5372 mono_array_set ((*data), gint64, 3, (gint64)(gmt_offset (&tt, t) - gmtoff) * 10000000L);
5374 gmtoff = gmt_offset (&tt, t);
5379 strftime (tzone, sizeof (tzone), "%Z", &tt);
5380 mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
5381 mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
5382 mono_array_set ((*data), gint64, 0, 0);
5383 mono_array_set ((*data), gint64, 1, 0);
5384 mono_array_set ((*data), gint64, 2, (gint64) gmtoff * 10000000L);
5385 mono_array_set ((*data), gint64, 3, 0);
5390 MonoDomain *domain = mono_domain_get ();
5391 TIME_ZONE_INFORMATION tz_info;
5396 tz_id = GetTimeZoneInformation (&tz_info);
5397 if (tz_id == TIME_ZONE_ID_INVALID)
5400 MONO_CHECK_ARG_NULL (data);
5401 MONO_CHECK_ARG_NULL (names);
5403 (*data) = mono_array_new (domain, mono_defaults.int64_class, 4);
5404 (*names) = mono_array_new (domain, mono_defaults.string_class, 2);
5406 for (i = 0; i < 32; ++i)
5407 if (!tz_info.DaylightName [i])
5409 mono_array_setref ((*names), 1, mono_string_new_utf16 (domain, tz_info.DaylightName, i));
5410 for (i = 0; i < 32; ++i)
5411 if (!tz_info.StandardName [i])
5413 mono_array_setref ((*names), 0, mono_string_new_utf16 (domain, tz_info.StandardName, i));
5415 if ((year <= 1601) || (year > 30827)) {
5417 * According to MSDN, the MS time functions can't handle dates outside
5423 /* even if the timezone has no daylight savings it may have Bias (e.g. GMT+13 it seems) */
5424 if (tz_id != TIME_ZONE_ID_UNKNOWN) {
5425 tz_info.StandardDate.wYear = year;
5426 convert_to_absolute_date(&tz_info.StandardDate);
5427 err = SystemTimeToFileTime (&tz_info.StandardDate, &ft);
5429 mono_array_set ((*data), gint64, 1, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
5430 tz_info.DaylightDate.wYear = year;
5431 convert_to_absolute_date(&tz_info.DaylightDate);
5432 err = SystemTimeToFileTime (&tz_info.DaylightDate, &ft);
5434 mono_array_set ((*data), gint64, 0, FILETIME_ADJUST + (((guint64)ft.dwHighDateTime<<32) | ft.dwLowDateTime));
5436 mono_array_set ((*data), gint64, 2, (tz_info.Bias + tz_info.StandardBias) * -600000000LL);
5437 mono_array_set ((*data), gint64, 3, (tz_info.DaylightBias - tz_info.StandardBias) * -600000000LL);
5444 ves_icall_System_Object_obj_address (MonoObject *this)
5446 MONO_ARCH_SAVE_REGS;
5453 static inline gint32
5454 mono_array_get_byte_length (MonoArray *array)
5460 klass = array->obj.vtable->klass;
5462 if (array->bounds == NULL)
5463 length = array->max_length;
5466 for (i = 0; i < klass->rank; ++ i)
5467 length *= array->bounds [i].length;
5470 switch (klass->element_class->byval_arg.type) {
5473 case MONO_TYPE_BOOLEAN:
5477 case MONO_TYPE_CHAR:
5485 return length * sizeof (gpointer);
5496 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array)
5498 MONO_ARCH_SAVE_REGS;
5500 return mono_array_get_byte_length (array);
5504 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx)
5506 MONO_ARCH_SAVE_REGS;
5508 return mono_array_get (array, gint8, idx);
5512 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value)
5514 MONO_ARCH_SAVE_REGS;
5516 mono_array_set (array, gint8, idx, value);
5520 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count)
5522 guint8 *src_buf, *dest_buf;
5524 MONO_ARCH_SAVE_REGS;
5526 /* watch out for integer overflow */
5527 if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count))
5530 src_buf = (guint8 *)src->vector + src_offset;
5531 dest_buf = (guint8 *)dest->vector + dest_offset;
5534 memcpy (dest_buf, src_buf, count);
5536 memmove (dest_buf, src_buf, count); /* Source and dest are the same array */
5542 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this, MonoString *class_name)
5544 MonoDomain *domain = mono_object_domain (this);
5546 MonoRealProxy *rp = ((MonoRealProxy *)this);
5547 MonoTransparentProxy *tp;
5551 MONO_ARCH_SAVE_REGS;
5553 res = mono_object_new (domain, mono_defaults.transparent_proxy_class);
5554 tp = (MonoTransparentProxy*) res;
5556 MONO_OBJECT_SETREF (tp, rp, rp);
5557 type = ((MonoReflectionType *)rp->class_to_proxy)->type;
5558 klass = mono_class_from_mono_type (type);
5560 tp->custom_type_info = (mono_object_isinst (this, mono_defaults.iremotingtypeinfo_class) != NULL);
5561 tp->remote_class = mono_remote_class (domain, class_name, klass);
5563 res->vtable = mono_remote_class_vtable (domain, tp->remote_class, rp);
5567 static MonoReflectionType *
5568 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
5570 return mono_type_get_object (mono_object_domain (tp), &tp->remote_class->proxy_class->byval_arg);
5573 /* System.Environment */
5576 ves_icall_System_Environment_get_MachineName (void)
5578 #if defined (PLATFORM_WIN32)
5583 len = MAX_COMPUTERNAME_LENGTH + 1;
5584 buf = g_new (gunichar2, len);
5587 if (GetComputerName (buf, (PDWORD) &len))
5588 result = mono_string_new_utf16 (mono_domain_get (), buf, len);
5596 if (gethostname (buf, sizeof (buf)) == 0)
5597 result = mono_string_new (mono_domain_get (), buf);
5606 ves_icall_System_Environment_get_Platform (void)
5608 MONO_ARCH_SAVE_REGS;
5610 #if defined (PLATFORM_WIN32)
5620 ves_icall_System_Environment_get_NewLine (void)
5622 MONO_ARCH_SAVE_REGS;
5624 #if defined (PLATFORM_WIN32)
5625 return mono_string_new (mono_domain_get (), "\r\n");
5627 return mono_string_new (mono_domain_get (), "\n");
5632 ves_icall_System_Environment_GetEnvironmentVariable (MonoString *name)
5637 MONO_ARCH_SAVE_REGS;
5642 utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
5643 value = g_getenv (utf8_name);
5650 return mono_string_new (mono_domain_get (), value);
5654 * There is no standard way to get at environ.
5656 #ifndef __MINGW32_VERSION
5664 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
5672 MONO_ARCH_SAVE_REGS;
5675 for (e = environ; *e != 0; ++ e)
5678 domain = mono_domain_get ();
5679 names = mono_array_new (domain, mono_defaults.string_class, n);
5682 for (e = environ; *e != 0; ++ e) {
5683 parts = g_strsplit (*e, "=", 2);
5685 str = mono_string_new (domain, *parts);
5686 mono_array_setref (names, n, str);
5698 * If your platform lacks setenv/unsetenv, you must upgrade your glib.
5700 #if !GLIB_CHECK_VERSION(2,4,0)
5701 #define g_setenv(a,b,c) setenv(a,b,c)
5702 #define g_unsetenv(a) unsetenv(a)
5706 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
5708 #ifdef PLATFORM_WIN32
5709 gunichar2 *utf16_name, *utf16_value;
5711 gchar *utf8_name, *utf8_value;
5714 MONO_ARCH_SAVE_REGS;
5716 #ifdef PLATFORM_WIN32
5717 utf16_name = mono_string_to_utf16 (name);
5718 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
5719 SetEnvironmentVariable (utf16_name, NULL);
5720 g_free (utf16_name);
5724 utf16_value = mono_string_to_utf16 (value);
5726 SetEnvironmentVariable (utf16_name, utf16_value);
5728 g_free (utf16_name);
5729 g_free (utf16_value);
5731 utf8_name = mono_string_to_utf8 (name); /* FIXME: this should be ascii */
5733 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
5734 g_unsetenv (utf8_name);
5739 utf8_value = mono_string_to_utf8 (value);
5740 g_setenv (utf8_name, utf8_value, TRUE);
5743 g_free (utf8_value);
5748 * Returns: the number of milliseconds elapsed since the system started.
5751 ves_icall_System_Environment_get_TickCount (void)
5753 return GetTickCount ();
5758 ves_icall_System_Environment_Exit (int result)
5760 MONO_ARCH_SAVE_REGS;
5762 mono_runtime_set_shutting_down ();
5764 /* Suspend all managed threads since the runtime is going away */
5765 mono_thread_suspend_all_other_threads ();
5767 mono_runtime_quit ();
5769 /* we may need to do some cleanup here... */
5774 ves_icall_System_Environment_GetGacPath (void)
5776 return mono_string_new (mono_domain_get (), mono_assembly_getrootdir ());
5780 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
5782 #if defined (PLATFORM_WIN32)
5783 #ifndef CSIDL_FLAG_CREATE
5784 #define CSIDL_FLAG_CREATE 0x8000
5787 WCHAR path [MAX_PATH];
5788 /* Create directory if no existing */
5789 if (SUCCEEDED (SHGetFolderPathW (NULL, folder | CSIDL_FLAG_CREATE, NULL, 0, path))) {
5793 return mono_string_new_utf16 (mono_domain_get (), path, len);
5796 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
5798 return mono_string_new (mono_domain_get (), "");
5802 ves_icall_System_Environment_GetLogicalDrives (void)
5804 gunichar2 buf [128], *ptr, *dname;
5806 gint initial_size = 127, size = 128;
5809 MonoString *drivestr;
5810 MonoDomain *domain = mono_domain_get ();
5813 MONO_ARCH_SAVE_REGS;
5818 while (size > initial_size) {
5819 size = GetLogicalDriveStrings (initial_size, ptr);
5820 if (size > initial_size) {
5823 ptr = g_malloc0 ((size + 1) * sizeof (gunichar2));
5824 initial_size = size;
5838 result = mono_array_new (domain, mono_defaults.string_class, ndrives);
5843 while (*u16) { u16++; len ++; }
5844 drivestr = mono_string_new_utf16 (domain, dname, len);
5845 mono_array_setref (result, ndrives++, drivestr);
5856 ves_icall_System_Environment_InternalGetHome (void)
5858 MONO_ARCH_SAVE_REGS;
5860 return mono_string_new (mono_domain_get (), g_get_home_dir ());
5863 static const char *encodings [] = {
5865 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
5866 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
5867 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
5869 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
5870 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
5871 "x_unicode_2_0_utf_7",
5873 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
5874 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
5876 "utf_16", "UTF_16LE", "ucs_2", "unicode",
5879 "unicodefffe", "utf_16be",
5886 * Returns the internal codepage, if the value of "int_code_page" is
5887 * 1 at entry, and we can not compute a suitable code page number,
5888 * returns the code page as a string
5891 ves_icall_System_Text_Encoding_InternalCodePage (gint32 *int_code_page)
5896 char *codepage = NULL;
5898 int want_name = *int_code_page;
5901 *int_code_page = -1;
5902 MONO_ARCH_SAVE_REGS;
5904 g_get_charset (&cset);
5905 c = codepage = strdup (cset);
5906 for (c = codepage; *c; c++){
5907 if (isascii (*c) && isalpha (*c))
5912 /* g_print ("charset: %s\n", cset); */
5914 /* handle some common aliases */
5917 for (i = 0; p != 0; ){
5918 if ((gssize) p < 7){
5920 p = encodings [++i];
5923 if (strcmp (p, codepage) == 0){
5924 *int_code_page = code;
5927 p = encodings [++i];
5930 if (strstr (codepage, "utf_8") != NULL)
5931 *int_code_page |= 0x10000000;
5934 if (want_name && *int_code_page == -1)
5935 return mono_string_new (mono_domain_get (), cset);
5941 ves_icall_System_Environment_get_HasShutdownStarted (void)
5943 if (mono_runtime_is_shutting_down ())
5946 if (mono_domain_is_unloading (mono_domain_get ()))
5953 ves_icall_MonoMethodMessage_InitMessage (MonoMethodMessage *this,
5954 MonoReflectionMethod *method,
5955 MonoArray *out_args)
5957 MONO_ARCH_SAVE_REGS;
5959 mono_message_init (mono_object_domain (this), this, method, out_args);
5963 ves_icall_IsTransparentProxy (MonoObject *proxy)
5965 MONO_ARCH_SAVE_REGS;
5970 if (proxy->vtable->klass == mono_defaults.transparent_proxy_class)
5977 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
5982 MONO_ARCH_SAVE_REGS;
5984 klass = mono_class_from_mono_type (type->type);
5985 vtable = mono_class_vtable (mono_domain_get (), klass);
5987 if (enable) vtable->remote = 1;
5988 else vtable->remote = 0;
5992 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type)
5997 MONO_ARCH_SAVE_REGS;
5999 domain = mono_object_domain (type);
6000 klass = mono_class_from_mono_type (type->type);
6002 if (klass->rank >= 1) {
6003 g_assert (klass->rank == 1);
6004 return (MonoObject *) mono_array_new (domain, klass->element_class, 0);
6006 /* Bypass remoting object creation check */
6007 return mono_object_new_alloc_specific (mono_class_vtable (domain, klass));
6012 ves_icall_System_IO_get_temp_path (void)
6014 MONO_ARCH_SAVE_REGS;
6016 return mono_string_new (mono_domain_get (), g_get_tmp_dir ());
6020 ves_icall_RuntimeMethod_GetFunctionPointer (MonoMethod *method)
6022 MONO_ARCH_SAVE_REGS;
6024 return mono_compile_method (method);
6028 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
6033 MONO_ARCH_SAVE_REGS;
6035 path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
6037 #if defined (PLATFORM_WIN32)
6038 /* Avoid mixing '/' and '\\' */
6041 for (i = strlen (path) - 1; i >= 0; i--)
6042 if (path [i] == '/')
6046 mcpath = mono_string_new (mono_domain_get (), path);
6053 ves_icall_System_Configuration_DefaultConfig_get_bundled_machine_config (void)
6055 const gchar *machine_config;
6057 MONO_ARCH_SAVE_REGS;
6059 machine_config = mono_get_machine_config ();
6061 if (!machine_config)
6064 return mono_string_new (mono_domain_get (), machine_config);
6068 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
6073 MONO_ARCH_SAVE_REGS;
6075 path = g_path_get_dirname (mono_get_config_dir ());
6077 #if defined (PLATFORM_WIN32)
6078 /* Avoid mixing '/' and '\\' */
6081 for (i = strlen (path) - 1; i >= 0; i--)
6082 if (path [i] == '/')
6086 ipath = mono_string_new (mono_domain_get (), path);
6093 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
6095 #if defined (PLATFORM_WIN32)
6096 OutputDebugString (mono_string_chars (message));
6098 g_warning ("WriteWindowsDebugString called and PLATFORM_WIN32 not defined!\n");
6102 /* Only used for value types */
6104 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
6109 MONO_ARCH_SAVE_REGS;
6111 domain = mono_object_domain (type);
6112 klass = mono_class_from_mono_type (type->type);
6114 if (mono_class_is_nullable (klass))
6115 /* No arguments -> null */
6118 return mono_object_new (domain, klass);
6121 static MonoReflectionMethod *
6122 ves_icall_MonoMethod_get_base_definition (MonoReflectionMethod *m)
6124 MonoClass *klass, *parent;
6125 MonoMethod *method = m->method;
6126 MonoMethod *result = NULL;
6128 MONO_ARCH_SAVE_REGS;
6130 if (method->klass == NULL)
6133 if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
6134 MONO_CLASS_IS_INTERFACE (method->klass) ||
6135 method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
6138 klass = method->klass;
6139 if (klass->generic_class)
6140 klass = klass->generic_class->container_class;
6142 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
6143 for (parent = klass->parent; parent != NULL; parent = parent->parent) {
6144 mono_class_setup_vtable (parent);
6145 if (parent->vtable_size <= method->slot)
6150 if (klass == method->klass)
6153 result = klass->vtable [method->slot];
6154 if (result == NULL) {
6155 /* It is an abstract method */
6156 gpointer iter = NULL;
6157 while ((result = mono_class_get_methods (klass, &iter)))
6158 if (result->slot == method->slot)
6165 return mono_method_get_object (mono_domain_get (), result, NULL);
6169 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
6171 MONO_ARCH_SAVE_REGS;
6173 iter->sig = *(MonoMethodSignature**)argsp;
6175 g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
6176 g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
6179 /* FIXME: it's not documented what start is exactly... */
6183 guint32 i, arg_size;
6185 iter->args = argsp + sizeof (gpointer);
6186 #ifndef MONO_ARCH_REGPARMS
6187 for (i = 0; i < iter->sig->sentinelpos; ++i) {
6188 arg_size = mono_type_stack_size (iter->sig->params [i], &align);
6189 iter->args = (char*)iter->args + arg_size;
6193 iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
6195 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
6199 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
6201 guint32 i, arg_size;
6204 MONO_ARCH_SAVE_REGS;
6206 i = iter->sig->sentinelpos + iter->next_arg;
6208 g_assert (i < iter->sig->param_count);
6210 res.type = iter->sig->params [i];
6211 res.klass = mono_class_from_mono_type (res.type);
6212 /* FIXME: endianess issue... */
6213 res.value = iter->args;
6214 arg_size = mono_type_stack_size (res.type, &align);
6215 iter->args = (char*)iter->args + arg_size;
6218 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6224 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
6226 guint32 i, arg_size;
6229 MONO_ARCH_SAVE_REGS;
6231 i = iter->sig->sentinelpos + iter->next_arg;
6233 g_assert (i < iter->sig->param_count);
6235 while (i < iter->sig->param_count) {
6236 if (!mono_metadata_type_equal (type, iter->sig->params [i]))
6238 res.type = iter->sig->params [i];
6239 res.klass = mono_class_from_mono_type (res.type);
6240 /* FIXME: endianess issue... */
6241 res.value = iter->args;
6242 arg_size = mono_type_stack_size (res.type, &align);
6243 iter->args = (char*)iter->args + arg_size;
6245 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
6248 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
6257 mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
6260 MONO_ARCH_SAVE_REGS;
6262 i = iter->sig->sentinelpos + iter->next_arg;
6264 g_assert (i < iter->sig->param_count);
6266 return iter->sig->params [i];
6270 mono_TypedReference_ToObject (MonoTypedRef tref)
6272 MONO_ARCH_SAVE_REGS;
6274 if (MONO_TYPE_IS_REFERENCE (tref.type)) {
6275 MonoObject** objp = tref.value;
6279 return mono_value_box (mono_domain_get (), tref.klass, tref.value);
6283 mono_TypedReference_ToObjectInternal (MonoType *type, gpointer value, MonoClass *klass)
6285 MONO_ARCH_SAVE_REGS;
6287 if (MONO_TYPE_IS_REFERENCE (type)) {
6288 MonoObject** objp = value;
6292 return mono_value_box (mono_domain_get (), klass, value);
6296 prelink_method (MonoMethod *method)
6298 const char *exc_class, *exc_arg;
6299 if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
6301 mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
6303 mono_raise_exception(
6304 mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg ) );
6306 /* create the wrapper, too? */
6310 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
6312 MONO_ARCH_SAVE_REGS;
6313 prelink_method (method->method);
6317 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
6319 MonoClass *klass = mono_class_from_mono_type (type->type);
6321 gpointer iter = NULL;
6322 MONO_ARCH_SAVE_REGS;
6324 while ((m = mono_class_get_methods (klass, &iter)))
6328 /* These parameters are "readonly" in corlib/System/Char.cs */
6330 ves_icall_System_Char_GetDataTablePointers (guint8 const **category_data,
6331 guint8 const **numeric_data,
6332 gdouble const **numeric_data_values,
6333 guint16 const **to_lower_data_low,
6334 guint16 const **to_lower_data_high,
6335 guint16 const **to_upper_data_low,
6336 guint16 const **to_upper_data_high)
6338 *category_data = CategoryData;
6339 *numeric_data = NumericData;
6340 *numeric_data_values = NumericDataValues;
6341 *to_lower_data_low = ToLowerDataLow;
6342 *to_lower_data_high = ToLowerDataHigh;
6343 *to_upper_data_low = ToUpperDataLow;
6344 *to_upper_data_high = ToUpperDataHigh;
6348 ves_icall_MonoDebugger_GetMethodToken (MonoReflectionMethod *method)
6350 return method->method->token;
6354 * We eturn NULL for no modifiers so the corlib code can return Type.EmptyTypes
6355 * and avoid useless allocations.
6358 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional)
6362 for (i = 0; i < type->num_mods; ++i) {
6363 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
6368 res = mono_array_new (mono_domain_get (), mono_defaults.systemtype_class, count);
6370 for (i = 0; i < type->num_mods; ++i) {
6371 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
6372 MonoClass *klass = mono_class_get (image, type->modifiers [i].token);
6373 mono_array_setref (res, count, mono_type_get_object (mono_domain_get (), &klass->byval_arg));
6381 param_info_get_type_modifiers (MonoReflectionParameter *param, MonoBoolean optional)
6383 MonoType *type = param->ClassImpl->type;
6384 MonoReflectionMethod *method = (MonoReflectionMethod*)param->MemberImpl;
6385 MonoImage *image = method->method->klass->image;
6386 int pos = param->PositionImpl;
6387 MonoMethodSignature *sig = mono_method_signature (method->method);
6391 type = sig->params [pos];
6393 return type_array_from_modifiers (image, type, optional);
6397 get_property_type (MonoProperty *prop)
6399 MonoMethodSignature *sig;
6401 sig = mono_method_signature (prop->get);
6403 } else if (prop->set) {
6404 sig = mono_method_signature (prop->set);
6405 return sig->params [sig->param_count - 1];
6411 property_info_get_type_modifiers (MonoReflectionProperty *property, MonoBoolean optional)
6413 MonoType *type = get_property_type (property->property);
6414 MonoImage *image = property->klass->image;
6418 return type_array_from_modifiers (image, type, optional);
6422 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
6424 MonoCustomAttrInfo *cinfo;
6427 cinfo = mono_reflection_get_custom_attrs_info (obj);
6430 found = mono_custom_attrs_has_attr (cinfo, mono_class_from_mono_type (attr_type->type));
6432 mono_custom_attrs_free (cinfo);
6437 custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
6439 return mono_reflection_get_custom_attrs_by_type (obj, attr_type ? mono_class_from_mono_type (attr_type->type) : NULL);
6443 GCHandle_CheckCurrentDomain (guint32 gchandle)
6445 return mono_gchandle_is_in_domain (gchandle, mono_domain_get ());
6449 ves_icall_Mono_Runtime_GetDisplayName (void)
6451 static const char display_name_str [] = "Mono " VERSION;
6452 MonoString *display_name = mono_string_new (mono_domain_get (), display_name_str);
6453 return display_name;
6458 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
6459 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
6460 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 62, 128, 128, 128, 63,
6461 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 0, 128, 128,
6462 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
6463 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 128, 128, 128, 128, 128,
6464 128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
6465 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
6469 base64_to_byte_array (gunichar2 *start, gint ilength, MonoBoolean allowWhitespaceOnly)
6474 gunichar2 last, prev_last;
6482 last = prev_last = 0;
6483 for (i = 0; i < ilength; i++) {
6485 if (c >= sizeof (dbase64)) {
6486 exc = mono_exception_from_name_msg (mono_get_corlib (),
6487 "System", "FormatException",
6488 "Invalid character found.");
6489 mono_raise_exception (exc);
6490 } else if (isspace (c)) {
6498 olength = ilength - ignored;
6500 if (allowWhitespaceOnly && olength == 0) {
6501 return mono_array_new (mono_domain_get (), mono_defaults.byte_class, 0);
6504 if ((olength & 3) != 0 || olength <= 0) {
6505 exc = mono_exception_from_name_msg (mono_get_corlib (), "System",
6506 "FormatException", "Invalid length.");
6507 mono_raise_exception (exc);
6510 olength = (olength * 3) / 4;
6514 if (prev_last == '=')
6517 result = mono_array_new (mono_domain_get (), mono_defaults.byte_class, olength);
6518 res_ptr = mono_array_addr (result, guchar, 0);
6519 for (i = 0; i < ilength; ) {
6522 for (k = 0; k < 4 && i < ilength;) {
6528 if (((b [k] = dbase64 [c]) & 0x80) != 0) {
6529 exc = mono_exception_from_name_msg (mono_get_corlib (),
6530 "System", "FormatException",
6531 "Invalid character found.");
6532 mono_raise_exception (exc);
6537 *res_ptr++ = (b [0] << 2) | (b [1] >> 4);
6539 *res_ptr++ = (b [1] << 4) | (b [2] >> 2);
6541 *res_ptr++ = (b [2] << 6) | b [3];
6543 while (i < ilength && isspace (start [i]))
6551 InternalFromBase64String (MonoString *str, MonoBoolean allowWhitespaceOnly)
6553 MONO_ARCH_SAVE_REGS;
6555 return base64_to_byte_array (mono_string_chars (str),
6556 mono_string_length (str), allowWhitespaceOnly);
6560 InternalFromBase64CharArray (MonoArray *input, gint offset, gint length)
6562 MONO_ARCH_SAVE_REGS;
6564 return base64_to_byte_array (mono_array_addr (input, gunichar2, offset),
6568 #define ICALL_TYPE(id,name,first)
6569 #define ICALL(id,name,func) Icall_ ## id,
6572 #include "metadata/icall-def.h"
6578 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
6579 #define ICALL(id,name,func)
6581 #include "metadata/icall-def.h"
6587 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
6588 #define ICALL(id,name,func)
6590 guint16 first_icall;
6593 static const IcallTypeDesc
6594 icall_type_descs [] = {
6595 #include "metadata/icall-def.h"
6599 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
6602 #define ICALL_TYPE(id,name,first)
6605 #ifdef HAVE_ARRAY_ELEM_INIT
6606 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
6607 #define MSGSTRFIELD1(line) str##line
6609 static const struct msgstrtn_t {
6610 #define ICALL(id,name,func)
6612 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
6613 #include "metadata/icall-def.h"
6615 } icall_type_names_str = {
6616 #define ICALL_TYPE(id,name,first) (name),
6617 #include "metadata/icall-def.h"
6620 static const guint16 icall_type_names_idx [] = {
6621 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
6622 #include "metadata/icall-def.h"
6625 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
6627 static const struct msgstr_t {
6629 #define ICALL_TYPE(id,name,first)
6630 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
6631 #include "metadata/icall-def.h"
6633 } icall_names_str = {
6634 #define ICALL(id,name,func) (name),
6635 #include "metadata/icall-def.h"
6638 static const guint16 icall_names_idx [] = {
6639 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
6640 #include "metadata/icall-def.h"
6643 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
6649 #define ICALL_TYPE(id,name,first) name,
6650 #define ICALL(id,name,func)
6651 static const char* const
6652 icall_type_names [] = {
6653 #include "metadata/icall-def.h"
6657 #define icall_type_name_get(id) (icall_type_names [(id)])
6661 #define ICALL_TYPE(id,name,first)
6662 #define ICALL(id,name,func) name,
6663 static const char* const
6665 #include "metadata/icall-def.h"
6668 #define icall_name_get(id) icall_names [(id)]
6670 #endif /* !HAVE_ARRAY_ELEM_INIT */
6674 #define ICALL_TYPE(id,name,first)
6675 #define ICALL(id,name,func) func,
6676 static const gconstpointer
6677 icall_functions [] = {
6678 #include "metadata/icall-def.h"
6682 static GHashTable *icall_hash = NULL;
6683 static GHashTable *jit_icall_hash_name = NULL;
6684 static GHashTable *jit_icall_hash_addr = NULL;
6687 mono_icall_init (void)
6691 /* check that tables are sorted: disable in release */
6694 const char *prev_class = NULL;
6695 const char *prev_method;
6697 for (i = 0; i < Icall_type_num; ++i) {
6698 const IcallTypeDesc *desc;
6701 if (prev_class && strcmp (prev_class, icall_type_name_get (i)) >= 0)
6702 g_print ("class %s should come before class %s\n", icall_type_name_get (i), prev_class);
6703 prev_class = icall_type_name_get (i);
6704 desc = &icall_type_descs [i];
6705 num_icalls = icall_desc_num_icalls (desc);
6706 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
6707 for (j = 0; j < num_icalls; ++j) {
6708 const char *methodn = icall_name_get (desc->first_icall + j);
6709 if (prev_method && strcmp (prev_method, methodn) >= 0)
6710 g_print ("method %s should come before method %s\n", methodn, prev_method);
6711 prev_method = methodn;
6716 icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
6720 mono_icall_cleanup (void)
6722 g_hash_table_destroy (icall_hash);
6723 g_hash_table_destroy (jit_icall_hash_name);
6724 g_hash_table_destroy (jit_icall_hash_addr);
6728 mono_add_internal_call (const char *name, gconstpointer method)
6730 mono_loader_lock ();
6732 g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
6734 mono_loader_unlock ();
6737 #ifdef HAVE_ARRAY_ELEM_INIT
6739 compare_method_imap (const void *key, const void *elem)
6741 const char* method_name = (const char*)&icall_names_str + (*(guint16*)elem);
6742 return strcmp (key, method_name);
6746 find_method_icall (const IcallTypeDesc *imap, const char *name)
6748 const guint16 *nameslot = bsearch (name, icall_names_idx + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names_idx [0]), compare_method_imap);
6751 return (gpointer)icall_functions [(nameslot - &icall_names_idx [0])];
6755 compare_class_imap (const void *key, const void *elem)
6757 const char* class_name = (const char*)&icall_type_names_str + (*(guint16*)elem);
6758 return strcmp (key, class_name);
6761 static const IcallTypeDesc*
6762 find_class_icalls (const char *name)
6764 const guint16 *nameslot = bsearch (name, icall_type_names_idx, Icall_type_num, sizeof (icall_type_names_idx [0]), compare_class_imap);
6767 return &icall_type_descs [nameslot - &icall_type_names_idx [0]];
6772 compare_method_imap (const void *key, const void *elem)
6774 const char** method_name = (const char**)elem;
6775 return strcmp (key, *method_name);
6779 find_method_icall (const IcallTypeDesc *imap, const char *name)
6781 const char **nameslot = bsearch (name, icall_names + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names [0]), compare_method_imap);
6784 return (gpointer)icall_functions [(nameslot - icall_names)];
6788 compare_class_imap (const void *key, const void *elem)
6790 const char** class_name = (const char**)elem;
6791 return strcmp (key, *class_name);
6794 static const IcallTypeDesc*
6795 find_class_icalls (const char *name)
6797 const char **nameslot = bsearch (name, icall_type_names, Icall_type_num, sizeof (icall_type_names [0]), compare_class_imap);
6800 return &icall_type_descs [nameslot - icall_type_names];
6806 * we should probably export this as an helper (handle nested types).
6807 * Returns the number of chars written in buf.
6810 concat_class_name (char *buf, int bufsize, MonoClass *klass)
6812 int nspacelen, cnamelen;
6813 nspacelen = strlen (klass->name_space);
6814 cnamelen = strlen (klass->name);
6815 if (nspacelen + cnamelen + 2 > bufsize)
6818 memcpy (buf, klass->name_space, nspacelen);
6819 buf [nspacelen ++] = '.';
6821 memcpy (buf + nspacelen, klass->name, cnamelen);
6822 buf [nspacelen + cnamelen] = 0;
6823 return nspacelen + cnamelen;
6827 mono_lookup_internal_call (MonoMethod *method)
6832 int typelen = 0, mlen, siglen;
6834 const IcallTypeDesc *imap;
6836 g_assert (method != NULL);
6838 if (method->is_inflated)
6839 method = ((MonoMethodInflated *) method)->declaring;
6841 if (method->klass->nested_in) {
6842 int pos = concat_class_name (mname, sizeof (mname)-2, method->klass->nested_in);
6846 mname [pos++] = '/';
6849 typelen = concat_class_name (mname+pos, sizeof (mname)-pos-1, method->klass);
6855 typelen = concat_class_name (mname, sizeof (mname), method->klass);
6860 imap = find_class_icalls (mname);
6862 mname [typelen] = ':';
6863 mname [typelen + 1] = ':';
6865 mlen = strlen (method->name);
6866 memcpy (mname + typelen + 2, method->name, mlen);
6867 sigstart = mname + typelen + 2 + mlen;
6870 tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
6871 siglen = strlen (tmpsig);
6872 if (typelen + mlen + siglen + 6 > sizeof (mname))
6875 memcpy (sigstart + 1, tmpsig, siglen);
6876 sigstart [siglen + 1] = ')';
6877 sigstart [siglen + 2] = 0;
6880 mono_loader_lock ();
6882 res = g_hash_table_lookup (icall_hash, mname);
6884 mono_loader_unlock ();
6887 /* try without signature */
6889 res = g_hash_table_lookup (icall_hash, mname);
6891 mono_loader_unlock ();
6895 /* it wasn't found in the static call tables */
6897 mono_loader_unlock ();
6900 res = find_method_icall (imap, sigstart - mlen);
6902 mono_loader_unlock ();
6905 /* try _with_ signature */
6907 res = find_method_icall (imap, sigstart - mlen);
6909 mono_loader_unlock ();
6913 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname);
6914 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
6915 g_print ("The out of sync library is: %s\n", method->klass->image->name);
6916 g_print ("\nWhen you update one from cvs you need to update, compile and install\nthe other too.\n");
6917 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");
6918 g_print ("If you see other errors or faults after this message they are probably related\n");
6919 g_print ("and you need to fix your mono install first.\n");
6921 mono_loader_unlock ();
6927 type_from_typename (char *typename)
6929 MonoClass *klass = NULL; /* assignment to shut GCC warning up */
6931 if (!strcmp (typename, "int"))
6932 klass = mono_defaults.int_class;
6933 else if (!strcmp (typename, "ptr"))
6934 klass = mono_defaults.int_class;
6935 else if (!strcmp (typename, "void"))
6936 klass = mono_defaults.void_class;
6937 else if (!strcmp (typename, "int32"))
6938 klass = mono_defaults.int32_class;
6939 else if (!strcmp (typename, "uint32"))
6940 klass = mono_defaults.uint32_class;
6941 else if (!strcmp (typename, "int8"))
6942 klass = mono_defaults.sbyte_class;
6943 else if (!strcmp (typename, "uint8"))
6944 klass = mono_defaults.byte_class;
6945 else if (!strcmp (typename, "int16"))
6946 klass = mono_defaults.int16_class;
6947 else if (!strcmp (typename, "uint16"))
6948 klass = mono_defaults.uint16_class;
6949 else if (!strcmp (typename, "long"))
6950 klass = mono_defaults.int64_class;
6951 else if (!strcmp (typename, "ulong"))
6952 klass = mono_defaults.uint64_class;
6953 else if (!strcmp (typename, "float"))
6954 klass = mono_defaults.single_class;
6955 else if (!strcmp (typename, "double"))
6956 klass = mono_defaults.double_class;
6957 else if (!strcmp (typename, "object"))
6958 klass = mono_defaults.object_class;
6959 else if (!strcmp (typename, "obj"))
6960 klass = mono_defaults.object_class;
6963 g_assert_not_reached ();
6965 return &klass->byval_arg;
6968 MonoMethodSignature*
6969 mono_create_icall_signature (const char *sigstr)
6974 MonoMethodSignature *res;
6976 mono_loader_lock ();
6977 res = g_hash_table_lookup (mono_defaults.corlib->helper_signatures, sigstr);
6979 mono_loader_unlock ();
6983 parts = g_strsplit (sigstr, " ", 256);
6992 res = mono_metadata_signature_alloc (mono_defaults.corlib, len - 1);
6995 #ifdef PLATFORM_WIN32
6997 * Under windows, the default pinvoke calling convention is STDCALL but
7000 res->call_convention = MONO_CALL_C;
7003 res->ret = type_from_typename (parts [0]);
7004 for (i = 1; i < len; ++i) {
7005 res->params [i - 1] = type_from_typename (parts [i]);
7010 g_hash_table_insert (mono_defaults.corlib->helper_signatures, (gpointer)sigstr, res);
7012 mono_loader_unlock ();
7018 mono_find_jit_icall_by_name (const char *name)
7020 MonoJitICallInfo *info;
7021 g_assert (jit_icall_hash_name);
7023 mono_loader_lock ();
7024 info = g_hash_table_lookup (jit_icall_hash_name, name);
7025 mono_loader_unlock ();
7030 mono_find_jit_icall_by_addr (gconstpointer addr)
7032 MonoJitICallInfo *info;
7033 g_assert (jit_icall_hash_addr);
7035 mono_loader_lock ();
7036 info = g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
7037 mono_loader_unlock ();
7043 mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
7045 mono_loader_lock ();
7046 g_hash_table_insert (jit_icall_hash_addr, (gpointer)wrapper, info);
7047 mono_loader_unlock ();
7051 mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
7053 MonoJitICallInfo *info;
7058 mono_loader_lock ();
7060 if (!jit_icall_hash_name) {
7061 jit_icall_hash_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
7062 jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
7065 if (g_hash_table_lookup (jit_icall_hash_name, name)) {
7066 g_warning ("jit icall already defined \"%s\"\n", name);
7067 g_assert_not_reached ();
7070 info = g_new0 (MonoJitICallInfo, 1);
7077 info->wrapper = func;
7079 info->wrapper = NULL;
7082 g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
7083 g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
7085 mono_loader_unlock ();