5 * Dietmar Maurer (dietmar@ximian.com)
6 * Paolo Molaro (lupus@ximian.com)
7 * Patrik Torstensson (patrik.torstensson@labs2.com)
8 * Marek Safar (marek.safar@gmail.com)
9 * Aleksey Kliger (aleksey@xamarin.com)
11 * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
12 * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
13 * Copyright 2011-2015 Xamarin Inc (http://www.xamarin.com).
14 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
25 #ifdef HAVE_SYS_TIME_H
31 #if defined (HAVE_WCHAR_H)
34 #include "mono/metadata/icall-internals.h"
35 #include "mono/utils/mono-membar.h"
36 #include <mono/metadata/object.h>
37 #include <mono/metadata/threads.h>
38 #include <mono/metadata/threads-types.h>
39 #include <mono/metadata/threadpool-ms.h>
40 #include <mono/metadata/threadpool-ms-io.h>
41 #include <mono/metadata/monitor.h>
42 #include <mono/metadata/reflection.h>
43 #include <mono/metadata/image-internals.h>
44 #include <mono/metadata/assembly.h>
45 #include <mono/metadata/assembly-internals.h>
46 #include <mono/metadata/tabledefs.h>
47 #include <mono/metadata/exception.h>
48 #include <mono/metadata/exception-internals.h>
49 #include <mono/metadata/file-io.h>
50 #include <mono/metadata/console-io.h>
51 #include <mono/metadata/mono-route.h>
52 #include <mono/metadata/socket-io.h>
53 #include <mono/metadata/mono-endian.h>
54 #include <mono/metadata/tokentype.h>
55 #include <mono/metadata/domain-internals.h>
56 #include <mono/metadata/metadata-internals.h>
57 #include <mono/metadata/class-internals.h>
58 #include <mono/metadata/reflection-internals.h>
59 #include <mono/metadata/marshal.h>
60 #include <mono/metadata/gc-internals.h>
61 #include <mono/metadata/mono-gc.h>
62 #include <mono/metadata/rand.h>
63 #include <mono/metadata/sysmath.h>
64 #include <mono/metadata/string-icalls.h>
65 #include <mono/metadata/debug-helpers.h>
66 #include <mono/metadata/w32process.h>
67 #include <mono/metadata/environment.h>
68 #include <mono/metadata/profiler-private.h>
69 #include <mono/metadata/locales.h>
70 #include <mono/metadata/filewatcher.h>
71 #include <mono/metadata/security.h>
72 #include <mono/metadata/mono-config.h>
73 #include <mono/metadata/cil-coff.h>
74 #include <mono/metadata/number-formatter.h>
75 #include <mono/metadata/security-manager.h>
76 #include <mono/metadata/security-core-clr.h>
77 #include <mono/metadata/mono-perfcounters.h>
78 #include <mono/metadata/mono-debug.h>
79 #include <mono/metadata/mono-ptr-array.h>
80 #include <mono/metadata/verify-internals.h>
81 #include <mono/metadata/runtime.h>
82 #include <mono/metadata/file-mmap.h>
83 #include <mono/metadata/seq-points-data.h>
84 #include <mono/metadata/handle.h>
85 #include <mono/metadata/w32mutex.h>
86 #include <mono/metadata/w32semaphore.h>
87 #include <mono/metadata/w32event.h>
88 #include <mono/io-layer/io-layer.h>
89 #include <mono/utils/monobitset.h>
90 #include <mono/utils/mono-time.h>
91 #include <mono/utils/mono-proclib.h>
92 #include <mono/utils/mono-string.h>
93 #include <mono/utils/mono-error-internals.h>
94 #include <mono/utils/mono-mmap.h>
95 #include <mono/utils/mono-io-portability.h>
96 #include <mono/utils/mono-digest.h>
97 #include <mono/utils/bsearch.h>
98 #include <mono/utils/mono-os-mutex.h>
99 #include <mono/utils/mono-threads.h>
101 #include "decimal-ms.h"
102 #include "number-ms.h"
104 #if !defined(HOST_WIN32) && defined(HAVE_SYS_UTSNAME_H)
105 #include <sys/utsname.h>
108 extern MonoString* ves_icall_System_Environment_GetOSVersionString (void);
110 ICALL_EXPORT MonoReflectionAssembly* ves_icall_System_Reflection_Assembly_GetCallingAssembly (void);
112 /* Lazy class loading functions */
113 static GENERATE_GET_CLASS_WITH_CACHE (system_version, System, Version)
114 static GENERATE_GET_CLASS_WITH_CACHE (assembly_name, System.Reflection, AssemblyName)
115 static GENERATE_GET_CLASS_WITH_CACHE (constructor_info, System.Reflection, ConstructorInfo)
116 static GENERATE_GET_CLASS_WITH_CACHE (property_info, System.Reflection, PropertyInfo)
117 static GENERATE_GET_CLASS_WITH_CACHE (event_info, System.Reflection, EventInfo)
118 static GENERATE_GET_CLASS_WITH_CACHE (module, System.Reflection, Module)
121 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional, MonoError *error);
123 static inline MonoBoolean
124 is_generic_parameter (MonoType *type)
126 return !type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR);
130 mono_class_init_checked (MonoClass *klass, MonoError *error)
132 mono_error_init (error);
134 if (!mono_class_init (klass))
135 mono_error_set_for_class_failure (error, klass);
140 mono_icall_make_platform_path (gchar *path)
145 static inline const gchar *
146 mono_icall_get_file_path_prefix (const gchar *path)
150 #endif /* HOST_WIN32 */
152 ICALL_EXPORT MonoObject *
153 ves_icall_System_Array_GetValueImpl (MonoArray *arr, guint32 pos)
159 MonoObject *result = NULL;
161 ac = (MonoClass *)arr->obj.vtable->klass;
163 esize = mono_array_element_size (ac);
164 ea = (gpointer*)((char*)arr->vector + (pos * esize));
166 if (ac->element_class->valuetype) {
167 result = mono_value_box_checked (arr->obj.vtable->domain, ac->element_class, ea, &error);
168 mono_error_set_pending_exception (&error);
170 result = (MonoObject *)*ea;
174 ICALL_EXPORT MonoObject *
175 ves_icall_System_Array_GetValue (MonoArray *arr, MonoArray *idxs)
181 MONO_CHECK_ARG_NULL (idxs, NULL);
184 ic = (MonoClass *)io->obj.vtable->klass;
186 ac = (MonoClass *)arr->obj.vtable->klass;
188 g_assert (ic->rank == 1);
189 if (io->bounds != NULL || io->max_length != ac->rank) {
190 mono_set_pending_exception (mono_get_exception_argument (NULL, NULL));
194 ind = (gint32 *)io->vector;
196 if (arr->bounds == NULL) {
197 if (*ind < 0 || *ind >= arr->max_length) {
198 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
202 return ves_icall_System_Array_GetValueImpl (arr, *ind);
205 for (i = 0; i < ac->rank; i++) {
206 if ((ind [i] < arr->bounds [i].lower_bound) ||
207 (ind [i] >= (mono_array_lower_bound_t)arr->bounds [i].length + arr->bounds [i].lower_bound)) {
208 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
213 pos = ind [0] - arr->bounds [0].lower_bound;
214 for (i = 1; i < ac->rank; i++)
215 pos = pos * arr->bounds [i].length + ind [i] -
216 arr->bounds [i].lower_bound;
218 return ves_icall_System_Array_GetValueImpl (arr, pos);
222 ves_icall_System_Array_SetValueImpl (MonoArray *arr, MonoObject *value, guint32 pos)
225 MonoClass *ac, *vc, *ec;
234 mono_error_init (&error);
237 vc = value->vtable->klass;
241 ac = arr->obj.vtable->klass;
242 ec = ac->element_class;
244 esize = mono_array_element_size (ac);
245 ea = (gpointer*)((char*)arr->vector + (pos * esize));
246 va = (gpointer*)((char*)value + sizeof (MonoObject));
248 if (mono_class_is_nullable (ec)) {
249 mono_nullable_init ((guint8*)ea, value, ec);
254 mono_gc_bzero_atomic (ea, esize);
258 #define NO_WIDENING_CONVERSION G_STMT_START{\
259 mono_set_pending_exception (mono_get_exception_argument ( \
260 "value", "not a widening conversion")); \
264 #define CHECK_WIDENING_CONVERSION(extra) G_STMT_START{\
265 if (esize < vsize + (extra)) { \
266 mono_set_pending_exception (mono_get_exception_argument ( \
267 "value", "not a widening conversion")); \
272 #define INVALID_CAST G_STMT_START{ \
273 mono_get_runtime_callbacks ()->set_cast_details (vc, ec); \
274 mono_set_pending_exception (mono_get_exception_invalid_cast ()); \
278 /* Check element (destination) type. */
279 switch (ec->byval_arg.type) {
280 case MONO_TYPE_STRING:
281 switch (vc->byval_arg.type) {
282 case MONO_TYPE_STRING:
288 case MONO_TYPE_BOOLEAN:
289 switch (vc->byval_arg.type) {
290 case MONO_TYPE_BOOLEAN:
303 NO_WIDENING_CONVERSION;
312 if (!ec->valuetype) {
313 gboolean castOk = (NULL != mono_object_isinst_checked (value, ec, &error));
314 if (mono_error_set_pending_exception (&error))
318 mono_gc_wbarrier_set_arrayref (arr, ea, (MonoObject*)value);
322 if (mono_object_isinst_checked (value, ec, &error)) {
323 if (ec->has_references)
324 mono_value_copy (ea, (char*)value + sizeof (MonoObject), ec);
326 mono_gc_memmove_atomic (ea, (char *)value + sizeof (MonoObject), esize);
329 if (mono_error_set_pending_exception (&error))
335 vsize = mono_class_instance_size (vc) - sizeof (MonoObject);
337 et = ec->byval_arg.type;
338 if (et == MONO_TYPE_VALUETYPE && ec->byval_arg.data.klass->enumtype)
339 et = mono_class_enum_basetype (ec->byval_arg.data.klass)->type;
341 vt = vc->byval_arg.type;
342 if (vt == MONO_TYPE_VALUETYPE && vc->byval_arg.data.klass->enumtype)
343 vt = mono_class_enum_basetype (vc->byval_arg.data.klass)->type;
345 #define ASSIGN_UNSIGNED(etype) G_STMT_START{\
351 case MONO_TYPE_CHAR: \
352 CHECK_WIDENING_CONVERSION(0); \
353 *(etype *) ea = (etype) u64; \
355 /* You can't assign a signed value to an unsigned array. */ \
360 /* You can't assign a floating point number to an integer array. */ \
363 NO_WIDENING_CONVERSION; \
367 #define ASSIGN_SIGNED(etype) G_STMT_START{\
373 CHECK_WIDENING_CONVERSION(0); \
374 *(etype *) ea = (etype) i64; \
376 /* You can assign an unsigned value to a signed array if the array's */ \
377 /* element size is larger than the value size. */ \
382 case MONO_TYPE_CHAR: \
383 CHECK_WIDENING_CONVERSION(1); \
384 *(etype *) ea = (etype) u64; \
386 /* You can't assign a floating point number to an integer array. */ \
389 NO_WIDENING_CONVERSION; \
393 #define ASSIGN_REAL(etype) G_STMT_START{\
397 CHECK_WIDENING_CONVERSION(0); \
398 *(etype *) ea = (etype) r64; \
400 /* All integer values fit into a floating point array, so we don't */ \
401 /* need to CHECK_WIDENING_CONVERSION here. */ \
406 *(etype *) ea = (etype) i64; \
412 case MONO_TYPE_CHAR: \
413 *(etype *) ea = (etype) u64; \
420 u64 = *(guint8 *) va;
423 u64 = *(guint16 *) va;
426 u64 = *(guint32 *) va;
429 u64 = *(guint64 *) va;
435 i64 = *(gint16 *) va;
438 i64 = *(gint32 *) va;
441 i64 = *(gint64 *) va;
444 r64 = *(gfloat *) va;
447 r64 = *(gdouble *) va;
450 u64 = *(guint16 *) va;
452 case MONO_TYPE_BOOLEAN:
453 /* Boolean is only compatible with itself. */
466 NO_WIDENING_CONVERSION;
473 /* If we can't do a direct copy, let's try a widening conversion. */
476 ASSIGN_UNSIGNED (guint16);
478 ASSIGN_UNSIGNED (guint8);
480 ASSIGN_UNSIGNED (guint16);
482 ASSIGN_UNSIGNED (guint32);
484 ASSIGN_UNSIGNED (guint64);
486 ASSIGN_SIGNED (gint8);
488 ASSIGN_SIGNED (gint16);
490 ASSIGN_SIGNED (gint32);
492 ASSIGN_SIGNED (gint64);
494 ASSIGN_REAL (gfloat);
496 ASSIGN_REAL (gdouble);
500 /* Not reached, INVALID_CAST does not return. Just to avoid a compiler warning ... */
504 #undef NO_WIDENING_CONVERSION
505 #undef CHECK_WIDENING_CONVERSION
506 #undef ASSIGN_UNSIGNED
512 ves_icall_System_Array_SetValue (MonoArray *arr, MonoObject *value,
518 MONO_CHECK_ARG_NULL (idxs,);
520 ic = idxs->obj.vtable->klass;
521 ac = arr->obj.vtable->klass;
523 g_assert (ic->rank == 1);
524 if (idxs->bounds != NULL || idxs->max_length != ac->rank) {
525 mono_set_pending_exception (mono_get_exception_argument (NULL, NULL));
529 ind = (gint32 *)idxs->vector;
531 if (arr->bounds == NULL) {
532 if (*ind < 0 || *ind >= arr->max_length) {
533 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
537 ves_icall_System_Array_SetValueImpl (arr, value, *ind);
541 for (i = 0; i < ac->rank; i++)
542 if ((ind [i] < arr->bounds [i].lower_bound) ||
543 (ind [i] >= (mono_array_lower_bound_t)arr->bounds [i].length + arr->bounds [i].lower_bound)) {
544 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
548 pos = ind [0] - arr->bounds [0].lower_bound;
549 for (i = 1; i < ac->rank; i++)
550 pos = pos * arr->bounds [i].length + ind [i] -
551 arr->bounds [i].lower_bound;
553 ves_icall_System_Array_SetValueImpl (arr, value, pos);
556 ICALL_EXPORT MonoArray *
557 ves_icall_System_Array_CreateInstanceImpl (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
560 MonoClass *aklass, *klass;
563 gboolean bounded = FALSE;
565 MONO_CHECK_ARG_NULL (type, NULL);
566 MONO_CHECK_ARG_NULL (lengths, NULL);
568 MONO_CHECK_ARG (lengths, mono_array_length (lengths) > 0, NULL);
570 MONO_CHECK_ARG (bounds, mono_array_length (lengths) == mono_array_length (bounds), NULL);
572 for (i = 0; i < mono_array_length (lengths); i++) {
573 if (mono_array_get (lengths, gint32, i) < 0) {
574 mono_set_pending_exception (mono_get_exception_argument_out_of_range (NULL));
579 klass = mono_class_from_mono_type (type->type);
580 mono_class_init_checked (klass, &error);
581 if (mono_error_set_pending_exception (&error))
584 if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint32, 0) != 0))
585 /* vectors are not the same as one dimensional arrays with no-zero bounds */
590 aklass = mono_bounded_array_class_get (klass, mono_array_length (lengths), bounded);
592 sizes = (uintptr_t *)alloca (aklass->rank * sizeof(intptr_t) * 2);
593 for (i = 0; i < aklass->rank; ++i) {
594 sizes [i] = mono_array_get (lengths, guint32, i);
596 sizes [i + aklass->rank] = mono_array_get (bounds, gint32, i);
598 sizes [i + aklass->rank] = 0;
601 array = mono_array_new_full_checked (mono_object_domain (type), aklass, sizes, (intptr_t*)sizes + aklass->rank, &error);
602 mono_error_set_pending_exception (&error);
607 ICALL_EXPORT MonoArray *
608 ves_icall_System_Array_CreateInstanceImpl64 (MonoReflectionType *type, MonoArray *lengths, MonoArray *bounds)
611 MonoClass *aklass, *klass;
614 gboolean bounded = FALSE;
616 MONO_CHECK_ARG_NULL (type, NULL);
617 MONO_CHECK_ARG_NULL (lengths, NULL);
619 MONO_CHECK_ARG (lengths, mono_array_length (lengths) > 0, NULL);
621 MONO_CHECK_ARG (bounds, mono_array_length (lengths) == mono_array_length (bounds), NULL);
623 for (i = 0; i < mono_array_length (lengths); i++) {
624 if ((mono_array_get (lengths, gint64, i) < 0) ||
625 (mono_array_get (lengths, gint64, i) > MONO_ARRAY_MAX_INDEX)) {
626 mono_set_pending_exception (mono_get_exception_argument_out_of_range (NULL));
631 klass = mono_class_from_mono_type (type->type);
632 mono_class_init_checked (klass, &error);
633 if (mono_error_set_pending_exception (&error))
636 if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint64, 0) != 0))
637 /* vectors are not the same as one dimensional arrays with no-zero bounds */
642 aklass = mono_bounded_array_class_get (klass, mono_array_length (lengths), bounded);
644 sizes = (uintptr_t *)alloca (aklass->rank * sizeof(intptr_t) * 2);
645 for (i = 0; i < aklass->rank; ++i) {
646 sizes [i] = mono_array_get (lengths, guint64, i);
648 sizes [i + aklass->rank] = (mono_array_size_t) mono_array_get (bounds, guint64, i);
650 sizes [i + aklass->rank] = 0;
653 array = mono_array_new_full_checked (mono_object_domain (type), aklass, sizes, (intptr_t*)sizes + aklass->rank, &error);
654 mono_error_set_pending_exception (&error);
660 ves_icall_System_Array_GetRank (MonoObject *arr)
662 return arr->vtable->klass->rank;
666 ves_icall_System_Array_GetLength (MonoArray *arr, gint32 dimension)
668 gint32 rank = arr->obj.vtable->klass->rank;
671 if ((dimension < 0) || (dimension >= rank)) {
672 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
676 if (arr->bounds == NULL)
677 length = arr->max_length;
679 length = arr->bounds [dimension].length;
681 #ifdef MONO_BIG_ARRAYS
682 if (length > G_MAXINT32) {
683 mono_set_pending_exception (mono_get_exception_overflow ());
691 ves_icall_System_Array_GetLongLength (MonoArray *arr, gint32 dimension)
693 gint32 rank = arr->obj.vtable->klass->rank;
695 if ((dimension < 0) || (dimension >= rank)) {
696 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
700 if (arr->bounds == NULL)
701 return arr->max_length;
703 return arr->bounds [dimension].length;
707 ves_icall_System_Array_GetLowerBound (MonoArray *arr, gint32 dimension)
709 gint32 rank = arr->obj.vtable->klass->rank;
711 if ((dimension < 0) || (dimension >= rank)) {
712 mono_set_pending_exception (mono_get_exception_index_out_of_range ());
716 if (arr->bounds == NULL)
719 return arr->bounds [dimension].lower_bound;
723 ves_icall_System_Array_ClearInternal (MonoArray *arr, int idx, int length)
725 int sz = mono_array_element_size (mono_object_class (arr));
726 mono_gc_bzero_atomic (mono_array_addr_with_size_fast (arr, sz, idx), length * sz);
729 ICALL_EXPORT MonoArray*
730 ves_icall_System_Array_Clone (MonoArray *arr)
733 MonoArray *result = mono_array_clone_checked (arr, &error);
734 mono_error_set_pending_exception (&error);
738 ICALL_EXPORT gboolean
739 ves_icall_System_Array_FastCopy (MonoArray *source, int source_idx, MonoArray* dest, int dest_idx, int length)
744 MonoVTable *src_vtable;
745 MonoVTable *dest_vtable;
746 MonoClass *src_class;
747 MonoClass *dest_class;
749 src_vtable = source->obj.vtable;
750 dest_vtable = dest->obj.vtable;
752 if (src_vtable->rank != dest_vtable->rank)
755 if (source->bounds || dest->bounds)
758 /* there's no integer overflow since mono_array_length returns an unsigned integer */
759 if ((dest_idx + length > mono_array_length_fast (dest)) ||
760 (source_idx + length > mono_array_length_fast (source)))
763 src_class = src_vtable->klass->element_class;
764 dest_class = dest_vtable->klass->element_class;
767 * Handle common cases.
770 /* Case1: object[] -> valuetype[] (ArrayList::ToArray)
771 We fallback to managed here since we need to typecheck each boxed valuetype before storing them in the dest array.
773 if (src_class == mono_defaults.object_class && dest_class->valuetype)
776 /* Check if we're copying a char[] <==> (u)short[] */
777 if (src_class != dest_class) {
778 if (dest_class->valuetype || dest_class->enumtype || src_class->valuetype || src_class->enumtype)
781 /* It's only safe to copy between arrays if we can ensure the source will always have a subtype of the destination. We bail otherwise. */
782 if (!mono_class_is_subclass_of (src_class, dest_class, FALSE))
786 if (dest_class->valuetype) {
787 element_size = mono_array_element_size (source->obj.vtable->klass);
788 source_addr = mono_array_addr_with_size_fast (source, element_size, source_idx);
789 if (dest_class->has_references) {
790 mono_value_copy_array (dest, dest_idx, source_addr, length);
792 dest_addr = mono_array_addr_with_size_fast (dest, element_size, dest_idx);
793 mono_gc_memmove_atomic (dest_addr, source_addr, element_size * length);
796 mono_array_memcpy_refs_fast (dest, dest_idx, source, source_idx, length);
803 ves_icall_System_Array_GetGenericValueImpl (MonoArray *arr, guint32 pos, gpointer value)
809 ac = (MonoClass *)arr->obj.vtable->klass;
811 esize = mono_array_element_size (ac);
812 ea = (gpointer*)((char*)arr->vector + (pos * esize));
814 mono_gc_memmove_atomic (value, ea, esize);
818 ves_icall_System_Array_SetGenericValueImpl (MonoArray *arr, guint32 pos, gpointer value)
824 ac = (MonoClass *)arr->obj.vtable->klass;
825 ec = ac->element_class;
827 esize = mono_array_element_size (ac);
828 ea = (gpointer*)((char*)arr->vector + (pos * esize));
830 if (MONO_TYPE_IS_REFERENCE (&ec->byval_arg)) {
831 g_assert (esize == sizeof (gpointer));
832 mono_gc_wbarrier_generic_store (ea, *(MonoObject **)value);
834 g_assert (ec->inited);
835 g_assert (esize == mono_class_value_size (ec, NULL));
836 if (ec->has_references)
837 mono_gc_wbarrier_value_copy (ea, value, 1, ec);
839 mono_gc_memmove_atomic (ea, value, esize);
844 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_InitializeArray (MonoArrayHandle array, MonoClassField *field_handle, MonoError *error)
846 mono_error_init (error);
848 MonoClass *klass = mono_handle_class (array);
849 guint32 size = mono_array_element_size (klass);
850 MonoType *type = mono_type_get_underlying_type (&klass->element_class->byval_arg);
852 const char *field_data;
854 if (MONO_TYPE_IS_REFERENCE (type) || type->type == MONO_TYPE_VALUETYPE) {
855 mono_error_set_argument (error, "array", "Cannot initialize array of non-primitive type");
859 if (!(field_handle->type->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA)) {
860 mono_error_set_argument (error, "field_handle", "Field '%s' doesn't have an RVA", mono_field_get_name (field_handle));
864 size *= MONO_HANDLE_GETVAL(array, max_length);
865 field_data = mono_field_get_data (field_handle);
867 if (size > mono_type_size (field_handle->type, &align)) {
868 mono_error_set_argument (error, "field_handle", "Field not large enough to fill array");
872 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
874 guint ## n *data = (guint ## n *) mono_array_addr (MONO_HANDLE_RAW(array), char, 0); \
875 guint ## n *src = (guint ## n *) field_data; \
877 nEnt = (size / sizeof(guint ## n)); \
879 for (i = 0; i < nEnt; i++) { \
880 data[i] = read ## n (&src[i]); \
884 /* printf ("Initialize array with elements of %s type\n", klass->element_class->name); */
886 switch (type->type) {
903 memcpy (mono_array_addr (MONO_HANDLE_RAW(array), char, 0), field_data, size);
907 memcpy (mono_array_addr (MONO_HANDLE_RAW(array), char, 0), field_data, size);
912 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData (void)
914 return offsetof (MonoString, chars);
917 ICALL_EXPORT MonoObject *
918 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetObjectValue (MonoObject *obj)
920 if ((obj == NULL) || (! (obj->vtable->klass->valuetype)))
924 MonoObject *ret = mono_object_clone_checked (obj, &error);
925 mono_error_set_pending_exception (&error);
932 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor (MonoType *handle)
938 MONO_CHECK_ARG_NULL (handle,);
940 klass = mono_class_from_mono_type (handle);
941 MONO_CHECK_ARG (handle, klass,);
943 if (mono_class_is_gtd (klass))
946 vtable = mono_class_vtable_full (mono_domain_get (), klass, &error);
947 if (!is_ok (&error)) {
948 mono_error_set_pending_exception (&error);
952 /* This will call the type constructor */
953 if (!mono_runtime_class_init_full (vtable, &error))
954 mono_error_set_pending_exception (&error);
958 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunModuleConstructor (MonoImage *image)
962 mono_image_check_for_module_cctor (image);
963 if (image->has_module_cctor) {
964 MonoClass *module_klass = mono_class_get_checked (image, MONO_TOKEN_TYPE_DEF | 1, &error);
965 if (!mono_error_ok (&error)) {
966 mono_error_set_pending_exception (&error);
969 /*It's fine to raise the exception here*/
970 MonoVTable * vtable = mono_class_vtable_full (mono_domain_get (), module_klass, &error);
971 if (!is_ok (&error)) {
972 mono_error_set_pending_exception (&error);
975 if (!mono_runtime_class_init_full (vtable, &error))
976 mono_error_set_pending_exception (&error);
980 ICALL_EXPORT MonoBoolean
981 ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_SufficientExecutionStack (void)
983 #if defined(TARGET_WIN32) || defined(HOST_WIN32)
984 // It does not work on win32
990 MonoInternalThread *thread;
992 mono_thread_info_get_stack_bounds (&stack_addr, &stack_size);
993 /* if we have no info we are optimistic and assume there is enough room */
997 thread = mono_thread_internal_current ();
998 // .net seems to check that at least 50% of stack is available
999 min_size = thread->stack_size / 2;
1001 // TODO: It's not always set
1005 current = (guint8 *)&stack_addr;
1006 if (current > stack_addr) {
1007 if ((current - stack_addr) < min_size)
1010 if (current - (stack_addr - stack_size) < min_size)
1017 ICALL_EXPORT MonoObject *
1018 ves_icall_System_Object_MemberwiseClone (MonoObject *this_obj)
1021 MonoObject *ret = mono_object_clone_checked (this_obj, &error);
1022 mono_error_set_pending_exception (&error);
1028 ves_icall_System_ValueType_InternalGetHashCode (MonoObject *this_obj, MonoArray **fields)
1032 MonoObject **values = NULL;
1035 gint32 result = (int)(gsize)mono_defaults.int32_class;
1036 MonoClassField* field;
1039 klass = mono_object_class (this_obj);
1041 if (mono_class_num_fields (klass) == 0)
1045 * Compute the starting value of the hashcode for fields of primitive
1046 * types, and return the remaining fields in an array to the managed side.
1047 * This way, we can avoid costly reflection operations in managed code.
1050 while ((field = mono_class_get_fields (klass, &iter))) {
1051 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
1053 if (mono_field_is_deleted (field))
1055 /* FIXME: Add more types */
1056 switch (field->type->type) {
1058 result ^= *(gint32*)((guint8*)this_obj + field->offset);
1060 case MONO_TYPE_STRING: {
1062 s = *(MonoString**)((guint8*)this_obj + field->offset);
1064 result ^= mono_string_hash (s);
1069 values = g_newa (MonoObject*, mono_class_num_fields (klass));
1070 o = mono_field_get_value_object_checked (mono_object_domain (this_obj), field, this_obj, &error);
1071 if (!is_ok (&error)) {
1072 mono_error_set_pending_exception (&error);
1075 values [count++] = o;
1081 MonoArray *fields_arr = mono_array_new_checked (mono_domain_get (), mono_defaults.object_class, count, &error);
1082 if (mono_error_set_pending_exception (&error))
1084 mono_gc_wbarrier_generic_store (fields, (MonoObject*) fields_arr);
1085 for (i = 0; i < count; ++i)
1086 mono_array_setref (*fields, i, values [i]);
1093 ICALL_EXPORT MonoBoolean
1094 ves_icall_System_ValueType_Equals (MonoObject *this_obj, MonoObject *that, MonoArray **fields)
1098 MonoObject **values = NULL;
1100 MonoClassField* field;
1104 MONO_CHECK_ARG_NULL (that, FALSE);
1106 if (this_obj->vtable != that->vtable)
1109 klass = mono_object_class (this_obj);
1111 if (klass->enumtype && mono_class_enum_basetype (klass) && mono_class_enum_basetype (klass)->type == MONO_TYPE_I4)
1112 return (*(gint32*)((guint8*)this_obj + sizeof (MonoObject)) == *(gint32*)((guint8*)that + sizeof (MonoObject)));
1115 * Do the comparison for fields of primitive type and return a result if
1116 * possible. Otherwise, return the remaining fields in an array to the
1117 * managed side. This way, we can avoid costly reflection operations in
1122 while ((field = mono_class_get_fields (klass, &iter))) {
1123 if (field->type->attrs & FIELD_ATTRIBUTE_STATIC)
1125 if (mono_field_is_deleted (field))
1127 /* FIXME: Add more types */
1128 switch (field->type->type) {
1131 case MONO_TYPE_BOOLEAN:
1132 if (*((guint8*)this_obj + field->offset) != *((guint8*)that + field->offset))
1137 case MONO_TYPE_CHAR:
1138 if (*(gint16*)((guint8*)this_obj + field->offset) != *(gint16*)((guint8*)that + field->offset))
1143 if (*(gint32*)((guint8*)this_obj + field->offset) != *(gint32*)((guint8*)that + field->offset))
1148 if (*(gint64*)((guint8*)this_obj + field->offset) != *(gint64*)((guint8*)that + field->offset))
1152 if (*(float*)((guint8*)this_obj + field->offset) != *(float*)((guint8*)that + field->offset))
1156 if (*(double*)((guint8*)this_obj + field->offset) != *(double*)((guint8*)that + field->offset))
1161 case MONO_TYPE_STRING: {
1162 MonoString *s1, *s2;
1163 guint32 s1len, s2len;
1164 s1 = *(MonoString**)((guint8*)this_obj + field->offset);
1165 s2 = *(MonoString**)((guint8*)that + field->offset);
1168 if ((s1 == NULL) || (s2 == NULL))
1170 s1len = mono_string_length (s1);
1171 s2len = mono_string_length (s2);
1175 if (memcmp (mono_string_chars (s1), mono_string_chars (s2), s1len * sizeof (gunichar2)) != 0)
1181 values = g_newa (MonoObject*, mono_class_num_fields (klass) * 2);
1182 o = mono_field_get_value_object_checked (mono_object_domain (this_obj), field, this_obj, &error);
1183 if (!is_ok (&error)) {
1184 mono_error_set_pending_exception (&error);
1187 values [count++] = o;
1188 o = mono_field_get_value_object_checked (mono_object_domain (this_obj), field, that, &error);
1189 if (!is_ok (&error)) {
1190 mono_error_set_pending_exception (&error);
1193 values [count++] = o;
1196 if (klass->enumtype)
1197 /* enums only have one non-static field */
1203 MonoArray *fields_arr = mono_array_new_checked (mono_domain_get (), mono_defaults.object_class, count, &error);
1204 if (mono_error_set_pending_exception (&error))
1206 mono_gc_wbarrier_generic_store (fields, (MonoObject*) fields_arr);
1207 for (i = 0; i < count; ++i)
1208 mono_array_setref_fast (*fields, i, values [i]);
1215 ICALL_EXPORT MonoReflectionType *
1216 ves_icall_System_Object_GetType (MonoObject *obj)
1219 MonoReflectionType *ret;
1220 #ifndef DISABLE_REMOTING
1221 if (obj->vtable->klass == mono_defaults.transparent_proxy_class)
1222 ret = mono_type_get_object_checked (mono_object_domain (obj), &((MonoTransparentProxy*)obj)->remote_class->proxy_class->byval_arg, &error);
1225 ret = mono_type_get_object_checked (mono_object_domain (obj), &obj->vtable->klass->byval_arg, &error);
1227 mono_error_set_pending_exception (&error);
1232 get_executing (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1234 MonoMethod **dest = (MonoMethod **)data;
1236 /* skip unmanaged frames */
1241 if (!strcmp (m->klass->name_space, "System.Reflection"))
1250 get_caller_no_reflection (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1252 MonoMethod **dest = (MonoMethod **)data;
1254 /* skip unmanaged frames */
1258 if (m->wrapper_type != MONO_WRAPPER_NONE)
1266 if (m->klass->image == mono_defaults.corlib && !strcmp (m->klass->name_space, "System.Reflection"))
1277 get_caller_no_system_or_reflection (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
1279 MonoMethod **dest = (MonoMethod **)data;
1281 /* skip unmanaged frames */
1285 if (m->wrapper_type != MONO_WRAPPER_NONE)
1293 if (m->klass->image == mono_defaults.corlib && ((!strcmp (m->klass->name_space, "System.Reflection"))
1294 || (!strcmp (m->klass->name_space, "System"))))
1304 static MonoReflectionType *
1305 type_from_parsed_name (MonoTypeNameParse *info, MonoBoolean ignoreCase, MonoAssembly **caller_assembly, MonoError *error)
1307 MonoMethod *m, *dest;
1309 MonoType *type = NULL;
1310 MonoAssembly *assembly = NULL;
1311 gboolean type_resolve = FALSE;
1312 MonoImage *rootimage = NULL;
1314 mono_error_init (error);
1317 * We must compute the calling assembly as type loading must happen under a metadata context.
1318 * For example. The main assembly is a.exe and Type.GetType is called from dir/b.dll. Without
1319 * the metadata context (basedir currently) set to dir/b.dll we won't be able to load a dir/c.dll.
1321 m = mono_method_get_last_managed ();
1323 if (m && m->klass->image != mono_defaults.corlib) {
1324 /* Happens with inlining */
1326 /* Ugly hack: type_from_parsed_name is called from
1327 * System.Type.internal_from_name, which is called most
1328 * directly from System.Type.GetType(string,bool,bool) but
1329 * also indirectly from places such as
1330 * System.Type.GetType(string,func,func) (via
1331 * System.TypeNameParser.GetType and System.TypeSpec.Resolve)
1332 * so we need to skip over all of those to find the true caller.
1334 * It would be nice if we had stack marks.
1336 mono_stack_walk_no_il (get_caller_no_system_or_reflection, &dest);
1342 * FIXME: mono_method_get_last_managed() sometimes returns NULL, thus
1343 * causing ves_icall_System_Reflection_Assembly_GetCallingAssembly()
1344 * to crash. This only seems to happen in some strange remoting
1345 * scenarios and I was unable to figure out what's happening there.
1346 * Dec 10, 2005 - Martin.
1350 assembly = dest->klass->image->assembly;
1351 type_resolve = TRUE;
1352 rootimage = assembly->image;
1354 g_warning (G_STRLOC);
1356 *caller_assembly = assembly;
1358 if (info->assembly.name)
1359 assembly = mono_assembly_load (&info->assembly, assembly ? assembly->basedir : NULL, NULL);
1362 /* When loading from the current assembly, AppDomain.TypeResolve will not be called yet */
1363 type = mono_reflection_get_type_checked (rootimage, assembly->image, info, ignoreCase, &type_resolve, error);
1364 return_val_if_nok (error, NULL);
1368 // Say we're looking for System.Generic.Dict<int, Local>
1369 // we FAIL the get type above, because S.G.Dict isn't in assembly->image. So we drop down here.
1370 // but then we FAIL AGAIN because now we pass null as the image and the rootimage and everything
1371 // is messed up when we go to construct the Local as the type arg...
1373 // By contrast, if we started with Mine<System.Generic.Dict<int, Local>> we'd go in with assembly->image
1374 // as the root and then even the detour into generics would still not screw us when we went to load Local.
1375 if (!info->assembly.name && !type) {
1377 type = mono_reflection_get_type_checked (rootimage, NULL, info, ignoreCase, &type_resolve, error);
1378 return_val_if_nok (error, NULL);
1380 if (assembly && !type && type_resolve) {
1381 type_resolve = FALSE; /* This will invoke TypeResolve if not done in the first 'if' */
1382 type = mono_reflection_get_type_checked (rootimage, assembly->image, info, ignoreCase, &type_resolve, error);
1383 return_val_if_nok (error, NULL);
1389 return mono_type_get_object_checked (mono_domain_get (), type, error);
1392 ICALL_EXPORT MonoReflectionType*
1393 ves_icall_System_Type_internal_from_name (MonoString *name,
1394 MonoBoolean throwOnError,
1395 MonoBoolean ignoreCase)
1398 MonoTypeNameParse info;
1399 MonoReflectionType *type = NULL;
1401 MonoAssembly *caller_assembly;
1403 char *str = mono_string_to_utf8_checked (name, &error);
1404 if (!is_ok (&error))
1407 parsedOk = mono_reflection_parse_type (str, &info);
1409 /* mono_reflection_parse_type() mangles the string */
1411 mono_reflection_free_type_info (&info);
1413 mono_error_set_argument (&error, "typeName", "failed parse: %s", str);
1417 type = type_from_parsed_name (&info, ignoreCase, &caller_assembly, &error);
1419 if (!is_ok (&error)) {
1420 mono_reflection_free_type_info (&info);
1426 char *tname = info.name_space ? g_strdup_printf ("%s.%s", info.name_space, info.name) : g_strdup (info.name);
1428 if (info.assembly.name)
1429 aname = mono_stringify_assembly_name (&info.assembly);
1430 else if (caller_assembly)
1431 aname = mono_stringify_assembly_name (mono_assembly_get_name (caller_assembly));
1433 aname = g_strdup ("");
1434 mono_error_set_type_load_name (&error, tname, aname, "");
1436 mono_reflection_free_type_info (&info);
1442 if (!is_ok (&error)) {
1444 mono_error_set_pending_exception (&error);
1446 mono_error_cleanup (&error);
1454 ICALL_EXPORT MonoReflectionType*
1455 ves_icall_System_Type_internal_from_handle (MonoType *handle)
1458 MonoReflectionType *ret;
1459 MonoDomain *domain = mono_domain_get ();
1461 ret = mono_type_get_object_checked (domain, handle, &error);
1462 mono_error_set_pending_exception (&error);
1467 ICALL_EXPORT MonoType*
1468 ves_icall_Mono_RuntimeClassHandle_GetTypeFromClass (MonoClass *klass)
1470 return mono_class_get_type (klass);
1474 ves_icall_Mono_RuntimeGPtrArrayHandle_GPtrArrayFree (GPtrArray *ptr_array)
1476 g_ptr_array_free (ptr_array, TRUE);
1480 ves_icall_Mono_SafeStringMarshal_GFree (void *c_str)
1486 ves_icall_Mono_SafeStringMarshal_StringToUtf8 (MonoString *s)
1489 char *res = mono_string_to_utf8_checked (s, &error);
1490 mono_error_set_pending_exception (&error);
1494 /* System.TypeCode */
1513 TYPECODE_STRING = 18
1516 ICALL_EXPORT guint32
1517 ves_icall_type_GetTypeCodeInternal (MonoReflectionType *type)
1519 int t = type->type->type;
1521 if (type->type->byref)
1522 return TYPECODE_OBJECT;
1526 case MONO_TYPE_VOID:
1527 return TYPECODE_OBJECT;
1528 case MONO_TYPE_BOOLEAN:
1529 return TYPECODE_BOOLEAN;
1531 return TYPECODE_BYTE;
1533 return TYPECODE_SBYTE;
1535 return TYPECODE_UINT16;
1537 return TYPECODE_INT16;
1538 case MONO_TYPE_CHAR:
1539 return TYPECODE_CHAR;
1543 return TYPECODE_OBJECT;
1545 return TYPECODE_UINT32;
1547 return TYPECODE_INT32;
1549 return TYPECODE_UINT64;
1551 return TYPECODE_INT64;
1553 return TYPECODE_SINGLE;
1555 return TYPECODE_DOUBLE;
1556 case MONO_TYPE_VALUETYPE: {
1557 MonoClass *klass = type->type->data.klass;
1559 if (klass->enumtype) {
1560 t = mono_class_enum_basetype (klass)->type;
1562 } else if (mono_is_corlib_image (klass->image)) {
1563 if (strcmp (klass->name_space, "System") == 0) {
1564 if (strcmp (klass->name, "Decimal") == 0)
1565 return TYPECODE_DECIMAL;
1566 else if (strcmp (klass->name, "DateTime") == 0)
1567 return TYPECODE_DATETIME;
1570 return TYPECODE_OBJECT;
1572 case MONO_TYPE_STRING:
1573 return TYPECODE_STRING;
1574 case MONO_TYPE_SZARRAY:
1575 case MONO_TYPE_ARRAY:
1576 case MONO_TYPE_OBJECT:
1578 case MONO_TYPE_MVAR:
1579 case MONO_TYPE_TYPEDBYREF:
1580 return TYPECODE_OBJECT;
1581 case MONO_TYPE_CLASS:
1583 MonoClass *klass = type->type->data.klass;
1584 if (klass->image == mono_defaults.corlib && strcmp (klass->name_space, "System") == 0) {
1585 if (strcmp (klass->name, "DBNull") == 0)
1586 return TYPECODE_DBNULL;
1589 return TYPECODE_OBJECT;
1590 case MONO_TYPE_GENERICINST:
1591 return TYPECODE_OBJECT;
1593 g_error ("type 0x%02x not handled in GetTypeCode()", t);
1599 mono_type_get_underlying_type_ignore_byref (MonoType *type)
1601 if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype)
1602 return mono_class_enum_basetype (type->data.klass);
1603 if (type->type == MONO_TYPE_GENERICINST && type->data.generic_class->container_class->enumtype)
1604 return mono_class_enum_basetype (type->data.generic_class->container_class);
1608 ICALL_EXPORT guint32
1609 ves_icall_RuntimeTypeHandle_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType *c)
1614 g_assert (type != NULL);
1616 klass = mono_class_from_mono_type (type->type);
1617 klassc = mono_class_from_mono_type (c->type);
1619 if (type->type->byref ^ c->type->byref)
1622 if (type->type->byref) {
1623 MonoType *t = mono_type_get_underlying_type_ignore_byref (type->type);
1624 MonoType *ot = mono_type_get_underlying_type_ignore_byref (c->type);
1626 klass = mono_class_from_mono_type (t);
1627 klassc = mono_class_from_mono_type (ot);
1629 if (mono_type_is_primitive (t)) {
1630 return mono_type_is_primitive (ot) && klass->instance_size == klassc->instance_size;
1631 } else if (t->type == MONO_TYPE_VAR || t->type == MONO_TYPE_MVAR) {
1632 return t->type == ot->type && t->data.generic_param->num == ot->data.generic_param->num;
1633 } else if (t->type == MONO_TYPE_PTR || t->type == MONO_TYPE_FNPTR) {
1634 return t->type == ot->type;
1636 if (ot->type == MONO_TYPE_VAR || ot->type == MONO_TYPE_MVAR)
1639 if (klass->valuetype)
1640 return klass == klassc;
1641 return klass->valuetype == klassc->valuetype;
1644 return mono_class_is_assignable_from (klass, klassc);
1647 ICALL_EXPORT guint32
1648 ves_icall_RuntimeTypeHandle_IsInstanceOfType (MonoReflectionType *type, MonoObject *obj)
1651 MonoClass *klass = mono_class_from_mono_type (type->type);
1652 mono_class_init_checked (klass, &error);
1653 if (!is_ok (&error)) {
1654 mono_error_set_pending_exception (&error);
1657 guint32 result = (mono_object_isinst_checked (obj, klass, &error) != NULL);
1658 mono_error_set_pending_exception (&error);
1662 ICALL_EXPORT guint32
1663 ves_icall_RuntimeTypeHandle_GetAttributes (MonoReflectionType *type)
1665 MonoClass *klass = mono_class_from_mono_type (type->type);
1666 return mono_class_get_flags (klass);
1669 ICALL_EXPORT MonoReflectionMarshalAsAttribute*
1670 ves_icall_System_Reflection_FieldInfo_get_marshal_info (MonoReflectionField *field)
1673 MonoClass *klass = field->field->parent;
1674 MonoMarshalType *info;
1678 MonoGenericClass *gklass = mono_class_try_get_generic_class (klass);
1679 if (mono_class_is_gtd (klass) ||
1680 (gklass && gklass->context.class_inst->is_open))
1683 ftype = mono_field_get_type (field->field);
1684 if (ftype && !(ftype->attrs & FIELD_ATTRIBUTE_HAS_FIELD_MARSHAL))
1687 info = mono_marshal_load_type_info (klass);
1689 for (i = 0; i < info->num_fields; ++i) {
1690 if (info->fields [i].field == field->field) {
1691 if (!info->fields [i].mspec)
1694 MonoReflectionMarshalAsAttribute* obj;
1695 obj = mono_reflection_marshal_as_attribute_from_marshal_spec (field->object.vtable->domain, klass, info->fields [i].mspec, &error);
1696 if (!mono_error_ok (&error))
1697 mono_error_set_pending_exception (&error);
1706 ICALL_EXPORT MonoReflectionField*
1707 ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoType *type)
1710 gboolean found = FALSE;
1716 klass = handle->parent;
1718 klass = mono_class_from_mono_type (type);
1720 found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1723 /* The managed code will throw the exception */
1727 MonoReflectionField *result = mono_field_get_object_checked (mono_domain_get (), klass, handle, &error);
1728 mono_error_set_pending_exception (&error);
1732 ICALL_EXPORT MonoReflectionEvent*
1733 ves_icall_System_Reflection_EventInfo_internal_from_handle_type (MonoEvent *handle, MonoType *type)
1741 klass = handle->parent;
1743 klass = mono_class_from_mono_type (type);
1745 gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1747 /* Managed code will throw an exception */
1751 MonoReflectionEvent *result = mono_event_get_object_checked (mono_domain_get (), klass, handle, &error);
1752 mono_error_set_pending_exception (&error);
1757 ICALL_EXPORT MonoReflectionProperty*
1758 ves_icall_System_Reflection_PropertyInfo_internal_from_handle_type (MonoProperty *handle, MonoType *type)
1766 klass = handle->parent;
1768 klass = mono_class_from_mono_type (type);
1770 gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1772 /* Managed code will throw an exception */
1776 MonoReflectionProperty *result = mono_property_get_object_checked (mono_domain_get (), klass, handle, &error);
1777 mono_error_set_pending_exception (&error);
1781 ICALL_EXPORT MonoArray*
1782 ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionField *field, MonoBoolean optional)
1785 MonoType *type = mono_field_get_type_checked (field->field, &error);
1788 if (!mono_error_ok (&error)) {
1789 mono_error_set_pending_exception (&error);
1793 res = type_array_from_modifiers (field->field->parent->image, type, optional, &error);
1794 mono_error_set_pending_exception (&error);
1799 vell_icall_get_method_attributes (MonoMethod *method)
1801 return method->flags;
1805 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
1808 MonoReflectionType *rt;
1809 MonoDomain *domain = mono_domain_get ();
1810 MonoMethodSignature* sig;
1812 sig = mono_method_signature_checked (method, &error);
1813 if (!mono_error_ok (&error)) {
1814 mono_error_set_pending_exception (&error);
1818 rt = mono_type_get_object_checked (domain, &method->klass->byval_arg, &error);
1819 if (!mono_error_ok (&error)) {
1820 mono_error_set_pending_exception (&error);
1824 MONO_STRUCT_SETREF (info, parent, rt);
1826 rt = mono_type_get_object_checked (domain, sig->ret, &error);
1827 if (!mono_error_ok (&error)) {
1828 mono_error_set_pending_exception (&error);
1832 MONO_STRUCT_SETREF (info, ret, rt);
1834 info->attrs = method->flags;
1835 info->implattrs = method->iflags;
1836 if (sig->call_convention == MONO_CALL_DEFAULT)
1837 info->callconv = sig->sentinelpos >= 0 ? 2 : 1;
1839 if (sig->call_convention == MONO_CALL_VARARG || sig->sentinelpos >= 0)
1844 info->callconv |= (sig->hasthis << 5) | (sig->explicit_this << 6);
1847 ICALL_EXPORT MonoArray*
1848 ves_icall_get_parameter_info (MonoMethod *method, MonoReflectionMethod *member)
1851 MonoDomain *domain = mono_domain_get ();
1853 MonoArray *result = mono_param_get_objects_internal (domain, method, member->reftype ? mono_class_from_mono_type (member->reftype->type) : NULL, &error);
1854 mono_error_set_pending_exception (&error);
1858 ICALL_EXPORT MonoReflectionMarshalAsAttribute*
1859 ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod *method)
1862 MonoDomain *domain = mono_domain_get ();
1863 MonoReflectionMarshalAsAttribute* res = NULL;
1864 MonoMarshalSpec **mspecs;
1867 mspecs = g_new (MonoMarshalSpec*, mono_method_signature (method)->param_count + 1);
1868 mono_method_get_marshal_info (method, mspecs);
1871 res = mono_reflection_marshal_as_attribute_from_marshal_spec (domain, method->klass, mspecs [0], &error);
1872 if (!mono_error_ok (&error)) {
1873 mono_error_set_pending_exception (&error);
1878 for (i = mono_method_signature (method)->param_count; i >= 0; i--)
1880 mono_metadata_free_marshal_spec (mspecs [i]);
1887 ves_icall_MonoField_GetFieldOffset (MonoReflectionField *field)
1889 MonoClass *parent = field->field->parent;
1890 mono_class_setup_fields (parent);
1892 return field->field->offset - sizeof (MonoObject);
1895 ICALL_EXPORT MonoReflectionType*
1896 ves_icall_MonoField_GetParentType (MonoReflectionField *field, MonoBoolean declaring)
1899 MonoReflectionType *ret;
1902 parent = declaring? field->field->parent: field->klass;
1904 ret = mono_type_get_object_checked (mono_object_domain (field), &parent->byval_arg, &error);
1905 mono_error_set_pending_exception (&error);
1911 ICALL_EXPORT MonoObject *
1912 ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj)
1915 MonoClass *fklass = field->klass;
1916 MonoClassField *cf = field->field;
1917 MonoDomain *domain = mono_object_domain (field);
1919 if (fklass->image->assembly->ref_only) {
1920 mono_set_pending_exception (mono_get_exception_invalid_operation (
1921 "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
1925 if (mono_security_core_clr_enabled () &&
1926 !mono_security_core_clr_ensure_reflection_access_field (cf, &error)) {
1927 mono_error_set_pending_exception (&error);
1931 MonoObject * result = mono_field_get_value_object_checked (domain, cf, obj, &error);
1932 mono_error_set_pending_exception (&error);
1937 ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value)
1940 MonoClassField *cf = field->field;
1944 if (field->klass->image->assembly->ref_only) {
1945 mono_set_pending_exception (mono_get_exception_invalid_operation (
1946 "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
1950 if (mono_security_core_clr_enabled () &&
1951 !mono_security_core_clr_ensure_reflection_access_field (cf, &error)) {
1952 mono_error_set_pending_exception (&error);
1956 type = mono_field_get_type_checked (cf, &error);
1957 if (!mono_error_ok (&error)) {
1958 mono_error_set_pending_exception (&error);
1962 v = (gchar *) value;
1964 switch (type->type) {
1967 case MONO_TYPE_BOOLEAN:
1970 case MONO_TYPE_CHAR:
1979 case MONO_TYPE_VALUETYPE:
1982 v += sizeof (MonoObject);
1984 case MONO_TYPE_STRING:
1985 case MONO_TYPE_OBJECT:
1986 case MONO_TYPE_CLASS:
1987 case MONO_TYPE_ARRAY:
1988 case MONO_TYPE_SZARRAY:
1991 case MONO_TYPE_GENERICINST: {
1992 MonoGenericClass *gclass = type->data.generic_class;
1993 g_assert (!gclass->context.class_inst->is_open);
1995 if (mono_class_is_nullable (mono_class_from_mono_type (type))) {
1996 MonoClass *nklass = mono_class_from_mono_type (type);
1997 MonoObject *nullable;
2000 * Convert the boxed vtype into a Nullable structure.
2001 * This is complicated by the fact that Nullables have
2002 * a variable structure.
2004 nullable = mono_object_new_checked (mono_domain_get (), nklass, &error);
2005 if (!mono_error_ok (&error)) {
2006 mono_error_set_pending_exception (&error);
2010 mono_nullable_init ((guint8 *)mono_object_unbox (nullable), value, nklass);
2012 v = (gchar *)mono_object_unbox (nullable);
2015 if (gclass->container_class->valuetype && (v != NULL))
2016 v += sizeof (MonoObject);
2020 g_error ("type 0x%x not handled in "
2021 "ves_icall_FieldInfo_SetValueInternal", type->type);
2026 if (type->attrs & FIELD_ATTRIBUTE_STATIC) {
2027 MonoVTable *vtable = mono_class_vtable_full (mono_object_domain (field), cf->parent, &error);
2028 if (!is_ok (&error)) {
2029 mono_error_set_pending_exception (&error);
2032 if (!vtable->initialized) {
2033 if (!mono_runtime_class_init_full (vtable, &error)) {
2034 mono_error_set_pending_exception (&error);
2038 mono_field_static_set_value (vtable, cf, v);
2040 mono_field_set_value (obj, cf, v);
2045 ves_icall_System_RuntimeFieldHandle_SetValueDirect (MonoReflectionField *field, MonoReflectionType *field_type, MonoTypedRef *obj, MonoObject *value, MonoReflectionType *context_type)
2054 if (!MONO_TYPE_ISSTRUCT (&f->parent->byval_arg)) {
2055 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2059 if (MONO_TYPE_IS_REFERENCE (f->type))
2060 mono_copy_value (f->type, (guint8*)obj->value + f->offset - sizeof (MonoObject), value, FALSE);
2062 mono_copy_value (f->type, (guint8*)obj->value + f->offset - sizeof (MonoObject), mono_object_unbox (value), FALSE);
2065 ICALL_EXPORT MonoObject *
2066 ves_icall_MonoField_GetRawConstantValue (MonoReflectionField *rfield)
2068 MonoObject *o = NULL;
2069 MonoClassField *field = rfield->field;
2071 MonoDomain *domain = mono_object_domain (rfield);
2073 MonoTypeEnum def_type;
2074 const char *def_value;
2078 mono_class_init (field->parent);
2080 t = mono_field_get_type_checked (field, &error);
2081 if (!mono_error_ok (&error)) {
2082 mono_error_set_pending_exception (&error);
2086 if (!(t->attrs & FIELD_ATTRIBUTE_HAS_DEFAULT)) {
2087 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2091 if (image_is_dynamic (field->parent->image)) {
2092 MonoClass *klass = field->parent;
2093 int fidx = field - klass->fields;
2094 MonoFieldDefaultValue *def_values = mono_class_get_field_def_values (klass);
2096 g_assert (def_values);
2097 def_type = def_values [fidx].def_type;
2098 def_value = def_values [fidx].data;
2100 if (def_type == MONO_TYPE_END) {
2101 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2105 def_value = mono_class_get_field_default_value (field, &def_type);
2106 /* FIXME, maybe we should try to raise TLE if field->parent is broken */
2108 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2113 /*FIXME unify this with reflection.c:mono_get_object_from_blob*/
2117 case MONO_TYPE_BOOLEAN:
2120 case MONO_TYPE_CHAR:
2128 case MONO_TYPE_R8: {
2131 /* boxed value type */
2132 t = g_new0 (MonoType, 1);
2134 klass = mono_class_from_mono_type (t);
2136 o = mono_object_new_checked (domain, klass, &error);
2137 if (!mono_error_ok (&error)) {
2138 mono_error_set_pending_exception (&error);
2141 v = ((gchar *) o) + sizeof (MonoObject);
2142 mono_get_constant_value_from_blob (domain, def_type, def_value, v, &error);
2143 if (mono_error_set_pending_exception (&error))
2147 case MONO_TYPE_STRING:
2148 case MONO_TYPE_CLASS:
2149 mono_get_constant_value_from_blob (domain, def_type, def_value, &o, &error);
2150 if (mono_error_set_pending_exception (&error))
2154 g_assert_not_reached ();
2160 ICALL_EXPORT MonoReflectionType*
2161 ves_icall_MonoField_ResolveType (MonoReflectionField *ref_field)
2164 MonoReflectionType *ret;
2167 type = mono_field_get_type_checked (ref_field->field, &error);
2168 if (!mono_error_ok (&error)) {
2169 mono_error_set_pending_exception (&error);
2173 ret = mono_type_get_object_checked (mono_object_domain (ref_field), type, &error);
2174 if (!mono_error_ok (&error)) {
2175 mono_error_set_pending_exception (&error);
2182 /* From MonoProperty.cs */
2184 PInfo_Attributes = 1,
2185 PInfo_GetMethod = 1 << 1,
2186 PInfo_SetMethod = 1 << 2,
2187 PInfo_ReflectedType = 1 << 3,
2188 PInfo_DeclaringType = 1 << 4,
2193 ves_icall_MonoPropertyInfo_get_property_info (const MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
2196 MonoReflectionType *rt;
2197 MonoReflectionMethod *rm;
2198 MonoDomain *domain = mono_object_domain (property);
2199 const MonoProperty *pproperty = property->property;
2201 if ((req_info & PInfo_ReflectedType) != 0) {
2202 rt = mono_type_get_object_checked (domain, &property->klass->byval_arg, &error);
2203 if (mono_error_set_pending_exception (&error))
2206 MONO_STRUCT_SETREF (info, parent, rt);
2208 if ((req_info & PInfo_DeclaringType) != 0) {
2209 rt = mono_type_get_object_checked (domain, &pproperty->parent->byval_arg, &error);
2210 if (mono_error_set_pending_exception (&error))
2213 MONO_STRUCT_SETREF (info, declaring_type, rt);
2216 if ((req_info & PInfo_Name) != 0)
2217 MONO_STRUCT_SETREF (info, name, mono_string_new (domain, pproperty->name));
2219 if ((req_info & PInfo_Attributes) != 0)
2220 info->attrs = pproperty->attrs;
2222 if ((req_info & PInfo_GetMethod) != 0) {
2223 if (pproperty->get &&
2224 (((pproperty->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) ||
2225 pproperty->get->klass == property->klass)) {
2226 rm = mono_method_get_object_checked (domain, pproperty->get, property->klass, &error);
2227 if (mono_error_set_pending_exception (&error))
2233 MONO_STRUCT_SETREF (info, get, rm);
2235 if ((req_info & PInfo_SetMethod) != 0) {
2236 if (pproperty->set &&
2237 (((pproperty->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) ||
2238 pproperty->set->klass == property->klass)) {
2239 rm = mono_method_get_object_checked (domain, pproperty->set, property->klass, &error);
2240 if (mono_error_set_pending_exception (&error))
2246 MONO_STRUCT_SETREF (info, set, rm);
2249 * There may be other methods defined for properties, though, it seems they are not exposed
2250 * in the reflection API
2255 ves_icall_MonoEventInfo_get_event_info (MonoReflectionMonoEvent *event, MonoEventInfo *info)
2258 MonoReflectionType *rt;
2259 MonoReflectionMethod *rm;
2260 MonoDomain *domain = mono_object_domain (event);
2262 rt = mono_type_get_object_checked (domain, &event->klass->byval_arg, &error);
2263 if (mono_error_set_pending_exception (&error))
2266 MONO_STRUCT_SETREF (info, reflected_type, rt);
2268 rt = mono_type_get_object_checked (domain, &event->event->parent->byval_arg, &error);
2269 if (mono_error_set_pending_exception (&error))
2272 MONO_STRUCT_SETREF (info, declaring_type, rt);
2274 MONO_STRUCT_SETREF (info, name, mono_string_new (domain, event->event->name));
2275 info->attrs = event->event->attrs;
2277 if (event->event->add) {
2278 rm = mono_method_get_object_checked (domain, event->event->add, NULL, &error);
2279 if (mono_error_set_pending_exception (&error))
2285 MONO_STRUCT_SETREF (info, add_method, rm);
2287 if (event->event->remove) {
2288 rm = mono_method_get_object_checked (domain, event->event->remove, NULL, &error);
2289 if (mono_error_set_pending_exception (&error))
2295 MONO_STRUCT_SETREF (info, remove_method, rm);
2297 if (event->event->raise) {
2298 rm = mono_method_get_object_checked (domain, event->event->raise, NULL, &error);
2299 if (mono_error_set_pending_exception (&error))
2305 MONO_STRUCT_SETREF (info, raise_method, rm);
2307 #ifndef MONO_SMALL_CONFIG
2308 if (event->event->other) {
2310 while (event->event->other [n])
2312 MonoArray *info_arr = mono_array_new_checked (domain, mono_defaults.method_info_class, n, &error);
2313 if (mono_error_set_pending_exception (&error))
2315 MONO_STRUCT_SETREF (info, other_methods, info_arr);
2317 for (i = 0; i < n; i++) {
2318 rm = mono_method_get_object_checked (domain, event->event->other [i], NULL, &error);
2319 if (mono_error_set_pending_exception (&error))
2321 mono_array_setref (info->other_methods, i, rm);
2328 collect_interfaces (MonoClass *klass, GHashTable *ifaces, MonoError *error)
2333 mono_class_setup_interfaces (klass, error);
2334 if (!mono_error_ok (error))
2337 for (i = 0; i < klass->interface_count; i++) {
2338 ic = klass->interfaces [i];
2339 g_hash_table_insert (ifaces, ic, ic);
2341 collect_interfaces (ic, ifaces, error);
2342 if (!mono_error_ok (error))
2348 MonoArray *iface_array;
2349 MonoGenericContext *context;
2353 } FillIfaceArrayData;
2356 fill_iface_array (gpointer key, gpointer value, gpointer user_data)
2358 MonoReflectionType *rt;
2359 FillIfaceArrayData *data = (FillIfaceArrayData *)user_data;
2360 MonoClass *ic = (MonoClass *)key;
2361 MonoType *ret = &ic->byval_arg, *inflated = NULL;
2363 if (!mono_error_ok (data->error))
2366 if (data->context && mono_class_is_ginst (ic) && mono_class_get_generic_class (ic)->context.class_inst->is_open) {
2367 inflated = ret = mono_class_inflate_generic_type_checked (ret, data->context, data->error);
2368 if (!mono_error_ok (data->error))
2372 rt = mono_type_get_object_checked (data->domain, ret, data->error);
2373 if (!mono_error_ok (data->error))
2376 mono_array_setref (data->iface_array, data->next_idx++, rt);
2379 mono_metadata_free_type (inflated);
2383 get_interfaces_hash (gconstpointer v1)
2385 MonoClass *k = (MonoClass*)v1;
2387 return k->type_token;
2390 ICALL_EXPORT MonoArray*
2391 ves_icall_RuntimeType_GetInterfaces (MonoReflectionType* type)
2394 MonoClass *klass = mono_class_from_mono_type (type->type);
2396 FillIfaceArrayData data = { 0 };
2399 GHashTable *iface_hash = g_hash_table_new (get_interfaces_hash, NULL);
2401 if (mono_class_is_ginst (klass) && mono_class_get_generic_class (klass)->context.class_inst->is_open) {
2402 data.context = mono_class_get_context (klass);
2403 klass = mono_class_get_generic_class (klass)->container_class;
2406 for (parent = klass; parent; parent = parent->parent) {
2407 mono_class_setup_interfaces (parent, &error);
2408 if (!mono_error_ok (&error))
2410 collect_interfaces (parent, iface_hash, &error);
2411 if (!mono_error_ok (&error))
2415 data.error = &error;
2416 data.domain = mono_object_domain (type);
2418 len = g_hash_table_size (iface_hash);
2420 g_hash_table_destroy (iface_hash);
2421 if (!data.domain->empty_types) {
2422 data.domain->empty_types = mono_array_new_cached (data.domain, mono_defaults.runtimetype_class, 0, &error);
2423 if (!is_ok (&error))
2426 return data.domain->empty_types;
2429 data.iface_array = mono_array_new_cached (data.domain, mono_defaults.runtimetype_class, len, &error);
2430 if (!is_ok (&error))
2432 g_hash_table_foreach (iface_hash, fill_iface_array, &data);
2433 if (!mono_error_ok (&error))
2436 g_hash_table_destroy (iface_hash);
2437 return data.iface_array;
2440 g_hash_table_destroy (iface_hash);
2441 mono_error_set_pending_exception (&error);
2446 ves_icall_RuntimeType_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType *iface, MonoArray **targets, MonoArray **methods)
2448 gboolean variance_used;
2449 MonoClass *klass = mono_class_from_mono_type (type->type);
2450 MonoClass *iclass = mono_class_from_mono_type (iface->type);
2451 MonoReflectionMethod *member;
2454 int i = 0, len, ioffset;
2458 mono_class_init_checked (klass, &error);
2459 if (mono_error_set_pending_exception (&error))
2461 mono_class_init_checked (iclass, &error);
2462 if (mono_error_set_pending_exception (&error))
2465 mono_class_setup_vtable (klass);
2467 ioffset = mono_class_interface_offset_with_variance (klass, iclass, &variance_used);
2471 len = mono_class_num_methods (iclass);
2472 domain = mono_object_domain (type);
2473 MonoArray *targets_arr = mono_array_new_checked (domain, mono_defaults.method_info_class, len, &error);
2474 if (mono_error_set_pending_exception (&error))
2476 mono_gc_wbarrier_generic_store (targets, (MonoObject*) targets_arr);
2477 MonoArray *methods_arr = mono_array_new_checked (domain, mono_defaults.method_info_class, len, &error);
2478 if (mono_error_set_pending_exception (&error))
2480 mono_gc_wbarrier_generic_store (methods, (MonoObject*) methods_arr);
2482 while ((method = mono_class_get_methods (iclass, &iter))) {
2483 member = mono_method_get_object_checked (domain, method, iclass, &error);
2484 if (mono_error_set_pending_exception (&error))
2486 mono_array_setref (*methods, i, member);
2487 member = mono_method_get_object_checked (domain, klass->vtable [i + ioffset], klass, &error);
2488 if (mono_error_set_pending_exception (&error))
2490 mono_array_setref (*targets, i, member);
2497 ves_icall_RuntimeType_GetPacking (MonoReflectionType *type, guint32 *packing, guint32 *size)
2500 MonoClass *klass = mono_class_from_mono_type (type->type);
2502 mono_class_init_checked (klass, &error);
2503 if (mono_error_set_pending_exception (&error))
2506 if (image_is_dynamic (klass->image)) {
2507 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)type;
2508 *packing = tb->packing_size;
2509 *size = tb->class_size;
2511 mono_metadata_packing_from_typedef (klass->image, klass->type_token, packing, size);
2515 ICALL_EXPORT MonoReflectionType*
2516 ves_icall_RuntimeTypeHandle_GetElementType (MonoReflectionType *type)
2519 MonoReflectionType *ret;
2522 if (!type->type->byref && type->type->type == MONO_TYPE_SZARRAY) {
2523 ret = mono_type_get_object_checked (mono_object_domain (type), &type->type->data.klass->byval_arg, &error);
2524 mono_error_set_pending_exception (&error);
2528 klass = mono_class_from_mono_type (type->type);
2529 mono_class_init_checked (klass, &error);
2530 if (mono_error_set_pending_exception (&error))
2534 // GetElementType should only return a type for:
2535 // Array Pointer PassedByRef
2536 if (type->type->byref)
2537 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->byval_arg, &error);
2538 else if (klass->element_class && MONO_CLASS_IS_ARRAY (klass))
2539 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->element_class->byval_arg, &error);
2540 else if (klass->element_class && type->type->type == MONO_TYPE_PTR)
2541 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->element_class->byval_arg, &error);
2545 mono_error_set_pending_exception (&error);
2550 ICALL_EXPORT MonoReflectionType*
2551 ves_icall_RuntimeTypeHandle_GetBaseType (MonoReflectionType *type)
2554 MonoReflectionType *ret;
2556 if (type->type->byref)
2559 MonoClass *klass = mono_class_from_mono_type (type->type);
2563 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->parent->byval_arg, &error);
2564 mono_error_set_pending_exception (&error);
2569 ICALL_EXPORT MonoBoolean
2570 ves_icall_RuntimeTypeHandle_IsPointer (MonoReflectionType *type)
2572 return type->type->type == MONO_TYPE_PTR;
2575 ICALL_EXPORT MonoBoolean
2576 ves_icall_RuntimeTypeHandle_IsPrimitive (MonoReflectionType *type)
2578 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)));
2581 ICALL_EXPORT MonoBoolean
2582 ves_icall_RuntimeTypeHandle_IsByRef (MonoReflectionType *type)
2584 return type->type->byref;
2587 ICALL_EXPORT MonoBoolean
2588 ves_icall_RuntimeTypeHandle_IsComObject (MonoReflectionType *type)
2591 MonoClass *klass = mono_class_from_mono_type (type->type);
2592 mono_class_init_checked (klass, &error);
2593 if (mono_error_set_pending_exception (&error))
2596 return mono_class_is_com_object (klass);
2599 ICALL_EXPORT guint32
2600 ves_icall_reflection_get_token (MonoObject* obj)
2603 guint32 result = mono_reflection_get_token_checked (obj, &error);
2604 mono_error_set_pending_exception (&error);
2608 ICALL_EXPORT MonoReflectionModule*
2609 ves_icall_RuntimeTypeHandle_GetModule (MonoReflectionType *type)
2612 MonoReflectionModule *result = NULL;
2613 MonoClass *klass = mono_class_from_mono_type (type->type);
2614 result = mono_module_get_object_checked (mono_object_domain (type), klass->image, &error);
2615 mono_error_set_pending_exception (&error);
2619 ICALL_EXPORT MonoReflectionAssembly*
2620 ves_icall_RuntimeTypeHandle_GetAssembly (MonoReflectionType *type)
2623 MonoDomain *domain = mono_domain_get ();
2624 MonoClass *klass = mono_class_from_mono_type (type->type);
2625 MonoReflectionAssembly *result = mono_assembly_get_object_checked (domain, klass->image->assembly, &error);
2626 mono_error_set_pending_exception (&error);
2630 ICALL_EXPORT MonoReflectionType*
2631 ves_icall_RuntimeType_get_DeclaringType (MonoReflectionType *type)
2634 MonoReflectionType *ret;
2635 MonoDomain *domain = mono_domain_get ();
2638 if (type->type->byref)
2640 if (type->type->type == MONO_TYPE_VAR) {
2641 MonoGenericContainer *param = mono_type_get_generic_param_owner (type->type);
2642 klass = param ? param->owner.klass : NULL;
2643 } else if (type->type->type == MONO_TYPE_MVAR) {
2644 MonoGenericContainer *param = mono_type_get_generic_param_owner (type->type);
2645 klass = param ? param->owner.method->klass : NULL;
2647 klass = mono_class_from_mono_type (type->type)->nested_in;
2653 ret = mono_type_get_object_checked (domain, &klass->byval_arg, &error);
2654 mono_error_set_pending_exception (&error);
2659 ICALL_EXPORT MonoStringHandle
2660 ves_icall_RuntimeType_get_Name (MonoReflectionTypeHandle reftype, MonoError *error)
2662 MonoDomain *domain = mono_domain_get ();
2663 MonoType *type = MONO_HANDLE_RAW(reftype)->type;
2664 MonoClass *klass = mono_class_from_mono_type (type);
2667 char *n = g_strdup_printf ("%s&", klass->name);
2668 MonoStringHandle res = mono_string_new_handle (domain, n, error);
2674 return mono_string_new_handle (domain, klass->name, error);
2678 ICALL_EXPORT MonoStringHandle
2679 ves_icall_RuntimeType_get_Namespace (MonoReflectionTypeHandle type, MonoError *error)
2681 MonoDomain *domain = mono_domain_get ();
2682 MonoClass *klass = mono_class_from_mono_type_handle (type);
2684 while (klass->nested_in)
2685 klass = klass->nested_in;
2687 if (klass->name_space [0] == '\0')
2688 return NULL_HANDLE_STRING;
2690 return mono_string_new_handle (domain, klass->name_space, error);
2694 ves_icall_RuntimeTypeHandle_GetArrayRank (MonoReflectionType *type)
2698 if (type->type->type != MONO_TYPE_ARRAY && type->type->type != MONO_TYPE_SZARRAY) {
2699 mono_set_pending_exception (mono_get_exception_argument ("type", "Type must be an array type"));
2703 klass = mono_class_from_mono_type (type->type);
2709 create_type_array (MonoDomain *domain, MonoBoolean runtimeTypeArray, int count, MonoError *error)
2711 return mono_array_new_checked (domain, runtimeTypeArray ? mono_defaults.runtimetype_class : mono_defaults.systemtype_class, count, error);
2714 ICALL_EXPORT MonoArray*
2715 ves_icall_RuntimeType_GetGenericArguments (MonoReflectionType *type, MonoBoolean runtimeTypeArray)
2718 MonoReflectionType *rt;
2720 MonoClass *klass, *pklass;
2721 MonoDomain *domain = mono_object_domain (type);
2724 klass = mono_class_from_mono_type (type->type);
2726 if (mono_class_is_gtd (klass)) {
2727 MonoGenericContainer *container = mono_class_get_generic_container (klass);
2728 res = create_type_array (domain, runtimeTypeArray, container->type_argc, &error);
2729 if (mono_error_set_pending_exception (&error))
2731 for (i = 0; i < container->type_argc; ++i) {
2732 pklass = mono_class_from_generic_parameter_internal (mono_generic_container_get_param (container, i));
2734 rt = mono_type_get_object_checked (domain, &pklass->byval_arg, &error);
2735 if (mono_error_set_pending_exception (&error))
2738 mono_array_setref (res, i, rt);
2740 } else if (mono_class_is_ginst (klass)) {
2741 MonoGenericInst *inst = mono_class_get_generic_class (klass)->context.class_inst;
2742 res = create_type_array (domain, runtimeTypeArray, inst->type_argc, &error);
2743 if (mono_error_set_pending_exception (&error))
2745 for (i = 0; i < inst->type_argc; ++i) {
2746 rt = mono_type_get_object_checked (domain, inst->type_argv [i], &error);
2747 if (mono_error_set_pending_exception (&error))
2750 mono_array_setref (res, i, rt);
2758 ICALL_EXPORT gboolean
2759 ves_icall_RuntimeTypeHandle_IsGenericTypeDefinition (MonoReflectionType *type)
2763 if (!IS_MONOTYPE (type))
2766 if (type->type->byref)
2769 klass = mono_class_from_mono_type (type->type);
2770 return mono_class_is_gtd (klass);
2773 ICALL_EXPORT MonoReflectionType*
2774 ves_icall_RuntimeTypeHandle_GetGenericTypeDefinition_impl (MonoReflectionType *type)
2777 MonoReflectionType *ret;
2780 if (type->type->byref)
2783 klass = mono_class_from_mono_type (type->type);
2785 if (mono_class_is_gtd (klass)) {
2786 return type; /* check this one */
2788 if (mono_class_is_ginst (klass)) {
2789 MonoClass *generic_class = mono_class_get_generic_class (klass)->container_class;
2792 tb = mono_class_get_ref_info (generic_class);
2794 if (generic_class->wastypebuilder && tb)
2795 return (MonoReflectionType *)tb;
2797 ret = mono_type_get_object_checked (mono_object_domain (type), &generic_class->byval_arg, &error);
2798 mono_error_set_pending_exception (&error);
2806 ICALL_EXPORT MonoReflectionType*
2807 ves_icall_RuntimeType_MakeGenericType (MonoReflectionType *type, MonoArray *type_array)
2810 MonoReflectionType *ret;
2812 MonoType *geninst, **types;
2815 g_assert (IS_MONOTYPE (type));
2816 mono_class_init_checked (mono_class_from_mono_type (type->type), &error);
2817 if (mono_error_set_pending_exception (&error))
2820 count = mono_array_length (type_array);
2821 types = g_new0 (MonoType *, count);
2823 for (i = 0; i < count; i++) {
2824 MonoReflectionType *t = (MonoReflectionType *)mono_array_get (type_array, gpointer, i);
2825 types [i] = t->type;
2828 geninst = mono_reflection_bind_generic_parameters (type, count, types, &error);
2831 mono_error_set_pending_exception (&error);
2835 klass = mono_class_from_mono_type (geninst);
2837 /*we might inflate to the GTD*/
2838 if (mono_class_is_ginst (klass) && !mono_verifier_class_is_valid_generic_instantiation (klass)) {
2839 mono_set_pending_exception (mono_get_exception_argument ("typeArguments", "Invalid generic arguments"));
2843 ret = mono_type_get_object_checked (mono_object_domain (type), geninst, &error);
2844 mono_error_set_pending_exception (&error);
2849 ICALL_EXPORT gboolean
2850 ves_icall_RuntimeTypeHandle_HasInstantiation (MonoReflectionType *type)
2854 if (!IS_MONOTYPE (type))
2857 if (type->type->byref)
2860 klass = mono_class_from_mono_type (type->type);
2861 return mono_class_is_ginst (klass) || mono_class_is_gtd (klass);
2865 ves_icall_RuntimeType_GetGenericParameterPosition (MonoReflectionType *type)
2867 if (!IS_MONOTYPE (type))
2870 if (is_generic_parameter (type->type))
2871 return mono_type_get_generic_param_num (type->type);
2875 ICALL_EXPORT MonoGenericParamInfo *
2876 ves_icall_RuntimeTypeHandle_GetGenericParameterInfo (MonoReflectionType *type)
2878 return mono_generic_param_info (type->type->data.generic_param);
2881 ICALL_EXPORT MonoBoolean
2882 ves_icall_RuntimeTypeHandle_IsGenericVariable (MonoReflectionType *type)
2884 return is_generic_parameter (type->type);
2887 ICALL_EXPORT MonoReflectionMethod*
2888 ves_icall_RuntimeType_GetCorrespondingInflatedMethod (MonoReflectionType *type,
2889 MonoReflectionMethod* generic)
2896 MonoReflectionMethod *ret = NULL;
2898 domain = ((MonoObject *)type)->vtable->domain;
2900 klass = mono_class_from_mono_type (type->type);
2901 mono_class_init_checked (klass, &error);
2902 if (mono_error_set_pending_exception (&error))
2906 while ((method = mono_class_get_methods (klass, &iter))) {
2907 if (method->token == generic->method->token) {
2908 ret = mono_method_get_object_checked (domain, method, klass, &error);
2909 if (mono_error_set_pending_exception (&error))
2917 ICALL_EXPORT MonoReflectionMethod *
2918 ves_icall_RuntimeType_get_DeclaringMethod (MonoReflectionType *ref_type)
2921 MonoType *type = ref_type->type;
2923 MonoReflectionMethod *ret = NULL;
2925 if (type->byref || (type->type != MONO_TYPE_MVAR && type->type != MONO_TYPE_VAR)) {
2926 mono_set_pending_exception (mono_get_exception_invalid_operation ("DeclaringMethod can only be used on generic arguments"));
2929 if (type->type == MONO_TYPE_VAR)
2932 method = mono_type_get_generic_param_owner (type)->owner.method;
2935 ret = mono_method_get_object_checked (mono_object_domain (ref_type), method, method->klass, &error);
2936 if (!mono_error_ok (&error))
2937 mono_set_pending_exception (mono_error_convert_to_exception (&error));
2941 ICALL_EXPORT MonoBoolean
2942 ves_icall_System_RuntimeType_IsTypeExportedToWindowsRuntime (void)
2944 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2948 ICALL_EXPORT MonoBoolean
2949 ves_icall_System_RuntimeType_IsWindowsRuntimeObjectType (void)
2951 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2956 ves_icall_MonoMethod_GetPInvoke (MonoReflectionMethod *method, int* flags, MonoString** entry_point, MonoString** dll_name)
2958 MonoDomain *domain = mono_domain_get ();
2959 MonoImage *image = method->method->klass->image;
2960 MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method->method;
2961 MonoTableInfo *tables = image->tables;
2962 MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
2963 MonoTableInfo *mr = &tables [MONO_TABLE_MODULEREF];
2964 guint32 im_cols [MONO_IMPLMAP_SIZE];
2965 guint32 scope_token;
2966 const char *import = NULL;
2967 const char *scope = NULL;
2969 if (image_is_dynamic (image)) {
2970 MonoReflectionMethodAux *method_aux =
2971 (MonoReflectionMethodAux *)g_hash_table_lookup (((MonoDynamicImage*)image)->method_aux_hash, method->method);
2973 import = method_aux->dllentry;
2974 scope = method_aux->dll;
2977 if (!import || !scope) {
2978 mono_set_pending_exception (mono_get_exception_argument ("method", "System.Reflection.Emit method with invalid pinvoke information"));
2983 if (piinfo->implmap_idx) {
2984 mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
2986 piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
2987 import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
2988 scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
2989 scope = mono_metadata_string_heap (image, scope_token);
2993 *flags = piinfo->piflags;
2994 *entry_point = mono_string_new (domain, import);
2995 *dll_name = mono_string_new (domain, scope);
2998 ICALL_EXPORT MonoReflectionMethod *
2999 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
3001 MonoMethodInflated *imethod;
3003 MonoReflectionMethod *ret = NULL;
3006 if (method->method->is_generic)
3009 if (!method->method->is_inflated)
3012 imethod = (MonoMethodInflated *) method->method;
3014 result = imethod->declaring;
3015 /* Not a generic method. */
3016 if (!result->is_generic)
3019 if (image_is_dynamic (method->method->klass->image)) {
3020 MonoDynamicImage *image = (MonoDynamicImage*)method->method->klass->image;
3021 MonoReflectionMethod *res;
3024 * FIXME: Why is this stuff needed at all ? Why can't the code below work for
3025 * the dynamic case as well ?
3027 mono_image_lock ((MonoImage*)image);
3028 res = (MonoReflectionMethod *)mono_g_hash_table_lookup (image->generic_def_objects, imethod);
3029 mono_image_unlock ((MonoImage*)image);
3035 if (imethod->context.class_inst) {
3036 MonoClass *klass = ((MonoMethod *) imethod)->klass;
3037 /*Generic methods gets the context of the GTD.*/
3038 if (mono_class_get_context (klass)) {
3039 result = mono_class_inflate_generic_method_full_checked (result, klass, mono_class_get_context (klass), &error);
3040 if (!mono_error_ok (&error))
3045 ret = mono_method_get_object_checked (mono_object_domain (method), result, NULL, &error);
3047 if (!mono_error_ok (&error))
3048 mono_error_set_pending_exception (&error);
3052 ICALL_EXPORT gboolean
3053 ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethod *method)
3055 return mono_method_signature (method->method)->generic_param_count != 0;
3058 ICALL_EXPORT gboolean
3059 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method)
3061 return method->method->is_generic;
3064 ICALL_EXPORT MonoArray*
3065 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
3068 MonoReflectionType *rt;
3073 domain = mono_object_domain (method);
3075 if (method->method->is_inflated) {
3076 MonoGenericInst *inst = mono_method_get_context (method->method)->method_inst;
3079 count = inst->type_argc;
3080 res = mono_array_new_checked (domain, mono_defaults.systemtype_class, count, &error);
3081 if (mono_error_set_pending_exception (&error))
3084 for (i = 0; i < count; i++) {
3085 rt = mono_type_get_object_checked (domain, inst->type_argv [i], &error);
3086 if (mono_error_set_pending_exception (&error))
3089 mono_array_setref (res, i, rt);
3096 count = mono_method_signature (method->method)->generic_param_count;
3097 res = mono_array_new_checked (domain, mono_defaults.systemtype_class, count, &error);
3098 if (mono_error_set_pending_exception (&error))
3101 for (i = 0; i < count; i++) {
3102 MonoGenericContainer *container = mono_method_get_generic_container (method->method);
3103 MonoGenericParam *param = mono_generic_container_get_param (container, i);
3104 MonoClass *pklass = mono_class_from_generic_parameter_internal (param);
3106 rt = mono_type_get_object_checked (domain, &pklass->byval_arg, &error);
3107 if (mono_error_set_pending_exception (&error))
3110 mono_array_setref (res, i, rt);
3116 ICALL_EXPORT MonoObject *
3117 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this_arg, MonoArray *params, MonoException **exc)
3121 * Invoke from reflection is supposed to always be a virtual call (the API
3122 * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
3123 * greater flexibility.
3125 MonoMethod *m = method->method;
3126 MonoMethodSignature *sig = mono_method_signature (m);
3129 void *obj = this_arg;
3133 if (mono_security_core_clr_enabled () &&
3134 !mono_security_core_clr_ensure_reflection_access_method (m, &error)) {
3135 mono_error_set_pending_exception (&error);
3139 if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
3140 if (!mono_class_vtable_full (mono_object_domain (method), m->klass, &error)) {
3141 mono_error_cleanup (&error); /* FIXME does this make sense? */
3142 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_class_get_exception_for_failure (m->klass));
3147 if (!mono_object_isinst_checked (this_arg, m->klass, &error)) {
3148 if (!is_ok (&error)) {
3149 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_error_convert_to_exception (&error));
3152 char *this_name = mono_type_get_full_name (mono_object_get_class (this_arg));
3153 char *target_name = mono_type_get_full_name (m->klass);
3154 char *msg = g_strdup_printf ("Object of type '%s' doesn't match target type '%s'", this_name, target_name);
3155 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", msg));
3157 g_free (target_name);
3161 m = mono_object_get_virtual_method (this_arg, m);
3162 /* must pass the pointer to the value for valuetype methods */
3163 if (m->klass->valuetype)
3164 obj = mono_object_unbox (this_arg);
3165 } else if (strcmp (m->name, ".ctor") && !m->wrapper_type) {
3166 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Non-static method requires a target."));
3171 if (sig->ret->byref) {
3172 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System", "NotSupportedException", "Cannot invoke method returning ByRef type via reflection"));
3176 pcount = params? mono_array_length (params): 0;
3177 if (pcount != sig->param_count) {
3178 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
3182 if (mono_class_is_abstract (m->klass) && !strcmp (m->name, ".ctor") && !this_arg) {
3183 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Cannot invoke constructor of an abstract class."));
3187 image = m->klass->image;
3188 if (image->assembly->ref_only) {
3189 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_get_exception_invalid_operation ("It is illegal to invoke a method on a type loaded using the ReflectionOnly api."));
3193 if (image_is_dynamic (image) && !((MonoDynamicImage*)image)->run) {
3194 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_get_exception_not_supported ("Cannot invoke a method in a dynamic assembly without run access."));
3198 if (m->klass->rank && !strcmp (m->name, ".ctor")) {
3202 intptr_t *lower_bounds;
3203 pcount = mono_array_length (params);
3204 lengths = (uintptr_t *)alloca (sizeof (uintptr_t) * pcount);
3205 /* Note: the synthetized array .ctors have int32 as argument type */
3206 for (i = 0; i < pcount; ++i)
3207 lengths [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
3209 if (m->klass->rank == 1 && sig->param_count == 2 && m->klass->element_class->rank) {
3210 /* This is a ctor for jagged arrays. MS creates an array of arrays. */
3211 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, NULL, &error);
3212 if (!mono_error_ok (&error)) {
3213 mono_error_set_pending_exception (&error);
3217 for (i = 0; i < mono_array_length (arr); ++i) {
3218 MonoArray *subarray = mono_array_new_full_checked (mono_object_domain (params), m->klass->element_class, &lengths [1], NULL, &error);
3219 if (!mono_error_ok (&error)) {
3220 mono_error_set_pending_exception (&error);
3223 mono_array_setref_fast (arr, i, subarray);
3225 return (MonoObject*)arr;
3228 if (m->klass->rank == pcount) {
3229 /* Only lengths provided. */
3230 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, NULL, &error);
3231 if (!mono_error_ok (&error)) {
3232 mono_error_set_pending_exception (&error);
3236 return (MonoObject*)arr;
3238 g_assert (pcount == (m->klass->rank * 2));
3239 /* The arguments are lower-bound-length pairs */
3240 lower_bounds = (intptr_t *)g_alloca (sizeof (intptr_t) * pcount);
3242 for (i = 0; i < pcount / 2; ++i) {
3243 lower_bounds [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, (i * 2)) + sizeof (MonoObject));
3244 lengths [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, (i * 2) + 1) + sizeof (MonoObject));
3247 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, lower_bounds, &error);
3248 if (!mono_error_ok (&error)) {
3249 mono_error_set_pending_exception (&error);
3253 return (MonoObject*)arr;
3256 MonoObject *result = mono_runtime_invoke_array_checked (m, obj, params, &error);
3257 mono_error_set_pending_exception (&error);
3261 #ifndef DISABLE_REMOTING
3262 ICALL_EXPORT MonoObject *
3263 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this_arg, MonoArray *params, MonoArray **outArgs)
3266 MonoDomain *domain = mono_object_domain (method);
3267 MonoMethod *m = method->method;
3268 MonoMethodSignature *sig = mono_method_signature (m);
3269 MonoArray *out_args;
3271 int i, j, outarg_count = 0;
3273 if (m->klass == mono_defaults.object_class) {
3274 if (!strcmp (m->name, "FieldGetter")) {
3275 MonoClass *k = this_arg->vtable->klass;
3279 /* If this is a proxy, then it must be a CBO */
3280 if (k == mono_defaults.transparent_proxy_class) {
3281 MonoTransparentProxy *tp = (MonoTransparentProxy*) this_arg;
3282 this_arg = tp->rp->unwrapped_server;
3283 g_assert (this_arg);
3284 k = this_arg->vtable->klass;
3287 name = mono_array_get (params, MonoString *, 1);
3288 str = mono_string_to_utf8_checked (name, &error);
3289 if (mono_error_set_pending_exception (&error))
3293 MonoClassField* field = mono_class_get_field_from_name (k, str);
3296 MonoClass *field_klass = mono_class_from_mono_type (field->type);
3297 if (field_klass->valuetype) {
3298 result = mono_value_box_checked (domain, field_klass, (char *)this_arg + field->offset, &error);
3299 if (mono_error_set_pending_exception (&error))
3302 result = (MonoObject *)*((gpointer *)((char *)this_arg + field->offset));
3304 out_args = mono_array_new_checked (domain, mono_defaults.object_class, 1, &error);
3305 if (mono_error_set_pending_exception (&error))
3307 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3308 mono_array_setref (out_args, 0, result);
3315 g_assert_not_reached ();
3317 } else if (!strcmp (m->name, "FieldSetter")) {
3318 MonoClass *k = this_arg->vtable->klass;
3324 /* If this is a proxy, then it must be a CBO */
3325 if (k == mono_defaults.transparent_proxy_class) {
3326 MonoTransparentProxy *tp = (MonoTransparentProxy*) this_arg;
3327 this_arg = tp->rp->unwrapped_server;
3328 g_assert (this_arg);
3329 k = this_arg->vtable->klass;
3332 name = mono_array_get (params, MonoString *, 1);
3333 str = mono_string_to_utf8_checked (name, &error);
3334 if (mono_error_set_pending_exception (&error))
3338 MonoClassField* field = mono_class_get_field_from_name (k, str);
3341 MonoClass *field_klass = mono_class_from_mono_type (field->type);
3342 MonoObject *val = (MonoObject *)mono_array_get (params, gpointer, 2);
3344 if (field_klass->valuetype) {
3345 size = mono_type_size (field->type, &align);
3346 g_assert (size == mono_class_value_size (field_klass, NULL));
3347 mono_gc_wbarrier_value_copy ((char *)this_arg + field->offset, (char*)val + sizeof (MonoObject), 1, field_klass);
3349 mono_gc_wbarrier_set_field (this_arg, (char*)this_arg + field->offset, val);
3352 out_args = mono_array_new_checked (domain, mono_defaults.object_class, 0, &error);
3353 if (mono_error_set_pending_exception (&error))
3355 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3364 g_assert_not_reached ();
3369 for (i = 0; i < mono_array_length (params); i++) {
3370 if (sig->params [i]->byref)
3374 out_args = mono_array_new_checked (domain, mono_defaults.object_class, outarg_count, &error);
3375 if (mono_error_set_pending_exception (&error))
3378 /* handle constructors only for objects already allocated */
3379 if (!strcmp (method->method->name, ".ctor"))
3380 g_assert (this_arg);
3382 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
3383 g_assert (!method->method->klass->valuetype);
3384 result = mono_runtime_invoke_array_checked (method->method, this_arg, params, &error);
3385 if (mono_error_set_pending_exception (&error))
3388 for (i = 0, j = 0; i < mono_array_length (params); i++) {
3389 if (sig->params [i]->byref) {
3391 arg = mono_array_get (params, gpointer, i);
3392 mono_array_setref (out_args, j, arg);
3397 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3404 read_enum_value (const char *mem, int type)
3407 case MONO_TYPE_BOOLEAN:
3409 return *(guint8*)mem;
3411 return *(gint8*)mem;
3412 case MONO_TYPE_CHAR:
3414 return read16 (mem);
3416 return (gint16) read16 (mem);
3418 return read32 (mem);
3420 return (gint32) read32 (mem);
3423 return read64 (mem);
3425 g_assert_not_reached ();
3431 write_enum_value (char *mem, int type, guint64 value)
3435 case MONO_TYPE_I1: {
3436 guint8 *p = (guint8*)mem;
3442 case MONO_TYPE_CHAR: {
3443 guint16 *p = (guint16 *)mem;
3448 case MONO_TYPE_I4: {
3449 guint32 *p = (guint32 *)mem;
3454 case MONO_TYPE_I8: {
3455 guint64 *p = (guint64 *)mem;
3460 g_assert_not_reached ();
3465 ICALL_EXPORT MonoObject *
3466 ves_icall_System_Enum_ToObject (MonoReflectionType *enumType, guint64 value)
3474 domain = mono_object_domain (enumType);
3475 enumc = mono_class_from_mono_type (enumType->type);
3477 mono_class_init_checked (enumc, &error);
3478 if (mono_error_set_pending_exception (&error))
3481 etype = mono_class_enum_basetype (enumc);
3483 res = mono_object_new_checked (domain, enumc, &error);
3484 if (mono_error_set_pending_exception (&error))
3486 write_enum_value ((char *)res + sizeof (MonoObject), etype->type, value);
3491 ICALL_EXPORT MonoBoolean
3492 ves_icall_System_Enum_InternalHasFlag (MonoObject *a, MonoObject *b)
3494 int size = mono_class_value_size (a->vtable->klass, NULL);
3495 guint64 a_val = 0, b_val = 0;
3497 memcpy (&a_val, mono_object_unbox (a), size);
3498 memcpy (&b_val, mono_object_unbox (b), size);
3500 return (a_val & b_val) == b_val;
3503 ICALL_EXPORT MonoObject *
3504 ves_icall_System_Enum_get_value (MonoObject *eobj)
3516 g_assert (eobj->vtable->klass->enumtype);
3518 enumc = mono_class_from_mono_type (mono_class_enum_basetype (eobj->vtable->klass));
3519 res = mono_object_new_checked (mono_object_domain (eobj), enumc, &error);
3520 if (mono_error_set_pending_exception (&error))
3522 dst = (char *)res + sizeof (MonoObject);
3523 src = (char *)eobj + sizeof (MonoObject);
3524 size = mono_class_value_size (enumc, NULL);
3526 memcpy (dst, src, size);
3531 ICALL_EXPORT MonoReflectionType *
3532 ves_icall_System_Enum_get_underlying_type (MonoReflectionType *type)
3535 MonoReflectionType *ret;
3539 klass = mono_class_from_mono_type (type->type);
3540 mono_class_init_checked (klass, &error);
3541 if (mono_error_set_pending_exception (&error))
3544 etype = mono_class_enum_basetype (klass);
3546 mono_set_pending_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
3550 ret = mono_type_get_object_checked (mono_object_domain (type), etype, &error);
3551 mono_error_set_pending_exception (&error);
3557 ves_icall_System_Enum_compare_value_to (MonoObject *eobj, MonoObject *other)
3559 gpointer tdata = (char *)eobj + sizeof (MonoObject);
3560 gpointer odata = (char *)other + sizeof (MonoObject);
3561 MonoType *basetype = mono_class_enum_basetype (eobj->vtable->klass);
3562 g_assert (basetype);
3567 if (eobj->vtable->klass != other->vtable->klass)
3570 #define COMPARE_ENUM_VALUES(ENUM_TYPE) do { \
3571 ENUM_TYPE me = *((ENUM_TYPE*)tdata); \
3572 ENUM_TYPE other = *((ENUM_TYPE*)odata); \
3575 return me > other ? 1 : -1; \
3578 switch (basetype->type) {
3580 COMPARE_ENUM_VALUES (guint8);
3582 COMPARE_ENUM_VALUES (gint8);
3583 case MONO_TYPE_CHAR:
3585 COMPARE_ENUM_VALUES (guint16);
3587 COMPARE_ENUM_VALUES (gint16);
3589 COMPARE_ENUM_VALUES (guint32);
3591 COMPARE_ENUM_VALUES (gint32);
3593 COMPARE_ENUM_VALUES (guint64);
3595 COMPARE_ENUM_VALUES (gint64);
3599 #undef COMPARE_ENUM_VALUES
3600 /* indicates that the enum was of an unsupported unerlying type */
3605 ves_icall_System_Enum_get_hashcode (MonoObject *eobj)
3607 gpointer data = (char *)eobj + sizeof (MonoObject);
3608 MonoType *basetype = mono_class_enum_basetype (eobj->vtable->klass);
3609 g_assert (basetype);
3611 switch (basetype->type) {
3612 case MONO_TYPE_I1: {
3613 gint8 value = *((gint8*)data);
3614 return ((int)value ^ (int)value << 8);
3617 return *((guint8*)data);
3618 case MONO_TYPE_CHAR:
3620 return *((guint16*)data);
3622 case MONO_TYPE_I2: {
3623 gint16 value = *((gint16*)data);
3624 return ((int)(guint16)value | (((int)value) << 16));
3627 return *((guint32*)data);
3629 return *((gint32*)data);
3631 case MONO_TYPE_I8: {
3632 gint64 value = *((gint64*)data);
3633 return (gint)(value & 0xffffffff) ^ (int)(value >> 32);
3636 g_error ("Implement type 0x%02x in get_hashcode", basetype->type);
3642 get_enum_field (MonoDomain *domain, MonoArrayHandle names, MonoArrayHandle values, int base_type, MonoClassField *field, guint* j, guint64 *previous_value, gboolean *sorted, MonoError *error)
3644 mono_error_init (error);
3645 HANDLE_FUNCTION_ENTER();
3646 guint64 field_value;
3648 MonoTypeEnum def_type;
3650 if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC))
3652 if (strcmp ("value__", mono_field_get_name (field)) == 0)
3654 if (mono_field_is_deleted (field))
3656 MonoStringHandle name = mono_string_new_handle (domain, mono_field_get_name (field), error);
3659 MONO_HANDLE_ARRAY_SETREF (names, *j, name);
3661 p = mono_class_get_field_default_value (field, &def_type);
3662 /* len = */ mono_metadata_decode_blob_size (p, &p);
3664 field_value = read_enum_value (p, base_type);
3665 MONO_HANDLE_ARRAY_SETVAL (values, guint64, *j, field_value);
3667 if (*previous_value > field_value)
3670 *previous_value = field_value;
3673 HANDLE_FUNCTION_RETURN();
3676 ICALL_EXPORT MonoBoolean
3677 ves_icall_System_Enum_GetEnumValuesAndNames (MonoReflectionTypeHandle type, MonoArrayHandleOut values, MonoArrayHandleOut names, MonoError *error)
3679 MonoDomain *domain = MONO_HANDLE_DOMAIN (type);
3680 MonoClass *enumc = mono_class_from_mono_type (MONO_HANDLE_RAW(type)->type);
3681 guint j = 0, nvalues;
3683 MonoClassField *field;
3685 guint64 previous_value = 0;
3686 gboolean sorted = TRUE;
3688 mono_error_init (error);
3689 mono_class_init_checked (enumc, error);
3690 return_val_if_nok (error, FALSE);
3692 if (!enumc->enumtype) {
3693 mono_error_set_argument (error, "enumType", "Type provided must be an Enum.");
3697 base_type = mono_class_enum_basetype (enumc)->type;
3699 nvalues = mono_class_num_fields (enumc) > 0 ? mono_class_num_fields (enumc) - 1 : 0;
3700 MONO_HANDLE_ASSIGN(names, mono_array_new_handle (domain, mono_defaults.string_class, nvalues, error));
3701 return_val_if_nok (error, FALSE);
3702 MONO_HANDLE_ASSIGN(values, mono_array_new_handle (domain, mono_defaults.uint64_class, nvalues, error));
3703 return_val_if_nok (error, FALSE);
3706 while ((field = mono_class_get_fields (enumc, &iter))) {
3707 get_enum_field(domain, names, values, base_type, field, &j, &previous_value, &sorted, error);
3711 return_val_if_nok (error, FALSE);
3717 BFLAGS_IgnoreCase = 1,
3718 BFLAGS_DeclaredOnly = 2,
3719 BFLAGS_Instance = 4,
3721 BFLAGS_Public = 0x10,
3722 BFLAGS_NonPublic = 0x20,
3723 BFLAGS_FlattenHierarchy = 0x40,
3724 BFLAGS_InvokeMethod = 0x100,
3725 BFLAGS_CreateInstance = 0x200,
3726 BFLAGS_GetField = 0x400,
3727 BFLAGS_SetField = 0x800,
3728 BFLAGS_GetProperty = 0x1000,
3729 BFLAGS_SetProperty = 0x2000,
3730 BFLAGS_ExactBinding = 0x10000,
3731 BFLAGS_SuppressChangeType = 0x20000,
3732 BFLAGS_OptionalParamBinding = 0x40000
3735 ICALL_EXPORT GPtrArray*
3736 ves_icall_RuntimeType_GetFields_native (MonoReflectionType *type, char *utf8_name, guint32 bflags)
3739 MonoClass *startklass, *klass;
3742 int (*compare_func) (const char *s1, const char *s2) = NULL;
3743 MonoClassField *field;
3745 if (type->type->byref) {
3746 return g_ptr_array_new ();
3749 mono_error_init (&error);
3751 compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
3753 klass = startklass = mono_class_from_mono_type (type->type);
3755 GPtrArray *ptr_array = g_ptr_array_sized_new (16);
3758 if (mono_class_has_failure (klass)) {
3759 mono_error_set_for_class_failure (&error, klass);
3764 while ((field = mono_class_get_fields_lazy (klass, &iter))) {
3765 guint32 flags = mono_field_get_flags (field);
3767 if (mono_field_is_deleted_with_flags (field, flags))
3769 if ((flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3770 if (bflags & BFLAGS_Public)
3772 } else if ((klass == startklass) || (flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
3773 if (bflags & BFLAGS_NonPublic) {
3780 if (flags & FIELD_ATTRIBUTE_STATIC) {
3781 if (bflags & BFLAGS_Static)
3782 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3785 if (bflags & BFLAGS_Instance)
3792 if (utf8_name != NULL && compare_func (mono_field_get_name (field), utf8_name))
3795 g_ptr_array_add (ptr_array, field);
3797 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3803 g_ptr_array_free (ptr_array, TRUE);
3804 mono_error_set_pending_exception (&error);
3809 method_nonpublic (MonoMethod* method, gboolean start_klass)
3811 switch (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) {
3812 case METHOD_ATTRIBUTE_ASSEM:
3813 return (start_klass || mono_defaults.generic_ilist_class);
3814 case METHOD_ATTRIBUTE_PRIVATE:
3816 case METHOD_ATTRIBUTE_PUBLIC:
3824 mono_class_get_methods_by_name (MonoClass *klass, const char *name, guint32 bflags, gboolean ignore_case, gboolean allow_ctors, MonoError *error)
3827 MonoClass *startklass;
3831 /*FIXME, use MonoBitSet*/
3832 guint32 method_slots_default [8];
3833 guint32 *method_slots = NULL;
3834 int (*compare_func) (const char *s1, const char *s2) = NULL;
3836 array = g_ptr_array_new ();
3838 mono_error_init (error);
3841 compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
3843 /* An optimization for calls made from Delegate:CreateDelegate () */
3844 if (klass->delegate && name && !strcmp (name, "Invoke") && (bflags == (BFLAGS_Public | BFLAGS_Static | BFLAGS_Instance))) {
3845 method = mono_get_delegate_invoke (klass);
3848 g_ptr_array_add (array, method);
3852 mono_class_setup_methods (klass);
3853 mono_class_setup_vtable (klass);
3854 if (mono_class_has_failure (klass))
3857 if (is_generic_parameter (&klass->byval_arg))
3858 nslots = mono_class_get_vtable_size (klass->parent);
3860 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : mono_class_get_vtable_size (klass);
3861 if (nslots >= sizeof (method_slots_default) * 8) {
3862 method_slots = g_new0 (guint32, nslots / 32 + 1);
3864 method_slots = method_slots_default;
3865 memset (method_slots, 0, sizeof (method_slots_default));
3868 mono_class_setup_methods (klass);
3869 mono_class_setup_vtable (klass);
3870 if (mono_class_has_failure (klass))
3874 while ((method = mono_class_get_methods (klass, &iter))) {
3876 if (method->slot != -1) {
3877 g_assert (method->slot < nslots);
3878 if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
3880 if (!(method->flags & METHOD_ATTRIBUTE_NEW_SLOT))
3881 method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
3884 if (!allow_ctors && method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
3886 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3887 if (bflags & BFLAGS_Public)
3889 } else if ((bflags & BFLAGS_NonPublic) && method_nonpublic (method, (klass == startklass))) {
3895 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3896 if (bflags & BFLAGS_Static)
3897 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3900 if (bflags & BFLAGS_Instance)
3908 if (compare_func (name, method->name))
3913 g_ptr_array_add (array, method);
3915 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3917 if (method_slots != method_slots_default)
3918 g_free (method_slots);
3923 if (method_slots != method_slots_default)
3924 g_free (method_slots);
3925 g_ptr_array_free (array, TRUE);
3927 g_assert (mono_class_has_failure (klass));
3928 mono_error_set_for_class_failure (error, klass);
3932 ICALL_EXPORT GPtrArray*
3933 ves_icall_RuntimeType_GetMethodsByName_native (MonoReflectionType *type, const char *mname, guint32 bflags, MonoBoolean ignore_case)
3936 GPtrArray *method_array;
3939 klass = mono_class_from_mono_type (type->type);
3940 if (type->type->byref) {
3941 return g_ptr_array_new ();
3944 method_array = mono_class_get_methods_by_name (klass, mname, bflags, ignore_case, FALSE, &error);
3945 mono_error_set_pending_exception (&error);
3946 return method_array;
3949 ICALL_EXPORT GPtrArray*
3950 ves_icall_RuntimeType_GetConstructors_native (MonoReflectionType *type, guint32 bflags)
3952 MonoClass *startklass, *klass;
3955 gpointer iter = NULL;
3956 GPtrArray *res_array;
3959 if (type->type->byref) {
3960 return g_ptr_array_new ();
3963 klass = startklass = mono_class_from_mono_type (type->type);
3965 mono_class_setup_methods (klass);
3966 if (mono_class_has_failure (klass)) {
3967 mono_error_init (&error);
3968 mono_error_set_for_class_failure (&error, klass);
3969 mono_error_set_pending_exception (&error);
3973 res_array = g_ptr_array_sized_new (4); /* FIXME, guestimating */
3976 while ((method = mono_class_get_methods (klass, &iter))) {
3978 if (strcmp (method->name, ".ctor") && strcmp (method->name, ".cctor"))
3980 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3981 if (bflags & BFLAGS_Public)
3984 if (bflags & BFLAGS_NonPublic)
3990 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3991 if (bflags & BFLAGS_Static)
3992 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3995 if (bflags & BFLAGS_Instance)
4001 g_ptr_array_add (res_array, method);
4008 property_hash (gconstpointer data)
4010 MonoProperty *prop = (MonoProperty*)data;
4012 return g_str_hash (prop->name);
4016 property_accessor_override (MonoMethod *method1, MonoMethod *method2)
4018 if (method1->slot != -1 && method1->slot == method2->slot)
4021 if (mono_class_get_generic_type_definition (method1->klass) == mono_class_get_generic_type_definition (method2->klass)) {
4022 if (method1->is_inflated)
4023 method1 = ((MonoMethodInflated*) method1)->declaring;
4024 if (method2->is_inflated)
4025 method2 = ((MonoMethodInflated*) method2)->declaring;
4028 return mono_metadata_signature_equal (mono_method_signature (method1), mono_method_signature (method2));
4032 property_equal (MonoProperty *prop1, MonoProperty *prop2)
4034 // Properties are hide-by-name-and-signature
4035 if (!g_str_equal (prop1->name, prop2->name))
4038 /* If we see a property in a generic method, we want to
4039 compare the generic signatures, not the inflated signatures
4040 because we might conflate two properties that were
4044 public T this[T t] { getter { return t; } } // method 1
4045 public U this[U u] { getter { return u; } } // method 2
4048 If we see int Foo<int,int>::Item[int] we need to know if
4049 the indexer came from method 1 or from method 2, and we
4050 shouldn't conflate them. (Bugzilla 36283)
4052 if (prop1->get && prop2->get && !property_accessor_override (prop1->get, prop2->get))
4055 if (prop1->set && prop2->set && !property_accessor_override (prop1->set, prop2->set))
4062 property_accessor_nonpublic (MonoMethod* accessor, gboolean start_klass)
4067 return method_nonpublic (accessor, start_klass);
4070 ICALL_EXPORT GPtrArray*
4071 ves_icall_RuntimeType_GetPropertiesByName_native (MonoReflectionType *type, gchar *propname, guint32 bflags, MonoBoolean ignore_case)
4074 MonoClass *startklass, *klass;
4079 int (*compare_func) (const char *s1, const char *s2) = NULL;
4081 GHashTable *properties = NULL;
4082 GPtrArray *res_array;
4084 if (type->type->byref) {
4085 return g_ptr_array_new ();
4088 mono_error_init (&error);
4090 klass = startklass = mono_class_from_mono_type (type->type);
4092 compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
4094 res_array = g_ptr_array_sized_new (8); /*This the average for ASP.NET types*/
4096 properties = g_hash_table_new (property_hash, (GEqualFunc)property_equal);
4098 mono_class_setup_methods (klass);
4099 mono_class_setup_vtable (klass);
4100 if (mono_class_has_failure (klass)) {
4101 mono_error_set_for_class_failure (&error, klass);
4106 while ((prop = mono_class_get_properties (klass, &iter))) {
4112 flags = method->flags;
4115 if ((prop->get && ((prop->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC)) ||
4116 (prop->set && ((prop->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC))) {
4117 if (bflags & BFLAGS_Public)
4119 } else if (bflags & BFLAGS_NonPublic) {
4120 if (property_accessor_nonpublic(prop->get, startklass == klass) ||
4121 property_accessor_nonpublic(prop->set, startklass == klass)) {
4128 if (flags & METHOD_ATTRIBUTE_STATIC) {
4129 if (bflags & BFLAGS_Static)
4130 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
4133 if (bflags & BFLAGS_Instance)
4141 if (propname != NULL && compare_func (propname, prop->name))
4144 if (g_hash_table_lookup (properties, prop))
4147 g_ptr_array_add (res_array, prop);
4149 g_hash_table_insert (properties, prop, prop);
4151 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
4154 g_hash_table_destroy (properties);
4161 g_hash_table_destroy (properties);
4162 g_ptr_array_free (res_array, TRUE);
4164 mono_error_set_pending_exception (&error);
4170 event_hash (gconstpointer data)
4172 MonoEvent *event = (MonoEvent*)data;
4174 return g_str_hash (event->name);
4178 event_equal (MonoEvent *event1, MonoEvent *event2)
4180 // Events are hide-by-name
4181 return g_str_equal (event1->name, event2->name);
4184 ICALL_EXPORT GPtrArray*
4185 ves_icall_RuntimeType_GetEvents_native (MonoReflectionType *type, char *utf8_name, guint32 bflags)
4188 MonoClass *startklass, *klass;
4193 int (*compare_func) (const char *s1, const char *s2) = NULL;
4194 GHashTable *events = NULL;
4195 GPtrArray *res_array;
4197 if (type->type->byref) {
4198 return g_ptr_array_new ();
4201 mono_error_init (&error);
4203 compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
4205 res_array = g_ptr_array_sized_new (4);
4207 klass = startklass = mono_class_from_mono_type (type->type);
4209 events = g_hash_table_new (event_hash, (GEqualFunc)event_equal);
4211 mono_class_setup_methods (klass);
4212 mono_class_setup_vtable (klass);
4213 if (mono_class_has_failure (klass)) {
4214 mono_error_set_for_class_failure (&error, klass);
4219 while ((event = mono_class_get_events (klass, &iter))) {
4221 method = event->add;
4223 method = event->remove;
4225 method = event->raise;
4227 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
4228 if (bflags & BFLAGS_Public)
4230 } else if ((klass == startklass) || (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) {
4231 if (bflags & BFLAGS_NonPublic)
4236 if (bflags & BFLAGS_NonPublic)
4242 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
4243 if (bflags & BFLAGS_Static)
4244 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
4247 if (bflags & BFLAGS_Instance)
4252 if (bflags & BFLAGS_Instance)
4257 if (utf8_name != NULL && compare_func (event->name, utf8_name))
4260 if (g_hash_table_lookup (events, event))
4263 g_ptr_array_add (res_array, event);
4265 g_hash_table_insert (events, event, event);
4267 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
4270 g_hash_table_destroy (events);
4276 g_hash_table_destroy (events);
4278 g_ptr_array_free (res_array, TRUE);
4280 mono_error_set_pending_exception (&error);
4284 ICALL_EXPORT GPtrArray *
4285 ves_icall_RuntimeType_GetNestedTypes_native (MonoReflectionType *type, char *str, guint32 bflags)
4291 GPtrArray *res_array;
4293 if (type->type->byref) {
4294 return g_ptr_array_new ();
4297 klass = mono_class_from_mono_type (type->type);
4300 * If a nested type is generic, return its generic type definition.
4301 * Note that this means that the return value is essentially the set
4302 * of nested types of the generic type definition of @klass.
4304 * A note in MSDN claims that a generic type definition can have
4305 * nested types that aren't generic. In any case, the container of that
4306 * nested type would be the generic type definition.
4308 if (mono_class_is_ginst (klass))
4309 klass = mono_class_get_generic_class (klass)->container_class;
4311 res_array = g_ptr_array_new ();
4314 while ((nested = mono_class_get_nested_types (klass, &iter))) {
4316 if ((mono_class_get_flags (nested) & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
4317 if (bflags & BFLAGS_Public)
4320 if (bflags & BFLAGS_NonPublic)
4326 if (str != NULL && strcmp (nested->name, str))
4329 g_ptr_array_add (res_array, &nested->byval_arg);
4335 ICALL_EXPORT MonoReflectionType*
4336 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *assembly, MonoReflectionModule *module, MonoString *name, MonoBoolean throwOnError, MonoBoolean ignoreCase)
4339 MonoReflectionType *ret;
4341 MonoType *type = NULL;
4342 MonoTypeNameParse info;
4343 gboolean type_resolve;
4345 /* On MS.NET, this does not fire a TypeResolve event */
4346 type_resolve = TRUE;
4347 str = mono_string_to_utf8_checked (name, &error);
4348 if (mono_error_set_pending_exception (&error))
4350 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
4351 if (!mono_reflection_parse_type (str, &info)) {
4353 mono_reflection_free_type_info (&info);
4355 mono_set_pending_exception (mono_get_exception_argument("name", "failed parse"));
4358 /*g_print ("failed parse\n");*/
4362 if (info.assembly.name) {
4364 mono_reflection_free_type_info (&info);
4366 /* 1.0 and 2.0 throw different exceptions */
4367 if (mono_defaults.generic_ilist_class)
4368 mono_set_pending_exception (mono_get_exception_argument (NULL, "Type names passed to Assembly.GetType() must not specify an assembly."));
4370 mono_set_pending_exception (mono_get_exception_type_load (name, NULL));
4376 if (module != NULL) {
4377 if (module->image) {
4378 type = mono_reflection_get_type_checked (module->image, module->image, &info, ignoreCase, &type_resolve, &error);
4379 if (!is_ok (&error)) {
4381 mono_reflection_free_type_info (&info);
4382 mono_error_set_pending_exception (&error);
4389 if (assembly_is_dynamic (assembly->assembly)) {
4390 /* Enumerate all modules */
4391 MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
4395 if (abuilder->modules) {
4396 for (i = 0; i < mono_array_length (abuilder->modules); ++i) {
4397 MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
4398 type = mono_reflection_get_type_checked (&mb->dynamic_image->image, &mb->dynamic_image->image, &info, ignoreCase, &type_resolve, &error);
4399 if (!is_ok (&error)) {
4401 mono_reflection_free_type_info (&info);
4402 mono_error_set_pending_exception (&error);
4410 if (!type && abuilder->loaded_modules) {
4411 for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) {
4412 MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
4413 type = mono_reflection_get_type_checked (mod->image, mod->image, &info, ignoreCase, &type_resolve, &error);
4414 if (!is_ok (&error)) {
4416 mono_reflection_free_type_info (&info);
4417 mono_error_set_pending_exception (&error);
4426 type = mono_reflection_get_type_checked (assembly->assembly->image, assembly->assembly->image, &info, ignoreCase, &type_resolve, &error);
4427 if (!is_ok (&error)) {
4429 mono_reflection_free_type_info (&info);
4430 mono_error_set_pending_exception (&error);
4435 mono_reflection_free_type_info (&info);
4437 MonoException *e = NULL;
4440 e = mono_get_exception_type_load (name, NULL);
4443 mono_set_pending_exception (e);
4447 if (type->type == MONO_TYPE_CLASS) {
4448 MonoClass *klass = mono_type_get_class (type);
4450 /* need to report exceptions ? */
4451 if (throwOnError && mono_class_has_failure (klass)) {
4452 /* report SecurityException (or others) that occured when loading the assembly */
4453 mono_error_set_for_class_failure (&error, klass);
4454 mono_error_set_pending_exception (&error);
4459 /* g_print ("got it\n"); */
4460 ret = mono_type_get_object_checked (mono_object_domain (assembly), type, &error);
4461 mono_error_set_pending_exception (&error);
4467 replace_shadow_path (MonoDomain *domain, gchar *dirname, gchar **filename)
4470 gchar *shadow_ini_file;
4473 /* Check for shadow-copied assembly */
4474 if (mono_is_shadow_copy_enabled (domain, dirname)) {
4475 shadow_ini_file = g_build_filename (dirname, "__AssemblyInfo__.ini", NULL);
4477 if (!g_file_get_contents (shadow_ini_file, &content, &len, NULL) ||
4478 !g_file_test (content, G_FILE_TEST_IS_REGULAR)) {
4484 g_free (shadow_ini_file);
4485 if (content != NULL) {
4488 *filename = content;
4495 ICALL_EXPORT MonoString *
4496 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssembly *assembly, MonoBoolean escaped)
4498 MonoDomain *domain = mono_object_domain (assembly);
4499 MonoAssembly *mass = assembly->assembly;
4500 MonoString *res = NULL;
4505 if (g_path_is_absolute (mass->image->name)) {
4506 absolute = g_strdup (mass->image->name);
4507 dirname = g_path_get_dirname (absolute);
4509 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4510 dirname = g_strdup (mass->basedir);
4513 replace_shadow_path (domain, dirname, &absolute);
4516 mono_icall_make_platform_path (absolute);
4519 uri = g_filename_to_uri (absolute, NULL, NULL);
4521 const gchar *prepend = mono_icall_get_file_path_prefix (absolute);
4522 uri = g_strconcat (prepend, absolute, NULL);
4526 res = mono_string_new (domain, uri);
4533 ICALL_EXPORT MonoBoolean
4534 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssembly *assembly)
4536 MonoAssembly *mass = assembly->assembly;
4538 return mass->in_gac;
4541 ICALL_EXPORT MonoReflectionAssembly*
4542 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoString *mname, MonoObject *evidence)
4547 MonoImageOpenStatus status;
4548 MonoReflectionAssembly* result = NULL;
4550 name = mono_string_to_utf8_checked (mname, &error);
4551 if (mono_error_set_pending_exception (&error))
4553 res = mono_assembly_load_with_partial_name (name, &status);
4559 result = mono_assembly_get_object_checked (mono_domain_get (), res, &error);
4561 mono_error_set_pending_exception (&error);
4565 ICALL_EXPORT MonoStringHandle
4566 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssemblyHandle refassembly, MonoError *error)
4568 MonoDomain *domain = MONO_HANDLE_DOMAIN (refassembly);
4569 MonoAssembly *assembly = MONO_HANDLE_RAW (refassembly)->assembly;
4570 return mono_string_new_handle (domain, mono_image_get_filename (assembly->image), error);
4573 ICALL_EXPORT MonoBoolean
4574 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssembly *assembly)
4576 return assembly->assembly->ref_only;
4579 ICALL_EXPORT MonoStringHandle
4580 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssemblyHandle refassembly, MonoError *error)
4582 MonoDomain *domain = MONO_HANDLE_DOMAIN (refassembly);
4583 MonoAssembly *assembly = MONO_HANDLE_RAW (refassembly)->assembly;
4585 return mono_string_new_handle (domain, assembly->image->version, error);
4588 ICALL_EXPORT MonoReflectionMethod*
4589 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssembly *assembly)
4592 MonoReflectionMethod *res = NULL;
4595 guint32 token = mono_image_get_entry_point (assembly->assembly->image);
4599 method = mono_get_method_checked (assembly->assembly->image, token, NULL, NULL, &error);
4600 if (!mono_error_ok (&error))
4603 res = mono_method_get_object_checked (mono_object_domain (assembly), method, NULL, &error);
4606 if (!mono_error_ok (&error))
4607 mono_error_set_pending_exception (&error);
4611 ICALL_EXPORT MonoReflectionModule*
4612 ves_icall_System_Reflection_Assembly_GetManifestModuleInternal (MonoReflectionAssembly *assembly)
4615 MonoReflectionModule *result = NULL;
4616 result = mono_module_get_object_checked (mono_object_domain (assembly), assembly->assembly->image, &error);
4617 if (!mono_error_ok (&error))
4618 mono_error_set_pending_exception (&error);
4622 ICALL_EXPORT MonoArray*
4623 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssembly *assembly)
4626 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4627 MonoArray *result = mono_array_new_checked (mono_object_domain (assembly), mono_defaults.string_class, table->rows, &error);
4628 if (mono_error_set_pending_exception (&error))
4633 for (i = 0; i < table->rows; ++i) {
4634 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_MANIFEST_NAME));
4635 mono_array_setref (result, i, mono_string_new (mono_object_domain (assembly), val));
4640 ICALL_EXPORT MonoStringHandle
4641 ves_icall_System_Reflection_Assembly_GetAotId (MonoError *error)
4644 guint8 aotid_sum = 0;
4645 MonoDomain* domain = mono_domain_get ();
4647 if (!domain->entry_assembly || !domain->entry_assembly->image)
4650 guint8 (*aotid)[16] = &domain->entry_assembly->image->aotid;
4652 for (i = 0; i < 16; ++i)
4653 aotid_sum |= (*aotid)[i];
4658 gchar *guid = mono_guid_to_string((guint8*) aotid);
4659 MonoStringHandle res = mono_string_new_handle (domain, guid, error);
4664 static MonoAssemblyName*
4665 create_referenced_assembly_name (MonoDomain *domain, MonoImage *image, MonoTableInfo *t, int i, MonoError *error)
4667 mono_error_init (error);
4668 MonoAssemblyName *aname = g_new0 (MonoAssemblyName, 1);
4670 mono_assembly_get_assemblyref (image, i, aname);
4671 aname->hash_alg = ASSEMBLY_HASH_SHA1 /* SHA1 (default) */;
4672 /* name and culture are pointers into the image tables, but we need
4673 * real malloc'd strings (so that we can g_free() them later from
4674 * Mono.RuntimeMarshal.FreeAssemblyName) */
4675 aname->name = g_strdup (aname->name);
4676 aname->culture = g_strdup (aname->culture);
4677 /* Don't need the hash value in managed */
4678 aname->hash_value = NULL;
4679 aname->hash_len = 0;
4680 g_assert (aname->public_key == NULL);
4682 /* note: this function doesn't return the codebase on purpose (i.e. it can
4683 be used under partial trust as path information isn't present). */
4687 ICALL_EXPORT GPtrArray*
4688 ves_icall_System_Reflection_Assembly_InternalGetReferencedAssemblies (MonoReflectionAssemblyHandle assembly, MonoError *error)
4690 mono_error_init (error);
4691 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly);
4692 MonoAssembly *ass = MONO_HANDLE_GETVAL(assembly, assembly);
4693 MonoImage *image = ass->image;
4695 MonoTableInfo *t = &image->tables [MONO_TABLE_ASSEMBLYREF];
4696 int count = t->rows;
4698 GPtrArray *result = g_ptr_array_sized_new (count);
4700 for (int i = 0; i < count; i++) {
4701 MonoAssemblyName *aname = create_referenced_assembly_name (domain, image, t, i, error);
4704 g_ptr_array_add (result, aname);
4709 /* move this in some file in mono/util/ */
4711 g_concat_dir_and_file (const char *dir, const char *file)
4713 g_return_val_if_fail (dir != NULL, NULL);
4714 g_return_val_if_fail (file != NULL, NULL);
4717 * If the directory name doesn't have a / on the end, we need
4718 * to add one so we get a proper path to the file
4720 if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
4721 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
4723 return g_strconcat (dir, file, NULL);
4727 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssembly *assembly, MonoString *name, gint32 *size, MonoReflectionModule **ref_module)
4730 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4732 guint32 cols [MONO_MANIFEST_SIZE];
4733 guint32 impl, file_idx;
4737 char *n = mono_string_to_utf8_checked (name, &error);
4738 if (mono_error_set_pending_exception (&error))
4741 for (i = 0; i < table->rows; ++i) {
4742 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4743 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4744 if (strcmp (val, n) == 0)
4748 if (i == table->rows)
4751 impl = cols [MONO_MANIFEST_IMPLEMENTATION];
4754 * this code should only be called after obtaining the
4755 * ResourceInfo and handling the other cases.
4757 g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
4758 file_idx = impl >> MONO_IMPLEMENTATION_BITS;
4760 module = mono_image_load_file_for_image_checked (assembly->assembly->image, file_idx, &error);
4761 if (mono_error_set_pending_exception (&error) || !module)
4765 module = assembly->assembly->image;
4768 MonoReflectionModule *rm = mono_module_get_object_checked (mono_domain_get (), module, &error);
4769 if (mono_error_set_pending_exception (&error))
4771 mono_gc_wbarrier_generic_store (ref_module, (MonoObject*) rm);
4773 return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
4776 ICALL_EXPORT gboolean
4777 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoManifestResourceInfo *info)
4780 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4782 guint32 cols [MONO_MANIFEST_SIZE];
4783 guint32 file_cols [MONO_FILE_SIZE];
4787 n = mono_string_to_utf8_checked (name, &error);
4788 if (mono_error_set_pending_exception (&error))
4790 for (i = 0; i < table->rows; ++i) {
4791 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4792 val = mono_metadata_string_heap (assembly->assembly->image, cols [MONO_MANIFEST_NAME]);
4793 if (strcmp (val, n) == 0)
4797 if (i == table->rows)
4800 if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
4801 info->location = RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST;
4804 switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
4805 case MONO_IMPLEMENTATION_FILE:
4806 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4807 table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4808 mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
4809 val = mono_metadata_string_heap (assembly->assembly->image, file_cols [MONO_FILE_NAME]);
4810 MONO_OBJECT_SETREF (info, filename, mono_string_new (mono_object_domain (assembly), val));
4811 if (file_cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA)
4814 info->location = RESOURCE_LOCATION_EMBEDDED;
4817 case MONO_IMPLEMENTATION_ASSEMBLYREF:
4818 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4819 mono_assembly_load_reference (assembly->assembly->image, i - 1);
4820 if (assembly->assembly->image->references [i - 1] == (gpointer)-1) {
4821 mono_error_set_assembly_load (&error, NULL, "Assembly %d referenced from assembly %s not found ", i - 1, assembly->assembly->image->name);
4822 mono_error_set_pending_exception (&error);
4825 MonoReflectionAssembly *assm_obj;
4826 assm_obj = mono_assembly_get_object_checked (mono_domain_get (), assembly->assembly->image->references [i - 1], &error);
4828 mono_error_set_pending_exception (&error);
4831 MONO_OBJECT_SETREF (info, assembly, assm_obj);
4833 /* Obtain info recursively */
4834 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (info->assembly, name, info);
4835 info->location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
4838 case MONO_IMPLEMENTATION_EXP_TYPE:
4839 g_assert_not_reached ();
4847 ICALL_EXPORT MonoObject*
4848 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssembly *assembly, MonoString *name, MonoBoolean resource_modules)
4851 MonoTableInfo *table = &assembly->assembly->image->tables [MONO_TABLE_FILE];
4852 MonoArray *result = NULL;
4857 /* check hash if needed */
4859 n = mono_string_to_utf8_checked (name, &error);
4860 if (mono_error_set_pending_exception (&error))
4863 for (i = 0; i < table->rows; ++i) {
4864 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4865 if (strcmp (val, n) == 0) {
4868 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4869 fn = mono_string_new (mono_object_domain (assembly), n);
4871 return (MonoObject*)fn;
4879 for (i = 0; i < table->rows; ++i) {
4880 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA))
4884 result = mono_array_new_checked (mono_object_domain (assembly), mono_defaults.string_class, count, &error);
4885 if (mono_error_set_pending_exception (&error))
4890 for (i = 0; i < table->rows; ++i) {
4891 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4892 val = mono_metadata_string_heap (assembly->assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4893 n = g_concat_dir_and_file (assembly->assembly->basedir, val);
4894 mono_array_setref (result, count, mono_string_new (mono_object_domain (assembly), n));
4899 return (MonoObject*)result;
4902 ICALL_EXPORT MonoArray*
4903 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssembly *assembly)
4906 MonoDomain *domain = mono_domain_get();
4909 int i, j, file_count = 0;
4910 MonoImage **modules;
4911 guint32 module_count, real_module_count;
4912 MonoTableInfo *table;
4913 guint32 cols [MONO_FILE_SIZE];
4914 MonoImage *image = assembly->assembly->image;
4916 g_assert (image != NULL);
4917 g_assert (!assembly_is_dynamic (assembly->assembly));
4919 table = &image->tables [MONO_TABLE_FILE];
4920 file_count = table->rows;
4922 modules = image->modules;
4923 module_count = image->module_count;
4925 real_module_count = 0;
4926 for (i = 0; i < module_count; ++i)
4928 real_module_count ++;
4930 klass = mono_class_get_module_class ();
4931 res = mono_array_new_checked (domain, klass, 1 + real_module_count + file_count, &error);
4932 if (mono_error_set_pending_exception (&error))
4935 MonoReflectionModule *image_obj = mono_module_get_object_checked (domain, image, &error);
4936 if (mono_error_set_pending_exception (&error))
4939 mono_array_setref (res, 0, image_obj);
4941 for (i = 0; i < module_count; ++i)
4943 MonoReflectionModule *rm = mono_module_get_object_checked (domain, modules[i], &error);
4944 if (mono_error_set_pending_exception (&error))
4946 mono_array_setref (res, j, rm);
4950 for (i = 0; i < file_count; ++i, ++j) {
4951 mono_metadata_decode_row (table, i, cols, MONO_FILE_SIZE);
4952 if (cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA) {
4953 MonoReflectionModule *rm = mono_module_file_get_object_checked (domain, image, i, &error);
4954 if (mono_error_set_pending_exception (&error))
4956 mono_array_setref (res, j, rm);
4959 MonoImage *m = mono_image_load_file_for_image_checked (image, i + 1, &error);
4960 if (mono_error_set_pending_exception (&error))
4963 const char *filename = mono_metadata_string_heap (image, cols [MONO_FILE_NAME]);
4964 mono_error_set_assembly_load (&error, g_strdup (filename), "%s", "");
4965 mono_error_set_pending_exception (&error);
4968 MonoReflectionModule *rm = mono_module_get_object_checked (domain, m, &error);
4969 if (mono_error_set_pending_exception (&error))
4971 mono_array_setref (res, j, rm);
4978 ICALL_EXPORT MonoReflectionMethod*
4979 ves_icall_GetCurrentMethod (void)
4981 MonoReflectionMethod *res = NULL;
4984 MonoMethod *m = mono_method_get_last_managed ();
4987 mono_set_pending_exception (mono_get_exception_not_supported ("Stack walks are not supported on this platform."));
4991 while (m->is_inflated)
4992 m = ((MonoMethodInflated*)m)->declaring;
4994 res = mono_method_get_object_checked (mono_domain_get (), m, NULL, &error);
4995 mono_error_set_pending_exception (&error);
5001 mono_method_get_equivalent_method (MonoMethod *method, MonoClass *klass)
5004 if (method->is_inflated && ((MonoMethodInflated*)method)->context.method_inst) {
5007 MonoMethodInflated *inflated = (MonoMethodInflated*)method;
5008 //method is inflated, we should inflate it on the other class
5009 MonoGenericContext ctx;
5010 ctx.method_inst = inflated->context.method_inst;
5011 ctx.class_inst = inflated->context.class_inst;
5012 if (mono_class_is_ginst (klass))
5013 ctx.class_inst = mono_class_get_generic_class (klass)->context.class_inst;
5014 else if (mono_class_is_gtd (klass))
5015 ctx.class_inst = mono_class_get_generic_container (klass)->context.class_inst;
5016 result = mono_class_inflate_generic_method_full_checked (inflated->declaring, klass, &ctx, &error);
5017 g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
5021 mono_class_setup_methods (method->klass);
5022 if (mono_class_has_failure (method->klass))
5024 int mcount = mono_class_get_method_count (method->klass);
5025 for (i = 0; i < mcount; ++i) {
5026 if (method->klass->methods [i] == method) {
5031 mono_class_setup_methods (klass);
5032 if (mono_class_has_failure (klass))
5034 g_assert (offset >= 0 && offset < mono_class_get_method_count (klass));
5035 return klass->methods [offset];
5038 ICALL_EXPORT MonoReflectionMethod*
5039 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType_native (MonoMethod *method, MonoType *type, MonoBoolean generic_check)
5041 MonoReflectionMethod *res = NULL;
5044 if (type && generic_check) {
5045 klass = mono_class_from_mono_type (type);
5046 if (mono_class_get_generic_type_definition (method->klass) != mono_class_get_generic_type_definition (klass))
5049 if (method->klass != klass) {
5050 method = mono_method_get_equivalent_method (method, klass);
5055 klass = mono_class_from_mono_type (type);
5057 klass = method->klass;
5058 res = mono_method_get_object_checked (mono_domain_get (), method, klass, &error);
5059 mono_error_set_pending_exception (&error);
5063 ICALL_EXPORT MonoReflectionMethodBody*
5064 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod *method)
5067 MonoReflectionMethodBody *result = mono_method_body_get_object_checked (mono_domain_get (), method, &error);
5068 mono_error_set_pending_exception (&error);
5072 ICALL_EXPORT MonoReflectionAssembly*
5073 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (void)
5076 MonoReflectionAssembly *result;
5077 MonoMethod *dest = NULL;
5079 mono_stack_walk_no_il (get_executing, &dest);
5081 result = mono_assembly_get_object_checked (mono_domain_get (), dest->klass->image->assembly, &error);
5083 mono_error_set_pending_exception (&error);
5088 ICALL_EXPORT MonoReflectionAssembly*
5089 ves_icall_System_Reflection_Assembly_GetEntryAssembly (void)
5092 MonoReflectionAssembly *result;
5093 MonoDomain* domain = mono_domain_get ();
5095 if (!domain->entry_assembly)
5098 result = mono_assembly_get_object_checked (domain, domain->entry_assembly, &error);
5100 mono_error_set_pending_exception (&error);
5104 ICALL_EXPORT MonoReflectionAssembly*
5105 ves_icall_System_Reflection_Assembly_GetCallingAssembly (void)
5110 MonoReflectionAssembly *result;
5113 mono_stack_walk_no_il (get_executing, &dest);
5115 mono_stack_walk_no_il (get_caller_no_reflection, &dest);
5119 mono_set_pending_exception (mono_get_exception_not_supported ("Stack walks are not supported on this platform."));
5122 result = mono_assembly_get_object_checked (mono_domain_get (), dest->klass->image->assembly, &error);
5124 mono_error_set_pending_exception (&error);
5128 ICALL_EXPORT MonoStringHandle
5129 ves_icall_System_RuntimeType_getFullName (MonoReflectionTypeHandle object, gboolean full_name,
5130 gboolean assembly_qualified, MonoError *error)
5132 MonoDomain *domain = mono_object_domain (MONO_HANDLE_RAW (object));
5133 MonoType *type = MONO_HANDLE_RAW (object)->type;
5134 MonoTypeNameFormat format;
5135 MonoStringHandle res;
5139 format = assembly_qualified ?
5140 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
5141 MONO_TYPE_NAME_FORMAT_FULL_NAME;
5143 format = MONO_TYPE_NAME_FORMAT_REFLECTION;
5145 name = mono_type_get_name_full (type, format);
5147 return NULL_HANDLE_STRING;
5149 if (full_name && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR)) {
5151 return NULL_HANDLE_STRING;
5154 res = mono_string_new_handle (domain, name, error);
5161 vell_icall_RuntimeType_get_core_clr_security_level (MonoReflectionType *rfield)
5164 MonoClass *klass = mono_class_from_mono_type (rfield->type);
5166 mono_class_init_checked (klass, &error);
5167 mono_error_set_pending_exception (&error);
5168 return mono_security_core_clr_class_level (klass);
5172 ves_icall_MonoField_get_core_clr_security_level (MonoReflectionField *rfield)
5174 MonoClassField *field = rfield->field;
5175 return mono_security_core_clr_field_level (field, TRUE);
5179 ves_icall_MonoMethod_get_core_clr_security_level (MonoReflectionMethod *rfield)
5181 MonoMethod *method = rfield->method;
5182 return mono_security_core_clr_method_level (method, TRUE);
5185 ICALL_EXPORT MonoString *
5186 ves_icall_System_Reflection_Assembly_get_fullName (MonoReflectionAssembly *assembly)
5188 MonoDomain *domain = mono_object_domain (assembly);
5189 MonoAssembly *mass = assembly->assembly;
5193 name = mono_stringify_assembly_name (&mass->aname);
5194 res = mono_string_new (domain, name);
5200 ICALL_EXPORT MonoAssemblyName *
5201 ves_icall_System_Reflection_AssemblyName_GetNativeName (MonoAssembly *mass)
5203 return &mass->aname;
5207 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoStringHandle fname, MonoAssemblyName *name, MonoStringHandleOut normalized_codebase, MonoError *error)
5210 MonoImageOpenStatus status = MONO_IMAGE_OK;
5211 char *codebase = NULL;
5216 mono_error_init (error);
5218 filename = mono_string_handle_to_utf8 (fname, error);
5219 return_if_nok (error);
5221 dirname = g_path_get_dirname (filename);
5222 replace_shadow_path (mono_domain_get (), dirname, &filename);
5225 image = mono_image_open (filename, &status);
5228 if (status == MONO_IMAGE_IMAGE_INVALID)
5229 mono_error_set_bad_image_name (error, g_strdup (filename), "%s", "");
5231 mono_error_set_assembly_load (error, g_strdup (filename), "%s", "");
5236 res = mono_assembly_fill_assembly_name_full (image, name, TRUE);
5238 mono_image_close (image);
5240 mono_error_set_argument (error, "assemblyFile", "The file does not contain a manifest");
5244 if (filename != NULL && *filename != '\0') {
5247 codebase = g_strdup (filename);
5249 mono_icall_make_platform_path (codebase);
5251 const gchar *prepend = mono_icall_get_file_path_prefix (codebase);
5253 result = g_strconcat (prepend, codebase, NULL);
5257 MONO_HANDLE_ASSIGN (normalized_codebase, mono_string_new_handle (mono_domain_get (), codebase, error));
5260 mono_image_close (image);
5264 ICALL_EXPORT MonoBoolean
5265 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssembly *assembly,
5266 char **minimum, guint32 *minLength, char **optional, guint32 *optLength, char **refused, guint32 *refLength)
5268 MonoBoolean result = FALSE;
5269 MonoDeclSecurityEntry entry;
5271 /* SecurityAction.RequestMinimum */
5272 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQMIN, &entry)) {
5273 *minimum = entry.blob;
5274 *minLength = entry.size;
5277 /* SecurityAction.RequestOptional */
5278 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQOPT, &entry)) {
5279 *optional = entry.blob;
5280 *optLength = entry.size;
5283 /* SecurityAction.RequestRefuse */
5284 if (mono_declsec_get_assembly_action (assembly->assembly, SECURITY_ACTION_REQREFUSE, &entry)) {
5285 *refused = entry.blob;
5286 *refLength = entry.size;
5294 mono_module_type_is_visible (MonoTableInfo *tdef, MonoImage *image, int type)
5296 guint32 attrs, visibility;
5298 attrs = mono_metadata_decode_row_col (tdef, type - 1, MONO_TYPEDEF_FLAGS);
5299 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
5300 if (visibility != TYPE_ATTRIBUTE_PUBLIC && visibility != TYPE_ATTRIBUTE_NESTED_PUBLIC)
5303 } while ((type = mono_metadata_token_index (mono_metadata_nested_in_typedef (image, type))));
5309 image_get_type (MonoDomain *domain, MonoImage *image, MonoTableInfo *tdef, int table_idx, int count, MonoArrayHandle res, MonoArrayHandle exceptions, MonoBoolean exportedOnly, MonoError *error)
5311 mono_error_init (error);
5312 HANDLE_FUNCTION_ENTER ();
5313 MonoError klass_error;
5314 MonoClass *klass = mono_class_get_checked (image, table_idx | MONO_TOKEN_TYPE_DEF, &klass_error);
5317 MonoReflectionTypeHandle rt = mono_type_get_object_handle (domain, &klass->byval_arg, error);
5318 return_if_nok (error);
5320 MONO_HANDLE_ARRAY_SETREF (res, count, rt);
5322 MonoException *ex = mono_error_convert_to_exception (error);
5323 MONO_HANDLE_ARRAY_SETRAW (exceptions, count, ex);
5325 HANDLE_FUNCTION_RETURN ();
5328 static MonoArrayHandle
5329 mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoArrayHandleOut exceptions, MonoBoolean exportedOnly, MonoError *error)
5331 MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
5334 mono_error_init (error);
5336 /* we start the count from 1 because we skip the special type <Module> */
5339 for (i = 1; i < tdef->rows; ++i) {
5340 if (mono_module_type_is_visible (tdef, image, i + 1))
5344 count = tdef->rows - 1;
5346 MonoArrayHandle res = mono_array_new_handle (domain, mono_defaults.runtimetype_class, count, error);
5347 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5348 MONO_HANDLE_ASSIGN (exceptions, mono_array_new_handle (domain, mono_defaults.exception_class, count, error));
5349 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5351 for (i = 1; i < tdef->rows; ++i) {
5352 if (!exportedOnly || mono_module_type_is_visible (tdef, image, i+1)) {
5353 image_get_type (domain, image, tdef, i + 1, count, res, exceptions, exportedOnly, error);
5354 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5363 append_module_types (MonoDomain *domain, MonoArrayHandleOut res, MonoArrayHandleOut exceptions, MonoImage *image, MonoBoolean exportedOnly, MonoError *error)
5365 HANDLE_FUNCTION_ENTER ();
5366 mono_error_init (error);
5367 MonoArrayHandle ex2 = MONO_HANDLE_NEW (MonoArray, NULL);
5368 MonoArrayHandle res2 = mono_module_get_types (domain, image, ex2, exportedOnly, error);
5372 /* Append the new types to the end of the array */
5373 if (mono_array_handle_length (res2) > 0) {
5376 len1 = mono_array_handle_length (res);
5377 len2 = mono_array_handle_length (res2);
5379 MonoArrayHandle res3 = mono_array_new_handle (domain, mono_defaults.runtimetype_class, len1 + len2, error);
5383 mono_array_handle_memcpy_refs (res3, 0, res, 0, len1);
5384 mono_array_handle_memcpy_refs (res3, len1, res2, 0, len2);
5385 MONO_HANDLE_ASSIGN (res, res3);
5387 MonoArrayHandle ex3 = mono_array_new_handle (domain, mono_defaults.runtimetype_class, len1 + len2, error);
5391 mono_array_handle_memcpy_refs (ex3, 0, exceptions, 0, len1);
5392 mono_array_handle_memcpy_refs (ex3, len1, ex2, 0, len2);
5393 MONO_HANDLE_ASSIGN (exceptions, ex3);
5396 HANDLE_FUNCTION_RETURN ();
5400 set_class_failure_in_array (MonoArrayHandle exl, int i, MonoClass *klass)
5402 HANDLE_FUNCTION_ENTER ();
5403 MonoError unboxed_error;
5404 mono_error_init (&unboxed_error);
5405 mono_error_set_for_class_failure (&unboxed_error, klass);
5407 MonoExceptionHandle exc = MONO_HANDLE_NEW (MonoException, mono_error_convert_to_exception (&unboxed_error));
5408 MONO_HANDLE_ARRAY_SETREF (exl, i, exc);
5409 HANDLE_FUNCTION_RETURN ();
5412 ICALL_EXPORT MonoArrayHandle
5413 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssemblyHandle assembly_handle, MonoBoolean exportedOnly, MonoError *error)
5415 MonoArrayHandle exceptions = MONO_HANDLE_NEW(MonoArray, NULL);
5418 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_handle);
5419 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_handle, assembly);
5421 g_assert (!assembly_is_dynamic (assembly));
5422 MonoImage *image = assembly->image;
5423 MonoTableInfo *table = &image->tables [MONO_TABLE_FILE];
5424 MonoArrayHandle res = mono_module_get_types (domain, image, exceptions, exportedOnly, error);
5425 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5427 /* Append data from all modules in the assembly */
5428 for (i = 0; i < table->rows; ++i) {
5429 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
5430 MonoImage *loaded_image = mono_assembly_load_module_checked (image->assembly, i + 1, error);
5431 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5434 append_module_types (domain, res, exceptions, loaded_image, exportedOnly, error);
5435 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5440 /* the ReflectionTypeLoadException must have all the types (Types property),
5441 * NULL replacing types which throws an exception. The LoaderException must
5442 * contain all exceptions for NULL items.
5445 int len = mono_array_handle_length (res);
5449 MonoReflectionTypeHandle t = MONO_HANDLE_NEW (MonoReflectionType, NULL);
5450 for (i = 0; i < len; i++) {
5451 MONO_HANDLE_ARRAY_GETREF (t, res, i);
5453 if (!MONO_HANDLE_IS_NULL (t)) {
5454 MonoClass *klass = mono_type_get_class (MONO_HANDLE_GETVAL (t, type));
5455 if ((klass != NULL) && mono_class_has_failure (klass)) {
5456 /* keep the class in the list */
5457 list = g_list_append (list, klass);
5458 /* and replace Type with NULL */
5459 MONO_HANDLE_ARRAY_SETRAW (res, i, NULL);
5466 if (list || ex_count) {
5468 int j, length = g_list_length (list) + ex_count;
5470 MonoArrayHandle exl = mono_array_new_handle (domain, mono_defaults.exception_class, length, error);
5471 if (!is_ok (error)) {
5473 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5475 /* Types for which mono_class_get_checked () succeeded */
5476 MonoExceptionHandle exc = MONO_HANDLE_NEW (MonoException, NULL);
5477 for (i = 0, tmp = list; tmp; i++, tmp = tmp->next) {
5478 set_class_failure_in_array (exl, i, (MonoClass*)tmp->data);
5480 /* Types for which it don't */
5481 for (j = 0; j < mono_array_handle_length (exceptions); ++j) {
5482 MONO_HANDLE_ARRAY_GETREF (exc, exceptions, j);
5483 if (!MONO_HANDLE_IS_NULL (exc)) {
5484 g_assert (i < length);
5485 MONO_HANDLE_ARRAY_SETREF (exl, i, exc);
5492 MONO_HANDLE_ASSIGN (exc, mono_get_exception_reflection_type_load_checked (res, exl, error));
5493 if (!is_ok (error)) {
5494 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5496 mono_error_set_exception_handle (error, exc);
5497 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5504 ves_icall_Mono_RuntimeMarshal_FreeAssemblyName (MonoAssemblyName *aname, gboolean free_struct)
5506 mono_assembly_name_free (aname);
5511 ICALL_EXPORT gboolean
5512 ves_icall_System_Reflection_AssemblyName_ParseAssemblyName (const char *name, MonoAssemblyName *aname, gboolean *is_version_definited, gboolean *is_token_defined)
5514 *is_version_definited = *is_token_defined = FALSE;
5516 return mono_assembly_name_parse_full (name, aname, TRUE, is_version_definited, is_token_defined);
5519 ICALL_EXPORT MonoReflectionTypeHandle
5520 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModuleHandle module, MonoError *error)
5522 MonoDomain *domain = MONO_HANDLE_DOMAIN (module);
5523 MonoImage *image = MONO_HANDLE_GETVAL (module, image);
5528 MonoReflectionTypeHandle ret = MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
5530 if (image_is_dynamic (image) && ((MonoDynamicImage*)image)->initial_image)
5531 /* These images do not have a global type */
5534 klass = mono_class_get_checked (image, 1 | MONO_TOKEN_TYPE_DEF, error);
5538 ret = mono_type_get_object_handle (domain, &klass->byval_arg, error);
5544 ves_icall_System_Reflection_Module_Close (MonoReflectionModuleHandle module, MonoError *error)
5546 /*if (module->image)
5547 mono_image_close (module->image);*/
5550 ICALL_EXPORT MonoStringHandle
5551 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModuleHandle refmodule, MonoError *error)
5553 MonoDomain *domain = MONO_HANDLE_DOMAIN (refmodule);
5554 MonoImage *image = MONO_HANDLE_GETVAL (refmodule, image);
5557 return mono_string_new_handle (domain, image->guid, error);
5561 static inline gpointer
5562 mono_icall_module_get_hinstance (MonoReflectionModuleHandle module)
5564 return (gpointer) (-1);
5566 #endif /* HOST_WIN32 */
5568 ICALL_EXPORT gpointer
5569 ves_icall_System_Reflection_Module_GetHINSTANCE (MonoReflectionModuleHandle module, MonoError *error)
5571 return mono_icall_module_get_hinstance (module);
5575 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine, MonoError *error)
5577 if (image_is_dynamic (image)) {
5578 MonoDynamicImage *dyn = (MonoDynamicImage*)image;
5579 *pe_kind = dyn->pe_kind;
5580 *machine = dyn->machine;
5583 *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
5584 *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
5589 ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage *image, MonoError *error)
5591 return (image->md_version_major << 16) | (image->md_version_minor);
5594 ICALL_EXPORT MonoArrayHandle
5595 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModuleHandle module, MonoError *error)
5597 mono_error_init (error);
5599 MonoImage *image = MONO_HANDLE_GETVAL (module, image);
5600 MonoDomain *domain = MONO_HANDLE_DOMAIN (module);
5603 MonoArrayHandle arr = mono_array_new_handle (domain, mono_defaults.runtimetype_class, 0, error);
5606 MonoArrayHandle exceptions = MONO_HANDLE_NEW (MonoArray, NULL);
5607 MonoArrayHandle res = mono_module_get_types (domain, image, exceptions, FALSE, error);
5608 return_val_if_nok (error, MONO_HANDLE_CAST(MonoArray, NULL_HANDLE));
5610 int n = mono_array_handle_length (exceptions);
5611 MonoExceptionHandle ex = MONO_HANDLE_NEW (MonoException, NULL);
5612 for (int i = 0; i < n; ++i) {
5613 MONO_HANDLE_ARRAY_GETREF(ex, exceptions, i);
5614 if (!MONO_HANDLE_IS_NULL (ex)) {
5615 mono_error_set_exception_handle (error, ex);
5616 return MONO_HANDLE_CAST(MonoArray, NULL_HANDLE);
5624 mono_memberref_is_method (MonoImage *image, guint32 token)
5626 if (!image_is_dynamic (image)) {
5627 guint32 cols [MONO_MEMBERREF_SIZE];
5629 mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
5630 sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
5631 mono_metadata_decode_blob_size (sig, &sig);
5632 return (*sig != 0x6);
5635 MonoClass *handle_class;
5637 if (!mono_lookup_dynamic_token_class (image, token, FALSE, &handle_class, NULL, &error)) {
5638 mono_error_cleanup (&error); /* just probing, ignore error */
5642 return mono_defaults.methodhandle_class == handle_class;
5647 init_generic_context_from_args (MonoGenericContext *context, MonoArray *type_args, MonoArray *method_args)
5650 context->class_inst = mono_metadata_get_generic_inst (mono_array_length (type_args),
5651 mono_array_addr (type_args, MonoType*, 0));
5653 context->class_inst = NULL;
5655 context->method_inst = mono_metadata_get_generic_inst (mono_array_length (method_args),
5656 mono_array_addr (method_args, MonoType*, 0));
5658 context->method_inst = NULL;
5661 ICALL_EXPORT MonoType*
5662 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *resolve_error)
5665 int table = mono_metadata_token_table (token);
5666 int index = mono_metadata_token_index (token);
5667 MonoGenericContext context;
5670 *resolve_error = ResolveTokenError_Other;
5672 /* Validate token */
5673 if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) &&
5674 (table != MONO_TABLE_TYPESPEC)) {
5675 *resolve_error = ResolveTokenError_BadTable;
5679 if (image_is_dynamic (image)) {
5680 if ((table == MONO_TABLE_TYPEDEF) || (table == MONO_TABLE_TYPEREF)) {
5681 klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5682 mono_error_cleanup (&error);
5683 return klass ? &klass->byval_arg : NULL;
5686 init_generic_context_from_args (&context, type_args, method_args);
5687 klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
5688 mono_error_cleanup (&error);
5689 return klass ? &klass->byval_arg : NULL;
5692 if ((index <= 0) || (index > image->tables [table].rows)) {
5693 *resolve_error = ResolveTokenError_OutOfRange;
5697 init_generic_context_from_args (&context, type_args, method_args);
5698 klass = mono_class_get_checked (image, token, &error);
5700 klass = mono_class_inflate_generic_class_checked (klass, &context, &error);
5701 if (!mono_error_ok (&error)) {
5702 mono_error_set_pending_exception (&error);
5707 return &klass->byval_arg;
5712 ICALL_EXPORT MonoMethod*
5713 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *resolve_error)
5716 int table = mono_metadata_token_table (token);
5717 int index = mono_metadata_token_index (token);
5718 MonoGenericContext context;
5721 *resolve_error = ResolveTokenError_Other;
5723 /* Validate token */
5724 if ((table != MONO_TABLE_METHOD) && (table != MONO_TABLE_METHODSPEC) &&
5725 (table != MONO_TABLE_MEMBERREF)) {
5726 *resolve_error = ResolveTokenError_BadTable;
5730 if (image_is_dynamic (image)) {
5731 if (table == MONO_TABLE_METHOD) {
5732 method = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5733 mono_error_cleanup (&error);
5737 if ((table == MONO_TABLE_MEMBERREF) && !(mono_memberref_is_method (image, token))) {
5738 *resolve_error = ResolveTokenError_BadTable;
5742 init_generic_context_from_args (&context, type_args, method_args);
5743 method = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
5744 mono_error_cleanup (&error);
5748 if ((index <= 0) || (index > image->tables [table].rows)) {
5749 *resolve_error = ResolveTokenError_OutOfRange;
5752 if ((table == MONO_TABLE_MEMBERREF) && (!mono_memberref_is_method (image, token))) {
5753 *resolve_error = ResolveTokenError_BadTable;
5757 init_generic_context_from_args (&context, type_args, method_args);
5758 method = mono_get_method_checked (image, token, NULL, &context, &error);
5759 mono_error_set_pending_exception (&error);
5764 ICALL_EXPORT MonoString*
5765 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *resolve_error)
5768 int index = mono_metadata_token_index (token);
5770 *resolve_error = ResolveTokenError_Other;
5772 /* Validate token */
5773 if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
5774 *resolve_error = ResolveTokenError_BadTable;
5778 if (image_is_dynamic (image)) {
5779 MonoString * result = (MonoString *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5780 mono_error_cleanup (&error);
5784 if ((index <= 0) || (index >= image->heap_us.size)) {
5785 *resolve_error = ResolveTokenError_OutOfRange;
5789 /* FIXME: What to do if the index points into the middle of a string ? */
5791 MonoString *result = mono_ldstr_checked (mono_domain_get (), image, index, &error);
5792 mono_error_set_pending_exception (&error);
5796 ICALL_EXPORT MonoClassField*
5797 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *resolve_error)
5801 int table = mono_metadata_token_table (token);
5802 int index = mono_metadata_token_index (token);
5803 MonoGenericContext context;
5804 MonoClassField *field;
5806 *resolve_error = ResolveTokenError_Other;
5808 /* Validate token */
5809 if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
5810 *resolve_error = ResolveTokenError_BadTable;
5814 if (image_is_dynamic (image)) {
5815 if (table == MONO_TABLE_FIELD) {
5816 field = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5817 mono_error_cleanup (&error);
5821 if (mono_memberref_is_method (image, token)) {
5822 *resolve_error = ResolveTokenError_BadTable;
5826 init_generic_context_from_args (&context, type_args, method_args);
5827 field = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
5828 mono_error_cleanup (&error);
5832 if ((index <= 0) || (index > image->tables [table].rows)) {
5833 *resolve_error = ResolveTokenError_OutOfRange;
5836 if ((table == MONO_TABLE_MEMBERREF) && (mono_memberref_is_method (image, token))) {
5837 *resolve_error = ResolveTokenError_BadTable;
5841 init_generic_context_from_args (&context, type_args, method_args);
5842 field = mono_field_from_token_checked (image, token, &klass, &context, &error);
5843 mono_error_set_pending_exception (&error);
5849 ICALL_EXPORT MonoObject*
5850 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoArray *type_args, MonoArray *method_args, MonoResolveTokenError *error)
5854 int table = mono_metadata_token_table (token);
5856 *error = ResolveTokenError_Other;
5859 case MONO_TABLE_TYPEDEF:
5860 case MONO_TABLE_TYPEREF:
5861 case MONO_TABLE_TYPESPEC: {
5862 MonoType *t = ves_icall_System_Reflection_Module_ResolveTypeToken (image, token, type_args, method_args, error);
5864 ret = (MonoObject*) mono_type_get_object_checked (mono_domain_get (), t, &merror);
5865 mono_error_set_pending_exception (&merror);
5872 case MONO_TABLE_METHOD:
5873 case MONO_TABLE_METHODSPEC: {
5874 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5876 ret = (MonoObject*)mono_method_get_object_checked (mono_domain_get (), m, m->klass, &merror);
5877 mono_error_set_pending_exception (&merror);
5883 case MONO_TABLE_FIELD: {
5884 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5886 ret =(MonoObject*)mono_field_get_object_checked (mono_domain_get (), f->parent, f, &merror);
5887 mono_error_set_pending_exception (&merror);
5893 case MONO_TABLE_MEMBERREF:
5894 if (mono_memberref_is_method (image, token)) {
5895 MonoMethod *m = ves_icall_System_Reflection_Module_ResolveMethodToken (image, token, type_args, method_args, error);
5897 ret = (MonoObject*)mono_method_get_object_checked (mono_domain_get (), m, m->klass, &merror);
5898 mono_error_set_pending_exception (&merror);
5905 MonoClassField *f = ves_icall_System_Reflection_Module_ResolveFieldToken (image, token, type_args, method_args, error);
5907 ret = (MonoObject*)mono_field_get_object_checked (mono_domain_get (), f->parent, f, &merror);
5908 mono_error_set_pending_exception (&merror);
5917 *error = ResolveTokenError_BadTable;
5923 ICALL_EXPORT MonoArray*
5924 ves_icall_System_Reflection_Module_ResolveSignature (MonoImage *image, guint32 token, MonoResolveTokenError *resolve_error)
5927 int table = mono_metadata_token_table (token);
5928 int idx = mono_metadata_token_index (token);
5929 MonoTableInfo *tables = image->tables;
5934 *resolve_error = ResolveTokenError_OutOfRange;
5936 /* FIXME: Support other tables ? */
5937 if (table != MONO_TABLE_STANDALONESIG)
5940 if (image_is_dynamic (image))
5943 if ((idx == 0) || (idx > tables [MONO_TABLE_STANDALONESIG].rows))
5946 sig = mono_metadata_decode_row_col (&tables [MONO_TABLE_STANDALONESIG], idx - 1, 0);
5948 ptr = mono_metadata_blob_heap (image, sig);
5949 len = mono_metadata_decode_blob_size (ptr, &ptr);
5951 res = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, len, &error);
5952 if (mono_error_set_pending_exception (&error))
5954 memcpy (mono_array_addr (res, guint8, 0), ptr, len);
5958 ICALL_EXPORT MonoBoolean
5959 ves_icall_RuntimeTypeHandle_IsArray (MonoReflectionType *t)
5965 res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
5971 check_for_invalid_type (MonoClass *klass, MonoError *error)
5975 mono_error_init (error);
5977 if (klass->byval_arg.type != MONO_TYPE_TYPEDBYREF)
5980 name = mono_type_get_full_name (klass);
5981 mono_error_set_type_load_name (error, name, g_strdup (""), "");
5983 ICALL_EXPORT MonoReflectionType *
5984 ves_icall_RuntimeType_make_array_type (MonoReflectionType *type, int rank)
5987 MonoReflectionType *ret;
5988 MonoClass *klass, *aklass;
5990 klass = mono_class_from_mono_type (type->type);
5991 check_for_invalid_type (klass, &error);
5992 if (mono_error_set_pending_exception (&error))
5995 if (rank == 0) //single dimentional array
5996 aklass = mono_array_class_get (klass, 1);
5998 aklass = mono_bounded_array_class_get (klass, rank, TRUE);
6000 ret = mono_type_get_object_checked (mono_object_domain (type), &aklass->byval_arg, &error);
6001 mono_error_set_pending_exception (&error);
6006 ICALL_EXPORT MonoReflectionType *
6007 ves_icall_RuntimeType_make_byref_type (MonoReflectionType *type)
6010 MonoReflectionType *ret;
6013 klass = mono_class_from_mono_type (type->type);
6014 mono_class_init_checked (klass, &error);
6015 if (mono_error_set_pending_exception (&error))
6018 check_for_invalid_type (klass, &error);
6019 if (mono_error_set_pending_exception (&error))
6022 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->this_arg, &error);
6023 mono_error_set_pending_exception (&error);
6028 ICALL_EXPORT MonoReflectionType *
6029 ves_icall_RuntimeType_MakePointerType (MonoReflectionType *type)
6032 MonoReflectionType *ret;
6033 MonoClass *klass, *pklass;
6035 klass = mono_class_from_mono_type (type->type);
6036 mono_class_init_checked (klass, &error);
6037 if (mono_error_set_pending_exception (&error))
6039 check_for_invalid_type (klass, &error);
6040 if (mono_error_set_pending_exception (&error))
6043 pklass = mono_ptr_class_get (type->type);
6045 ret = mono_type_get_object_checked (mono_object_domain (type), &pklass->byval_arg, &error);
6046 mono_error_set_pending_exception (&error);
6051 ICALL_EXPORT MonoObject *
6052 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
6053 MonoReflectionMethod *info, MonoBoolean throwOnBindFailure)
6056 MonoClass *delegate_class = mono_class_from_mono_type (type->type);
6057 MonoObject *delegate;
6059 MonoMethod *method = info->method;
6060 MonoMethodSignature *sig = mono_method_signature(method);
6062 mono_class_init_checked (delegate_class, &error);
6063 if (mono_error_set_pending_exception (&error))
6066 if (!(delegate_class->parent == mono_defaults.multicastdelegate_class)) {
6067 /* FIXME improve this exception message */
6068 mono_error_set_execution_engine (&error, "file %s: line %d (%s): assertion failed: (%s)", __FILE__, __LINE__,
6070 "delegate_class->parent == mono_defaults.multicastdelegate_class");
6071 mono_error_set_pending_exception (&error);
6075 if (mono_security_core_clr_enabled ()) {
6076 if (!mono_security_core_clr_ensure_delegate_creation (method, &error)) {
6077 if (throwOnBindFailure)
6078 mono_error_set_pending_exception (&error);
6080 mono_error_cleanup (&error);
6085 if (sig->generic_param_count && method->wrapper_type == MONO_WRAPPER_NONE) {
6086 if (!method->is_inflated) {
6087 mono_set_pending_exception(mono_get_exception_argument("method", " Cannot bind to the target method because its signature differs from that of the delegate type"));
6092 delegate = mono_object_new_checked (mono_object_domain (type), delegate_class, &error);
6093 if (mono_error_set_pending_exception (&error))
6096 if (method_is_dynamic (method)) {
6097 /* Creating a trampoline would leak memory */
6098 func = mono_compile_method_checked (method, &error);
6099 if (mono_error_set_pending_exception (&error))
6102 if (target && method->flags & METHOD_ATTRIBUTE_VIRTUAL && method->klass != mono_object_class (target))
6103 method = mono_object_get_virtual_method (target, method);
6104 gpointer trampoline = mono_runtime_create_jump_trampoline (mono_domain_get (), method, TRUE, &error);
6105 if (mono_error_set_pending_exception (&error))
6107 func = mono_create_ftnptr (mono_domain_get (), trampoline);
6110 mono_delegate_ctor_with_method (delegate, target, func, method, &error);
6111 if (mono_error_set_pending_exception (&error))
6116 ICALL_EXPORT MonoMulticastDelegate *
6117 ves_icall_System_Delegate_AllocDelegateLike_internal (MonoDelegate *delegate)
6120 MonoMulticastDelegate *ret;
6122 g_assert (mono_class_has_parent (mono_object_class (delegate), mono_defaults.multicastdelegate_class));
6124 ret = (MonoMulticastDelegate*) mono_object_new_checked (mono_object_domain (delegate), mono_object_class (delegate), &error);
6125 if (mono_error_set_pending_exception (&error))
6128 ret->delegate.invoke_impl = mono_runtime_create_delegate_trampoline (mono_object_class (delegate));
6133 ICALL_EXPORT MonoReflectionMethod*
6134 ves_icall_System_Delegate_GetVirtualMethod_internal (MonoDelegate *delegate)
6136 MonoReflectionMethod *ret = NULL;
6138 ret = mono_method_get_object_checked (mono_domain_get (), mono_object_get_virtual_method (delegate->target, delegate->method), mono_object_class (delegate->target), &error);
6139 mono_error_set_pending_exception (&error);
6145 static inline gint32
6146 mono_array_get_byte_length (MonoArray *array)
6152 klass = array->obj.vtable->klass;
6154 if (array->bounds == NULL)
6155 length = array->max_length;
6158 for (i = 0; i < klass->rank; ++ i)
6159 length *= array->bounds [i].length;
6162 switch (klass->element_class->byval_arg.type) {
6165 case MONO_TYPE_BOOLEAN:
6169 case MONO_TYPE_CHAR:
6177 return length * sizeof (gpointer);
6188 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array)
6190 return mono_array_get_byte_length (array);
6194 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx)
6196 return mono_array_get (array, gint8, idx);
6200 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value)
6202 mono_array_set (array, gint8, idx, value);
6205 ICALL_EXPORT MonoBoolean
6206 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count)
6208 guint8 *src_buf, *dest_buf;
6211 mono_set_pending_exception (mono_get_exception_argument ("count", "is negative"));
6215 g_assert (count >= 0);
6217 /* This is called directly from the class libraries without going through the managed wrapper */
6218 MONO_CHECK_ARG_NULL (src, FALSE);
6219 MONO_CHECK_ARG_NULL (dest, FALSE);
6221 /* watch out for integer overflow */
6222 if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count))
6225 src_buf = (guint8 *)src->vector + src_offset;
6226 dest_buf = (guint8 *)dest->vector + dest_offset;
6229 memcpy (dest_buf, src_buf, count);
6231 memmove (dest_buf, src_buf, count); /* Source and dest are the same array */
6236 #ifndef DISABLE_REMOTING
6237 ICALL_EXPORT MonoObject *
6238 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this_obj, MonoString *class_name)
6241 MonoDomain *domain = mono_object_domain (this_obj);
6243 MonoRealProxy *rp = ((MonoRealProxy *)this_obj);
6244 MonoTransparentProxy *tp;
6248 res = mono_object_new_checked (domain, mono_defaults.transparent_proxy_class, &error);
6249 if (mono_error_set_pending_exception (&error))
6252 tp = (MonoTransparentProxy*) res;
6254 MONO_OBJECT_SETREF (tp, rp, rp);
6255 type = ((MonoReflectionType *)rp->class_to_proxy)->type;
6256 klass = mono_class_from_mono_type (type);
6258 // mono_remote_class_vtable cannot handle errors well, so force any loading error to occur early
6259 mono_class_setup_vtable (klass);
6260 if (mono_class_has_failure (klass)) {
6261 mono_set_pending_exception (mono_class_get_exception_for_failure (klass));
6265 tp->custom_type_info = (mono_object_isinst_checked (this_obj, mono_defaults.iremotingtypeinfo_class, &error) != NULL);
6266 if (mono_error_set_pending_exception (&error))
6268 tp->remote_class = mono_remote_class (domain, class_name, klass, &error);
6269 if (mono_error_set_pending_exception (&error))
6272 res->vtable = (MonoVTable *)mono_remote_class_vtable (domain, tp->remote_class, rp, &error);
6273 if (mono_error_set_pending_exception (&error))
6278 ICALL_EXPORT MonoReflectionType *
6279 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
6282 MonoReflectionType *ret = mono_type_get_object_checked (mono_object_domain (tp), &tp->remote_class->proxy_class->byval_arg, &error);
6283 mono_error_set_pending_exception (&error);
6289 /* System.Environment */
6292 ves_icall_System_Environment_get_UserName (void)
6294 /* using glib is more portable */
6295 return mono_string_new (mono_domain_get (), g_get_user_name ());
6300 mono_icall_get_machine_name (void)
6302 #if !defined(DISABLE_SOCKETS)
6306 #if defined _SC_HOST_NAME_MAX
6307 n = sysconf (_SC_HOST_NAME_MAX);
6311 buf = g_malloc (n+1);
6313 if (gethostname (buf, n) == 0){
6315 result = mono_string_new (mono_domain_get (), buf);
6322 return mono_string_new (mono_domain_get (), "mono");
6325 #endif /* !HOST_WIN32 */
6327 ICALL_EXPORT MonoString *
6328 ves_icall_System_Environment_get_MachineName (void)
6330 return mono_icall_get_machine_name ();
6335 mono_icall_get_platform (void)
6337 #if defined(__MACH__)
6340 // Notice that the value is hidden from user code, and only exposed
6341 // to mscorlib. This is due to Mono's Unix/MacOS code predating the
6342 // define and making assumptions based on Unix/128/4 values before there
6343 // was a MacOS define. Lots of code would assume that not-Unix meant
6344 // Windows, but in this case, it would be OSX.
6352 #endif /* !HOST_WIN32 */
6355 ves_icall_System_Environment_get_Platform (void)
6357 return mono_icall_get_platform ();
6361 static inline MonoString *
6362 mono_icall_get_new_line (void)
6364 return mono_string_new (mono_domain_get (), "\n");
6366 #endif /* !HOST_WIN32 */
6368 ICALL_EXPORT MonoString *
6369 ves_icall_System_Environment_get_NewLine (void)
6371 return mono_icall_get_new_line ();
6375 static inline MonoBoolean
6376 mono_icall_is_64bit_os (void)
6378 #if SIZEOF_VOID_P == 8
6381 #if defined(HAVE_SYS_UTSNAME_H)
6382 struct utsname name;
6384 if (uname (&name) >= 0) {
6385 return strcmp (name.machine, "x86_64") == 0 || strncmp (name.machine, "aarch64", 7) == 0 || strncmp (name.machine, "ppc64", 5) == 0;
6391 #endif /* !HOST_WIN32 */
6393 ICALL_EXPORT MonoBoolean
6394 ves_icall_System_Environment_GetIs64BitOperatingSystem (void)
6396 return mono_icall_is_64bit_os ();
6399 ICALL_EXPORT MonoStringHandle
6400 ves_icall_System_Environment_GetEnvironmentVariable_native (const gchar *utf8_name, MonoError *error)
6404 if (utf8_name == NULL)
6405 return NULL_HANDLE_STRING;
6407 value = g_getenv (utf8_name);
6410 return NULL_HANDLE_STRING;
6412 return mono_string_new_handle (mono_domain_get (), value, error);
6416 * There is no standard way to get at environ.
6419 #ifndef __MINGW32_VERSION
6420 #if defined(__APPLE__)
6421 #if defined (TARGET_OSX)
6422 /* Apple defines this in crt_externs.h but doesn't provide that header for
6423 * arm-apple-darwin9. We'll manually define the symbol on Apple as it does
6424 * in fact exist on all implementations (so far)
6426 gchar ***_NSGetEnviron(void);
6427 #define environ (*_NSGetEnviron())
6429 static char *mono_environ[1] = { NULL };
6430 #define environ mono_environ
6431 #endif /* defined (TARGET_OSX) */
6439 ICALL_EXPORT MonoArray *
6440 ves_icall_System_Environment_GetCoomandLineArgs (void)
6443 MonoArray *result = mono_runtime_get_main_args_checked (&error);
6444 mono_error_set_pending_exception (&error);
6450 mono_icall_get_environment_variable_names (void)
6460 for (e = environ; *e != 0; ++ e)
6463 domain = mono_domain_get ();
6464 names = mono_array_new_checked (domain, mono_defaults.string_class, n, &error);
6465 if (mono_error_set_pending_exception (&error))
6469 for (e = environ; *e != 0; ++ e) {
6470 parts = g_strsplit (*e, "=", 2);
6472 str = mono_string_new (domain, *parts);
6473 mono_array_setref (names, n, str);
6483 #endif /* !HOST_WIN32 */
6485 ICALL_EXPORT MonoArray *
6486 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
6488 return mono_icall_get_environment_variable_names ();
6493 mono_icall_set_environment_variable (MonoString *name, MonoString *value)
6495 gchar *utf8_name, *utf8_value;
6498 utf8_name = mono_string_to_utf8_checked (name, &error); /* FIXME: this should be ascii */
6499 if (mono_error_set_pending_exception (&error))
6502 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
6503 g_unsetenv (utf8_name);
6508 utf8_value = mono_string_to_utf8_checked (value, &error);
6509 if (!mono_error_ok (&error)) {
6511 mono_error_set_pending_exception (&error);
6514 g_setenv (utf8_name, utf8_value, TRUE);
6517 g_free (utf8_value);
6519 #endif /* !HOST_WIN32 */
6522 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
6524 mono_icall_set_environment_variable (name, value);
6528 ves_icall_System_Environment_Exit (int result)
6530 mono_environment_exitcode_set (result);
6532 /* FIXME: There are some cleanup hangs that should be worked out, but
6533 * if the program is going to exit, everything will be cleaned up when
6534 * NaCl exits anyway.
6536 #ifndef __native_client__
6537 if (!mono_runtime_try_shutdown ())
6538 mono_thread_exit ();
6540 /* Suspend all managed threads since the runtime is going away */
6541 mono_thread_suspend_all_other_threads ();
6543 mono_runtime_quit ();
6546 /* we may need to do some cleanup here... */
6550 ICALL_EXPORT MonoStringHandle
6551 ves_icall_System_Environment_GetGacPath (MonoError *error)
6553 return mono_string_new_handle (mono_domain_get (), mono_assembly_getrootdir (), error);
6557 static inline MonoString *
6558 mono_icall_get_windows_folder_path (int folder)
6560 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
6561 return mono_string_new (mono_domain_get (), "");
6563 #endif /* !HOST_WIN32 */
6565 ICALL_EXPORT MonoString*
6566 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
6568 return mono_icall_get_windows_folder_path (folder);
6571 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
6573 mono_icall_get_logical_drives (void)
6576 gunichar2 buf [256], *ptr, *dname;
6578 guint initial_size = 127, size = 128;
6581 MonoString *drivestr;
6582 MonoDomain *domain = mono_domain_get ();
6588 while (size > initial_size) {
6589 size = (guint) GetLogicalDriveStrings (initial_size, ptr);
6590 if (size > initial_size) {
6593 ptr = (gunichar2 *)g_malloc0 ((size + 1) * sizeof (gunichar2));
6594 initial_size = size;
6608 result = mono_array_new_checked (domain, mono_defaults.string_class, ndrives, &error);
6609 if (mono_error_set_pending_exception (&error))
6616 while (*u16) { u16++; len ++; }
6617 drivestr = mono_string_new_utf16_checked (domain, dname, len, &error);
6618 if (mono_error_set_pending_exception (&error))
6621 mono_array_setref (result, ndrives++, drivestr);
6631 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
6633 ICALL_EXPORT MonoArray *
6634 ves_icall_System_Environment_GetLogicalDrives (void)
6636 return mono_icall_get_logical_drives ();
6639 ICALL_EXPORT MonoString *
6640 ves_icall_System_IO_DriveInfo_GetDriveFormat (MonoString *path)
6643 gunichar2 volume_name [MAX_PATH + 1];
6645 if (GetVolumeInformation (mono_string_chars (path), NULL, 0, NULL, NULL, NULL, volume_name, MAX_PATH + 1) == FALSE)
6647 MonoString *result = mono_string_from_utf16_checked (volume_name, &error);
6648 mono_error_set_pending_exception (&error);
6652 ICALL_EXPORT MonoStringHandle
6653 ves_icall_System_Environment_InternalGetHome (MonoError *error)
6655 return mono_string_new_handle (mono_domain_get (), g_get_home_dir (), error);
6658 static const char *encodings [] = {
6660 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
6661 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
6662 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
6664 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
6665 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
6666 "x_unicode_2_0_utf_7",
6668 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
6669 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
6671 "utf_16", "UTF_16LE", "ucs_2", "unicode",
6674 "unicodefffe", "utf_16be",
6681 * Returns the internal codepage, if the value of "int_code_page" is
6682 * 1 at entry, and we can not compute a suitable code page number,
6683 * returns the code page as a string
6685 ICALL_EXPORT MonoString*
6686 ves_icall_System_Text_EncodingHelper_InternalCodePage (gint32 *int_code_page)
6691 char *codepage = NULL;
6693 int want_name = *int_code_page;
6696 *int_code_page = -1;
6698 g_get_charset (&cset);
6699 c = codepage = g_strdup (cset);
6700 for (c = codepage; *c; c++){
6701 if (isascii (*c) && isalpha (*c))
6706 /* g_print ("charset: %s\n", cset); */
6708 /* handle some common aliases */
6711 for (i = 0; p != 0; ){
6714 p = encodings [++i];
6717 if (strcmp (p, codepage) == 0){
6718 *int_code_page = code;
6721 p = encodings [++i];
6724 if (strstr (codepage, "utf_8") != NULL)
6725 *int_code_page |= 0x10000000;
6728 if (want_name && *int_code_page == -1)
6729 return mono_string_new (mono_domain_get (), cset);
6734 ICALL_EXPORT MonoBoolean
6735 ves_icall_System_Environment_get_HasShutdownStarted (void)
6737 if (mono_runtime_is_shutting_down ())
6740 if (mono_domain_is_unloading (mono_domain_get ()))
6748 mono_icall_broadcast_setting_change (void)
6752 #endif /* !HOST_WIN32 */
6755 ves_icall_System_Environment_BroadcastSettingChange (void)
6757 mono_icall_broadcast_setting_change ();
6762 ves_icall_System_Environment_get_TickCount (void)
6764 /* this will overflow after ~24 days */
6765 return (gint32) (mono_msec_boottime () & 0xffffffff);
6769 ves_icall_System_Runtime_Versioning_VersioningHelper_GetRuntimeId (void)
6774 #ifndef DISABLE_REMOTING
6775 ICALL_EXPORT MonoBoolean
6776 ves_icall_IsTransparentProxy (MonoObject *proxy)
6781 if (proxy->vtable->klass == mono_defaults.transparent_proxy_class)
6787 ICALL_EXPORT MonoReflectionMethod *
6788 ves_icall_Remoting_RemotingServices_GetVirtualMethod (
6789 MonoReflectionType *rtype, MonoReflectionMethod *rmethod)
6791 MonoReflectionMethod *ret = NULL;
6796 MonoMethod **vtable;
6797 MonoMethod *res = NULL;
6799 MONO_CHECK_ARG_NULL (rtype, NULL);
6800 MONO_CHECK_ARG_NULL (rmethod, NULL);
6802 method = rmethod->method;
6803 klass = mono_class_from_mono_type (rtype->type);
6804 mono_class_init_checked (klass, &error);
6805 if (mono_error_set_pending_exception (&error))
6808 if (MONO_CLASS_IS_INTERFACE (klass))
6811 if (method->flags & METHOD_ATTRIBUTE_STATIC)
6814 if ((method->flags & METHOD_ATTRIBUTE_FINAL) || !(method->flags & METHOD_ATTRIBUTE_VIRTUAL)) {
6815 if (klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE))
6821 mono_class_setup_vtable (klass);
6822 vtable = klass->vtable;
6824 if (mono_class_is_interface (method->klass)) {
6825 gboolean variance_used = FALSE;
6826 /*MS fails with variant interfaces but it's the right thing to do anyway.*/
6827 int offs = mono_class_interface_offset_with_variance (klass, method->klass, &variance_used);
6829 res = vtable [offs + method->slot];
6831 if (!(klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE)))
6834 if (method->slot != -1)
6835 res = vtable [method->slot];
6841 ret = mono_method_get_object_checked (mono_domain_get (), res, NULL, &error);
6842 mono_error_set_pending_exception (&error);
6847 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6853 klass = mono_class_from_mono_type (type->type);
6854 vtable = mono_class_vtable_full (mono_domain_get (), klass, &error);
6855 if (!is_ok (&error)) {
6856 mono_error_set_pending_exception (&error);
6860 mono_vtable_set_is_remote (vtable, enable);
6863 #else /* DISABLE_REMOTING */
6866 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6868 g_assert_not_reached ();
6873 ICALL_EXPORT MonoObject *
6874 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type)
6881 domain = mono_object_domain (type);
6882 klass = mono_class_from_mono_type (type->type);
6883 mono_class_init_checked (klass, &error);
6884 if (mono_error_set_pending_exception (&error))
6887 if (MONO_CLASS_IS_INTERFACE (klass) || mono_class_is_abstract (klass)) {
6888 mono_set_pending_exception (mono_get_exception_argument ("type", "Type cannot be instantiated"));
6892 if (klass->rank >= 1) {
6893 g_assert (klass->rank == 1);
6894 ret = (MonoObject *) mono_array_new_checked (domain, klass->element_class, 0, &error);
6895 mono_error_set_pending_exception (&error);
6898 MonoVTable *vtable = mono_class_vtable_full (domain, klass, &error);
6899 if (!is_ok (&error)) {
6900 mono_error_set_pending_exception (&error);
6903 /* Bypass remoting object creation check */
6904 ret = mono_object_new_alloc_specific_checked (vtable, &error);
6905 mono_error_set_pending_exception (&error);
6911 ICALL_EXPORT MonoStringHandle
6912 ves_icall_System_IO_get_temp_path (MonoError *error)
6914 return mono_string_new_handle (mono_domain_get (), g_get_tmp_dir (), error);
6917 #ifndef PLATFORM_NO_DRIVEINFO
6918 ICALL_EXPORT MonoBoolean
6919 ves_icall_System_IO_DriveInfo_GetDiskFreeSpace (MonoString *path_name, guint64 *free_bytes_avail,
6920 guint64 *total_number_of_bytes, guint64 *total_number_of_free_bytes,
6924 ULARGE_INTEGER wapi_free_bytes_avail;
6925 ULARGE_INTEGER wapi_total_number_of_bytes;
6926 ULARGE_INTEGER wapi_total_number_of_free_bytes;
6928 *error = ERROR_SUCCESS;
6929 result = GetDiskFreeSpaceEx (mono_string_chars (path_name), &wapi_free_bytes_avail, &wapi_total_number_of_bytes,
6930 &wapi_total_number_of_free_bytes);
6933 *free_bytes_avail = wapi_free_bytes_avail.QuadPart;
6934 *total_number_of_bytes = wapi_total_number_of_bytes.QuadPart;
6935 *total_number_of_free_bytes = wapi_total_number_of_free_bytes.QuadPart;
6937 *free_bytes_avail = 0;
6938 *total_number_of_bytes = 0;
6939 *total_number_of_free_bytes = 0;
6940 *error = GetLastError ();
6946 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
6947 static inline guint32
6948 mono_icall_drive_info_get_drive_type (MonoString *root_path_name)
6950 return GetDriveType (mono_string_chars (root_path_name));
6952 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
6954 ICALL_EXPORT guint32
6955 ves_icall_System_IO_DriveInfo_GetDriveType (MonoString *root_path_name)
6957 return mono_icall_drive_info_get_drive_type (root_path_name);
6960 #endif /* PLATFORM_NO_DRIVEINFO */
6962 ICALL_EXPORT gpointer
6963 ves_icall_RuntimeMethodHandle_GetFunctionPointer (MonoMethod *method)
6966 gpointer result = mono_compile_method_checked (method, &error);
6967 mono_error_set_pending_exception (&error);
6971 ICALL_EXPORT MonoString *
6972 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
6977 path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
6979 mono_icall_make_platform_path (path);
6981 mcpath = mono_string_new (mono_domain_get (), path);
6987 /* this is an icall */
6989 get_bundled_app_config (void)
6992 const gchar *app_config;
6995 gchar *config_file_name, *config_file_path;
6996 gsize len, config_file_path_length, config_ext_length;
6999 domain = mono_domain_get ();
7000 file = domain->setup->configuration_file;
7001 if (!file || file->length == 0)
7004 // Retrieve config file and remove the extension
7005 config_file_name = mono_string_to_utf8_checked (file, &error);
7006 if (mono_error_set_pending_exception (&error))
7008 config_file_path = mono_portability_find_file (config_file_name, TRUE);
7009 if (!config_file_path)
7010 config_file_path = config_file_name;
7012 config_file_path_length = strlen (config_file_path);
7013 config_ext_length = strlen (".config");
7014 if (config_file_path_length <= config_ext_length)
7017 len = config_file_path_length - config_ext_length;
7018 module = (gchar *)g_malloc0 (len + 1);
7019 memcpy (module, config_file_path, len);
7020 // Get the config file from the module name
7021 app_config = mono_config_string_for_assembly_file (module);
7024 if (config_file_name != config_file_path)
7025 g_free (config_file_name);
7026 g_free (config_file_path);
7031 return mono_string_new (mono_domain_get (), app_config);
7034 static MonoStringHandle
7035 get_bundled_machine_config (MonoError *error)
7037 const gchar *machine_config;
7039 machine_config = mono_get_machine_config ();
7041 if (!machine_config)
7042 return NULL_HANDLE_STRING;
7044 return mono_string_new_handle (mono_domain_get (), machine_config, error);
7047 ICALL_EXPORT MonoStringHandle
7048 ves_icall_System_Environment_get_bundled_machine_config (MonoError *error)
7050 return get_bundled_machine_config (error);
7054 ICALL_EXPORT MonoStringHandle
7055 ves_icall_System_Configuration_DefaultConfig_get_bundled_machine_config (MonoError *error)
7057 return get_bundled_machine_config (error);
7060 ICALL_EXPORT MonoStringHandle
7061 ves_icall_System_Configuration_InternalConfigurationHost_get_bundled_machine_config (MonoError *error)
7063 return get_bundled_machine_config (error);
7067 ICALL_EXPORT MonoString *
7068 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
7073 path = g_path_get_dirname (mono_get_config_dir ());
7075 mono_icall_make_platform_path (path);
7077 ipath = mono_string_new (mono_domain_get (), path);
7083 ICALL_EXPORT gboolean
7084 ves_icall_get_resources_ptr (MonoReflectionAssembly *assembly, gpointer *result, gint32 *size)
7086 MonoPEResourceDataEntry *entry;
7089 if (!assembly || !result || !size)
7094 image = assembly->assembly->image;
7095 entry = (MonoPEResourceDataEntry *)mono_image_lookup_resource (image, MONO_PE_RESOURCE_ID_ASPNET_STRING, 0, NULL);
7099 *result = mono_image_rva_map (image, entry->rde_data_offset);
7104 *size = entry->rde_size;
7109 ICALL_EXPORT MonoBoolean
7110 ves_icall_System_Diagnostics_Debugger_IsAttached_internal (void)
7112 return mono_is_debugger_attached ();
7115 ICALL_EXPORT MonoBoolean
7116 ves_icall_System_Diagnostics_Debugger_IsLogging (void)
7118 if (mono_get_runtime_callbacks ()->debug_log_is_enabled)
7119 return mono_get_runtime_callbacks ()->debug_log_is_enabled ();
7125 ves_icall_System_Diagnostics_Debugger_Log (int level, MonoString *category, MonoString *message)
7127 if (mono_get_runtime_callbacks ()->debug_log)
7128 mono_get_runtime_callbacks ()->debug_log (level, category, message);
7133 mono_icall_write_windows_debug_string (MonoString *message)
7135 g_warning ("WriteWindowsDebugString called and HOST_WIN32 not defined!\n");
7137 #endif /* !HOST_WIN32 */
7140 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
7142 mono_icall_write_windows_debug_string (message);
7145 /* Only used for value types */
7146 ICALL_EXPORT MonoObject *
7147 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
7154 domain = mono_object_domain (type);
7155 klass = mono_class_from_mono_type (type->type);
7156 mono_class_init_checked (klass, &error);
7157 if (mono_error_set_pending_exception (&error))
7160 if (mono_class_is_nullable (klass))
7161 /* No arguments -> null */
7164 result = mono_object_new_checked (domain, klass, &error);
7165 mono_error_set_pending_exception (&error);
7169 ICALL_EXPORT MonoReflectionMethod *
7170 ves_icall_MonoMethod_get_base_method (MonoReflectionMethod *m, gboolean definition)
7172 MonoReflectionMethod *ret = NULL;
7175 MonoClass *klass, *parent;
7176 MonoGenericContext *generic_inst = NULL;
7177 MonoMethod *method = m->method;
7178 MonoMethod *result = NULL;
7181 if (method->klass == NULL)
7184 if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
7185 MONO_CLASS_IS_INTERFACE (method->klass) ||
7186 method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
7189 slot = mono_method_get_vtable_slot (method);
7193 klass = method->klass;
7194 if (mono_class_is_ginst (klass)) {
7195 generic_inst = mono_class_get_context (klass);
7196 klass = mono_class_get_generic_class (klass)->container_class;
7201 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
7202 for (parent = klass->parent; parent != NULL; parent = parent->parent) {
7203 /* on entry, klass is either a plain old non-generic class and generic_inst == NULL
7204 or klass is the generic container class and generic_inst is the instantiation.
7206 when we go to the parent, if the parent is an open constructed type, we need to
7207 replace the type parameters by the definitions from the generic_inst, and then take it
7208 apart again into the klass and the generic_inst.
7210 For cases like this:
7211 class C<T> : B<T, int> {
7212 public override void Foo () { ... }
7214 class B<U,V> : A<HashMap<U,V>> {
7215 public override void Foo () { ... }
7218 public virtual void Foo () { ... }
7221 if at each iteration the parent isn't open, we can skip inflating it. if at some
7222 iteration the parent isn't generic (after possible inflation), we set generic_inst to
7225 MonoGenericContext *parent_inst = NULL;
7226 if (mono_class_is_open_constructed_type (mono_class_get_type (parent))) {
7227 parent = mono_class_inflate_generic_class_checked (parent, generic_inst, &error);
7228 if (!mono_error_ok (&error)) {
7229 mono_error_set_pending_exception (&error);
7233 if (mono_class_is_ginst (parent)) {
7234 parent_inst = mono_class_get_context (parent);
7235 parent = mono_class_get_generic_class (parent)->container_class;
7238 mono_class_setup_vtable (parent);
7239 if (parent->vtable_size <= slot)
7242 generic_inst = parent_inst;
7245 klass = klass->parent;
7248 if (mono_class_is_open_constructed_type (mono_class_get_type (klass))) {
7249 klass = mono_class_inflate_generic_class_checked (klass, generic_inst, &error);
7250 if (!mono_error_ok (&error)) {
7251 mono_error_set_pending_exception (&error);
7255 generic_inst = NULL;
7257 if (mono_class_is_ginst (klass)) {
7258 generic_inst = mono_class_get_context (klass);
7259 klass = mono_class_get_generic_class (klass)->container_class;
7265 klass = mono_class_inflate_generic_class_checked (klass, generic_inst, &error);
7266 if (!mono_error_ok (&error)) {
7267 mono_error_set_pending_exception (&error);
7272 if (klass == method->klass)
7275 /*This is possible if definition == FALSE.
7276 * Do it here to be really sure we don't read invalid memory.
7278 if (slot >= klass->vtable_size)
7281 mono_class_setup_vtable (klass);
7283 result = klass->vtable [slot];
7284 if (result == NULL) {
7285 /* It is an abstract method */
7286 gboolean found = FALSE;
7287 gpointer iter = NULL;
7288 while ((result = mono_class_get_methods (klass, &iter))) {
7289 if (result->slot == slot) {
7294 /* found might be FALSE if we looked in an abstract class
7295 * that doesn't override an abstract method of its
7297 * abstract class Base {
7298 * public abstract void Foo ();
7300 * abstract class Derived : Base { }
7301 * class Child : Derived {
7302 * public override void Foo () { }
7305 * if m was Child.Foo and we ask for the base method,
7306 * then we get here with klass == Derived and found == FALSE
7308 /* but it shouldn't be the case that if we're looking
7309 * for the definition and didn't find a result; the
7310 * loop above should've taken us as far as we could
7312 g_assert (!(definition && !found));
7317 g_assert (result != NULL);
7319 ret = mono_method_get_object_checked (mono_domain_get (), result, NULL, &error);
7320 mono_error_set_pending_exception (&error);
7324 ICALL_EXPORT MonoString*
7325 ves_icall_MonoMethod_get_name (MonoReflectionMethod *m)
7327 MonoMethod *method = m->method;
7329 MONO_OBJECT_SETREF (m, name, mono_string_new (mono_object_domain (m), method->name));
7334 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
7336 iter->sig = *(MonoMethodSignature**)argsp;
7338 g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
7339 g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
7342 /* FIXME: it's not documented what start is exactly... */
7346 iter->args = argsp + sizeof (gpointer);
7348 iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
7350 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
7353 ICALL_EXPORT MonoTypedRef
7354 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
7356 guint32 i, arg_size;
7360 i = iter->sig->sentinelpos + iter->next_arg;
7362 g_assert (i < iter->sig->param_count);
7364 res.type = iter->sig->params [i];
7365 res.klass = mono_class_from_mono_type (res.type);
7366 arg_size = mono_type_stack_size (res.type, &align);
7367 #if defined(__arm__) || defined(__mips__)
7368 iter->args = (guint8*)(((gsize)iter->args + (align) - 1) & ~(align - 1));
7370 res.value = iter->args;
7371 #if defined(__native_client__) && SIZEOF_REGISTER == 8
7372 /* Values are stored as 8 byte register sized objects, but 'value'
7373 * is dereferenced as a pointer in other routines.
7375 res.value = (char*)res.value + 4;
7377 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
7378 if (arg_size <= sizeof (gpointer)) {
7380 int padding = arg_size - mono_type_size (res.type, &dummy);
7381 res.value = (guint8*)res.value + padding;
7384 iter->args = (char*)iter->args + arg_size;
7387 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7392 ICALL_EXPORT MonoTypedRef
7393 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
7395 guint32 i, arg_size;
7399 i = iter->sig->sentinelpos + iter->next_arg;
7401 g_assert (i < iter->sig->param_count);
7403 while (i < iter->sig->param_count) {
7404 if (!mono_metadata_type_equal (type, iter->sig->params [i]))
7406 res.type = iter->sig->params [i];
7407 res.klass = mono_class_from_mono_type (res.type);
7408 /* FIXME: endianess issue... */
7409 arg_size = mono_type_stack_size (res.type, &align);
7410 #if defined(__arm__) || defined(__mips__)
7411 iter->args = (guint8*)(((gsize)iter->args + (align) - 1) & ~(align - 1));
7413 res.value = iter->args;
7414 iter->args = (char*)iter->args + arg_size;
7416 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7419 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
7427 ICALL_EXPORT MonoType*
7428 mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
7432 i = iter->sig->sentinelpos + iter->next_arg;
7434 g_assert (i < iter->sig->param_count);
7436 return iter->sig->params [i];
7439 ICALL_EXPORT MonoObject*
7440 mono_TypedReference_ToObject (MonoTypedRef* tref)
7443 MonoObject *result = NULL;
7444 if (MONO_TYPE_IS_REFERENCE (tref->type)) {
7445 MonoObject** objp = (MonoObject **)tref->value;
7449 result = mono_value_box_checked (mono_domain_get (), tref->klass, tref->value, &error);
7450 mono_error_set_pending_exception (&error);
7454 ICALL_EXPORT MonoTypedRef
7455 mono_TypedReference_MakeTypedReferenceInternal (MonoObject *target, MonoArray *fields)
7458 MonoReflectionField *f;
7460 MonoType *ftype = NULL;
7464 memset (&res, 0, sizeof (res));
7467 g_assert (mono_array_length (fields) > 0);
7469 klass = target->vtable->klass;
7471 for (i = 0; i < mono_array_length (fields); ++i) {
7472 f = mono_array_get (fields, MonoReflectionField*, i);
7474 mono_set_pending_exception (mono_get_exception_argument_null ("field"));
7477 if (f->field->parent != klass) {
7478 mono_set_pending_exception (mono_get_exception_argument ("field", ""));
7482 p = (guint8*)target + f->field->offset;
7484 p += f->field->offset - sizeof (MonoObject);
7485 klass = mono_class_from_mono_type (f->field->type);
7486 ftype = f->field->type;
7490 res.klass = mono_class_from_mono_type (ftype);
7497 prelink_method (MonoMethod *method, MonoError *error)
7499 const char *exc_class, *exc_arg;
7501 mono_error_init (error);
7502 if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
7504 mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
7506 mono_error_set_exception_instance (error,
7507 mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg));
7510 /* create the wrapper, too? */
7514 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
7518 prelink_method (method->method, &error);
7519 mono_error_set_pending_exception (&error);
7523 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
7526 MonoClass *klass = mono_class_from_mono_type (type->type);
7528 gpointer iter = NULL;
7530 mono_class_init_checked (klass, &error);
7531 if (mono_error_set_pending_exception (&error))
7534 while ((m = mono_class_get_methods (klass, &iter))) {
7535 prelink_method (m, &error);
7536 if (mono_error_set_pending_exception (&error))
7541 /* These parameters are "readonly" in corlib/System/NumberFormatter.cs */
7543 ves_icall_System_NumberFormatter_GetFormatterTables (guint64 const **mantissas,
7544 gint32 const **exponents,
7545 gunichar2 const **digitLowerTable,
7546 gunichar2 const **digitUpperTable,
7547 gint64 const **tenPowersList,
7548 gint32 const **decHexDigits)
7550 *mantissas = Formatter_MantissaBitsTable;
7551 *exponents = Formatter_TensExponentTable;
7552 *digitLowerTable = Formatter_DigitLowerTable;
7553 *digitUpperTable = Formatter_DigitUpperTable;
7554 *tenPowersList = Formatter_TenPowersList;
7555 *decHexDigits = Formatter_DecHexDigits;
7559 * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
7560 * and avoid useless allocations.
7563 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional, MonoError *error)
7565 MonoReflectionType *rt;
7569 mono_error_init (error);
7570 for (i = 0; i < type->num_mods; ++i) {
7571 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
7576 res = mono_array_new_checked (mono_domain_get (), mono_defaults.systemtype_class, count, error);
7577 return_val_if_nok (error, NULL);
7579 for (i = 0; i < type->num_mods; ++i) {
7580 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
7581 MonoClass *klass = mono_class_get_checked (image, type->modifiers [i].token, error);
7582 return_val_if_nok (error, NULL);
7584 rt = mono_type_get_object_checked (mono_domain_get (), &klass->byval_arg, error);
7585 return_val_if_nok (error, NULL);
7587 mono_array_setref (res, count, rt);
7594 ICALL_EXPORT MonoArray*
7595 ves_icall_ParameterInfo_GetTypeModifiers (MonoReflectionParameter *param, MonoBoolean optional)
7598 MonoType *type = param->ClassImpl->type;
7599 MonoClass *member_class = mono_object_class (param->MemberImpl);
7600 MonoMethod *method = NULL;
7603 MonoMethodSignature *sig;
7606 if (mono_class_is_reflection_method_or_constructor (member_class)) {
7607 MonoReflectionMethod *rmethod = (MonoReflectionMethod*)param->MemberImpl;
7608 method = rmethod->method;
7609 } else if (member_class->image == mono_defaults.corlib && !strcmp ("MonoProperty", member_class->name)) {
7610 MonoReflectionProperty *prop = (MonoReflectionProperty *)param->MemberImpl;
7611 if (!(method = prop->property->get))
7612 method = prop->property->set;
7615 char *type_name = mono_type_get_full_name (member_class);
7616 char *msg = g_strdup_printf ("Custom modifiers on a ParamInfo with member %s are not supported", type_name);
7617 MonoException *ex = mono_get_exception_not_supported (msg);
7620 mono_set_pending_exception (ex);
7624 image = method->klass->image;
7625 pos = param->PositionImpl;
7626 sig = mono_method_signature (method);
7630 type = sig->params [pos];
7632 res = type_array_from_modifiers (image, type, optional, &error);
7633 mono_error_set_pending_exception (&error);
7638 get_property_type (MonoProperty *prop)
7640 MonoMethodSignature *sig;
7642 sig = mono_method_signature (prop->get);
7644 } else if (prop->set) {
7645 sig = mono_method_signature (prop->set);
7646 return sig->params [sig->param_count - 1];
7651 ICALL_EXPORT MonoArray*
7652 ves_icall_MonoPropertyInfo_GetTypeModifiers (MonoReflectionProperty *property, MonoBoolean optional)
7655 MonoType *type = get_property_type (property->property);
7656 MonoImage *image = property->klass->image;
7661 res = type_array_from_modifiers (image, type, optional, &error);
7662 mono_error_set_pending_exception (&error);
7667 *Construct a MonoType suited to be used to decode a constant blob object.
7669 * @type is the target type which will be constructed
7670 * @blob_type is the blob type, for example, that comes from the constant table
7671 * @real_type is the expected constructed type.
7674 mono_type_from_blob_type (MonoType *type, MonoTypeEnum blob_type, MonoType *real_type)
7676 type->type = blob_type;
7677 type->data.klass = NULL;
7678 if (blob_type == MONO_TYPE_CLASS)
7679 type->data.klass = mono_defaults.object_class;
7680 else if (real_type->type == MONO_TYPE_VALUETYPE && real_type->data.klass->enumtype) {
7681 /* For enums, we need to use the base type */
7682 type->type = MONO_TYPE_VALUETYPE;
7683 type->data.klass = mono_class_from_mono_type (real_type);
7685 type->data.klass = mono_class_from_mono_type (real_type);
7688 ICALL_EXPORT MonoObject*
7689 property_info_get_default_value (MonoReflectionProperty *property)
7693 MonoProperty *prop = property->property;
7694 MonoType *type = get_property_type (prop);
7695 MonoDomain *domain = mono_object_domain (property);
7696 MonoTypeEnum def_type;
7697 const char *def_value;
7700 mono_class_init (prop->parent);
7702 if (!(prop->attrs & PROPERTY_ATTRIBUTE_HAS_DEFAULT)) {
7703 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
7707 def_value = mono_class_get_property_default_value (prop, &def_type);
7709 mono_type_from_blob_type (&blob_type, def_type, type);
7710 o = mono_get_object_from_blob (domain, &blob_type, def_value, &error);
7712 mono_error_set_pending_exception (&error);
7716 ICALL_EXPORT MonoBoolean
7717 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
7720 MonoClass *attr_class = mono_class_from_mono_type (attr_type->type);
7721 MonoCustomAttrInfo *cinfo;
7724 mono_class_init_checked (attr_class, &error);
7725 if (mono_error_set_pending_exception (&error))
7728 cinfo = mono_reflection_get_custom_attrs_info_checked (obj, &error);
7729 if (!is_ok (&error)) {
7730 mono_error_set_pending_exception (&error);
7735 found = mono_custom_attrs_has_attr (cinfo, attr_class);
7737 mono_custom_attrs_free (cinfo);
7741 ICALL_EXPORT MonoArray*
7742 custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
7744 MonoClass *attr_class = attr_type ? mono_class_from_mono_type (attr_type->type) : NULL;
7749 mono_class_init_checked (attr_class, &error);
7750 if (mono_error_set_pending_exception (&error))
7754 res = mono_reflection_get_custom_attrs_by_type (obj, attr_class, &error);
7755 if (!mono_error_ok (&error)) {
7756 mono_error_set_pending_exception (&error);
7763 ICALL_EXPORT MonoArray*
7764 ves_icall_MonoCustomAttrs_GetCustomAttributesDataInternal (MonoObject *obj)
7768 result = mono_reflection_get_custom_attrs_data_checked (obj, &error);
7769 mono_error_set_pending_exception (&error);
7774 ICALL_EXPORT MonoStringHandle
7775 ves_icall_Mono_Runtime_GetDisplayName (MonoError *error)
7778 MonoStringHandle display_name;
7780 mono_error_init (error);
7781 info = mono_get_runtime_callbacks ()->get_runtime_build_info ();
7782 display_name = mono_string_new_handle (mono_domain_get (), info, error);
7784 return display_name;
7787 ICALL_EXPORT MonoString*
7788 ves_icall_System_ComponentModel_Win32Exception_W32ErrorMessage (guint32 code)
7791 MonoString *message;
7795 ret = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM |
7796 FORMAT_MESSAGE_IGNORE_INSERTS, NULL, code, 0,
7799 message = mono_string_new (mono_domain_get (), "Error looking up error string");
7801 message = mono_string_new_utf16_checked (mono_domain_get (), buf, ret, &error);
7802 if (mono_error_set_pending_exception (&error))
7810 static inline gint32
7811 mono_icall_wait_for_input_idle (gpointer handle, gint32 milliseconds)
7813 return WAIT_TIMEOUT;
7815 #endif /* !HOST_WIN32 */
7818 ves_icall_Microsoft_Win32_NativeMethods_WaitForInputIdle (gpointer handle, gint32 milliseconds)
7820 return mono_icall_wait_for_input_idle (handle, milliseconds);
7824 ves_icall_Microsoft_Win32_NativeMethods_GetCurrentProcessId (void)
7826 return mono_process_current_pid ();
7829 ICALL_EXPORT MonoBoolean
7830 ves_icall_Mono_TlsProviderFactory_IsBtlsSupported (void)
7842 ves_icall_System_Runtime_InteropServices_Marshal_GetHRForException_WinRT(MonoException* ex)
7844 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetHRForException_WinRT internal call is not implemented."));
7848 ICALL_EXPORT MonoObject*
7849 ves_icall_System_Runtime_InteropServices_Marshal_GetNativeActivationFactory(MonoObject* type)
7851 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetNativeActivationFactory internal call is not implemented."));
7856 ves_icall_System_Runtime_InteropServices_Marshal_GetRawIUnknownForComObjectNoAddRef(MonoObject* obj)
7858 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetRawIUnknownForComObjectNoAddRef internal call is not implemented."));
7862 ICALL_EXPORT MonoObject*
7863 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_GetRestrictedErrorInfo()
7865 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.GetRestrictedErrorInfo internal call is not implemented."));
7869 ICALL_EXPORT MonoBoolean
7870 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_RoOriginateLanguageException(int error, MonoString* message, void* languageException)
7872 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.RoOriginateLanguageException internal call is not implemented."));
7877 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_RoReportUnhandledError(MonoObject* error)
7879 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.RoReportUnhandledError internal call is not implemented."));
7883 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsCreateString(MonoString* sourceString, int length, void** hstring)
7885 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsCreateString internal call is not implemented."));
7890 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsDeleteString(void* hstring)
7892 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsDeleteString internal call is not implemented."));
7896 ICALL_EXPORT mono_unichar2*
7897 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsGetStringRawBuffer(void* hstring, unsigned* length)
7899 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsGetStringRawBuffer internal call is not implemented."));
7906 #ifndef DISABLE_ICALL_TABLES
7908 #define ICALL_TYPE(id,name,first)
7909 #define ICALL(id,name,func) Icall_ ## id,
7910 #define HANDLES(inner) inner
7913 #include "metadata/icall-def.h"
7919 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
7920 #define ICALL(id,name,func)
7922 #define HANDLES(inner) inner
7924 #include "metadata/icall-def.h"
7930 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
7931 #define ICALL(id,name,func)
7933 #define HANDLES(inner) inner
7935 guint16 first_icall;
7938 static const IcallTypeDesc
7939 icall_type_descs [] = {
7940 #include "metadata/icall-def.h"
7944 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
7947 #define HANDLES(inner) inner
7949 #define ICALL_TYPE(id,name,first)
7952 #ifdef HAVE_ARRAY_ELEM_INIT
7953 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
7954 #define MSGSTRFIELD1(line) str##line
7956 static const struct msgstrtn_t {
7957 #define ICALL(id,name,func)
7959 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7960 #include "metadata/icall-def.h"
7962 } icall_type_names_str = {
7963 #define ICALL_TYPE(id,name,first) (name),
7964 #include "metadata/icall-def.h"
7967 static const guint16 icall_type_names_idx [] = {
7968 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
7969 #include "metadata/icall-def.h"
7972 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
7974 static const struct msgstr_t {
7976 #define ICALL_TYPE(id,name,first)
7977 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
7978 #include "metadata/icall-def.h"
7980 } icall_names_str = {
7981 #define ICALL(id,name,func) (name),
7982 #include "metadata/icall-def.h"
7985 static const guint16 icall_names_idx [] = {
7986 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
7987 #include "metadata/icall-def.h"
7990 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
7996 #define ICALL_TYPE(id,name,first) name,
7997 #define ICALL(id,name,func)
7998 static const char* const
7999 icall_type_names [] = {
8000 #include "metadata/icall-def.h"
8004 #define icall_type_name_get(id) (icall_type_names [(id)])
8008 #define ICALL_TYPE(id,name,first)
8009 #define ICALL(id,name,func) name,
8010 static const char* const
8012 #include "metadata/icall-def.h"
8015 #define icall_name_get(id) icall_names [(id)]
8017 #endif /* !HAVE_ARRAY_ELEM_INIT */
8020 #define HANDLES(inner) inner
8023 #define ICALL_TYPE(id,name,first)
8024 #define ICALL(id,name,func) func,
8025 static const gconstpointer
8026 icall_functions [] = {
8027 #include "metadata/icall-def.h"
8031 #ifdef ENABLE_ICALL_SYMBOL_MAP
8033 #define HANDLES(inner) inner
8036 #define ICALL_TYPE(id,name,first)
8037 #define ICALL(id,name,func) #func,
8038 static const gconstpointer
8039 icall_symbols [] = {
8040 #include "metadata/icall-def.h"
8047 #define ICALL_TYPE(id,name,first)
8048 #define ICALL(id,name,func) 0,
8050 #define HANDLES(inner) 1,
8052 icall_uses_handles [] = {
8053 #include "metadata/icall-def.h"
8058 #endif /* DISABLE_ICALL_TABLES */
8060 static mono_mutex_t icall_mutex;
8061 static GHashTable *icall_hash = NULL;
8062 static GHashTable *jit_icall_hash_name = NULL;
8063 static GHashTable *jit_icall_hash_addr = NULL;
8066 mono_icall_init (void)
8068 #ifndef DISABLE_ICALL_TABLES
8071 /* check that tables are sorted: disable in release */
8074 const char *prev_class = NULL;
8075 const char *prev_method;
8077 for (i = 0; i < Icall_type_num; ++i) {
8078 const IcallTypeDesc *desc;
8081 if (prev_class && strcmp (prev_class, icall_type_name_get (i)) >= 0)
8082 g_print ("class %s should come before class %s\n", icall_type_name_get (i), prev_class);
8083 prev_class = icall_type_name_get (i);
8084 desc = &icall_type_descs [i];
8085 num_icalls = icall_desc_num_icalls (desc);
8086 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
8087 for (j = 0; j < num_icalls; ++j) {
8088 const char *methodn = icall_name_get (desc->first_icall + j);
8089 if (prev_method && strcmp (prev_method, methodn) >= 0)
8090 g_print ("method %s should come before method %s\n", methodn, prev_method);
8091 prev_method = methodn;
8097 icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
8098 mono_os_mutex_init (&icall_mutex);
8102 mono_icall_lock (void)
8104 mono_locks_os_acquire (&icall_mutex, IcallLock);
8108 mono_icall_unlock (void)
8110 mono_locks_os_release (&icall_mutex, IcallLock);
8114 mono_icall_cleanup (void)
8116 g_hash_table_destroy (icall_hash);
8117 g_hash_table_destroy (jit_icall_hash_name);
8118 g_hash_table_destroy (jit_icall_hash_addr);
8119 mono_os_mutex_destroy (&icall_mutex);
8123 * mono_add_internal_call:
8124 * @name: method specification to surface to the managed world
8125 * @method: pointer to a C method to invoke when the method is called
8127 * This method surfaces the C function pointed by @method as a method
8128 * that has been surfaced in managed code with the method specified in
8129 * @name as an internal call.
8131 * Internal calls are surfaced to all app domains loaded and they are
8132 * accessibly by a type with the specified name.
8134 * You must provide a fully qualified type name, that is namespaces
8135 * and type name, followed by a colon and the method name, with an
8136 * optional signature to bind.
8138 * For example, the following are all valid declarations:
8140 * "MyApp.Services.ScriptService:Accelerate"
8141 * "MyApp.Services.ScriptService:Slowdown(int,bool)"
8143 * You use method parameters in cases where there might be more than
8144 * one surface method to managed code. That way you can register different
8145 * internal calls for different method overloads.
8147 * The internal calls are invoked with no marshalling. This means that .NET
8148 * types like System.String are exposed as `MonoString *` parameters. This is
8149 * different than the way that strings are surfaced in P/Invoke.
8151 * For more information on how the parameters are marshalled, see the
8152 * <a href="http://www.mono-project.com/docs/advanced/embedding/">Mono Embedding</a>
8155 * See the <a href="mono-api-methods.html#method-desc">Method Description</a>
8156 * reference for more information on the format of method descriptions.
8159 mono_add_internal_call (const char *name, gconstpointer method)
8163 g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
8165 mono_icall_unlock ();
8168 #ifndef DISABLE_ICALL_TABLES
8170 #ifdef HAVE_ARRAY_ELEM_INIT
8172 compare_method_imap (const void *key, const void *elem)
8174 const char* method_name = (const char*)&icall_names_str + (*(guint16*)elem);
8175 return strcmp (key, method_name);
8179 find_slot_icall (const IcallTypeDesc *imap, const char *name)
8181 const guint16 *nameslot = (const guint16 *)mono_binary_search (name, icall_names_idx + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names_idx [0]), compare_method_imap);
8184 return (nameslot - &icall_names_idx [0]);
8188 find_uses_handles_icall (const IcallTypeDesc *imap, const char *name)
8190 gsize slotnum = find_slot_icall (imap, name);
8193 return (gboolean)icall_uses_handles [slotnum];
8197 find_method_icall (const IcallTypeDesc *imap, const char *name)
8199 gsize slotnum = find_slot_icall (imap, name);
8202 return (gpointer)icall_functions [slotnum];
8206 compare_class_imap (const void *key, const void *elem)
8208 const char* class_name = (const char*)&icall_type_names_str + (*(guint16*)elem);
8209 return strcmp (key, class_name);
8212 static const IcallTypeDesc*
8213 find_class_icalls (const char *name)
8215 const guint16 *nameslot = (const guint16 *)mono_binary_search (name, icall_type_names_idx, Icall_type_num, sizeof (icall_type_names_idx [0]), compare_class_imap);
8218 return &icall_type_descs [nameslot - &icall_type_names_idx [0]];
8221 #else /* HAVE_ARRAY_ELEM_INIT */
8224 compare_method_imap (const void *key, const void *elem)
8226 const char** method_name = (const char**)elem;
8227 return strcmp (key, *method_name);
8231 find_slot_icall (const IcallTypeDesc *imap, const char *name)
8233 const char **nameslot = mono_binary_search (name, icall_names + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names [0]), compare_method_imap);
8236 return nameslot - icall_names;
8240 find_method_icall (const IcallTypeDesc *imap, const char *name)
8242 gsize slotnum = find_slot_icall (imap, name);
8245 return (gpointer)icall_functions [slotnum];
8249 find_uses_handles_icall (const IcallTypeDesc *imap, const char *name)
8251 gsize slotnum = find_slot_icall (imap, name);
8254 return (gboolean)icall_uses_handles [slotnum];
8258 compare_class_imap (const void *key, const void *elem)
8260 const char** class_name = (const char**)elem;
8261 return strcmp (key, *class_name);
8264 static const IcallTypeDesc*
8265 find_class_icalls (const char *name)
8267 const char **nameslot = mono_binary_search (name, icall_type_names, Icall_type_num, sizeof (icall_type_names [0]), compare_class_imap);
8270 return &icall_type_descs [nameslot - icall_type_names];
8273 #endif /* HAVE_ARRAY_ELEM_INIT */
8275 #endif /* DISABLE_ICALL_TABLES */
8278 * we should probably export this as an helper (handle nested types).
8279 * Returns the number of chars written in buf.
8282 concat_class_name (char *buf, int bufsize, MonoClass *klass)
8284 int nspacelen, cnamelen;
8285 nspacelen = strlen (klass->name_space);
8286 cnamelen = strlen (klass->name);
8287 if (nspacelen + cnamelen + 2 > bufsize)
8290 memcpy (buf, klass->name_space, nspacelen);
8291 buf [nspacelen ++] = '.';
8293 memcpy (buf + nspacelen, klass->name, cnamelen);
8294 buf [nspacelen + cnamelen] = 0;
8295 return nspacelen + cnamelen;
8298 #ifdef DISABLE_ICALL_TABLES
8300 no_icall_table (void)
8302 g_assert_not_reached ();
8307 * mono_lookup_internal_call_full:
8308 * @method: the method to look up
8309 * @uses_handles: out argument if method needs handles around managed objects.
8311 * Returns a pointer to the icall code for the given method. If
8312 * uses_handles is not NULL, it will be set to TRUE if the method
8313 * needs managed objects wrapped using the infrastructure in handle.h
8315 * If the method is not found, warns and returns NULL.
8318 mono_lookup_internal_call_full (MonoMethod *method, mono_bool *uses_handles)
8323 int typelen = 0, mlen, siglen;
8325 #ifndef DISABLE_ICALL_TABLES
8326 const IcallTypeDesc *imap = NULL;
8329 g_assert (method != NULL);
8331 if (method->is_inflated)
8332 method = ((MonoMethodInflated *) method)->declaring;
8334 if (method->klass->nested_in) {
8335 int pos = concat_class_name (mname, sizeof (mname)-2, method->klass->nested_in);
8339 mname [pos++] = '/';
8342 typelen = concat_class_name (mname+pos, sizeof (mname)-pos-1, method->klass);
8348 typelen = concat_class_name (mname, sizeof (mname), method->klass);
8353 #ifndef DISABLE_ICALL_TABLES
8354 imap = find_class_icalls (mname);
8357 mname [typelen] = ':';
8358 mname [typelen + 1] = ':';
8360 mlen = strlen (method->name);
8361 memcpy (mname + typelen + 2, method->name, mlen);
8362 sigstart = mname + typelen + 2 + mlen;
8365 tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
8366 siglen = strlen (tmpsig);
8367 if (typelen + mlen + siglen + 6 > sizeof (mname))
8370 memcpy (sigstart + 1, tmpsig, siglen);
8371 sigstart [siglen + 1] = ')';
8372 sigstart [siglen + 2] = 0;
8377 res = g_hash_table_lookup (icall_hash, mname);
8380 *uses_handles = FALSE;
8381 mono_icall_unlock ();;
8384 /* try without signature */
8386 res = g_hash_table_lookup (icall_hash, mname);
8389 *uses_handles = FALSE;
8390 mono_icall_unlock ();
8394 #ifdef DISABLE_ICALL_TABLES
8395 mono_icall_unlock ();
8396 /* Fail only when the result is actually used */
8397 /* mono_marshal_get_native_wrapper () depends on this */
8398 if (method->klass == mono_defaults.string_class && !strcmp (method->name, ".ctor"))
8399 return ves_icall_System_String_ctor_RedirectToCreateString;
8401 return no_icall_table;
8403 /* it wasn't found in the static call tables */
8406 *uses_handles = FALSE;
8407 mono_icall_unlock ();
8410 res = find_method_icall (imap, sigstart - mlen);
8413 *uses_handles = find_uses_handles_icall (imap, sigstart - mlen);
8414 mono_icall_unlock ();
8417 /* try _with_ signature */
8419 res = find_method_icall (imap, sigstart - mlen);
8422 *uses_handles = find_uses_handles_icall (imap, sigstart - mlen);
8423 mono_icall_unlock ();
8427 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname);
8428 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
8429 g_print ("The out of sync library is: %s\n", method->klass->image->name);
8430 g_print ("\nWhen you update one from git you need to update, compile and install\nthe other too.\n");
8431 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");
8432 g_print ("If you see other errors or faults after this message they are probably related\n");
8433 g_print ("and you need to fix your mono install first.\n");
8435 mono_icall_unlock ();
8442 mono_lookup_internal_call (MonoMethod *method)
8444 return mono_lookup_internal_call_full (method, NULL);
8447 #ifdef ENABLE_ICALL_SYMBOL_MAP
8449 func_cmp (gconstpointer key, gconstpointer p)
8451 return (gsize)key - (gsize)*(gsize*)p;
8456 * mono_lookup_icall_symbol:
8458 * Given the icall METHOD, returns its C symbol.
8461 mono_lookup_icall_symbol (MonoMethod *m)
8463 #ifdef DISABLE_ICALL_TABLES
8464 g_assert_not_reached ();
8467 #ifdef ENABLE_ICALL_SYMBOL_MAP
8471 static gconstpointer *functions_sorted;
8472 static const char**symbols_sorted;
8473 static gboolean inited;
8478 functions_sorted = g_malloc (G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8479 memcpy (functions_sorted, icall_functions, G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8480 symbols_sorted = g_malloc (G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8481 memcpy (symbols_sorted, icall_symbols, G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8482 /* Bubble sort the two arrays */
8486 for (i = 0; i < G_N_ELEMENTS (icall_functions) - 1; ++i) {
8487 if (functions_sorted [i] > functions_sorted [i + 1]) {
8490 tmp = functions_sorted [i];
8491 functions_sorted [i] = functions_sorted [i + 1];
8492 functions_sorted [i + 1] = tmp;
8493 tmp = symbols_sorted [i];
8494 symbols_sorted [i] = symbols_sorted [i + 1];
8495 symbols_sorted [i + 1] = tmp;
8502 func = mono_lookup_internal_call (m);
8505 slot = mono_binary_search (func, functions_sorted, G_N_ELEMENTS (icall_functions), sizeof (gpointer), func_cmp);
8509 return symbols_sorted [(gpointer*)slot - (gpointer*)functions_sorted];
8511 fprintf (stderr, "icall symbol maps not enabled, pass --enable-icall-symbol-map to configure.\n");
8512 g_assert_not_reached ();
8519 type_from_typename (char *type_name)
8521 MonoClass *klass = NULL; /* assignment to shut GCC warning up */
8523 if (!strcmp (type_name, "int"))
8524 klass = mono_defaults.int_class;
8525 else if (!strcmp (type_name, "ptr"))
8526 klass = mono_defaults.int_class;
8527 else if (!strcmp (type_name, "void"))
8528 klass = mono_defaults.void_class;
8529 else if (!strcmp (type_name, "int32"))
8530 klass = mono_defaults.int32_class;
8531 else if (!strcmp (type_name, "uint32"))
8532 klass = mono_defaults.uint32_class;
8533 else if (!strcmp (type_name, "int8"))
8534 klass = mono_defaults.sbyte_class;
8535 else if (!strcmp (type_name, "uint8"))
8536 klass = mono_defaults.byte_class;
8537 else if (!strcmp (type_name, "int16"))
8538 klass = mono_defaults.int16_class;
8539 else if (!strcmp (type_name, "uint16"))
8540 klass = mono_defaults.uint16_class;
8541 else if (!strcmp (type_name, "long"))
8542 klass = mono_defaults.int64_class;
8543 else if (!strcmp (type_name, "ulong"))
8544 klass = mono_defaults.uint64_class;
8545 else if (!strcmp (type_name, "float"))
8546 klass = mono_defaults.single_class;
8547 else if (!strcmp (type_name, "double"))
8548 klass = mono_defaults.double_class;
8549 else if (!strcmp (type_name, "object"))
8550 klass = mono_defaults.object_class;
8551 else if (!strcmp (type_name, "obj"))
8552 klass = mono_defaults.object_class;
8553 else if (!strcmp (type_name, "string"))
8554 klass = mono_defaults.string_class;
8555 else if (!strcmp (type_name, "bool"))
8556 klass = mono_defaults.boolean_class;
8557 else if (!strcmp (type_name, "boolean"))
8558 klass = mono_defaults.boolean_class;
8560 g_error ("%s", type_name);
8561 g_assert_not_reached ();
8563 return &klass->byval_arg;
8567 * LOCKING: Take the corlib image lock.
8569 MonoMethodSignature*
8570 mono_create_icall_signature (const char *sigstr)
8575 MonoMethodSignature *res, *res2;
8576 MonoImage *corlib = mono_defaults.corlib;
8578 mono_image_lock (corlib);
8579 res = (MonoMethodSignature *)g_hash_table_lookup (corlib->helper_signatures, sigstr);
8580 mono_image_unlock (corlib);
8585 parts = g_strsplit (sigstr, " ", 256);
8594 res = mono_metadata_signature_alloc (corlib, len - 1);
8599 * Under windows, the default pinvoke calling convention is STDCALL but
8602 res->call_convention = MONO_CALL_C;
8605 res->ret = type_from_typename (parts [0]);
8606 for (i = 1; i < len; ++i) {
8607 res->params [i - 1] = type_from_typename (parts [i]);
8612 mono_image_lock (corlib);
8613 res2 = (MonoMethodSignature *)g_hash_table_lookup (corlib->helper_signatures, sigstr);
8615 res = res2; /*Value is allocated in the image pool*/
8617 g_hash_table_insert (corlib->helper_signatures, (gpointer)sigstr, res);
8618 mono_image_unlock (corlib);
8624 mono_find_jit_icall_by_name (const char *name)
8626 MonoJitICallInfo *info;
8627 g_assert (jit_icall_hash_name);
8630 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_name, name);
8631 mono_icall_unlock ();
8636 mono_find_jit_icall_by_addr (gconstpointer addr)
8638 MonoJitICallInfo *info;
8639 g_assert (jit_icall_hash_addr);
8642 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
8643 mono_icall_unlock ();
8649 * mono_get_jit_icall_info:
8651 * Return the hashtable mapping JIT icall names to MonoJitICallInfo structures. The
8652 * caller should access it while holding the icall lock.
8655 mono_get_jit_icall_info (void)
8657 return jit_icall_hash_name;
8661 * mono_lookup_jit_icall_symbol:
8663 * Given the jit icall NAME, returns its C symbol if possible, or NULL.
8666 mono_lookup_jit_icall_symbol (const char *name)
8668 MonoJitICallInfo *info;
8669 const char *res = NULL;
8672 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_name, name);
8674 res = info->c_symbol;
8675 mono_icall_unlock ();
8680 mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
8683 g_hash_table_insert (jit_icall_hash_addr, (gpointer)wrapper, info);
8684 mono_icall_unlock ();
8688 * If NO_RAISE is set, that means the icall is not calling mono_raise_exception () directly or indirectly. The JIT might be able to call these
8689 * icalls without wrappers in some cases.
8692 mono_register_jit_icall_full (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save, gboolean no_raise, const char *c_symbol)
8694 MonoJitICallInfo *info;
8701 if (!jit_icall_hash_name) {
8702 jit_icall_hash_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
8703 jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
8706 if (g_hash_table_lookup (jit_icall_hash_name, name)) {
8707 g_warning ("jit icall already defined \"%s\"\n", name);
8708 g_assert_not_reached ();
8711 info = g_new0 (MonoJitICallInfo, 1);
8716 info->c_symbol = c_symbol;
8717 info->no_raise = no_raise;
8720 info->wrapper = func;
8722 info->wrapper = NULL;
8725 g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
8726 g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
8728 mono_icall_unlock ();
8733 mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
8735 return mono_register_jit_icall_full (func, name, sig, is_save, FALSE, NULL);