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.h>
40 #include <mono/metadata/threadpool-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/metadata-internals.h>
56 #include <mono/metadata/class-internals.h>
57 #include <mono/metadata/reflection-internals.h>
58 #include <mono/metadata/marshal.h>
59 #include <mono/metadata/gc-internals.h>
60 #include <mono/metadata/mono-gc.h>
61 #include <mono/metadata/rand.h>
62 #include <mono/metadata/sysmath.h>
63 #include <mono/metadata/appdomain-icalls.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 MonoReflectionAssemblyHandle ves_icall_System_Reflection_Assembly_GetCallingAssembly (MonoError *error);
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)
120 static MonoArrayHandle
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 MonoReflectionMarshalAsAttributeHandle
1670 ves_icall_System_Reflection_FieldInfo_get_marshal_info (MonoReflectionFieldHandle field_h, MonoError *error)
1672 mono_error_init (error);
1673 MonoDomain *domain = MONO_HANDLE_DOMAIN (field_h);
1674 MonoClassField *field = MONO_HANDLE_GETVAL (field_h, field);
1675 MonoClass *klass = field->parent;
1677 MonoGenericClass *gklass = mono_class_try_get_generic_class (klass);
1678 if (mono_class_is_gtd (klass) ||
1679 (gklass && gklass->context.class_inst->is_open))
1680 return MONO_HANDLE_CAST (MonoReflectionMarshalAsAttribute, NULL_HANDLE);
1682 MonoType *ftype = mono_field_get_type (field);
1683 if (ftype && !(ftype->attrs & FIELD_ATTRIBUTE_HAS_FIELD_MARSHAL))
1684 return MONO_HANDLE_CAST (MonoReflectionMarshalAsAttribute, NULL_HANDLE);
1686 MonoMarshalType *info = mono_marshal_load_type_info (klass);
1688 for (int i = 0; i < info->num_fields; ++i) {
1689 if (info->fields [i].field == field) {
1690 if (!info->fields [i].mspec)
1691 return MONO_HANDLE_CAST (MonoReflectionMarshalAsAttribute, NULL_HANDLE);
1693 return mono_reflection_marshal_as_attribute_from_marshal_spec (domain, klass, info->fields [i].mspec, error);
1698 return MONO_HANDLE_CAST (MonoReflectionMarshalAsAttribute, NULL_HANDLE);
1701 ICALL_EXPORT MonoReflectionFieldHandle
1702 ves_icall_System_Reflection_FieldInfo_internal_from_handle_type (MonoClassField *handle, MonoType *type, MonoError *error)
1708 mono_error_init (error);
1711 klass = handle->parent;
1713 klass = mono_class_from_mono_type (type);
1715 gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1718 /* The managed code will throw the exception */
1719 return MONO_HANDLE_CAST (MonoReflectionField, NULL_HANDLE);
1722 return mono_field_get_object_handle (mono_domain_get (), klass, handle, error);
1725 ICALL_EXPORT MonoReflectionEventHandle
1726 ves_icall_System_Reflection_EventInfo_internal_from_handle_type (MonoEvent *handle, MonoType *type, MonoError *error)
1732 mono_error_init (error);
1735 klass = handle->parent;
1737 klass = mono_class_from_mono_type (type);
1739 gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1741 /* Managed code will throw an exception */
1742 return MONO_HANDLE_CAST (MonoReflectionEvent, NULL_HANDLE);
1745 return mono_event_get_object_handle (mono_domain_get (), klass, handle, error);
1749 ICALL_EXPORT MonoReflectionPropertyHandle
1750 ves_icall_System_Reflection_PropertyInfo_internal_from_handle_type (MonoProperty *handle, MonoType *type, MonoError *error)
1752 mono_error_init (error);
1758 klass = handle->parent;
1760 klass = mono_class_from_mono_type (type);
1762 gboolean found = klass == handle->parent || mono_class_has_parent (klass, handle->parent);
1764 /* Managed code will throw an exception */
1765 return MONO_HANDLE_CAST (MonoReflectionProperty, NULL_HANDLE);
1768 return mono_property_get_object_handle (mono_domain_get (), klass, handle, error);
1771 ICALL_EXPORT MonoArrayHandle
1772 ves_icall_System_Reflection_FieldInfo_GetTypeModifiers (MonoReflectionFieldHandle field_h, MonoBoolean optional, MonoError *error)
1774 mono_error_init (error);
1775 MonoClassField *field = MONO_HANDLE_GETVAL (field_h, field);
1777 MonoType *type = mono_field_get_type_checked (field, error);
1779 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
1781 return type_array_from_modifiers (field->parent->image, type, optional, error);
1785 vell_icall_get_method_attributes (MonoMethod *method)
1787 return method->flags;
1791 ves_icall_get_method_info (MonoMethod *method, MonoMethodInfo *info)
1794 MonoReflectionType *rt;
1795 MonoDomain *domain = mono_domain_get ();
1796 MonoMethodSignature* sig;
1798 sig = mono_method_signature_checked (method, &error);
1799 if (!mono_error_ok (&error)) {
1800 mono_error_set_pending_exception (&error);
1804 rt = mono_type_get_object_checked (domain, &method->klass->byval_arg, &error);
1805 if (!mono_error_ok (&error)) {
1806 mono_error_set_pending_exception (&error);
1810 MONO_STRUCT_SETREF (info, parent, rt);
1812 rt = mono_type_get_object_checked (domain, sig->ret, &error);
1813 if (!mono_error_ok (&error)) {
1814 mono_error_set_pending_exception (&error);
1818 MONO_STRUCT_SETREF (info, ret, rt);
1820 info->attrs = method->flags;
1821 info->implattrs = method->iflags;
1822 if (sig->call_convention == MONO_CALL_DEFAULT)
1823 info->callconv = sig->sentinelpos >= 0 ? 2 : 1;
1825 if (sig->call_convention == MONO_CALL_VARARG || sig->sentinelpos >= 0)
1830 info->callconv |= (sig->hasthis << 5) | (sig->explicit_this << 6);
1833 ICALL_EXPORT MonoArrayHandle
1834 ves_icall_System_Reflection_MonoMethodInfo_get_parameter_info (MonoMethod *method, MonoReflectionMethodHandle member, MonoError *error)
1836 mono_error_init (error);
1837 MonoDomain *domain = mono_domain_get ();
1839 MonoReflectionTypeHandle reftype = MONO_HANDLE_NEW (MonoReflectionType, NULL);
1840 MONO_HANDLE_GET (reftype, member, reftype);
1841 MonoClass *klass = NULL;
1842 if (!MONO_HANDLE_IS_NULL (reftype))
1843 klass = mono_class_from_mono_type (MONO_HANDLE_GETVAL (reftype, type));
1844 return mono_param_get_objects_internal (domain, method, klass, error);
1847 ICALL_EXPORT MonoReflectionMarshalAsAttributeHandle
1848 ves_icall_System_MonoMethodInfo_get_retval_marshal (MonoMethod *method, MonoError *error)
1850 mono_error_init (error);
1851 MonoDomain *domain = mono_domain_get ();
1852 MonoReflectionMarshalAsAttributeHandle res = MONO_HANDLE_NEW (MonoReflectionMarshalAsAttribute, NULL);
1854 MonoMarshalSpec **mspecs = g_new (MonoMarshalSpec*, mono_method_signature (method)->param_count + 1);
1855 mono_method_get_marshal_info (method, mspecs);
1858 MONO_HANDLE_ASSIGN (res, mono_reflection_marshal_as_attribute_from_marshal_spec (domain, method->klass, mspecs [0], error));
1864 for (int i = mono_method_signature (method)->param_count; i >= 0; i--)
1866 mono_metadata_free_marshal_spec (mspecs [i]);
1873 ves_icall_MonoField_GetFieldOffset (MonoReflectionField *field)
1875 MonoClass *parent = field->field->parent;
1876 mono_class_setup_fields (parent);
1878 return field->field->offset - sizeof (MonoObject);
1881 ICALL_EXPORT MonoReflectionType*
1882 ves_icall_MonoField_GetParentType (MonoReflectionField *field, MonoBoolean declaring)
1885 MonoReflectionType *ret;
1888 parent = declaring? field->field->parent: field->klass;
1890 ret = mono_type_get_object_checked (mono_object_domain (field), &parent->byval_arg, &error);
1891 mono_error_set_pending_exception (&error);
1897 ICALL_EXPORT MonoObject *
1898 ves_icall_MonoField_GetValueInternal (MonoReflectionField *field, MonoObject *obj)
1901 MonoClass *fklass = field->klass;
1902 MonoClassField *cf = field->field;
1903 MonoDomain *domain = mono_object_domain (field);
1905 if (fklass->image->assembly->ref_only) {
1906 mono_set_pending_exception (mono_get_exception_invalid_operation (
1907 "It is illegal to get the value on a field on a type loaded using the ReflectionOnly methods."));
1911 if (mono_security_core_clr_enabled () &&
1912 !mono_security_core_clr_ensure_reflection_access_field (cf, &error)) {
1913 mono_error_set_pending_exception (&error);
1917 MonoObject * result = mono_field_get_value_object_checked (domain, cf, obj, &error);
1918 mono_error_set_pending_exception (&error);
1923 ves_icall_MonoField_SetValueInternal (MonoReflectionField *field, MonoObject *obj, MonoObject *value)
1926 MonoClassField *cf = field->field;
1930 if (field->klass->image->assembly->ref_only) {
1931 mono_set_pending_exception (mono_get_exception_invalid_operation (
1932 "It is illegal to set the value on a field on a type loaded using the ReflectionOnly methods."));
1936 if (mono_security_core_clr_enabled () &&
1937 !mono_security_core_clr_ensure_reflection_access_field (cf, &error)) {
1938 mono_error_set_pending_exception (&error);
1942 type = mono_field_get_type_checked (cf, &error);
1943 if (!mono_error_ok (&error)) {
1944 mono_error_set_pending_exception (&error);
1948 v = (gchar *) value;
1950 switch (type->type) {
1953 case MONO_TYPE_BOOLEAN:
1956 case MONO_TYPE_CHAR:
1965 case MONO_TYPE_VALUETYPE:
1968 v += sizeof (MonoObject);
1970 case MONO_TYPE_STRING:
1971 case MONO_TYPE_OBJECT:
1972 case MONO_TYPE_CLASS:
1973 case MONO_TYPE_ARRAY:
1974 case MONO_TYPE_SZARRAY:
1977 case MONO_TYPE_GENERICINST: {
1978 MonoGenericClass *gclass = type->data.generic_class;
1979 g_assert (!gclass->context.class_inst->is_open);
1981 if (mono_class_is_nullable (mono_class_from_mono_type (type))) {
1982 MonoClass *nklass = mono_class_from_mono_type (type);
1983 MonoObject *nullable;
1986 * Convert the boxed vtype into a Nullable structure.
1987 * This is complicated by the fact that Nullables have
1988 * a variable structure.
1990 nullable = mono_object_new_checked (mono_domain_get (), nklass, &error);
1991 if (!mono_error_ok (&error)) {
1992 mono_error_set_pending_exception (&error);
1996 mono_nullable_init ((guint8 *)mono_object_unbox (nullable), value, nklass);
1998 v = (gchar *)mono_object_unbox (nullable);
2001 if (gclass->container_class->valuetype && (v != NULL))
2002 v += sizeof (MonoObject);
2006 g_error ("type 0x%x not handled in "
2007 "ves_icall_FieldInfo_SetValueInternal", type->type);
2012 if (type->attrs & FIELD_ATTRIBUTE_STATIC) {
2013 MonoVTable *vtable = mono_class_vtable_full (mono_object_domain (field), cf->parent, &error);
2014 if (!is_ok (&error)) {
2015 mono_error_set_pending_exception (&error);
2018 if (!vtable->initialized) {
2019 if (!mono_runtime_class_init_full (vtable, &error)) {
2020 mono_error_set_pending_exception (&error);
2024 mono_field_static_set_value (vtable, cf, v);
2026 mono_field_set_value (obj, cf, v);
2031 ves_icall_System_RuntimeFieldHandle_SetValueDirect (MonoReflectionField *field, MonoReflectionType *field_type, MonoTypedRef *obj, MonoObject *value, MonoReflectionType *context_type)
2040 if (!MONO_TYPE_ISSTRUCT (&f->parent->byval_arg)) {
2041 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2045 if (MONO_TYPE_IS_REFERENCE (f->type))
2046 mono_copy_value (f->type, (guint8*)obj->value + f->offset - sizeof (MonoObject), value, FALSE);
2048 mono_copy_value (f->type, (guint8*)obj->value + f->offset - sizeof (MonoObject), mono_object_unbox (value), FALSE);
2051 ICALL_EXPORT MonoObject *
2052 ves_icall_MonoField_GetRawConstantValue (MonoReflectionField *rfield)
2054 MonoObject *o = NULL;
2055 MonoClassField *field = rfield->field;
2057 MonoDomain *domain = mono_object_domain (rfield);
2059 MonoTypeEnum def_type;
2060 const char *def_value;
2064 mono_class_init (field->parent);
2066 t = mono_field_get_type_checked (field, &error);
2067 if (!mono_error_ok (&error)) {
2068 mono_error_set_pending_exception (&error);
2072 if (!(t->attrs & FIELD_ATTRIBUTE_HAS_DEFAULT)) {
2073 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2077 if (image_is_dynamic (field->parent->image)) {
2078 MonoClass *klass = field->parent;
2079 int fidx = field - klass->fields;
2080 MonoFieldDefaultValue *def_values = mono_class_get_field_def_values (klass);
2082 g_assert (def_values);
2083 def_type = def_values [fidx].def_type;
2084 def_value = def_values [fidx].data;
2086 if (def_type == MONO_TYPE_END) {
2087 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2091 def_value = mono_class_get_field_default_value (field, &def_type);
2092 /* FIXME, maybe we should try to raise TLE if field->parent is broken */
2094 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
2099 /*FIXME unify this with reflection.c:mono_get_object_from_blob*/
2103 case MONO_TYPE_BOOLEAN:
2106 case MONO_TYPE_CHAR:
2114 case MONO_TYPE_R8: {
2117 /* boxed value type */
2118 t = g_new0 (MonoType, 1);
2120 klass = mono_class_from_mono_type (t);
2122 o = mono_object_new_checked (domain, klass, &error);
2123 if (!mono_error_ok (&error)) {
2124 mono_error_set_pending_exception (&error);
2127 v = ((gchar *) o) + sizeof (MonoObject);
2128 mono_get_constant_value_from_blob (domain, def_type, def_value, v, &error);
2129 if (mono_error_set_pending_exception (&error))
2133 case MONO_TYPE_STRING:
2134 case MONO_TYPE_CLASS:
2135 mono_get_constant_value_from_blob (domain, def_type, def_value, &o, &error);
2136 if (mono_error_set_pending_exception (&error))
2140 g_assert_not_reached ();
2146 ICALL_EXPORT MonoReflectionType*
2147 ves_icall_MonoField_ResolveType (MonoReflectionField *ref_field)
2150 MonoReflectionType *ret;
2153 type = mono_field_get_type_checked (ref_field->field, &error);
2154 if (!mono_error_ok (&error)) {
2155 mono_error_set_pending_exception (&error);
2159 ret = mono_type_get_object_checked (mono_object_domain (ref_field), type, &error);
2160 if (!mono_error_ok (&error)) {
2161 mono_error_set_pending_exception (&error);
2168 /* From MonoProperty.cs */
2170 PInfo_Attributes = 1,
2171 PInfo_GetMethod = 1 << 1,
2172 PInfo_SetMethod = 1 << 2,
2173 PInfo_ReflectedType = 1 << 3,
2174 PInfo_DeclaringType = 1 << 4,
2179 ves_icall_MonoPropertyInfo_get_property_info (const MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
2182 MonoReflectionType *rt;
2183 MonoReflectionMethod *rm;
2184 MonoDomain *domain = mono_object_domain (property);
2185 const MonoProperty *pproperty = property->property;
2187 if ((req_info & PInfo_ReflectedType) != 0) {
2188 rt = mono_type_get_object_checked (domain, &property->klass->byval_arg, &error);
2189 if (mono_error_set_pending_exception (&error))
2192 MONO_STRUCT_SETREF (info, parent, rt);
2194 if ((req_info & PInfo_DeclaringType) != 0) {
2195 rt = mono_type_get_object_checked (domain, &pproperty->parent->byval_arg, &error);
2196 if (mono_error_set_pending_exception (&error))
2199 MONO_STRUCT_SETREF (info, declaring_type, rt);
2202 if ((req_info & PInfo_Name) != 0)
2203 MONO_STRUCT_SETREF (info, name, mono_string_new (domain, pproperty->name));
2205 if ((req_info & PInfo_Attributes) != 0)
2206 info->attrs = pproperty->attrs;
2208 if ((req_info & PInfo_GetMethod) != 0) {
2209 if (pproperty->get &&
2210 (((pproperty->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) ||
2211 pproperty->get->klass == property->klass)) {
2212 rm = mono_method_get_object_checked (domain, pproperty->get, property->klass, &error);
2213 if (mono_error_set_pending_exception (&error))
2219 MONO_STRUCT_SETREF (info, get, rm);
2221 if ((req_info & PInfo_SetMethod) != 0) {
2222 if (pproperty->set &&
2223 (((pproperty->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) ||
2224 pproperty->set->klass == property->klass)) {
2225 rm = mono_method_get_object_checked (domain, pproperty->set, property->klass, &error);
2226 if (mono_error_set_pending_exception (&error))
2232 MONO_STRUCT_SETREF (info, set, rm);
2235 * There may be other methods defined for properties, though, it seems they are not exposed
2236 * in the reflection API
2241 ves_icall_MonoEventInfo_get_event_info (MonoReflectionMonoEvent *event, MonoEventInfo *info)
2244 MonoReflectionType *rt;
2245 MonoReflectionMethod *rm;
2246 MonoDomain *domain = mono_object_domain (event);
2248 rt = mono_type_get_object_checked (domain, &event->klass->byval_arg, &error);
2249 if (mono_error_set_pending_exception (&error))
2252 MONO_STRUCT_SETREF (info, reflected_type, rt);
2254 rt = mono_type_get_object_checked (domain, &event->event->parent->byval_arg, &error);
2255 if (mono_error_set_pending_exception (&error))
2258 MONO_STRUCT_SETREF (info, declaring_type, rt);
2260 MONO_STRUCT_SETREF (info, name, mono_string_new (domain, event->event->name));
2261 info->attrs = event->event->attrs;
2263 if (event->event->add) {
2264 rm = mono_method_get_object_checked (domain, event->event->add, NULL, &error);
2265 if (mono_error_set_pending_exception (&error))
2271 MONO_STRUCT_SETREF (info, add_method, rm);
2273 if (event->event->remove) {
2274 rm = mono_method_get_object_checked (domain, event->event->remove, NULL, &error);
2275 if (mono_error_set_pending_exception (&error))
2281 MONO_STRUCT_SETREF (info, remove_method, rm);
2283 if (event->event->raise) {
2284 rm = mono_method_get_object_checked (domain, event->event->raise, NULL, &error);
2285 if (mono_error_set_pending_exception (&error))
2291 MONO_STRUCT_SETREF (info, raise_method, rm);
2293 #ifndef MONO_SMALL_CONFIG
2294 if (event->event->other) {
2296 while (event->event->other [n])
2298 MonoArray *info_arr = mono_array_new_checked (domain, mono_defaults.method_info_class, n, &error);
2299 if (mono_error_set_pending_exception (&error))
2301 MONO_STRUCT_SETREF (info, other_methods, info_arr);
2303 for (i = 0; i < n; i++) {
2304 rm = mono_method_get_object_checked (domain, event->event->other [i], NULL, &error);
2305 if (mono_error_set_pending_exception (&error))
2307 mono_array_setref (info->other_methods, i, rm);
2314 collect_interfaces (MonoClass *klass, GHashTable *ifaces, MonoError *error)
2319 mono_class_setup_interfaces (klass, error);
2320 if (!mono_error_ok (error))
2323 for (i = 0; i < klass->interface_count; i++) {
2324 ic = klass->interfaces [i];
2325 g_hash_table_insert (ifaces, ic, ic);
2327 collect_interfaces (ic, ifaces, error);
2328 if (!mono_error_ok (error))
2334 MonoArray *iface_array;
2335 MonoGenericContext *context;
2339 } FillIfaceArrayData;
2342 fill_iface_array (gpointer key, gpointer value, gpointer user_data)
2344 MonoReflectionType *rt;
2345 FillIfaceArrayData *data = (FillIfaceArrayData *)user_data;
2346 MonoClass *ic = (MonoClass *)key;
2347 MonoType *ret = &ic->byval_arg, *inflated = NULL;
2349 if (!mono_error_ok (data->error))
2352 if (data->context && mono_class_is_ginst (ic) && mono_class_get_generic_class (ic)->context.class_inst->is_open) {
2353 inflated = ret = mono_class_inflate_generic_type_checked (ret, data->context, data->error);
2354 if (!mono_error_ok (data->error))
2358 rt = mono_type_get_object_checked (data->domain, ret, data->error);
2359 if (!mono_error_ok (data->error))
2362 mono_array_setref (data->iface_array, data->next_idx++, rt);
2365 mono_metadata_free_type (inflated);
2369 get_interfaces_hash (gconstpointer v1)
2371 MonoClass *k = (MonoClass*)v1;
2373 return k->type_token;
2376 ICALL_EXPORT MonoArray*
2377 ves_icall_RuntimeType_GetInterfaces (MonoReflectionType* type)
2380 MonoClass *klass = mono_class_from_mono_type (type->type);
2382 FillIfaceArrayData data = { 0 };
2385 GHashTable *iface_hash = g_hash_table_new (get_interfaces_hash, NULL);
2387 if (mono_class_is_ginst (klass) && mono_class_get_generic_class (klass)->context.class_inst->is_open) {
2388 data.context = mono_class_get_context (klass);
2389 klass = mono_class_get_generic_class (klass)->container_class;
2392 for (parent = klass; parent; parent = parent->parent) {
2393 mono_class_setup_interfaces (parent, &error);
2394 if (!mono_error_ok (&error))
2396 collect_interfaces (parent, iface_hash, &error);
2397 if (!mono_error_ok (&error))
2401 data.error = &error;
2402 data.domain = mono_object_domain (type);
2404 len = g_hash_table_size (iface_hash);
2406 g_hash_table_destroy (iface_hash);
2407 if (!data.domain->empty_types) {
2408 data.domain->empty_types = mono_array_new_cached (data.domain, mono_defaults.runtimetype_class, 0, &error);
2409 if (!is_ok (&error))
2412 return data.domain->empty_types;
2415 data.iface_array = mono_array_new_cached (data.domain, mono_defaults.runtimetype_class, len, &error);
2416 if (!is_ok (&error))
2418 g_hash_table_foreach (iface_hash, fill_iface_array, &data);
2419 if (!mono_error_ok (&error))
2422 g_hash_table_destroy (iface_hash);
2423 return data.iface_array;
2426 g_hash_table_destroy (iface_hash);
2427 mono_error_set_pending_exception (&error);
2432 ves_icall_RuntimeType_GetInterfaceMapData (MonoReflectionType *type, MonoReflectionType *iface, MonoArray **targets, MonoArray **methods)
2434 gboolean variance_used;
2435 MonoClass *klass = mono_class_from_mono_type (type->type);
2436 MonoClass *iclass = mono_class_from_mono_type (iface->type);
2437 MonoReflectionMethod *member;
2440 int i = 0, len, ioffset;
2444 mono_class_init_checked (klass, &error);
2445 if (mono_error_set_pending_exception (&error))
2447 mono_class_init_checked (iclass, &error);
2448 if (mono_error_set_pending_exception (&error))
2451 mono_class_setup_vtable (klass);
2453 ioffset = mono_class_interface_offset_with_variance (klass, iclass, &variance_used);
2457 len = mono_class_num_methods (iclass);
2458 domain = mono_object_domain (type);
2459 MonoArray *targets_arr = mono_array_new_checked (domain, mono_defaults.method_info_class, len, &error);
2460 if (mono_error_set_pending_exception (&error))
2462 mono_gc_wbarrier_generic_store (targets, (MonoObject*) targets_arr);
2463 MonoArray *methods_arr = mono_array_new_checked (domain, mono_defaults.method_info_class, len, &error);
2464 if (mono_error_set_pending_exception (&error))
2466 mono_gc_wbarrier_generic_store (methods, (MonoObject*) methods_arr);
2468 while ((method = mono_class_get_methods (iclass, &iter))) {
2469 member = mono_method_get_object_checked (domain, method, iclass, &error);
2470 if (mono_error_set_pending_exception (&error))
2472 mono_array_setref (*methods, i, member);
2473 member = mono_method_get_object_checked (domain, klass->vtable [i + ioffset], klass, &error);
2474 if (mono_error_set_pending_exception (&error))
2476 mono_array_setref (*targets, i, member);
2483 ves_icall_RuntimeType_GetPacking (MonoReflectionType *type, guint32 *packing, guint32 *size)
2486 MonoClass *klass = mono_class_from_mono_type (type->type);
2488 mono_class_init_checked (klass, &error);
2489 if (mono_error_set_pending_exception (&error))
2492 if (image_is_dynamic (klass->image)) {
2493 MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)type;
2494 *packing = tb->packing_size;
2495 *size = tb->class_size;
2497 mono_metadata_packing_from_typedef (klass->image, klass->type_token, packing, size);
2501 ICALL_EXPORT MonoReflectionType*
2502 ves_icall_RuntimeTypeHandle_GetElementType (MonoReflectionType *type)
2505 MonoReflectionType *ret;
2508 if (!type->type->byref && type->type->type == MONO_TYPE_SZARRAY) {
2509 ret = mono_type_get_object_checked (mono_object_domain (type), &type->type->data.klass->byval_arg, &error);
2510 mono_error_set_pending_exception (&error);
2514 klass = mono_class_from_mono_type (type->type);
2515 mono_class_init_checked (klass, &error);
2516 if (mono_error_set_pending_exception (&error))
2520 // GetElementType should only return a type for:
2521 // Array Pointer PassedByRef
2522 if (type->type->byref)
2523 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->byval_arg, &error);
2524 else if (klass->element_class && MONO_CLASS_IS_ARRAY (klass))
2525 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->element_class->byval_arg, &error);
2526 else if (klass->element_class && type->type->type == MONO_TYPE_PTR)
2527 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->element_class->byval_arg, &error);
2531 mono_error_set_pending_exception (&error);
2536 ICALL_EXPORT MonoReflectionType*
2537 ves_icall_RuntimeTypeHandle_GetBaseType (MonoReflectionType *type)
2540 MonoReflectionType *ret;
2542 if (type->type->byref)
2545 MonoClass *klass = mono_class_from_mono_type (type->type);
2549 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->parent->byval_arg, &error);
2550 mono_error_set_pending_exception (&error);
2555 ICALL_EXPORT MonoBoolean
2556 ves_icall_RuntimeTypeHandle_IsPointer (MonoReflectionType *type)
2558 return type->type->type == MONO_TYPE_PTR;
2561 ICALL_EXPORT MonoBoolean
2562 ves_icall_RuntimeTypeHandle_IsPrimitive (MonoReflectionType *type)
2564 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)));
2567 ICALL_EXPORT MonoBoolean
2568 ves_icall_RuntimeTypeHandle_IsByRef (MonoReflectionType *type)
2570 return type->type->byref;
2573 ICALL_EXPORT MonoBoolean
2574 ves_icall_RuntimeTypeHandle_IsComObject (MonoReflectionType *type)
2577 MonoClass *klass = mono_class_from_mono_type (type->type);
2578 mono_class_init_checked (klass, &error);
2579 if (mono_error_set_pending_exception (&error))
2582 return mono_class_is_com_object (klass);
2585 ICALL_EXPORT guint32
2586 ves_icall_reflection_get_token (MonoObject* obj)
2589 guint32 result = mono_reflection_get_token_checked (obj, &error);
2590 mono_error_set_pending_exception (&error);
2594 ICALL_EXPORT MonoReflectionModuleHandle
2595 ves_icall_RuntimeTypeHandle_GetModule (MonoReflectionTypeHandle type, MonoError *error)
2597 mono_error_init (error);
2598 MonoDomain *domain = MONO_HANDLE_DOMAIN (type);
2599 MonoType *t = MONO_HANDLE_GETVAL (type, type);
2600 MonoClass *klass = mono_class_from_mono_type (t);
2601 return mono_module_get_object_handle (domain, klass->image, error);
2604 ICALL_EXPORT MonoReflectionAssemblyHandle
2605 ves_icall_RuntimeTypeHandle_GetAssembly (MonoReflectionTypeHandle type, MonoError *error)
2607 mono_error_init (error);
2608 MonoDomain *domain = mono_domain_get ();
2609 MonoType *t = MONO_HANDLE_GETVAL (type, type);
2610 MonoClass *klass = mono_class_from_mono_type (t);
2611 return mono_assembly_get_object_handle (domain, klass->image->assembly, error);
2614 ICALL_EXPORT MonoReflectionType*
2615 ves_icall_RuntimeType_get_DeclaringType (MonoReflectionType *type)
2618 MonoReflectionType *ret;
2619 MonoDomain *domain = mono_domain_get ();
2622 if (type->type->byref)
2624 if (type->type->type == MONO_TYPE_VAR) {
2625 MonoGenericContainer *param = mono_type_get_generic_param_owner (type->type);
2626 klass = param ? param->owner.klass : NULL;
2627 } else if (type->type->type == MONO_TYPE_MVAR) {
2628 MonoGenericContainer *param = mono_type_get_generic_param_owner (type->type);
2629 klass = param ? param->owner.method->klass : NULL;
2631 klass = mono_class_from_mono_type (type->type)->nested_in;
2637 ret = mono_type_get_object_checked (domain, &klass->byval_arg, &error);
2638 mono_error_set_pending_exception (&error);
2643 ICALL_EXPORT MonoStringHandle
2644 ves_icall_RuntimeType_get_Name (MonoReflectionTypeHandle reftype, MonoError *error)
2646 MonoDomain *domain = mono_domain_get ();
2647 MonoType *type = MONO_HANDLE_RAW(reftype)->type;
2648 MonoClass *klass = mono_class_from_mono_type (type);
2651 char *n = g_strdup_printf ("%s&", klass->name);
2652 MonoStringHandle res = mono_string_new_handle (domain, n, error);
2658 return mono_string_new_handle (domain, klass->name, error);
2662 ICALL_EXPORT MonoStringHandle
2663 ves_icall_RuntimeType_get_Namespace (MonoReflectionTypeHandle type, MonoError *error)
2665 MonoDomain *domain = mono_domain_get ();
2666 MonoClass *klass = mono_class_from_mono_type_handle (type);
2668 while (klass->nested_in)
2669 klass = klass->nested_in;
2671 if (klass->name_space [0] == '\0')
2672 return NULL_HANDLE_STRING;
2674 return mono_string_new_handle (domain, klass->name_space, error);
2678 ves_icall_RuntimeTypeHandle_GetArrayRank (MonoReflectionType *type)
2682 if (type->type->type != MONO_TYPE_ARRAY && type->type->type != MONO_TYPE_SZARRAY) {
2683 mono_set_pending_exception (mono_get_exception_argument ("type", "Type must be an array type"));
2687 klass = mono_class_from_mono_type (type->type);
2693 create_type_array (MonoDomain *domain, MonoBoolean runtimeTypeArray, int count, MonoError *error)
2695 return mono_array_new_checked (domain, runtimeTypeArray ? mono_defaults.runtimetype_class : mono_defaults.systemtype_class, count, error);
2698 ICALL_EXPORT MonoArray*
2699 ves_icall_RuntimeType_GetGenericArguments (MonoReflectionType *type, MonoBoolean runtimeTypeArray)
2702 MonoReflectionType *rt;
2704 MonoClass *klass, *pklass;
2705 MonoDomain *domain = mono_object_domain (type);
2708 klass = mono_class_from_mono_type (type->type);
2710 if (mono_class_is_gtd (klass)) {
2711 MonoGenericContainer *container = mono_class_get_generic_container (klass);
2712 res = create_type_array (domain, runtimeTypeArray, container->type_argc, &error);
2713 if (mono_error_set_pending_exception (&error))
2715 for (i = 0; i < container->type_argc; ++i) {
2716 pklass = mono_class_from_generic_parameter_internal (mono_generic_container_get_param (container, i));
2718 rt = mono_type_get_object_checked (domain, &pklass->byval_arg, &error);
2719 if (mono_error_set_pending_exception (&error))
2722 mono_array_setref (res, i, rt);
2724 } else if (mono_class_is_ginst (klass)) {
2725 MonoGenericInst *inst = mono_class_get_generic_class (klass)->context.class_inst;
2726 res = create_type_array (domain, runtimeTypeArray, inst->type_argc, &error);
2727 if (mono_error_set_pending_exception (&error))
2729 for (i = 0; i < inst->type_argc; ++i) {
2730 rt = mono_type_get_object_checked (domain, inst->type_argv [i], &error);
2731 if (mono_error_set_pending_exception (&error))
2734 mono_array_setref (res, i, rt);
2742 ICALL_EXPORT gboolean
2743 ves_icall_RuntimeTypeHandle_IsGenericTypeDefinition (MonoReflectionType *type)
2747 if (!IS_MONOTYPE (type))
2750 if (type->type->byref)
2753 klass = mono_class_from_mono_type (type->type);
2754 return mono_class_is_gtd (klass);
2757 ICALL_EXPORT MonoReflectionType*
2758 ves_icall_RuntimeTypeHandle_GetGenericTypeDefinition_impl (MonoReflectionType *type)
2761 MonoReflectionType *ret;
2764 if (type->type->byref)
2767 klass = mono_class_from_mono_type (type->type);
2769 if (mono_class_is_gtd (klass)) {
2770 return type; /* check this one */
2772 if (mono_class_is_ginst (klass)) {
2773 MonoClass *generic_class = mono_class_get_generic_class (klass)->container_class;
2776 tb = mono_class_get_ref_info (generic_class);
2778 if (generic_class->wastypebuilder && tb)
2779 return (MonoReflectionType *)tb;
2781 ret = mono_type_get_object_checked (mono_object_domain (type), &generic_class->byval_arg, &error);
2782 mono_error_set_pending_exception (&error);
2790 ICALL_EXPORT MonoReflectionType*
2791 ves_icall_RuntimeType_MakeGenericType (MonoReflectionType *type, MonoArray *type_array)
2794 MonoReflectionType *ret;
2796 MonoType *geninst, **types;
2799 g_assert (IS_MONOTYPE (type));
2800 mono_class_init_checked (mono_class_from_mono_type (type->type), &error);
2801 if (mono_error_set_pending_exception (&error))
2804 count = mono_array_length (type_array);
2805 types = g_new0 (MonoType *, count);
2807 for (i = 0; i < count; i++) {
2808 MonoReflectionType *t = (MonoReflectionType *)mono_array_get (type_array, gpointer, i);
2809 types [i] = t->type;
2812 geninst = mono_reflection_bind_generic_parameters (type, count, types, &error);
2815 mono_error_set_pending_exception (&error);
2819 klass = mono_class_from_mono_type (geninst);
2821 /*we might inflate to the GTD*/
2822 if (mono_class_is_ginst (klass) && !mono_verifier_class_is_valid_generic_instantiation (klass)) {
2823 mono_set_pending_exception (mono_get_exception_argument ("typeArguments", "Invalid generic arguments"));
2827 ret = mono_type_get_object_checked (mono_object_domain (type), geninst, &error);
2828 mono_error_set_pending_exception (&error);
2833 ICALL_EXPORT gboolean
2834 ves_icall_RuntimeTypeHandle_HasInstantiation (MonoReflectionType *type)
2838 if (!IS_MONOTYPE (type))
2841 if (type->type->byref)
2844 klass = mono_class_from_mono_type (type->type);
2845 return mono_class_is_ginst (klass) || mono_class_is_gtd (klass);
2849 ves_icall_RuntimeType_GetGenericParameterPosition (MonoReflectionType *type)
2851 if (!IS_MONOTYPE (type))
2854 if (is_generic_parameter (type->type))
2855 return mono_type_get_generic_param_num (type->type);
2859 ICALL_EXPORT MonoGenericParamInfo *
2860 ves_icall_RuntimeTypeHandle_GetGenericParameterInfo (MonoReflectionType *type)
2862 return mono_generic_param_info (type->type->data.generic_param);
2865 ICALL_EXPORT MonoBoolean
2866 ves_icall_RuntimeTypeHandle_IsGenericVariable (MonoReflectionType *type)
2868 return is_generic_parameter (type->type);
2871 ICALL_EXPORT MonoReflectionMethod*
2872 ves_icall_RuntimeType_GetCorrespondingInflatedMethod (MonoReflectionType *type,
2873 MonoReflectionMethod* generic)
2880 MonoReflectionMethod *ret = NULL;
2882 domain = ((MonoObject *)type)->vtable->domain;
2884 klass = mono_class_from_mono_type (type->type);
2885 mono_class_init_checked (klass, &error);
2886 if (mono_error_set_pending_exception (&error))
2890 while ((method = mono_class_get_methods (klass, &iter))) {
2891 if (method->token == generic->method->token) {
2892 ret = mono_method_get_object_checked (domain, method, klass, &error);
2893 if (mono_error_set_pending_exception (&error))
2901 ICALL_EXPORT MonoReflectionMethod *
2902 ves_icall_RuntimeType_get_DeclaringMethod (MonoReflectionType *ref_type)
2905 MonoType *type = ref_type->type;
2907 MonoReflectionMethod *ret = NULL;
2909 if (type->byref || (type->type != MONO_TYPE_MVAR && type->type != MONO_TYPE_VAR)) {
2910 mono_set_pending_exception (mono_get_exception_invalid_operation ("DeclaringMethod can only be used on generic arguments"));
2913 if (type->type == MONO_TYPE_VAR)
2916 method = mono_type_get_generic_param_owner (type)->owner.method;
2919 ret = mono_method_get_object_checked (mono_object_domain (ref_type), method, method->klass, &error);
2920 if (!mono_error_ok (&error))
2921 mono_set_pending_exception (mono_error_convert_to_exception (&error));
2925 ICALL_EXPORT MonoBoolean
2926 ves_icall_System_RuntimeType_IsTypeExportedToWindowsRuntime (void)
2928 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2932 ICALL_EXPORT MonoBoolean
2933 ves_icall_System_RuntimeType_IsWindowsRuntimeObjectType (void)
2935 mono_set_pending_exception (mono_get_exception_not_implemented (NULL));
2940 ves_icall_MonoMethod_GetPInvoke (MonoReflectionMethod *method, int* flags, MonoString** entry_point, MonoString** dll_name)
2942 MonoDomain *domain = mono_domain_get ();
2943 MonoImage *image = method->method->klass->image;
2944 MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method->method;
2945 MonoTableInfo *tables = image->tables;
2946 MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
2947 MonoTableInfo *mr = &tables [MONO_TABLE_MODULEREF];
2948 guint32 im_cols [MONO_IMPLMAP_SIZE];
2949 guint32 scope_token;
2950 const char *import = NULL;
2951 const char *scope = NULL;
2953 if (image_is_dynamic (image)) {
2954 MonoReflectionMethodAux *method_aux =
2955 (MonoReflectionMethodAux *)g_hash_table_lookup (((MonoDynamicImage*)image)->method_aux_hash, method->method);
2957 import = method_aux->dllentry;
2958 scope = method_aux->dll;
2961 if (!import || !scope) {
2962 mono_set_pending_exception (mono_get_exception_argument ("method", "System.Reflection.Emit method with invalid pinvoke information"));
2967 if (piinfo->implmap_idx) {
2968 mono_metadata_decode_row (im, piinfo->implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE);
2970 piinfo->piflags = im_cols [MONO_IMPLMAP_FLAGS];
2971 import = mono_metadata_string_heap (image, im_cols [MONO_IMPLMAP_NAME]);
2972 scope_token = mono_metadata_decode_row_col (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME);
2973 scope = mono_metadata_string_heap (image, scope_token);
2977 *flags = piinfo->piflags;
2978 *entry_point = mono_string_new (domain, import);
2979 *dll_name = mono_string_new (domain, scope);
2982 ICALL_EXPORT MonoReflectionMethod *
2983 ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
2985 MonoMethodInflated *imethod;
2987 MonoReflectionMethod *ret = NULL;
2990 if (method->method->is_generic)
2993 if (!method->method->is_inflated)
2996 imethod = (MonoMethodInflated *) method->method;
2998 result = imethod->declaring;
2999 /* Not a generic method. */
3000 if (!result->is_generic)
3003 if (image_is_dynamic (method->method->klass->image)) {
3004 MonoDynamicImage *image = (MonoDynamicImage*)method->method->klass->image;
3005 MonoReflectionMethod *res;
3008 * FIXME: Why is this stuff needed at all ? Why can't the code below work for
3009 * the dynamic case as well ?
3011 mono_image_lock ((MonoImage*)image);
3012 res = (MonoReflectionMethod *)mono_g_hash_table_lookup (image->generic_def_objects, imethod);
3013 mono_image_unlock ((MonoImage*)image);
3019 if (imethod->context.class_inst) {
3020 MonoClass *klass = ((MonoMethod *) imethod)->klass;
3021 /*Generic methods gets the context of the GTD.*/
3022 if (mono_class_get_context (klass)) {
3023 result = mono_class_inflate_generic_method_full_checked (result, klass, mono_class_get_context (klass), &error);
3024 if (!mono_error_ok (&error))
3029 ret = mono_method_get_object_checked (mono_object_domain (method), result, NULL, &error);
3031 if (!mono_error_ok (&error))
3032 mono_error_set_pending_exception (&error);
3036 ICALL_EXPORT gboolean
3037 ves_icall_MonoMethod_get_IsGenericMethod (MonoReflectionMethod *method)
3039 return mono_method_signature (method->method)->generic_param_count != 0;
3042 ICALL_EXPORT gboolean
3043 ves_icall_MonoMethod_get_IsGenericMethodDefinition (MonoReflectionMethod *method)
3045 return method->method->is_generic;
3048 ICALL_EXPORT MonoArray*
3049 ves_icall_MonoMethod_GetGenericArguments (MonoReflectionMethod *method)
3052 MonoReflectionType *rt;
3057 domain = mono_object_domain (method);
3059 if (method->method->is_inflated) {
3060 MonoGenericInst *inst = mono_method_get_context (method->method)->method_inst;
3063 count = inst->type_argc;
3064 res = mono_array_new_checked (domain, mono_defaults.systemtype_class, count, &error);
3065 if (mono_error_set_pending_exception (&error))
3068 for (i = 0; i < count; i++) {
3069 rt = mono_type_get_object_checked (domain, inst->type_argv [i], &error);
3070 if (mono_error_set_pending_exception (&error))
3073 mono_array_setref (res, i, rt);
3080 count = mono_method_signature (method->method)->generic_param_count;
3081 res = mono_array_new_checked (domain, mono_defaults.systemtype_class, count, &error);
3082 if (mono_error_set_pending_exception (&error))
3085 for (i = 0; i < count; i++) {
3086 MonoGenericContainer *container = mono_method_get_generic_container (method->method);
3087 MonoGenericParam *param = mono_generic_container_get_param (container, i);
3088 MonoClass *pklass = mono_class_from_generic_parameter_internal (param);
3090 rt = mono_type_get_object_checked (domain, &pklass->byval_arg, &error);
3091 if (mono_error_set_pending_exception (&error))
3094 mono_array_setref (res, i, rt);
3100 ICALL_EXPORT MonoObject *
3101 ves_icall_InternalInvoke (MonoReflectionMethod *method, MonoObject *this_arg, MonoArray *params, MonoException **exc)
3105 * Invoke from reflection is supposed to always be a virtual call (the API
3106 * is stupid), mono_runtime_invoke_*() calls the provided method, allowing
3107 * greater flexibility.
3109 MonoMethod *m = method->method;
3110 MonoMethodSignature *sig = mono_method_signature (m);
3113 void *obj = this_arg;
3117 if (mono_security_core_clr_enabled () &&
3118 !mono_security_core_clr_ensure_reflection_access_method (m, &error)) {
3119 mono_error_set_pending_exception (&error);
3123 if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
3124 if (!mono_class_vtable_full (mono_object_domain (method), m->klass, &error)) {
3125 mono_error_cleanup (&error); /* FIXME does this make sense? */
3126 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_class_get_exception_for_failure (m->klass));
3131 if (!mono_object_isinst_checked (this_arg, m->klass, &error)) {
3132 if (!is_ok (&error)) {
3133 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_error_convert_to_exception (&error));
3136 char *this_name = mono_type_get_full_name (mono_object_get_class (this_arg));
3137 char *target_name = mono_type_get_full_name (m->klass);
3138 char *msg = g_strdup_printf ("Object of type '%s' doesn't match target type '%s'", this_name, target_name);
3139 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", msg));
3141 g_free (target_name);
3145 m = mono_object_get_virtual_method (this_arg, m);
3146 /* must pass the pointer to the value for valuetype methods */
3147 if (m->klass->valuetype)
3148 obj = mono_object_unbox (this_arg);
3149 } else if (strcmp (m->name, ".ctor") && !m->wrapper_type) {
3150 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name_msg (mono_defaults.corlib, "System.Reflection", "TargetException", "Non-static method requires a target."));
3155 if (sig->ret->byref) {
3156 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"));
3160 pcount = params? mono_array_length (params): 0;
3161 if (pcount != sig->param_count) {
3162 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_exception_from_name (mono_defaults.corlib, "System.Reflection", "TargetParameterCountException"));
3166 if (mono_class_is_abstract (m->klass) && !strcmp (m->name, ".ctor") && !this_arg) {
3167 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."));
3171 image = m->klass->image;
3172 if (image->assembly->ref_only) {
3173 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."));
3177 if (image_is_dynamic (image) && !((MonoDynamicImage*)image)->run) {
3178 mono_gc_wbarrier_generic_store (exc, (MonoObject*) mono_get_exception_not_supported ("Cannot invoke a method in a dynamic assembly without run access."));
3182 if (m->klass->rank && !strcmp (m->name, ".ctor")) {
3186 intptr_t *lower_bounds;
3187 pcount = mono_array_length (params);
3188 lengths = (uintptr_t *)alloca (sizeof (uintptr_t) * pcount);
3189 /* Note: the synthetized array .ctors have int32 as argument type */
3190 for (i = 0; i < pcount; ++i)
3191 lengths [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, i) + sizeof (MonoObject));
3193 if (m->klass->rank == 1 && sig->param_count == 2 && m->klass->element_class->rank) {
3194 /* This is a ctor for jagged arrays. MS creates an array of arrays. */
3195 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, NULL, &error);
3196 if (!mono_error_ok (&error)) {
3197 mono_error_set_pending_exception (&error);
3201 for (i = 0; i < mono_array_length (arr); ++i) {
3202 MonoArray *subarray = mono_array_new_full_checked (mono_object_domain (params), m->klass->element_class, &lengths [1], NULL, &error);
3203 if (!mono_error_ok (&error)) {
3204 mono_error_set_pending_exception (&error);
3207 mono_array_setref_fast (arr, i, subarray);
3209 return (MonoObject*)arr;
3212 if (m->klass->rank == pcount) {
3213 /* Only lengths provided. */
3214 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, NULL, &error);
3215 if (!mono_error_ok (&error)) {
3216 mono_error_set_pending_exception (&error);
3220 return (MonoObject*)arr;
3222 g_assert (pcount == (m->klass->rank * 2));
3223 /* The arguments are lower-bound-length pairs */
3224 lower_bounds = (intptr_t *)g_alloca (sizeof (intptr_t) * pcount);
3226 for (i = 0; i < pcount / 2; ++i) {
3227 lower_bounds [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, (i * 2)) + sizeof (MonoObject));
3228 lengths [i] = *(int32_t*) ((char*)mono_array_get (params, gpointer, (i * 2) + 1) + sizeof (MonoObject));
3231 arr = mono_array_new_full_checked (mono_object_domain (params), m->klass, lengths, lower_bounds, &error);
3232 if (!mono_error_ok (&error)) {
3233 mono_error_set_pending_exception (&error);
3237 return (MonoObject*)arr;
3240 MonoObject *result = mono_runtime_invoke_array_checked (m, obj, params, &error);
3241 mono_error_set_pending_exception (&error);
3245 #ifndef DISABLE_REMOTING
3246 ICALL_EXPORT MonoObject *
3247 ves_icall_InternalExecute (MonoReflectionMethod *method, MonoObject *this_arg, MonoArray *params, MonoArray **outArgs)
3250 MonoDomain *domain = mono_object_domain (method);
3251 MonoMethod *m = method->method;
3252 MonoMethodSignature *sig = mono_method_signature (m);
3253 MonoArray *out_args;
3255 int i, j, outarg_count = 0;
3257 if (m->klass == mono_defaults.object_class) {
3258 if (!strcmp (m->name, "FieldGetter")) {
3259 MonoClass *k = this_arg->vtable->klass;
3263 /* If this is a proxy, then it must be a CBO */
3264 if (k == mono_defaults.transparent_proxy_class) {
3265 MonoTransparentProxy *tp = (MonoTransparentProxy*) this_arg;
3266 this_arg = tp->rp->unwrapped_server;
3267 g_assert (this_arg);
3268 k = this_arg->vtable->klass;
3271 name = mono_array_get (params, MonoString *, 1);
3272 str = mono_string_to_utf8_checked (name, &error);
3273 if (mono_error_set_pending_exception (&error))
3277 MonoClassField* field = mono_class_get_field_from_name (k, str);
3280 MonoClass *field_klass = mono_class_from_mono_type (field->type);
3281 if (field_klass->valuetype) {
3282 result = mono_value_box_checked (domain, field_klass, (char *)this_arg + field->offset, &error);
3283 if (mono_error_set_pending_exception (&error))
3286 result = (MonoObject *)*((gpointer *)((char *)this_arg + field->offset));
3288 out_args = mono_array_new_checked (domain, mono_defaults.object_class, 1, &error);
3289 if (mono_error_set_pending_exception (&error))
3291 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3292 mono_array_setref (out_args, 0, result);
3299 g_assert_not_reached ();
3301 } else if (!strcmp (m->name, "FieldSetter")) {
3302 MonoClass *k = this_arg->vtable->klass;
3308 /* If this is a proxy, then it must be a CBO */
3309 if (k == mono_defaults.transparent_proxy_class) {
3310 MonoTransparentProxy *tp = (MonoTransparentProxy*) this_arg;
3311 this_arg = tp->rp->unwrapped_server;
3312 g_assert (this_arg);
3313 k = this_arg->vtable->klass;
3316 name = mono_array_get (params, MonoString *, 1);
3317 str = mono_string_to_utf8_checked (name, &error);
3318 if (mono_error_set_pending_exception (&error))
3322 MonoClassField* field = mono_class_get_field_from_name (k, str);
3325 MonoClass *field_klass = mono_class_from_mono_type (field->type);
3326 MonoObject *val = (MonoObject *)mono_array_get (params, gpointer, 2);
3328 if (field_klass->valuetype) {
3329 size = mono_type_size (field->type, &align);
3330 g_assert (size == mono_class_value_size (field_klass, NULL));
3331 mono_gc_wbarrier_value_copy ((char *)this_arg + field->offset, (char*)val + sizeof (MonoObject), 1, field_klass);
3333 mono_gc_wbarrier_set_field (this_arg, (char*)this_arg + field->offset, val);
3336 out_args = mono_array_new_checked (domain, mono_defaults.object_class, 0, &error);
3337 if (mono_error_set_pending_exception (&error))
3339 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3348 g_assert_not_reached ();
3353 for (i = 0; i < mono_array_length (params); i++) {
3354 if (sig->params [i]->byref)
3358 out_args = mono_array_new_checked (domain, mono_defaults.object_class, outarg_count, &error);
3359 if (mono_error_set_pending_exception (&error))
3362 /* handle constructors only for objects already allocated */
3363 if (!strcmp (method->method->name, ".ctor"))
3364 g_assert (this_arg);
3366 /* This can be called only on MBR objects, so no need to unbox for valuetypes. */
3367 g_assert (!method->method->klass->valuetype);
3368 result = mono_runtime_invoke_array_checked (method->method, this_arg, params, &error);
3369 if (mono_error_set_pending_exception (&error))
3372 for (i = 0, j = 0; i < mono_array_length (params); i++) {
3373 if (sig->params [i]->byref) {
3375 arg = mono_array_get (params, gpointer, i);
3376 mono_array_setref (out_args, j, arg);
3381 mono_gc_wbarrier_generic_store (outArgs, (MonoObject*) out_args);
3388 read_enum_value (const char *mem, int type)
3391 case MONO_TYPE_BOOLEAN:
3393 return *(guint8*)mem;
3395 return *(gint8*)mem;
3396 case MONO_TYPE_CHAR:
3398 return read16 (mem);
3400 return (gint16) read16 (mem);
3402 return read32 (mem);
3404 return (gint32) read32 (mem);
3407 return read64 (mem);
3409 g_assert_not_reached ();
3415 write_enum_value (char *mem, int type, guint64 value)
3419 case MONO_TYPE_I1: {
3420 guint8 *p = (guint8*)mem;
3426 case MONO_TYPE_CHAR: {
3427 guint16 *p = (guint16 *)mem;
3432 case MONO_TYPE_I4: {
3433 guint32 *p = (guint32 *)mem;
3438 case MONO_TYPE_I8: {
3439 guint64 *p = (guint64 *)mem;
3444 g_assert_not_reached ();
3449 ICALL_EXPORT MonoObject *
3450 ves_icall_System_Enum_ToObject (MonoReflectionType *enumType, guint64 value)
3458 domain = mono_object_domain (enumType);
3459 enumc = mono_class_from_mono_type (enumType->type);
3461 mono_class_init_checked (enumc, &error);
3462 if (mono_error_set_pending_exception (&error))
3465 etype = mono_class_enum_basetype (enumc);
3467 res = mono_object_new_checked (domain, enumc, &error);
3468 if (mono_error_set_pending_exception (&error))
3470 write_enum_value ((char *)res + sizeof (MonoObject), etype->type, value);
3475 ICALL_EXPORT MonoBoolean
3476 ves_icall_System_Enum_InternalHasFlag (MonoObject *a, MonoObject *b)
3478 int size = mono_class_value_size (a->vtable->klass, NULL);
3479 guint64 a_val = 0, b_val = 0;
3481 memcpy (&a_val, mono_object_unbox (a), size);
3482 memcpy (&b_val, mono_object_unbox (b), size);
3484 return (a_val & b_val) == b_val;
3487 ICALL_EXPORT MonoObject *
3488 ves_icall_System_Enum_get_value (MonoObject *eobj)
3500 g_assert (eobj->vtable->klass->enumtype);
3502 enumc = mono_class_from_mono_type (mono_class_enum_basetype (eobj->vtable->klass));
3503 res = mono_object_new_checked (mono_object_domain (eobj), enumc, &error);
3504 if (mono_error_set_pending_exception (&error))
3506 dst = (char *)res + sizeof (MonoObject);
3507 src = (char *)eobj + sizeof (MonoObject);
3508 size = mono_class_value_size (enumc, NULL);
3510 memcpy (dst, src, size);
3515 ICALL_EXPORT MonoReflectionType *
3516 ves_icall_System_Enum_get_underlying_type (MonoReflectionType *type)
3519 MonoReflectionType *ret;
3523 klass = mono_class_from_mono_type (type->type);
3524 mono_class_init_checked (klass, &error);
3525 if (mono_error_set_pending_exception (&error))
3528 etype = mono_class_enum_basetype (klass);
3530 mono_set_pending_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
3534 ret = mono_type_get_object_checked (mono_object_domain (type), etype, &error);
3535 mono_error_set_pending_exception (&error);
3541 ves_icall_System_Enum_compare_value_to (MonoObject *eobj, MonoObject *other)
3543 gpointer tdata = (char *)eobj + sizeof (MonoObject);
3544 gpointer odata = (char *)other + sizeof (MonoObject);
3545 MonoType *basetype = mono_class_enum_basetype (eobj->vtable->klass);
3546 g_assert (basetype);
3551 if (eobj->vtable->klass != other->vtable->klass)
3554 #define COMPARE_ENUM_VALUES(ENUM_TYPE) do { \
3555 ENUM_TYPE me = *((ENUM_TYPE*)tdata); \
3556 ENUM_TYPE other = *((ENUM_TYPE*)odata); \
3559 return me > other ? 1 : -1; \
3562 switch (basetype->type) {
3564 COMPARE_ENUM_VALUES (guint8);
3566 COMPARE_ENUM_VALUES (gint8);
3567 case MONO_TYPE_CHAR:
3569 COMPARE_ENUM_VALUES (guint16);
3571 COMPARE_ENUM_VALUES (gint16);
3573 COMPARE_ENUM_VALUES (guint32);
3575 COMPARE_ENUM_VALUES (gint32);
3577 COMPARE_ENUM_VALUES (guint64);
3579 COMPARE_ENUM_VALUES (gint64);
3583 #undef COMPARE_ENUM_VALUES
3584 /* indicates that the enum was of an unsupported unerlying type */
3589 ves_icall_System_Enum_get_hashcode (MonoObject *eobj)
3591 gpointer data = (char *)eobj + sizeof (MonoObject);
3592 MonoType *basetype = mono_class_enum_basetype (eobj->vtable->klass);
3593 g_assert (basetype);
3595 switch (basetype->type) {
3596 case MONO_TYPE_I1: {
3597 gint8 value = *((gint8*)data);
3598 return ((int)value ^ (int)value << 8);
3601 return *((guint8*)data);
3602 case MONO_TYPE_CHAR:
3604 return *((guint16*)data);
3606 case MONO_TYPE_I2: {
3607 gint16 value = *((gint16*)data);
3608 return ((int)(guint16)value | (((int)value) << 16));
3611 return *((guint32*)data);
3613 return *((gint32*)data);
3615 case MONO_TYPE_I8: {
3616 gint64 value = *((gint64*)data);
3617 return (gint)(value & 0xffffffff) ^ (int)(value >> 32);
3620 g_error ("Implement type 0x%02x in get_hashcode", basetype->type);
3626 get_enum_field (MonoDomain *domain, MonoArrayHandle names, MonoArrayHandle values, int base_type, MonoClassField *field, guint* j, guint64 *previous_value, gboolean *sorted, MonoError *error)
3628 mono_error_init (error);
3629 HANDLE_FUNCTION_ENTER();
3630 guint64 field_value;
3632 MonoTypeEnum def_type;
3634 if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC))
3636 if (strcmp ("value__", mono_field_get_name (field)) == 0)
3638 if (mono_field_is_deleted (field))
3640 MonoStringHandle name = mono_string_new_handle (domain, mono_field_get_name (field), error);
3643 MONO_HANDLE_ARRAY_SETREF (names, *j, name);
3645 p = mono_class_get_field_default_value (field, &def_type);
3646 /* len = */ mono_metadata_decode_blob_size (p, &p);
3648 field_value = read_enum_value (p, base_type);
3649 MONO_HANDLE_ARRAY_SETVAL (values, guint64, *j, field_value);
3651 if (*previous_value > field_value)
3654 *previous_value = field_value;
3657 HANDLE_FUNCTION_RETURN();
3660 ICALL_EXPORT MonoBoolean
3661 ves_icall_System_Enum_GetEnumValuesAndNames (MonoReflectionTypeHandle type, MonoArrayHandleOut values, MonoArrayHandleOut names, MonoError *error)
3663 MonoDomain *domain = MONO_HANDLE_DOMAIN (type);
3664 MonoClass *enumc = mono_class_from_mono_type (MONO_HANDLE_RAW(type)->type);
3665 guint j = 0, nvalues;
3667 MonoClassField *field;
3669 guint64 previous_value = 0;
3670 gboolean sorted = TRUE;
3672 mono_error_init (error);
3673 mono_class_init_checked (enumc, error);
3674 return_val_if_nok (error, FALSE);
3676 if (!enumc->enumtype) {
3677 mono_error_set_argument (error, "enumType", "Type provided must be an Enum.");
3681 base_type = mono_class_enum_basetype (enumc)->type;
3683 nvalues = mono_class_num_fields (enumc) > 0 ? mono_class_num_fields (enumc) - 1 : 0;
3684 MONO_HANDLE_ASSIGN(names, mono_array_new_handle (domain, mono_defaults.string_class, nvalues, error));
3685 return_val_if_nok (error, FALSE);
3686 MONO_HANDLE_ASSIGN(values, mono_array_new_handle (domain, mono_defaults.uint64_class, nvalues, error));
3687 return_val_if_nok (error, FALSE);
3690 while ((field = mono_class_get_fields (enumc, &iter))) {
3691 get_enum_field(domain, names, values, base_type, field, &j, &previous_value, &sorted, error);
3695 return_val_if_nok (error, FALSE);
3701 BFLAGS_IgnoreCase = 1,
3702 BFLAGS_DeclaredOnly = 2,
3703 BFLAGS_Instance = 4,
3705 BFLAGS_Public = 0x10,
3706 BFLAGS_NonPublic = 0x20,
3707 BFLAGS_FlattenHierarchy = 0x40,
3708 BFLAGS_InvokeMethod = 0x100,
3709 BFLAGS_CreateInstance = 0x200,
3710 BFLAGS_GetField = 0x400,
3711 BFLAGS_SetField = 0x800,
3712 BFLAGS_GetProperty = 0x1000,
3713 BFLAGS_SetProperty = 0x2000,
3714 BFLAGS_ExactBinding = 0x10000,
3715 BFLAGS_SuppressChangeType = 0x20000,
3716 BFLAGS_OptionalParamBinding = 0x40000
3719 ICALL_EXPORT GPtrArray*
3720 ves_icall_RuntimeType_GetFields_native (MonoReflectionType *type, char *utf8_name, guint32 bflags)
3723 MonoClass *startklass, *klass;
3726 int (*compare_func) (const char *s1, const char *s2) = NULL;
3727 MonoClassField *field;
3729 if (type->type->byref) {
3730 return g_ptr_array_new ();
3733 mono_error_init (&error);
3735 compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
3737 klass = startklass = mono_class_from_mono_type (type->type);
3739 GPtrArray *ptr_array = g_ptr_array_sized_new (16);
3742 if (mono_class_has_failure (klass)) {
3743 mono_error_set_for_class_failure (&error, klass);
3748 while ((field = mono_class_get_fields_lazy (klass, &iter))) {
3749 guint32 flags = mono_field_get_flags (field);
3751 if (mono_field_is_deleted_with_flags (field, flags))
3753 if ((flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) == FIELD_ATTRIBUTE_PUBLIC) {
3754 if (bflags & BFLAGS_Public)
3756 } else if ((klass == startklass) || (flags & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK) != FIELD_ATTRIBUTE_PRIVATE) {
3757 if (bflags & BFLAGS_NonPublic) {
3764 if (flags & FIELD_ATTRIBUTE_STATIC) {
3765 if (bflags & BFLAGS_Static)
3766 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3769 if (bflags & BFLAGS_Instance)
3776 if (utf8_name != NULL && compare_func (mono_field_get_name (field), utf8_name))
3779 g_ptr_array_add (ptr_array, field);
3781 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3787 g_ptr_array_free (ptr_array, TRUE);
3788 mono_error_set_pending_exception (&error);
3793 method_nonpublic (MonoMethod* method, gboolean start_klass)
3795 switch (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) {
3796 case METHOD_ATTRIBUTE_ASSEM:
3797 return (start_klass || mono_defaults.generic_ilist_class);
3798 case METHOD_ATTRIBUTE_PRIVATE:
3800 case METHOD_ATTRIBUTE_PUBLIC:
3808 mono_class_get_methods_by_name (MonoClass *klass, const char *name, guint32 bflags, gboolean ignore_case, gboolean allow_ctors, MonoError *error)
3811 MonoClass *startklass;
3815 /*FIXME, use MonoBitSet*/
3816 guint32 method_slots_default [8];
3817 guint32 *method_slots = NULL;
3818 int (*compare_func) (const char *s1, const char *s2) = NULL;
3820 array = g_ptr_array_new ();
3822 mono_error_init (error);
3825 compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
3827 /* An optimization for calls made from Delegate:CreateDelegate () */
3828 if (klass->delegate && name && !strcmp (name, "Invoke") && (bflags == (BFLAGS_Public | BFLAGS_Static | BFLAGS_Instance))) {
3829 method = mono_get_delegate_invoke (klass);
3832 g_ptr_array_add (array, method);
3836 mono_class_setup_methods (klass);
3837 mono_class_setup_vtable (klass);
3838 if (mono_class_has_failure (klass))
3841 if (is_generic_parameter (&klass->byval_arg))
3842 nslots = mono_class_get_vtable_size (klass->parent);
3844 nslots = MONO_CLASS_IS_INTERFACE (klass) ? mono_class_num_methods (klass) : mono_class_get_vtable_size (klass);
3845 if (nslots >= sizeof (method_slots_default) * 8) {
3846 method_slots = g_new0 (guint32, nslots / 32 + 1);
3848 method_slots = method_slots_default;
3849 memset (method_slots, 0, sizeof (method_slots_default));
3852 mono_class_setup_methods (klass);
3853 mono_class_setup_vtable (klass);
3854 if (mono_class_has_failure (klass))
3858 while ((method = mono_class_get_methods (klass, &iter))) {
3860 if (method->slot != -1) {
3861 g_assert (method->slot < nslots);
3862 if (method_slots [method->slot >> 5] & (1 << (method->slot & 0x1f)))
3864 if (!(method->flags & METHOD_ATTRIBUTE_NEW_SLOT))
3865 method_slots [method->slot >> 5] |= 1 << (method->slot & 0x1f);
3868 if (!allow_ctors && method->name [0] == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
3870 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3871 if (bflags & BFLAGS_Public)
3873 } else if ((bflags & BFLAGS_NonPublic) && method_nonpublic (method, (klass == startklass))) {
3879 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3880 if (bflags & BFLAGS_Static)
3881 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3884 if (bflags & BFLAGS_Instance)
3892 if (compare_func (name, method->name))
3897 g_ptr_array_add (array, method);
3899 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
3901 if (method_slots != method_slots_default)
3902 g_free (method_slots);
3907 if (method_slots != method_slots_default)
3908 g_free (method_slots);
3909 g_ptr_array_free (array, TRUE);
3911 g_assert (mono_class_has_failure (klass));
3912 mono_error_set_for_class_failure (error, klass);
3916 ICALL_EXPORT GPtrArray*
3917 ves_icall_RuntimeType_GetMethodsByName_native (MonoReflectionType *type, const char *mname, guint32 bflags, MonoBoolean ignore_case)
3920 GPtrArray *method_array;
3923 klass = mono_class_from_mono_type (type->type);
3924 if (type->type->byref) {
3925 return g_ptr_array_new ();
3928 method_array = mono_class_get_methods_by_name (klass, mname, bflags, ignore_case, FALSE, &error);
3929 mono_error_set_pending_exception (&error);
3930 return method_array;
3933 ICALL_EXPORT GPtrArray*
3934 ves_icall_RuntimeType_GetConstructors_native (MonoReflectionType *type, guint32 bflags)
3936 MonoClass *startklass, *klass;
3939 gpointer iter = NULL;
3940 GPtrArray *res_array;
3943 if (type->type->byref) {
3944 return g_ptr_array_new ();
3947 klass = startklass = mono_class_from_mono_type (type->type);
3949 mono_class_setup_methods (klass);
3950 if (mono_class_has_failure (klass)) {
3951 mono_error_init (&error);
3952 mono_error_set_for_class_failure (&error, klass);
3953 mono_error_set_pending_exception (&error);
3957 res_array = g_ptr_array_sized_new (4); /* FIXME, guestimating */
3960 while ((method = mono_class_get_methods (klass, &iter))) {
3962 if (strcmp (method->name, ".ctor") && strcmp (method->name, ".cctor"))
3964 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
3965 if (bflags & BFLAGS_Public)
3968 if (bflags & BFLAGS_NonPublic)
3974 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
3975 if (bflags & BFLAGS_Static)
3976 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
3979 if (bflags & BFLAGS_Instance)
3985 g_ptr_array_add (res_array, method);
3992 property_hash (gconstpointer data)
3994 MonoProperty *prop = (MonoProperty*)data;
3996 return g_str_hash (prop->name);
4000 property_accessor_override (MonoMethod *method1, MonoMethod *method2)
4002 if (method1->slot != -1 && method1->slot == method2->slot)
4005 if (mono_class_get_generic_type_definition (method1->klass) == mono_class_get_generic_type_definition (method2->klass)) {
4006 if (method1->is_inflated)
4007 method1 = ((MonoMethodInflated*) method1)->declaring;
4008 if (method2->is_inflated)
4009 method2 = ((MonoMethodInflated*) method2)->declaring;
4012 return mono_metadata_signature_equal (mono_method_signature (method1), mono_method_signature (method2));
4016 property_equal (MonoProperty *prop1, MonoProperty *prop2)
4018 // Properties are hide-by-name-and-signature
4019 if (!g_str_equal (prop1->name, prop2->name))
4022 /* If we see a property in a generic method, we want to
4023 compare the generic signatures, not the inflated signatures
4024 because we might conflate two properties that were
4028 public T this[T t] { getter { return t; } } // method 1
4029 public U this[U u] { getter { return u; } } // method 2
4032 If we see int Foo<int,int>::Item[int] we need to know if
4033 the indexer came from method 1 or from method 2, and we
4034 shouldn't conflate them. (Bugzilla 36283)
4036 if (prop1->get && prop2->get && !property_accessor_override (prop1->get, prop2->get))
4039 if (prop1->set && prop2->set && !property_accessor_override (prop1->set, prop2->set))
4046 property_accessor_nonpublic (MonoMethod* accessor, gboolean start_klass)
4051 return method_nonpublic (accessor, start_klass);
4054 ICALL_EXPORT GPtrArray*
4055 ves_icall_RuntimeType_GetPropertiesByName_native (MonoReflectionType *type, gchar *propname, guint32 bflags, MonoBoolean ignore_case)
4058 MonoClass *startklass, *klass;
4063 int (*compare_func) (const char *s1, const char *s2) = NULL;
4065 GHashTable *properties = NULL;
4066 GPtrArray *res_array;
4068 if (type->type->byref) {
4069 return g_ptr_array_new ();
4072 mono_error_init (&error);
4074 klass = startklass = mono_class_from_mono_type (type->type);
4076 compare_func = (ignore_case) ? mono_utf8_strcasecmp : strcmp;
4078 res_array = g_ptr_array_sized_new (8); /*This the average for ASP.NET types*/
4080 properties = g_hash_table_new (property_hash, (GEqualFunc)property_equal);
4082 mono_class_setup_methods (klass);
4083 mono_class_setup_vtable (klass);
4084 if (mono_class_has_failure (klass)) {
4085 mono_error_set_for_class_failure (&error, klass);
4090 while ((prop = mono_class_get_properties (klass, &iter))) {
4096 flags = method->flags;
4099 if ((prop->get && ((prop->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC)) ||
4100 (prop->set && ((prop->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC))) {
4101 if (bflags & BFLAGS_Public)
4103 } else if (bflags & BFLAGS_NonPublic) {
4104 if (property_accessor_nonpublic(prop->get, startklass == klass) ||
4105 property_accessor_nonpublic(prop->set, startklass == klass)) {
4112 if (flags & METHOD_ATTRIBUTE_STATIC) {
4113 if (bflags & BFLAGS_Static)
4114 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
4117 if (bflags & BFLAGS_Instance)
4125 if (propname != NULL && compare_func (propname, prop->name))
4128 if (g_hash_table_lookup (properties, prop))
4131 g_ptr_array_add (res_array, prop);
4133 g_hash_table_insert (properties, prop, prop);
4135 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
4138 g_hash_table_destroy (properties);
4145 g_hash_table_destroy (properties);
4146 g_ptr_array_free (res_array, TRUE);
4148 mono_error_set_pending_exception (&error);
4154 event_hash (gconstpointer data)
4156 MonoEvent *event = (MonoEvent*)data;
4158 return g_str_hash (event->name);
4162 event_equal (MonoEvent *event1, MonoEvent *event2)
4164 // Events are hide-by-name
4165 return g_str_equal (event1->name, event2->name);
4168 ICALL_EXPORT GPtrArray*
4169 ves_icall_RuntimeType_GetEvents_native (MonoReflectionType *type, char *utf8_name, guint32 bflags)
4172 MonoClass *startklass, *klass;
4177 int (*compare_func) (const char *s1, const char *s2) = NULL;
4178 GHashTable *events = NULL;
4179 GPtrArray *res_array;
4181 if (type->type->byref) {
4182 return g_ptr_array_new ();
4185 mono_error_init (&error);
4187 compare_func = (bflags & BFLAGS_IgnoreCase) ? mono_utf8_strcasecmp : strcmp;
4189 res_array = g_ptr_array_sized_new (4);
4191 klass = startklass = mono_class_from_mono_type (type->type);
4193 events = g_hash_table_new (event_hash, (GEqualFunc)event_equal);
4195 mono_class_setup_methods (klass);
4196 mono_class_setup_vtable (klass);
4197 if (mono_class_has_failure (klass)) {
4198 mono_error_set_for_class_failure (&error, klass);
4203 while ((event = mono_class_get_events (klass, &iter))) {
4205 method = event->add;
4207 method = event->remove;
4209 method = event->raise;
4211 if ((method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) == METHOD_ATTRIBUTE_PUBLIC) {
4212 if (bflags & BFLAGS_Public)
4214 } else if ((klass == startklass) || (method->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) {
4215 if (bflags & BFLAGS_NonPublic)
4220 if (bflags & BFLAGS_NonPublic)
4226 if (method->flags & METHOD_ATTRIBUTE_STATIC) {
4227 if (bflags & BFLAGS_Static)
4228 if ((bflags & BFLAGS_FlattenHierarchy) || (klass == startklass))
4231 if (bflags & BFLAGS_Instance)
4236 if (bflags & BFLAGS_Instance)
4241 if (utf8_name != NULL && compare_func (event->name, utf8_name))
4244 if (g_hash_table_lookup (events, event))
4247 g_ptr_array_add (res_array, event);
4249 g_hash_table_insert (events, event, event);
4251 if (!(bflags & BFLAGS_DeclaredOnly) && (klass = klass->parent))
4254 g_hash_table_destroy (events);
4260 g_hash_table_destroy (events);
4262 g_ptr_array_free (res_array, TRUE);
4264 mono_error_set_pending_exception (&error);
4268 ICALL_EXPORT GPtrArray *
4269 ves_icall_RuntimeType_GetNestedTypes_native (MonoReflectionType *type, char *str, guint32 bflags)
4275 GPtrArray *res_array;
4277 if (type->type->byref) {
4278 return g_ptr_array_new ();
4281 klass = mono_class_from_mono_type (type->type);
4284 * If a nested type is generic, return its generic type definition.
4285 * Note that this means that the return value is essentially the set
4286 * of nested types of the generic type definition of @klass.
4288 * A note in MSDN claims that a generic type definition can have
4289 * nested types that aren't generic. In any case, the container of that
4290 * nested type would be the generic type definition.
4292 if (mono_class_is_ginst (klass))
4293 klass = mono_class_get_generic_class (klass)->container_class;
4295 res_array = g_ptr_array_new ();
4298 while ((nested = mono_class_get_nested_types (klass, &iter))) {
4300 if ((mono_class_get_flags (nested) & TYPE_ATTRIBUTE_VISIBILITY_MASK) == TYPE_ATTRIBUTE_NESTED_PUBLIC) {
4301 if (bflags & BFLAGS_Public)
4304 if (bflags & BFLAGS_NonPublic)
4310 if (str != NULL && strcmp (nested->name, str))
4313 g_ptr_array_add (res_array, &nested->byval_arg);
4320 get_type_from_module_builder_module (MonoArrayHandle modules, int i, MonoTypeNameParse *info, MonoBoolean ignoreCase, gboolean *type_resolve, MonoError *error)
4322 HANDLE_FUNCTION_ENTER ();
4323 mono_error_init (error);
4324 MonoType *type = NULL;
4325 MonoReflectionModuleBuilderHandle mb = MONO_HANDLE_NEW (MonoReflectionModuleBuilder, NULL);
4326 MONO_HANDLE_ARRAY_GETREF (mb, modules, i);
4327 MonoDynamicImage *dynamic_image = MONO_HANDLE_GETVAL (mb, dynamic_image);
4328 type = mono_reflection_get_type_checked (&dynamic_image->image, &dynamic_image->image, info, ignoreCase, type_resolve, error);
4329 HANDLE_FUNCTION_RETURN_VAL (type);
4333 get_type_from_module_builder_loaded_modules (MonoArrayHandle loaded_modules, int i, MonoTypeNameParse *info, MonoBoolean ignoreCase, gboolean *type_resolve, MonoError *error)
4335 HANDLE_FUNCTION_ENTER ();
4336 mono_error_init (error);
4337 MonoType *type = NULL;
4338 MonoReflectionModuleHandle mod = MONO_HANDLE_NEW (MonoReflectionModule, NULL);
4339 MONO_HANDLE_ARRAY_GETREF (mod, loaded_modules, i);
4340 MonoImage *image = MONO_HANDLE_GETVAL (mod, image);
4341 type = mono_reflection_get_type_checked (image, image, info, ignoreCase, type_resolve, error);
4342 HANDLE_FUNCTION_RETURN_VAL (type);
4345 ICALL_EXPORT MonoReflectionTypeHandle
4346 ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssemblyHandle assembly_h, MonoReflectionModuleHandle module, MonoStringHandle name, MonoBoolean throwOnError, MonoBoolean ignoreCase, MonoError *error)
4348 mono_error_init (error);
4350 MonoTypeNameParse info;
4351 gboolean type_resolve;
4353 /* On MS.NET, this does not fire a TypeResolve event */
4354 type_resolve = TRUE;
4355 char *str = mono_string_handle_to_utf8 (name, error);
4359 /*g_print ("requested type %s in %s\n", str, assembly->assembly->aname.name);*/
4360 if (!mono_reflection_parse_type (str, &info)) {
4362 mono_reflection_free_type_info (&info);
4364 mono_error_set_argument (error, "name", "failed to parse the type");
4367 /*g_print ("failed parse\n");*/
4368 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
4371 if (info.assembly.name) {
4373 mono_reflection_free_type_info (&info);
4375 /* 1.0 and 2.0 throw different exceptions */
4376 if (mono_defaults.generic_ilist_class)
4377 mono_error_set_argument (error, NULL, "Type names passed to Assembly.GetType() must not specify an assembly.");
4379 mono_error_set_type_load_name (error, g_strdup (""), g_strdup (""), "Type names passed to Assembly.GetType() must not specify an assembly.");
4382 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
4385 MonoType *type = NULL;
4386 if (!MONO_HANDLE_IS_NULL (module)) {
4387 MonoImage *image = MONO_HANDLE_GETVAL (module, image);
4389 type = mono_reflection_get_type_checked (image, image, &info, ignoreCase, &type_resolve, error);
4390 if (!is_ok (error)) {
4392 mono_reflection_free_type_info (&info);
4398 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4399 if (assembly_is_dynamic (assembly)) {
4400 /* Enumerate all modules */
4401 MonoReflectionAssemblyBuilderHandle abuilder = MONO_HANDLE_NEW (MonoReflectionAssemblyBuilder, NULL);
4402 MONO_HANDLE_ASSIGN (abuilder, assembly_h);
4405 MonoArrayHandle modules = MONO_HANDLE_NEW (MonoArray, NULL);
4406 MONO_HANDLE_GET (modules, abuilder, modules);
4407 if (!MONO_HANDLE_IS_NULL (modules)) {
4408 int n = mono_array_handle_length (modules);
4409 for (i = 0; i < n; ++i) {
4410 type = get_type_from_module_builder_module (modules, i, &info, ignoreCase, &type_resolve, error);
4411 if (!is_ok (error)) {
4413 mono_reflection_free_type_info (&info);
4421 MonoArrayHandle loaded_modules = MONO_HANDLE_NEW (MonoArray, NULL);
4422 MONO_HANDLE_GET (loaded_modules, abuilder, loaded_modules);
4423 if (!type && !MONO_HANDLE_IS_NULL (loaded_modules)) {
4424 int n = mono_array_handle_length (loaded_modules);
4425 for (i = 0; i < n; ++i) {
4426 type = get_type_from_module_builder_loaded_modules (loaded_modules, i, &info, ignoreCase, &type_resolve, error);
4428 if (!is_ok (error)) {
4430 mono_reflection_free_type_info (&info);
4439 type = mono_reflection_get_type_checked (assembly->image, assembly->image, &info, ignoreCase, &type_resolve, error);
4440 if (!is_ok (error)) {
4442 mono_reflection_free_type_info (&info);
4448 mono_reflection_free_type_info (&info);
4452 MonoError inner_error;
4453 char *typename = mono_string_handle_to_utf8 (name, &inner_error);
4454 mono_error_assert_ok (&inner_error);
4455 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4456 char *assmname = mono_stringify_assembly_name (&assembly->aname);
4457 mono_error_set_type_load_name (error, typename, assmname, "%s", "");
4461 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
4464 if (type->type == MONO_TYPE_CLASS) {
4465 MonoClass *klass = mono_type_get_class (type);
4467 /* need to report exceptions ? */
4468 if (throwOnError && mono_class_has_failure (klass)) {
4469 /* report SecurityException (or others) that occured when loading the assembly */
4470 mono_error_set_for_class_failure (error, klass);
4475 /* g_print ("got it\n"); */
4476 return mono_type_get_object_handle (MONO_HANDLE_DOMAIN (assembly_h), type, error);
4478 g_assert (!is_ok (error));
4479 return MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
4483 replace_shadow_path (MonoDomain *domain, gchar *dirname, gchar **filename)
4486 gchar *shadow_ini_file;
4489 /* Check for shadow-copied assembly */
4490 if (mono_is_shadow_copy_enabled (domain, dirname)) {
4491 shadow_ini_file = g_build_filename (dirname, "__AssemblyInfo__.ini", NULL);
4493 if (!g_file_get_contents (shadow_ini_file, &content, &len, NULL) ||
4494 !g_file_test (content, G_FILE_TEST_IS_REGULAR)) {
4500 g_free (shadow_ini_file);
4501 if (content != NULL) {
4504 *filename = content;
4511 ICALL_EXPORT MonoStringHandle
4512 ves_icall_System_Reflection_Assembly_get_code_base (MonoReflectionAssemblyHandle assembly, MonoBoolean escaped, MonoError *error)
4514 mono_error_init (error);
4515 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly);
4516 MonoAssembly *mass = MONO_HANDLE_GETVAL (assembly, assembly);
4520 if (g_path_is_absolute (mass->image->name)) {
4521 absolute = g_strdup (mass->image->name);
4522 dirname = g_path_get_dirname (absolute);
4524 absolute = g_build_filename (mass->basedir, mass->image->name, NULL);
4525 dirname = g_strdup (mass->basedir);
4528 replace_shadow_path (domain, dirname, &absolute);
4531 mono_icall_make_platform_path (absolute);
4535 uri = g_filename_to_uri (absolute, NULL, NULL);
4537 const gchar *prepend = mono_icall_get_file_path_prefix (absolute);
4538 uri = g_strconcat (prepend, absolute, NULL);
4543 MonoStringHandle res;
4545 res = mono_string_new_handle (domain, uri, error);
4548 res = MONO_HANDLE_NEW (MonoString, NULL);
4553 ICALL_EXPORT MonoBoolean
4554 ves_icall_System_Reflection_Assembly_get_global_assembly_cache (MonoReflectionAssemblyHandle assembly, MonoError *error)
4556 mono_error_init (error);
4557 MonoAssembly *mass = MONO_HANDLE_GETVAL (assembly,assembly);
4559 return mass->in_gac;
4562 ICALL_EXPORT MonoReflectionAssemblyHandle
4563 ves_icall_System_Reflection_Assembly_load_with_partial_name (MonoStringHandle mname, MonoObjectHandle evidence, MonoError *error)
4566 MonoImageOpenStatus status;
4567 MonoReflectionAssemblyHandle result = MONO_HANDLE_CAST (MonoReflectionAssembly, NULL_HANDLE);
4569 name = mono_string_handle_to_utf8 (mname, error);
4572 MonoAssembly *res = mono_assembly_load_with_partial_name (name, &status);
4578 result = mono_assembly_get_object_handle (mono_domain_get (), res, error);
4583 ICALL_EXPORT MonoStringHandle
4584 ves_icall_System_Reflection_Assembly_get_location (MonoReflectionAssemblyHandle refassembly, MonoError *error)
4586 MonoDomain *domain = MONO_HANDLE_DOMAIN (refassembly);
4587 MonoAssembly *assembly = MONO_HANDLE_GETVAL (refassembly, assembly);
4588 return mono_string_new_handle (domain, mono_image_get_filename (assembly->image), error);
4591 ICALL_EXPORT MonoBoolean
4592 ves_icall_System_Reflection_Assembly_get_ReflectionOnly (MonoReflectionAssemblyHandle assembly_h, MonoError *error)
4594 mono_error_init (error);
4595 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4596 return assembly->ref_only;
4599 ICALL_EXPORT MonoStringHandle
4600 ves_icall_System_Reflection_Assembly_InternalImageRuntimeVersion (MonoReflectionAssemblyHandle refassembly, MonoError *error)
4602 MonoDomain *domain = MONO_HANDLE_DOMAIN (refassembly);
4603 MonoAssembly *assembly = MONO_HANDLE_GETVAL (refassembly, assembly);
4605 return mono_string_new_handle (domain, assembly->image->version, error);
4608 ICALL_EXPORT MonoReflectionMethodHandle
4609 ves_icall_System_Reflection_Assembly_get_EntryPoint (MonoReflectionAssemblyHandle assembly_h, MonoError *error)
4611 mono_error_init (error);
4612 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4613 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4616 MonoReflectionMethodHandle res = MONO_HANDLE_NEW (MonoReflectionMethod, NULL);
4617 guint32 token = mono_image_get_entry_point (assembly->image);
4621 method = mono_get_method_checked (assembly->image, token, NULL, NULL, error);
4625 MONO_HANDLE_ASSIGN (res, mono_method_get_object_handle (domain, method, NULL, error));
4630 ICALL_EXPORT MonoReflectionModuleHandle
4631 ves_icall_System_Reflection_Assembly_GetManifestModuleInternal (MonoReflectionAssemblyHandle assembly, MonoError *error)
4633 mono_error_init (error);
4634 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly);
4635 MonoAssembly *a = MONO_HANDLE_GETVAL (assembly, assembly);
4636 return mono_module_get_object_handle (domain, a->image, error);
4640 add_manifest_resource_name_to_array (MonoDomain *domain, MonoImage *image, MonoTableInfo *table, int i, MonoArrayHandle dest, MonoError *error)
4642 HANDLE_FUNCTION_ENTER ();
4643 mono_error_init (error);
4644 const char *val = mono_metadata_string_heap (image, mono_metadata_decode_row_col (table, i, MONO_MANIFEST_NAME));
4645 MonoStringHandle str = mono_string_new_handle (domain, val, error);
4648 MONO_HANDLE_ARRAY_SETREF (dest, i, str);
4650 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
4653 ICALL_EXPORT MonoArrayHandle
4654 ves_icall_System_Reflection_Assembly_GetManifestResourceNames (MonoReflectionAssemblyHandle assembly_h, MonoError *error)
4656 mono_error_init (error);
4657 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4658 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4659 MonoTableInfo *table = &assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4660 MonoArrayHandle result = mono_array_new_handle (domain, mono_defaults.string_class, table->rows, error);
4665 for (i = 0; i < table->rows; ++i) {
4666 if (!add_manifest_resource_name_to_array (domain, assembly->image, table, i, result, error))
4671 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
4674 ICALL_EXPORT MonoStringHandle
4675 ves_icall_System_Reflection_Assembly_GetAotId (MonoError *error)
4677 char *guid = mono_runtime_get_aotid ();
4680 MonoStringHandle res = mono_string_new_handle (mono_domain_get (), guid, error);
4685 static MonoAssemblyName*
4686 create_referenced_assembly_name (MonoDomain *domain, MonoImage *image, MonoTableInfo *t, int i, MonoError *error)
4688 mono_error_init (error);
4689 MonoAssemblyName *aname = g_new0 (MonoAssemblyName, 1);
4691 mono_assembly_get_assemblyref (image, i, aname);
4692 aname->hash_alg = ASSEMBLY_HASH_SHA1 /* SHA1 (default) */;
4693 /* name and culture are pointers into the image tables, but we need
4694 * real malloc'd strings (so that we can g_free() them later from
4695 * Mono.RuntimeMarshal.FreeAssemblyName) */
4696 aname->name = g_strdup (aname->name);
4697 aname->culture = g_strdup (aname->culture);
4698 /* Don't need the hash value in managed */
4699 aname->hash_value = NULL;
4700 aname->hash_len = 0;
4701 g_assert (aname->public_key == NULL);
4703 /* note: this function doesn't return the codebase on purpose (i.e. it can
4704 be used under partial trust as path information isn't present). */
4708 ICALL_EXPORT GPtrArray*
4709 ves_icall_System_Reflection_Assembly_InternalGetReferencedAssemblies (MonoReflectionAssemblyHandle assembly, MonoError *error)
4711 mono_error_init (error);
4712 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly);
4713 MonoAssembly *ass = MONO_HANDLE_GETVAL(assembly, assembly);
4714 MonoImage *image = ass->image;
4716 MonoTableInfo *t = &image->tables [MONO_TABLE_ASSEMBLYREF];
4717 int count = t->rows;
4719 GPtrArray *result = g_ptr_array_sized_new (count);
4721 for (int i = 0; i < count; i++) {
4722 MonoAssemblyName *aname = create_referenced_assembly_name (domain, image, t, i, error);
4725 g_ptr_array_add (result, aname);
4730 /* move this in some file in mono/util/ */
4732 g_concat_dir_and_file (const char *dir, const char *file)
4734 g_return_val_if_fail (dir != NULL, NULL);
4735 g_return_val_if_fail (file != NULL, NULL);
4738 * If the directory name doesn't have a / on the end, we need
4739 * to add one so we get a proper path to the file
4741 if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
4742 return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
4744 return g_strconcat (dir, file, NULL);
4748 ves_icall_System_Reflection_Assembly_GetManifestResourceInternal (MonoReflectionAssemblyHandle assembly_h, MonoStringHandle name, gint32 *size, MonoReflectionModuleHandleOut ref_module, MonoError *error)
4750 mono_error_init (error);
4751 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4752 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4753 MonoTableInfo *table = &assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4755 guint32 cols [MONO_MANIFEST_SIZE];
4756 guint32 impl, file_idx;
4760 char *n = mono_string_handle_to_utf8 (name, error);
4761 return_val_if_nok (error, NULL);
4763 for (i = 0; i < table->rows; ++i) {
4764 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4765 val = mono_metadata_string_heap (assembly->image, cols [MONO_MANIFEST_NAME]);
4766 if (strcmp (val, n) == 0)
4770 if (i == table->rows)
4773 impl = cols [MONO_MANIFEST_IMPLEMENTATION];
4776 * this code should only be called after obtaining the
4777 * ResourceInfo and handling the other cases.
4779 g_assert ((impl & MONO_IMPLEMENTATION_MASK) == MONO_IMPLEMENTATION_FILE);
4780 file_idx = impl >> MONO_IMPLEMENTATION_BITS;
4782 module = mono_image_load_file_for_image_checked (assembly->image, file_idx, error);
4783 if (!is_ok (error) || !module)
4787 module = assembly->image;
4790 MonoReflectionModuleHandle rm = mono_module_get_object_handle (domain, module, error);
4793 MONO_HANDLE_ASSIGN (ref_module, rm);
4795 return (void*)mono_image_get_resource (module, cols [MONO_MANIFEST_OFFSET], (guint32*)size);
4799 get_manifest_resource_info_internal (MonoReflectionAssemblyHandle assembly_h, MonoStringHandle name, MonoManifestResourceInfoHandle info, MonoError *error)
4801 HANDLE_FUNCTION_ENTER ();
4802 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4803 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4804 MonoTableInfo *table = &assembly->image->tables [MONO_TABLE_MANIFESTRESOURCE];
4806 guint32 cols [MONO_MANIFEST_SIZE];
4807 guint32 file_cols [MONO_FILE_SIZE];
4811 gboolean result = FALSE;
4813 n = mono_string_handle_to_utf8 (name, error);
4817 for (i = 0; i < table->rows; ++i) {
4818 mono_metadata_decode_row (table, i, cols, MONO_MANIFEST_SIZE);
4819 val = mono_metadata_string_heap (assembly->image, cols [MONO_MANIFEST_NAME]);
4820 if (strcmp (val, n) == 0)
4824 if (i == table->rows)
4827 if (!cols [MONO_MANIFEST_IMPLEMENTATION]) {
4828 MONO_HANDLE_SETVAL (info, location, guint32, RESOURCE_LOCATION_EMBEDDED | RESOURCE_LOCATION_IN_MANIFEST);
4831 switch (cols [MONO_MANIFEST_IMPLEMENTATION] & MONO_IMPLEMENTATION_MASK) {
4832 case MONO_IMPLEMENTATION_FILE:
4833 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4834 table = &assembly->image->tables [MONO_TABLE_FILE];
4835 mono_metadata_decode_row (table, i - 1, file_cols, MONO_FILE_SIZE);
4836 val = mono_metadata_string_heap (assembly->image, file_cols [MONO_FILE_NAME]);
4837 MONO_HANDLE_SET (info, filename, mono_string_new_handle (domain, val, error));
4838 if (file_cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA)
4839 MONO_HANDLE_SETVAL (info, location, guint32, 0);
4841 MONO_HANDLE_SETVAL (info, location, guint32, RESOURCE_LOCATION_EMBEDDED);
4844 case MONO_IMPLEMENTATION_ASSEMBLYREF:
4845 i = cols [MONO_MANIFEST_IMPLEMENTATION] >> MONO_IMPLEMENTATION_BITS;
4846 mono_assembly_load_reference (assembly->image, i - 1);
4847 if (assembly->image->references [i - 1] == REFERENCE_MISSING) {
4848 mono_error_set_assembly_load (error, NULL, "Assembly %d referenced from assembly %s not found ", i - 1, assembly->image->name);
4851 MonoReflectionAssemblyHandle assm_obj = mono_assembly_get_object_handle (mono_domain_get (), assembly->image->references [i - 1], error);
4854 MONO_HANDLE_SET (info, assembly, assm_obj);
4856 /* Obtain info recursively */
4857 get_manifest_resource_info_internal (assm_obj, name, info, error);
4860 guint32 location = MONO_HANDLE_GETVAL (info, location);
4861 location |= RESOURCE_LOCATION_ANOTHER_ASSEMBLY;
4862 MONO_HANDLE_SETVAL (info, location, guint32, location);
4865 case MONO_IMPLEMENTATION_EXP_TYPE:
4866 g_assert_not_reached ();
4873 HANDLE_FUNCTION_RETURN_VAL (result);
4876 ICALL_EXPORT gboolean
4877 ves_icall_System_Reflection_Assembly_GetManifestResourceInfoInternal (MonoReflectionAssemblyHandle assembly_h, MonoStringHandle name, MonoManifestResourceInfoHandle info_h, MonoError *error)
4879 mono_error_init (error);
4880 return get_manifest_resource_info_internal (assembly_h, name, info_h, error);
4884 add_filename_to_files_array (MonoDomain *domain, MonoAssembly * assembly, MonoTableInfo *table, int i, MonoArrayHandle dest, int dest_idx, MonoError *error)
4886 HANDLE_FUNCTION_ENTER();
4887 mono_error_init (error);
4888 const char *val = mono_metadata_string_heap (assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4889 char *n = g_concat_dir_and_file (assembly->basedir, val);
4890 MonoStringHandle str = mono_string_new_handle (domain, n, error);
4894 MONO_HANDLE_ARRAY_SETREF (dest, dest_idx, str);
4896 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
4899 ICALL_EXPORT MonoObjectHandle
4900 ves_icall_System_Reflection_Assembly_GetFilesInternal (MonoReflectionAssemblyHandle assembly_h, MonoStringHandle name, MonoBoolean resource_modules, MonoError *error)
4902 mono_error_init (error);
4903 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_h);
4904 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
4905 MonoTableInfo *table = &assembly->image->tables [MONO_TABLE_FILE];
4908 /* check hash if needed */
4909 if (!MONO_HANDLE_IS_NULL(name)) {
4910 char *n = mono_string_handle_to_utf8 (name, error);
4914 for (i = 0; i < table->rows; ++i) {
4915 const char *val = mono_metadata_string_heap (assembly->image, mono_metadata_decode_row_col (table, i, MONO_FILE_NAME));
4916 if (strcmp (val, n) == 0) {
4918 n = g_concat_dir_and_file (assembly->basedir, val);
4919 MonoStringHandle fn = mono_string_new_handle (domain, n, error);
4923 return MONO_HANDLE_CAST (MonoObject, fn);
4931 for (i = 0; i < table->rows; ++i) {
4932 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA))
4936 MonoArrayHandle result = mono_array_new_handle (domain, mono_defaults.string_class, count, error);
4941 for (i = 0; i < table->rows; ++i) {
4942 if (resource_modules || !(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
4943 if (!add_filename_to_files_array (domain, assembly, table, i, result, count, error))
4948 return MONO_HANDLE_CAST (MonoObject, result);
4954 add_module_to_modules_array (MonoDomain *domain, MonoArrayHandle dest, int *dest_idx, MonoImage* module, MonoError *error)
4956 HANDLE_FUNCTION_ENTER ();
4957 mono_error_init (error);
4959 MonoReflectionModuleHandle rm = mono_module_get_object_handle (domain, module, error);
4963 MONO_HANDLE_ARRAY_SETREF (dest, *dest_idx, rm);
4968 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
4972 add_file_to_modules_array (MonoDomain *domain, MonoArrayHandle dest, int dest_idx, MonoImage *image, MonoTableInfo *table, int table_idx, MonoError *error)
4974 HANDLE_FUNCTION_ENTER ();
4975 mono_error_init (error);
4977 guint32 cols [MONO_FILE_SIZE];
4978 mono_metadata_decode_row (table, table_idx, cols, MONO_FILE_SIZE);
4979 if (cols [MONO_FILE_FLAGS] & FILE_CONTAINS_NO_METADATA) {
4980 MonoReflectionModuleHandle rm = mono_module_file_get_object_handle (domain, image, table_idx, error);
4983 MONO_HANDLE_ARRAY_SETREF (dest, dest_idx, rm);
4985 MonoImage *m = mono_image_load_file_for_image_checked (image, table_idx + 1, error);
4989 const char *filename = mono_metadata_string_heap (image, cols [MONO_FILE_NAME]);
4990 mono_error_set_assembly_load (error, g_strdup (filename), "%s", "");
4993 MonoReflectionModuleHandle rm = mono_module_get_object_handle (domain, m, error);
4996 MONO_HANDLE_ARRAY_SETREF (dest, dest_idx, rm);
5000 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
5003 ICALL_EXPORT MonoArrayHandle
5004 ves_icall_System_Reflection_Assembly_GetModulesInternal (MonoReflectionAssemblyHandle assembly_h, MonoError *error)
5006 mono_error_init (error);
5007 MonoDomain *domain = mono_domain_get();
5008 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
5010 int i, j, file_count = 0;
5011 MonoImage **modules;
5012 guint32 module_count, real_module_count;
5013 MonoTableInfo *table;
5014 MonoImage *image = assembly->image;
5016 g_assert (image != NULL);
5017 g_assert (!assembly_is_dynamic (assembly));
5019 table = &image->tables [MONO_TABLE_FILE];
5020 file_count = table->rows;
5022 modules = image->modules;
5023 module_count = image->module_count;
5025 real_module_count = 0;
5026 for (i = 0; i < module_count; ++i)
5028 real_module_count ++;
5030 klass = mono_class_get_module_class ();
5031 MonoArrayHandle res = mono_array_new_handle (domain, klass, 1 + real_module_count + file_count, error);
5035 MonoReflectionModuleHandle image_obj = mono_module_get_object_handle (domain, image, error);
5039 MONO_HANDLE_ARRAY_SETREF (res, 0, image_obj);
5042 for (i = 0; i < module_count; ++i)
5043 if (!add_module_to_modules_array (domain, res, &j, modules[i], error))
5046 for (i = 0; i < file_count; ++i, ++j) {
5047 if (!add_file_to_modules_array (domain, res, j, image, table, i, error))
5053 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5056 ICALL_EXPORT MonoReflectionMethod*
5057 ves_icall_GetCurrentMethod (void)
5059 MonoReflectionMethod *res = NULL;
5062 MonoMethod *m = mono_method_get_last_managed ();
5065 mono_set_pending_exception (mono_get_exception_not_supported ("Stack walks are not supported on this platform."));
5069 while (m->is_inflated)
5070 m = ((MonoMethodInflated*)m)->declaring;
5072 res = mono_method_get_object_checked (mono_domain_get (), m, NULL, &error);
5073 mono_error_set_pending_exception (&error);
5079 mono_method_get_equivalent_method (MonoMethod *method, MonoClass *klass)
5082 if (method->is_inflated && ((MonoMethodInflated*)method)->context.method_inst) {
5085 MonoMethodInflated *inflated = (MonoMethodInflated*)method;
5086 //method is inflated, we should inflate it on the other class
5087 MonoGenericContext ctx;
5088 ctx.method_inst = inflated->context.method_inst;
5089 ctx.class_inst = inflated->context.class_inst;
5090 if (mono_class_is_ginst (klass))
5091 ctx.class_inst = mono_class_get_generic_class (klass)->context.class_inst;
5092 else if (mono_class_is_gtd (klass))
5093 ctx.class_inst = mono_class_get_generic_container (klass)->context.class_inst;
5094 result = mono_class_inflate_generic_method_full_checked (inflated->declaring, klass, &ctx, &error);
5095 g_assert (mono_error_ok (&error)); /* FIXME don't swallow the error */
5099 mono_class_setup_methods (method->klass);
5100 if (mono_class_has_failure (method->klass))
5102 int mcount = mono_class_get_method_count (method->klass);
5103 for (i = 0; i < mcount; ++i) {
5104 if (method->klass->methods [i] == method) {
5109 mono_class_setup_methods (klass);
5110 if (mono_class_has_failure (klass))
5112 g_assert (offset >= 0 && offset < mono_class_get_method_count (klass));
5113 return klass->methods [offset];
5116 ICALL_EXPORT MonoReflectionMethod*
5117 ves_icall_System_Reflection_MethodBase_GetMethodFromHandleInternalType_native (MonoMethod *method, MonoType *type, MonoBoolean generic_check)
5119 MonoReflectionMethod *res = NULL;
5122 if (type && generic_check) {
5123 klass = mono_class_from_mono_type (type);
5124 if (mono_class_get_generic_type_definition (method->klass) != mono_class_get_generic_type_definition (klass))
5127 if (method->klass != klass) {
5128 method = mono_method_get_equivalent_method (method, klass);
5133 klass = mono_class_from_mono_type (type);
5135 klass = method->klass;
5136 res = mono_method_get_object_checked (mono_domain_get (), method, klass, &error);
5137 mono_error_set_pending_exception (&error);
5141 ICALL_EXPORT MonoReflectionMethodBodyHandle
5142 ves_icall_System_Reflection_MethodBase_GetMethodBodyInternal (MonoMethod *method, MonoError *error)
5144 mono_error_init (error);
5145 return mono_method_body_get_object_handle (mono_domain_get (), method, error);
5148 ICALL_EXPORT MonoReflectionAssemblyHandle
5149 ves_icall_System_Reflection_Assembly_GetExecutingAssembly (MonoError *error)
5151 mono_error_init (error);
5153 MonoMethod *dest = NULL;
5154 mono_stack_walk_no_il (get_executing, &dest);
5156 return mono_assembly_get_object_handle (mono_domain_get (), dest->klass->image->assembly, error);
5160 ICALL_EXPORT MonoReflectionAssemblyHandle
5161 ves_icall_System_Reflection_Assembly_GetEntryAssembly (MonoError *error)
5163 mono_error_init (error);
5165 MonoDomain* domain = mono_domain_get ();
5167 if (!domain->entry_assembly)
5168 return MONO_HANDLE_CAST (MonoReflectionAssembly, NULL_HANDLE);
5170 return mono_assembly_get_object_handle (domain, domain->entry_assembly, error);
5173 ICALL_EXPORT MonoReflectionAssemblyHandle
5174 ves_icall_System_Reflection_Assembly_GetCallingAssembly (MonoError *error)
5176 mono_error_init (error);
5181 mono_stack_walk_no_il (get_executing, &dest);
5183 mono_stack_walk_no_il (get_caller_no_reflection, &dest);
5187 mono_error_set_not_supported (error, "Stack walks are not supported on this platform.");
5188 return MONO_HANDLE_CAST (MonoReflectionAssembly, NULL_HANDLE);
5190 return mono_assembly_get_object_handle (mono_domain_get (), dest->klass->image->assembly, error);
5193 ICALL_EXPORT MonoStringHandle
5194 ves_icall_System_RuntimeType_getFullName (MonoReflectionTypeHandle object, gboolean full_name,
5195 gboolean assembly_qualified, MonoError *error)
5197 MonoDomain *domain = mono_object_domain (MONO_HANDLE_RAW (object));
5198 MonoType *type = MONO_HANDLE_RAW (object)->type;
5199 MonoTypeNameFormat format;
5200 MonoStringHandle res;
5204 format = assembly_qualified ?
5205 MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED :
5206 MONO_TYPE_NAME_FORMAT_FULL_NAME;
5208 format = MONO_TYPE_NAME_FORMAT_REFLECTION;
5210 name = mono_type_get_name_full (type, format);
5212 return NULL_HANDLE_STRING;
5214 if (full_name && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR)) {
5216 return NULL_HANDLE_STRING;
5219 res = mono_string_new_handle (domain, name, error);
5226 vell_icall_RuntimeType_get_core_clr_security_level (MonoReflectionType *rfield)
5229 MonoClass *klass = mono_class_from_mono_type (rfield->type);
5231 mono_class_init_checked (klass, &error);
5232 mono_error_set_pending_exception (&error);
5233 return mono_security_core_clr_class_level (klass);
5237 ves_icall_MonoField_get_core_clr_security_level (MonoReflectionField *rfield)
5239 MonoClassField *field = rfield->field;
5240 return mono_security_core_clr_field_level (field, TRUE);
5244 ves_icall_MonoMethod_get_core_clr_security_level (MonoReflectionMethod *rfield)
5246 MonoMethod *method = rfield->method;
5247 return mono_security_core_clr_method_level (method, TRUE);
5250 ICALL_EXPORT MonoStringHandle
5251 ves_icall_System_Reflection_Assembly_get_fullName (MonoReflectionAssemblyHandle assembly, MonoError *error)
5253 mono_error_init (error);
5254 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly);
5255 MonoAssembly *mass = MONO_HANDLE_GETVAL (assembly, assembly);
5258 name = mono_stringify_assembly_name (&mass->aname);
5259 MonoStringHandle res = mono_string_new_handle (domain, name, error);
5264 ICALL_EXPORT MonoAssemblyName *
5265 ves_icall_System_Reflection_AssemblyName_GetNativeName (MonoAssembly *mass)
5267 return &mass->aname;
5271 ves_icall_System_Reflection_Assembly_InternalGetAssemblyName (MonoStringHandle fname, MonoAssemblyName *name, MonoStringHandleOut normalized_codebase, MonoError *error)
5274 MonoImageOpenStatus status = MONO_IMAGE_OK;
5275 char *codebase = NULL;
5280 mono_error_init (error);
5282 filename = mono_string_handle_to_utf8 (fname, error);
5283 return_if_nok (error);
5285 dirname = g_path_get_dirname (filename);
5286 replace_shadow_path (mono_domain_get (), dirname, &filename);
5289 image = mono_image_open (filename, &status);
5292 if (status == MONO_IMAGE_IMAGE_INVALID)
5293 mono_error_set_bad_image_name (error, g_strdup (filename), "%s", "");
5295 mono_error_set_assembly_load (error, g_strdup (filename), "%s", "");
5300 res = mono_assembly_fill_assembly_name_full (image, name, TRUE);
5302 mono_image_close (image);
5304 mono_error_set_argument (error, "assemblyFile", "The file does not contain a manifest");
5308 if (filename != NULL && *filename != '\0') {
5311 codebase = g_strdup (filename);
5313 mono_icall_make_platform_path (codebase);
5315 const gchar *prepend = mono_icall_get_file_path_prefix (codebase);
5317 result = g_strconcat (prepend, codebase, NULL);
5321 MONO_HANDLE_ASSIGN (normalized_codebase, mono_string_new_handle (mono_domain_get (), codebase, error));
5324 mono_image_close (image);
5328 ICALL_EXPORT MonoBoolean
5329 ves_icall_System_Reflection_Assembly_LoadPermissions (MonoReflectionAssemblyHandle assembly_h,
5330 char **minimum, guint32 *minLength, char **optional, guint32 *optLength, char **refused, guint32 *refLength, MonoError *error)
5332 mono_error_init (error);
5333 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly);
5334 MonoBoolean result = FALSE;
5335 MonoDeclSecurityEntry entry;
5337 /* SecurityAction.RequestMinimum */
5338 if (mono_declsec_get_assembly_action (assembly, SECURITY_ACTION_REQMIN, &entry)) {
5339 *minimum = entry.blob;
5340 *minLength = entry.size;
5343 /* SecurityAction.RequestOptional */
5344 if (mono_declsec_get_assembly_action (assembly, SECURITY_ACTION_REQOPT, &entry)) {
5345 *optional = entry.blob;
5346 *optLength = entry.size;
5349 /* SecurityAction.RequestRefuse */
5350 if (mono_declsec_get_assembly_action (assembly, SECURITY_ACTION_REQREFUSE, &entry)) {
5351 *refused = entry.blob;
5352 *refLength = entry.size;
5360 mono_module_type_is_visible (MonoTableInfo *tdef, MonoImage *image, int type)
5362 guint32 attrs, visibility;
5364 attrs = mono_metadata_decode_row_col (tdef, type - 1, MONO_TYPEDEF_FLAGS);
5365 visibility = attrs & TYPE_ATTRIBUTE_VISIBILITY_MASK;
5366 if (visibility != TYPE_ATTRIBUTE_PUBLIC && visibility != TYPE_ATTRIBUTE_NESTED_PUBLIC)
5369 } while ((type = mono_metadata_token_index (mono_metadata_nested_in_typedef (image, type))));
5375 image_get_type (MonoDomain *domain, MonoImage *image, MonoTableInfo *tdef, int table_idx, int count, MonoArrayHandle res, MonoArrayHandle exceptions, MonoBoolean exportedOnly, MonoError *error)
5377 mono_error_init (error);
5378 HANDLE_FUNCTION_ENTER ();
5379 MonoError klass_error;
5380 MonoClass *klass = mono_class_get_checked (image, table_idx | MONO_TOKEN_TYPE_DEF, &klass_error);
5383 MonoReflectionTypeHandle rt = mono_type_get_object_handle (domain, &klass->byval_arg, error);
5384 return_if_nok (error);
5386 MONO_HANDLE_ARRAY_SETREF (res, count, rt);
5388 MonoException *ex = mono_error_convert_to_exception (error);
5389 MONO_HANDLE_ARRAY_SETRAW (exceptions, count, ex);
5391 HANDLE_FUNCTION_RETURN ();
5394 static MonoArrayHandle
5395 mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoArrayHandleOut exceptions, MonoBoolean exportedOnly, MonoError *error)
5397 MonoTableInfo *tdef = &image->tables [MONO_TABLE_TYPEDEF];
5400 mono_error_init (error);
5402 /* we start the count from 1 because we skip the special type <Module> */
5405 for (i = 1; i < tdef->rows; ++i) {
5406 if (mono_module_type_is_visible (tdef, image, i + 1))
5410 count = tdef->rows - 1;
5412 MonoArrayHandle res = mono_array_new_handle (domain, mono_defaults.runtimetype_class, count, error);
5413 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5414 MONO_HANDLE_ASSIGN (exceptions, mono_array_new_handle (domain, mono_defaults.exception_class, count, error));
5415 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5417 for (i = 1; i < tdef->rows; ++i) {
5418 if (!exportedOnly || mono_module_type_is_visible (tdef, image, i+1)) {
5419 image_get_type (domain, image, tdef, i + 1, count, res, exceptions, exportedOnly, error);
5420 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5429 append_module_types (MonoDomain *domain, MonoArrayHandleOut res, MonoArrayHandleOut exceptions, MonoImage *image, MonoBoolean exportedOnly, MonoError *error)
5431 HANDLE_FUNCTION_ENTER ();
5432 mono_error_init (error);
5433 MonoArrayHandle ex2 = MONO_HANDLE_NEW (MonoArray, NULL);
5434 MonoArrayHandle res2 = mono_module_get_types (domain, image, ex2, exportedOnly, error);
5438 /* Append the new types to the end of the array */
5439 if (mono_array_handle_length (res2) > 0) {
5442 len1 = mono_array_handle_length (res);
5443 len2 = mono_array_handle_length (res2);
5445 MonoArrayHandle res3 = mono_array_new_handle (domain, mono_defaults.runtimetype_class, len1 + len2, error);
5449 mono_array_handle_memcpy_refs (res3, 0, res, 0, len1);
5450 mono_array_handle_memcpy_refs (res3, len1, res2, 0, len2);
5451 MONO_HANDLE_ASSIGN (res, res3);
5453 MonoArrayHandle ex3 = mono_array_new_handle (domain, mono_defaults.runtimetype_class, len1 + len2, error);
5457 mono_array_handle_memcpy_refs (ex3, 0, exceptions, 0, len1);
5458 mono_array_handle_memcpy_refs (ex3, len1, ex2, 0, len2);
5459 MONO_HANDLE_ASSIGN (exceptions, ex3);
5462 HANDLE_FUNCTION_RETURN ();
5466 set_class_failure_in_array (MonoArrayHandle exl, int i, MonoClass *klass)
5468 HANDLE_FUNCTION_ENTER ();
5469 MonoError unboxed_error;
5470 mono_error_init (&unboxed_error);
5471 mono_error_set_for_class_failure (&unboxed_error, klass);
5473 MonoExceptionHandle exc = MONO_HANDLE_NEW (MonoException, mono_error_convert_to_exception (&unboxed_error));
5474 MONO_HANDLE_ARRAY_SETREF (exl, i, exc);
5475 HANDLE_FUNCTION_RETURN ();
5478 ICALL_EXPORT MonoArrayHandle
5479 ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssemblyHandle assembly_handle, MonoBoolean exportedOnly, MonoError *error)
5481 MonoArrayHandle exceptions = MONO_HANDLE_NEW(MonoArray, NULL);
5484 MonoDomain *domain = MONO_HANDLE_DOMAIN (assembly_handle);
5485 MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_handle, assembly);
5487 g_assert (!assembly_is_dynamic (assembly));
5488 MonoImage *image = assembly->image;
5489 MonoTableInfo *table = &image->tables [MONO_TABLE_FILE];
5490 MonoArrayHandle res = mono_module_get_types (domain, image, exceptions, exportedOnly, error);
5491 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5493 /* Append data from all modules in the assembly */
5494 for (i = 0; i < table->rows; ++i) {
5495 if (!(mono_metadata_decode_row_col (table, i, MONO_FILE_FLAGS) & FILE_CONTAINS_NO_METADATA)) {
5496 MonoImage *loaded_image = mono_assembly_load_module_checked (image->assembly, i + 1, error);
5497 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5500 append_module_types (domain, res, exceptions, loaded_image, exportedOnly, error);
5501 return_val_if_nok (error, MONO_HANDLE_CAST (MonoArray, NULL_HANDLE));
5506 /* the ReflectionTypeLoadException must have all the types (Types property),
5507 * NULL replacing types which throws an exception. The LoaderException must
5508 * contain all exceptions for NULL items.
5511 int len = mono_array_handle_length (res);
5515 MonoReflectionTypeHandle t = MONO_HANDLE_NEW (MonoReflectionType, NULL);
5516 for (i = 0; i < len; i++) {
5517 MONO_HANDLE_ARRAY_GETREF (t, res, i);
5519 if (!MONO_HANDLE_IS_NULL (t)) {
5520 MonoClass *klass = mono_type_get_class (MONO_HANDLE_GETVAL (t, type));
5521 if ((klass != NULL) && mono_class_has_failure (klass)) {
5522 /* keep the class in the list */
5523 list = g_list_append (list, klass);
5524 /* and replace Type with NULL */
5525 MONO_HANDLE_ARRAY_SETRAW (res, i, NULL);
5532 if (list || ex_count) {
5534 int j, length = g_list_length (list) + ex_count;
5536 MonoArrayHandle exl = mono_array_new_handle (domain, mono_defaults.exception_class, length, error);
5537 if (!is_ok (error)) {
5539 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5541 /* Types for which mono_class_get_checked () succeeded */
5542 MonoExceptionHandle exc = MONO_HANDLE_NEW (MonoException, NULL);
5543 for (i = 0, tmp = list; tmp; i++, tmp = tmp->next) {
5544 set_class_failure_in_array (exl, i, (MonoClass*)tmp->data);
5546 /* Types for which it don't */
5547 for (j = 0; j < mono_array_handle_length (exceptions); ++j) {
5548 MONO_HANDLE_ARRAY_GETREF (exc, exceptions, j);
5549 if (!MONO_HANDLE_IS_NULL (exc)) {
5550 g_assert (i < length);
5551 MONO_HANDLE_ARRAY_SETREF (exl, i, exc);
5558 MONO_HANDLE_ASSIGN (exc, mono_get_exception_reflection_type_load_checked (res, exl, error));
5559 if (!is_ok (error)) {
5560 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5562 mono_error_set_exception_handle (error, exc);
5563 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
5570 ves_icall_Mono_RuntimeMarshal_FreeAssemblyName (MonoAssemblyName *aname, gboolean free_struct)
5572 mono_assembly_name_free (aname);
5577 ICALL_EXPORT gboolean
5578 ves_icall_System_Reflection_AssemblyName_ParseAssemblyName (const char *name, MonoAssemblyName *aname, gboolean *is_version_definited, gboolean *is_token_defined)
5580 *is_version_definited = *is_token_defined = FALSE;
5582 return mono_assembly_name_parse_full (name, aname, TRUE, is_version_definited, is_token_defined);
5585 ICALL_EXPORT MonoReflectionTypeHandle
5586 ves_icall_System_Reflection_Module_GetGlobalType (MonoReflectionModuleHandle module, MonoError *error)
5588 MonoDomain *domain = MONO_HANDLE_DOMAIN (module);
5589 MonoImage *image = MONO_HANDLE_GETVAL (module, image);
5594 MonoReflectionTypeHandle ret = MONO_HANDLE_CAST (MonoReflectionType, NULL_HANDLE);
5596 if (image_is_dynamic (image) && ((MonoDynamicImage*)image)->initial_image)
5597 /* These images do not have a global type */
5600 klass = mono_class_get_checked (image, 1 | MONO_TOKEN_TYPE_DEF, error);
5604 ret = mono_type_get_object_handle (domain, &klass->byval_arg, error);
5610 ves_icall_System_Reflection_Module_Close (MonoReflectionModuleHandle module, MonoError *error)
5612 /*if (module->image)
5613 mono_image_close (module->image);*/
5616 ICALL_EXPORT MonoStringHandle
5617 ves_icall_System_Reflection_Module_GetGuidInternal (MonoReflectionModuleHandle refmodule, MonoError *error)
5619 MonoDomain *domain = MONO_HANDLE_DOMAIN (refmodule);
5620 MonoImage *image = MONO_HANDLE_GETVAL (refmodule, image);
5623 return mono_string_new_handle (domain, image->guid, error);
5627 static inline gpointer
5628 mono_icall_module_get_hinstance (MonoReflectionModuleHandle module)
5630 return (gpointer) (-1);
5632 #endif /* HOST_WIN32 */
5634 ICALL_EXPORT gpointer
5635 ves_icall_System_Reflection_Module_GetHINSTANCE (MonoReflectionModuleHandle module, MonoError *error)
5637 return mono_icall_module_get_hinstance (module);
5641 ves_icall_System_Reflection_Module_GetPEKind (MonoImage *image, gint32 *pe_kind, gint32 *machine, MonoError *error)
5643 if (image_is_dynamic (image)) {
5644 MonoDynamicImage *dyn = (MonoDynamicImage*)image;
5645 *pe_kind = dyn->pe_kind;
5646 *machine = dyn->machine;
5649 *pe_kind = ((MonoCLIImageInfo*)(image->image_info))->cli_cli_header.ch_flags & 0x3;
5650 *machine = ((MonoCLIImageInfo*)(image->image_info))->cli_header.coff.coff_machine;
5655 ves_icall_System_Reflection_Module_GetMDStreamVersion (MonoImage *image, MonoError *error)
5657 return (image->md_version_major << 16) | (image->md_version_minor);
5660 ICALL_EXPORT MonoArrayHandle
5661 ves_icall_System_Reflection_Module_InternalGetTypes (MonoReflectionModuleHandle module, MonoError *error)
5663 mono_error_init (error);
5665 MonoImage *image = MONO_HANDLE_GETVAL (module, image);
5666 MonoDomain *domain = MONO_HANDLE_DOMAIN (module);
5669 MonoArrayHandle arr = mono_array_new_handle (domain, mono_defaults.runtimetype_class, 0, error);
5672 MonoArrayHandle exceptions = MONO_HANDLE_NEW (MonoArray, NULL);
5673 MonoArrayHandle res = mono_module_get_types (domain, image, exceptions, FALSE, error);
5674 return_val_if_nok (error, MONO_HANDLE_CAST(MonoArray, NULL_HANDLE));
5676 int n = mono_array_handle_length (exceptions);
5677 MonoExceptionHandle ex = MONO_HANDLE_NEW (MonoException, NULL);
5678 for (int i = 0; i < n; ++i) {
5679 MONO_HANDLE_ARRAY_GETREF(ex, exceptions, i);
5680 if (!MONO_HANDLE_IS_NULL (ex)) {
5681 mono_error_set_exception_handle (error, ex);
5682 return MONO_HANDLE_CAST(MonoArray, NULL_HANDLE);
5690 mono_memberref_is_method (MonoImage *image, guint32 token)
5692 if (!image_is_dynamic (image)) {
5693 guint32 cols [MONO_MEMBERREF_SIZE];
5695 mono_metadata_decode_row (&image->tables [MONO_TABLE_MEMBERREF], mono_metadata_token_index (token) - 1, cols, MONO_MEMBERREF_SIZE);
5696 sig = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
5697 mono_metadata_decode_blob_size (sig, &sig);
5698 return (*sig != 0x6);
5701 MonoClass *handle_class;
5703 if (!mono_lookup_dynamic_token_class (image, token, FALSE, &handle_class, NULL, &error)) {
5704 mono_error_cleanup (&error); /* just probing, ignore error */
5708 return mono_defaults.methodhandle_class == handle_class;
5712 static MonoGenericInst *
5713 get_generic_inst_from_array_handle (MonoArrayHandle type_args)
5715 int type_argc = mono_array_handle_length (type_args);
5716 int size = MONO_SIZEOF_GENERIC_INST + type_argc * sizeof (MonoType *);
5718 MonoGenericInst *ginst = (MonoGenericInst *)g_alloca (size);
5719 memset (ginst, 0, sizeof (MonoGenericInst));
5720 ginst->type_argc = type_argc;
5721 for (int i = 0; i < type_argc; i++) {
5722 MONO_HANDLE_ARRAY_GETVAL (ginst->type_argv[i], type_args, MonoType*, i);
5724 ginst->is_open = FALSE;
5725 for (int i = 0; i < type_argc; i++) {
5726 if (mono_class_is_open_constructed_type (ginst->type_argv[i])) {
5727 ginst->is_open = TRUE;
5732 return mono_metadata_get_canonical_generic_inst (ginst);
5736 init_generic_context_from_args_handles (MonoGenericContext *context, MonoArrayHandle type_args, MonoArrayHandle method_args)
5738 if (!MONO_HANDLE_IS_NULL (type_args)) {
5739 context->class_inst = get_generic_inst_from_array_handle (type_args);
5741 context->class_inst = NULL;
5743 if (!MONO_HANDLE_IS_NULL (method_args)) {
5744 context->method_inst = get_generic_inst_from_array_handle (method_args);
5746 context->method_inst = NULL;
5752 module_resolve_type_token (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *resolve_error, MonoError *error)
5754 HANDLE_FUNCTION_ENTER ();
5755 mono_error_init (error);
5756 MonoType *result = NULL;
5758 int table = mono_metadata_token_table (token);
5759 int index = mono_metadata_token_index (token);
5760 MonoGenericContext context;
5762 *resolve_error = ResolveTokenError_Other;
5764 /* Validate token */
5765 if ((table != MONO_TABLE_TYPEDEF) && (table != MONO_TABLE_TYPEREF) &&
5766 (table != MONO_TABLE_TYPESPEC)) {
5767 *resolve_error = ResolveTokenError_BadTable;
5771 if (image_is_dynamic (image)) {
5772 if ((table == MONO_TABLE_TYPEDEF) || (table == MONO_TABLE_TYPEREF)) {
5773 MonoError inner_error;
5774 klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &inner_error);
5775 mono_error_cleanup (&inner_error);
5776 result = klass ? &klass->byval_arg : NULL;
5780 init_generic_context_from_args_handles (&context, type_args, method_args);
5781 MonoError inner_error;
5782 klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &inner_error);
5783 mono_error_cleanup (&inner_error);
5784 result = klass ? &klass->byval_arg : NULL;
5788 if ((index <= 0) || (index > image->tables [table].rows)) {
5789 *resolve_error = ResolveTokenError_OutOfRange;
5793 init_generic_context_from_args_handles (&context, type_args, method_args);
5794 klass = mono_class_get_checked (image, token, error);
5796 klass = mono_class_inflate_generic_class_checked (klass, &context, error);
5801 result = &klass->byval_arg;
5803 HANDLE_FUNCTION_RETURN_VAL (result);
5806 ICALL_EXPORT MonoType*
5807 ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *resolve_error, MonoError *error)
5809 return module_resolve_type_token (image, token, type_args, method_args, resolve_error, error);
5813 module_resolve_method_token (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *resolve_error, MonoError *error)
5815 HANDLE_FUNCTION_ENTER ();
5816 mono_error_init (error);
5817 MonoMethod *method = NULL;
5818 int table = mono_metadata_token_table (token);
5819 int index = mono_metadata_token_index (token);
5820 MonoGenericContext context;
5822 *resolve_error = ResolveTokenError_Other;
5824 /* Validate token */
5825 if ((table != MONO_TABLE_METHOD) && (table != MONO_TABLE_METHODSPEC) &&
5826 (table != MONO_TABLE_MEMBERREF)) {
5827 *resolve_error = ResolveTokenError_BadTable;
5831 if (image_is_dynamic (image)) {
5832 if (table == MONO_TABLE_METHOD) {
5833 MonoError inner_error;
5834 method = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &inner_error);
5835 mono_error_cleanup (&inner_error);
5839 if ((table == MONO_TABLE_MEMBERREF) && !(mono_memberref_is_method (image, token))) {
5840 *resolve_error = ResolveTokenError_BadTable;
5844 init_generic_context_from_args_handles (&context, type_args, method_args);
5845 MonoError inner_error;
5846 method = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &inner_error);
5847 mono_error_cleanup (&inner_error);
5851 if ((index <= 0) || (index > image->tables [table].rows)) {
5852 *resolve_error = ResolveTokenError_OutOfRange;
5855 if ((table == MONO_TABLE_MEMBERREF) && (!mono_memberref_is_method (image, token))) {
5856 *resolve_error = ResolveTokenError_BadTable;
5860 init_generic_context_from_args_handles (&context, type_args, method_args);
5861 method = mono_get_method_checked (image, token, NULL, &context, error);
5864 HANDLE_FUNCTION_RETURN_VAL (method);
5867 ICALL_EXPORT MonoMethod*
5868 ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *resolve_error, MonoError *error)
5870 return module_resolve_method_token (image, token, type_args, method_args, resolve_error, error);
5873 ICALL_EXPORT MonoString*
5874 ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *resolve_error)
5877 int index = mono_metadata_token_index (token);
5879 *resolve_error = ResolveTokenError_Other;
5881 /* Validate token */
5882 if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
5883 *resolve_error = ResolveTokenError_BadTable;
5887 if (image_is_dynamic (image)) {
5888 MonoString * result = (MonoString *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
5889 mono_error_cleanup (&error);
5893 if ((index <= 0) || (index >= image->heap_us.size)) {
5894 *resolve_error = ResolveTokenError_OutOfRange;
5898 /* FIXME: What to do if the index points into the middle of a string ? */
5900 MonoString *result = mono_ldstr_checked (mono_domain_get (), image, index, &error);
5901 mono_error_set_pending_exception (&error);
5905 static MonoClassField*
5906 module_resolve_field_token (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *resolve_error, MonoError *error)
5908 HANDLE_FUNCTION_ENTER ();
5910 int table = mono_metadata_token_table (token);
5911 int index = mono_metadata_token_index (token);
5912 MonoGenericContext context;
5913 MonoClassField *field = NULL;
5915 mono_error_init (error);
5916 *resolve_error = ResolveTokenError_Other;
5918 /* Validate token */
5919 if ((table != MONO_TABLE_FIELD) && (table != MONO_TABLE_MEMBERREF)) {
5920 *resolve_error = ResolveTokenError_BadTable;
5924 if (image_is_dynamic (image)) {
5925 if (table == MONO_TABLE_FIELD) {
5926 MonoError inner_error;
5927 field = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &inner_error);
5928 mono_error_cleanup (&inner_error);
5932 if (mono_memberref_is_method (image, token)) {
5933 *resolve_error = ResolveTokenError_BadTable;
5937 init_generic_context_from_args_handles (&context, type_args, method_args);
5938 MonoError inner_error;
5939 field = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &inner_error);
5940 mono_error_cleanup (&inner_error);
5944 if ((index <= 0) || (index > image->tables [table].rows)) {
5945 *resolve_error = ResolveTokenError_OutOfRange;
5948 if ((table == MONO_TABLE_MEMBERREF) && (mono_memberref_is_method (image, token))) {
5949 *resolve_error = ResolveTokenError_BadTable;
5953 init_generic_context_from_args_handles (&context, type_args, method_args);
5954 field = mono_field_from_token_checked (image, token, &klass, &context, error);
5957 HANDLE_FUNCTION_RETURN_VAL (field);
5960 ICALL_EXPORT MonoClassField*
5961 ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *resolve_error, MonoError *error)
5963 return module_resolve_field_token (image, token, type_args, method_args, resolve_error, error);
5966 ICALL_EXPORT MonoObjectHandle
5967 ves_icall_System_Reflection_Module_ResolveMemberToken (MonoImage *image, guint32 token, MonoArrayHandle type_args, MonoArrayHandle method_args, MonoResolveTokenError *error, MonoError *merror)
5969 int table = mono_metadata_token_table (token);
5971 mono_error_init (merror);
5972 *error = ResolveTokenError_Other;
5975 case MONO_TABLE_TYPEDEF:
5976 case MONO_TABLE_TYPEREF:
5977 case MONO_TABLE_TYPESPEC: {
5978 MonoType *t = module_resolve_type_token (image, token, type_args, method_args, error, merror);
5980 return MONO_HANDLE_CAST (MonoObject, mono_type_get_object_handle (mono_domain_get (), t, merror));
5985 case MONO_TABLE_METHOD:
5986 case MONO_TABLE_METHODSPEC: {
5987 MonoMethod *m = module_resolve_method_token (image, token, type_args, method_args, error, merror);
5989 return MONO_HANDLE_CAST (MonoObject, mono_method_get_object_handle (mono_domain_get (), m, m->klass, merror));
5993 case MONO_TABLE_FIELD: {
5994 MonoClassField *f = module_resolve_field_token (image, token, type_args, method_args, error, merror);
5996 return MONO_HANDLE_CAST (MonoObject, mono_field_get_object_handle (mono_domain_get (), f->parent, f, merror));
6001 case MONO_TABLE_MEMBERREF:
6002 if (mono_memberref_is_method (image, token)) {
6003 MonoMethod *m = module_resolve_method_token (image, token, type_args, method_args, error, merror);
6005 return MONO_HANDLE_CAST (MonoObject, mono_method_get_object_handle (mono_domain_get (), m, m->klass, merror));
6010 MonoClassField *f = module_resolve_field_token (image, token, type_args, method_args, error, merror);
6012 return MONO_HANDLE_CAST (MonoObject, mono_field_get_object_handle (mono_domain_get (), f->parent, f, merror));
6020 *error = ResolveTokenError_BadTable;
6026 ICALL_EXPORT MonoArray*
6027 ves_icall_System_Reflection_Module_ResolveSignature (MonoImage *image, guint32 token, MonoResolveTokenError *resolve_error)
6030 int table = mono_metadata_token_table (token);
6031 int idx = mono_metadata_token_index (token);
6032 MonoTableInfo *tables = image->tables;
6037 *resolve_error = ResolveTokenError_OutOfRange;
6039 /* FIXME: Support other tables ? */
6040 if (table != MONO_TABLE_STANDALONESIG)
6043 if (image_is_dynamic (image))
6046 if ((idx == 0) || (idx > tables [MONO_TABLE_STANDALONESIG].rows))
6049 sig = mono_metadata_decode_row_col (&tables [MONO_TABLE_STANDALONESIG], idx - 1, 0);
6051 ptr = mono_metadata_blob_heap (image, sig);
6052 len = mono_metadata_decode_blob_size (ptr, &ptr);
6054 res = mono_array_new_checked (mono_domain_get (), mono_defaults.byte_class, len, &error);
6055 if (mono_error_set_pending_exception (&error))
6057 memcpy (mono_array_addr (res, guint8, 0), ptr, len);
6061 ICALL_EXPORT MonoBoolean
6062 ves_icall_RuntimeTypeHandle_IsArray (MonoReflectionType *t)
6068 res = !type->byref && (type->type == MONO_TYPE_ARRAY || type->type == MONO_TYPE_SZARRAY);
6074 check_for_invalid_type (MonoClass *klass, MonoError *error)
6078 mono_error_init (error);
6080 if (klass->byval_arg.type != MONO_TYPE_TYPEDBYREF)
6083 name = mono_type_get_full_name (klass);
6084 mono_error_set_type_load_name (error, name, g_strdup (""), "");
6086 ICALL_EXPORT MonoReflectionType *
6087 ves_icall_RuntimeType_make_array_type (MonoReflectionType *type, int rank)
6090 MonoReflectionType *ret;
6091 MonoClass *klass, *aklass;
6093 klass = mono_class_from_mono_type (type->type);
6094 check_for_invalid_type (klass, &error);
6095 if (mono_error_set_pending_exception (&error))
6098 if (rank == 0) //single dimentional array
6099 aklass = mono_array_class_get (klass, 1);
6101 aklass = mono_bounded_array_class_get (klass, rank, TRUE);
6103 ret = mono_type_get_object_checked (mono_object_domain (type), &aklass->byval_arg, &error);
6104 mono_error_set_pending_exception (&error);
6109 ICALL_EXPORT MonoReflectionType *
6110 ves_icall_RuntimeType_make_byref_type (MonoReflectionType *type)
6113 MonoReflectionType *ret;
6116 klass = mono_class_from_mono_type (type->type);
6117 mono_class_init_checked (klass, &error);
6118 if (mono_error_set_pending_exception (&error))
6121 check_for_invalid_type (klass, &error);
6122 if (mono_error_set_pending_exception (&error))
6125 ret = mono_type_get_object_checked (mono_object_domain (type), &klass->this_arg, &error);
6126 mono_error_set_pending_exception (&error);
6131 ICALL_EXPORT MonoReflectionType *
6132 ves_icall_RuntimeType_MakePointerType (MonoReflectionType *type)
6135 MonoReflectionType *ret;
6136 MonoClass *klass, *pklass;
6138 klass = mono_class_from_mono_type (type->type);
6139 mono_class_init_checked (klass, &error);
6140 if (mono_error_set_pending_exception (&error))
6142 check_for_invalid_type (klass, &error);
6143 if (mono_error_set_pending_exception (&error))
6146 pklass = mono_ptr_class_get (type->type);
6148 ret = mono_type_get_object_checked (mono_object_domain (type), &pklass->byval_arg, &error);
6149 mono_error_set_pending_exception (&error);
6154 ICALL_EXPORT MonoObject *
6155 ves_icall_System_Delegate_CreateDelegate_internal (MonoReflectionType *type, MonoObject *target,
6156 MonoReflectionMethod *info, MonoBoolean throwOnBindFailure)
6159 MonoClass *delegate_class = mono_class_from_mono_type (type->type);
6160 MonoObject *delegate;
6162 MonoMethod *method = info->method;
6163 MonoMethodSignature *sig = mono_method_signature(method);
6165 mono_class_init_checked (delegate_class, &error);
6166 if (mono_error_set_pending_exception (&error))
6169 if (!(delegate_class->parent == mono_defaults.multicastdelegate_class)) {
6170 /* FIXME improve this exception message */
6171 mono_error_set_execution_engine (&error, "file %s: line %d (%s): assertion failed: (%s)", __FILE__, __LINE__,
6173 "delegate_class->parent == mono_defaults.multicastdelegate_class");
6174 mono_error_set_pending_exception (&error);
6178 if (mono_security_core_clr_enabled ()) {
6179 if (!mono_security_core_clr_ensure_delegate_creation (method, &error)) {
6180 if (throwOnBindFailure)
6181 mono_error_set_pending_exception (&error);
6183 mono_error_cleanup (&error);
6188 if (sig->generic_param_count && method->wrapper_type == MONO_WRAPPER_NONE) {
6189 if (!method->is_inflated) {
6190 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"));
6195 delegate = mono_object_new_checked (mono_object_domain (type), delegate_class, &error);
6196 if (mono_error_set_pending_exception (&error))
6199 if (method_is_dynamic (method)) {
6200 /* Creating a trampoline would leak memory */
6201 func = mono_compile_method_checked (method, &error);
6202 if (mono_error_set_pending_exception (&error))
6205 if (target && method->flags & METHOD_ATTRIBUTE_VIRTUAL && method->klass != mono_object_class (target))
6206 method = mono_object_get_virtual_method (target, method);
6207 gpointer trampoline = mono_runtime_create_jump_trampoline (mono_domain_get (), method, TRUE, &error);
6208 if (mono_error_set_pending_exception (&error))
6210 func = mono_create_ftnptr (mono_domain_get (), trampoline);
6213 mono_delegate_ctor_with_method (delegate, target, func, method, &error);
6214 if (mono_error_set_pending_exception (&error))
6219 ICALL_EXPORT MonoMulticastDelegate *
6220 ves_icall_System_Delegate_AllocDelegateLike_internal (MonoDelegate *delegate)
6223 MonoMulticastDelegate *ret;
6225 g_assert (mono_class_has_parent (mono_object_class (delegate), mono_defaults.multicastdelegate_class));
6227 ret = (MonoMulticastDelegate*) mono_object_new_checked (mono_object_domain (delegate), mono_object_class (delegate), &error);
6228 if (mono_error_set_pending_exception (&error))
6231 ret->delegate.invoke_impl = mono_runtime_create_delegate_trampoline (mono_object_class (delegate));
6236 ICALL_EXPORT MonoReflectionMethod*
6237 ves_icall_System_Delegate_GetVirtualMethod_internal (MonoDelegate *delegate)
6239 MonoReflectionMethod *ret = NULL;
6241 ret = mono_method_get_object_checked (mono_domain_get (), mono_object_get_virtual_method (delegate->target, delegate->method), mono_object_class (delegate->target), &error);
6242 mono_error_set_pending_exception (&error);
6248 static inline gint32
6249 mono_array_get_byte_length (MonoArray *array)
6255 klass = array->obj.vtable->klass;
6257 if (array->bounds == NULL)
6258 length = array->max_length;
6261 for (i = 0; i < klass->rank; ++ i)
6262 length *= array->bounds [i].length;
6265 switch (klass->element_class->byval_arg.type) {
6268 case MONO_TYPE_BOOLEAN:
6272 case MONO_TYPE_CHAR:
6280 return length * sizeof (gpointer);
6291 ves_icall_System_Buffer_ByteLengthInternal (MonoArray *array)
6293 return mono_array_get_byte_length (array);
6297 ves_icall_System_Buffer_GetByteInternal (MonoArray *array, gint32 idx)
6299 return mono_array_get (array, gint8, idx);
6303 ves_icall_System_Buffer_SetByteInternal (MonoArray *array, gint32 idx, gint8 value)
6305 mono_array_set (array, gint8, idx, value);
6308 ICALL_EXPORT MonoBoolean
6309 ves_icall_System_Buffer_BlockCopyInternal (MonoArray *src, gint32 src_offset, MonoArray *dest, gint32 dest_offset, gint32 count)
6311 guint8 *src_buf, *dest_buf;
6314 mono_set_pending_exception (mono_get_exception_argument ("count", "is negative"));
6318 g_assert (count >= 0);
6320 /* This is called directly from the class libraries without going through the managed wrapper */
6321 MONO_CHECK_ARG_NULL (src, FALSE);
6322 MONO_CHECK_ARG_NULL (dest, FALSE);
6324 /* watch out for integer overflow */
6325 if ((src_offset > mono_array_get_byte_length (src) - count) || (dest_offset > mono_array_get_byte_length (dest) - count))
6328 src_buf = (guint8 *)src->vector + src_offset;
6329 dest_buf = (guint8 *)dest->vector + dest_offset;
6332 memcpy (dest_buf, src_buf, count);
6334 memmove (dest_buf, src_buf, count); /* Source and dest are the same array */
6339 #ifndef DISABLE_REMOTING
6340 ICALL_EXPORT MonoObject *
6341 ves_icall_Remoting_RealProxy_GetTransparentProxy (MonoObject *this_obj, MonoString *class_name)
6344 MonoDomain *domain = mono_object_domain (this_obj);
6346 MonoRealProxy *rp = ((MonoRealProxy *)this_obj);
6347 MonoTransparentProxy *tp;
6351 res = mono_object_new_checked (domain, mono_defaults.transparent_proxy_class, &error);
6352 if (mono_error_set_pending_exception (&error))
6355 tp = (MonoTransparentProxy*) res;
6357 MONO_OBJECT_SETREF (tp, rp, rp);
6358 type = ((MonoReflectionType *)rp->class_to_proxy)->type;
6359 klass = mono_class_from_mono_type (type);
6361 // mono_remote_class_vtable cannot handle errors well, so force any loading error to occur early
6362 mono_class_setup_vtable (klass);
6363 if (mono_class_has_failure (klass)) {
6364 mono_set_pending_exception (mono_class_get_exception_for_failure (klass));
6368 tp->custom_type_info = (mono_object_isinst_checked (this_obj, mono_defaults.iremotingtypeinfo_class, &error) != NULL);
6369 if (mono_error_set_pending_exception (&error))
6371 tp->remote_class = mono_remote_class (domain, class_name, klass, &error);
6372 if (mono_error_set_pending_exception (&error))
6375 res->vtable = (MonoVTable *)mono_remote_class_vtable (domain, tp->remote_class, rp, &error);
6376 if (mono_error_set_pending_exception (&error))
6381 ICALL_EXPORT MonoReflectionType *
6382 ves_icall_Remoting_RealProxy_InternalGetProxyType (MonoTransparentProxy *tp)
6385 MonoReflectionType *ret = mono_type_get_object_checked (mono_object_domain (tp), &tp->remote_class->proxy_class->byval_arg, &error);
6386 mono_error_set_pending_exception (&error);
6392 /* System.Environment */
6395 ves_icall_System_Environment_get_UserName (void)
6397 /* using glib is more portable */
6398 return mono_string_new (mono_domain_get (), g_get_user_name ());
6403 mono_icall_get_machine_name (void)
6405 #if !defined(DISABLE_SOCKETS)
6409 #if defined _SC_HOST_NAME_MAX
6410 n = sysconf (_SC_HOST_NAME_MAX);
6414 buf = g_malloc (n+1);
6416 if (gethostname (buf, n) == 0){
6418 result = mono_string_new (mono_domain_get (), buf);
6425 return mono_string_new (mono_domain_get (), "mono");
6428 #endif /* !HOST_WIN32 */
6430 ICALL_EXPORT MonoString *
6431 ves_icall_System_Environment_get_MachineName (void)
6433 return mono_icall_get_machine_name ();
6438 mono_icall_get_platform (void)
6440 #if defined(__MACH__)
6443 // Notice that the value is hidden from user code, and only exposed
6444 // to mscorlib. This is due to Mono's Unix/MacOS code predating the
6445 // define and making assumptions based on Unix/128/4 values before there
6446 // was a MacOS define. Lots of code would assume that not-Unix meant
6447 // Windows, but in this case, it would be OSX.
6455 #endif /* !HOST_WIN32 */
6458 ves_icall_System_Environment_get_Platform (void)
6460 return mono_icall_get_platform ();
6464 static inline MonoString *
6465 mono_icall_get_new_line (void)
6467 return mono_string_new (mono_domain_get (), "\n");
6469 #endif /* !HOST_WIN32 */
6471 ICALL_EXPORT MonoString *
6472 ves_icall_System_Environment_get_NewLine (void)
6474 return mono_icall_get_new_line ();
6478 static inline MonoBoolean
6479 mono_icall_is_64bit_os (void)
6481 #if SIZEOF_VOID_P == 8
6484 #if defined(HAVE_SYS_UTSNAME_H)
6485 struct utsname name;
6487 if (uname (&name) >= 0) {
6488 return strcmp (name.machine, "x86_64") == 0 || strncmp (name.machine, "aarch64", 7) == 0 || strncmp (name.machine, "ppc64", 5) == 0;
6494 #endif /* !HOST_WIN32 */
6496 ICALL_EXPORT MonoBoolean
6497 ves_icall_System_Environment_GetIs64BitOperatingSystem (void)
6499 return mono_icall_is_64bit_os ();
6502 ICALL_EXPORT MonoStringHandle
6503 ves_icall_System_Environment_GetEnvironmentVariable_native (const gchar *utf8_name, MonoError *error)
6507 if (utf8_name == NULL)
6508 return NULL_HANDLE_STRING;
6510 value = g_getenv (utf8_name);
6513 return NULL_HANDLE_STRING;
6515 return mono_string_new_handle (mono_domain_get (), value, error);
6519 * There is no standard way to get at environ.
6522 #ifndef __MINGW32_VERSION
6523 #if defined(__APPLE__)
6524 #if defined (TARGET_OSX)
6525 /* Apple defines this in crt_externs.h but doesn't provide that header for
6526 * arm-apple-darwin9. We'll manually define the symbol on Apple as it does
6527 * in fact exist on all implementations (so far)
6529 gchar ***_NSGetEnviron(void);
6530 #define environ (*_NSGetEnviron())
6532 static char *mono_environ[1] = { NULL };
6533 #define environ mono_environ
6534 #endif /* defined (TARGET_OSX) */
6542 ICALL_EXPORT MonoArray *
6543 ves_icall_System_Environment_GetCoomandLineArgs (void)
6546 MonoArray *result = mono_runtime_get_main_args_checked (&error);
6547 mono_error_set_pending_exception (&error);
6553 mono_icall_get_environment_variable_names (void)
6563 for (e = environ; *e != 0; ++ e)
6566 domain = mono_domain_get ();
6567 names = mono_array_new_checked (domain, mono_defaults.string_class, n, &error);
6568 if (mono_error_set_pending_exception (&error))
6572 for (e = environ; *e != 0; ++ e) {
6573 parts = g_strsplit (*e, "=", 2);
6575 str = mono_string_new (domain, *parts);
6576 mono_array_setref (names, n, str);
6586 #endif /* !HOST_WIN32 */
6588 ICALL_EXPORT MonoArray *
6589 ves_icall_System_Environment_GetEnvironmentVariableNames (void)
6591 return mono_icall_get_environment_variable_names ();
6596 mono_icall_set_environment_variable (MonoString *name, MonoString *value)
6598 gchar *utf8_name, *utf8_value;
6601 utf8_name = mono_string_to_utf8_checked (name, &error); /* FIXME: this should be ascii */
6602 if (mono_error_set_pending_exception (&error))
6605 if ((value == NULL) || (mono_string_length (value) == 0) || (mono_string_chars (value)[0] == 0)) {
6606 g_unsetenv (utf8_name);
6611 utf8_value = mono_string_to_utf8_checked (value, &error);
6612 if (!mono_error_ok (&error)) {
6614 mono_error_set_pending_exception (&error);
6617 g_setenv (utf8_name, utf8_value, TRUE);
6620 g_free (utf8_value);
6622 #endif /* !HOST_WIN32 */
6625 ves_icall_System_Environment_InternalSetEnvironmentVariable (MonoString *name, MonoString *value)
6627 mono_icall_set_environment_variable (name, value);
6631 ves_icall_System_Environment_Exit (int result)
6633 mono_environment_exitcode_set (result);
6635 /* FIXME: There are some cleanup hangs that should be worked out, but
6636 * if the program is going to exit, everything will be cleaned up when
6637 * NaCl exits anyway.
6639 #ifndef __native_client__
6640 if (!mono_runtime_try_shutdown ())
6641 mono_thread_exit ();
6643 /* Suspend all managed threads since the runtime is going away */
6644 mono_thread_suspend_all_other_threads ();
6646 mono_runtime_quit ();
6649 /* we may need to do some cleanup here... */
6653 ICALL_EXPORT MonoStringHandle
6654 ves_icall_System_Environment_GetGacPath (MonoError *error)
6656 return mono_string_new_handle (mono_domain_get (), mono_assembly_getrootdir (), error);
6660 static inline MonoString *
6661 mono_icall_get_windows_folder_path (int folder)
6663 g_warning ("ves_icall_System_Environment_GetWindowsFolderPath should only be called on Windows!");
6664 return mono_string_new (mono_domain_get (), "");
6666 #endif /* !HOST_WIN32 */
6668 ICALL_EXPORT MonoString*
6669 ves_icall_System_Environment_GetWindowsFolderPath (int folder)
6671 return mono_icall_get_windows_folder_path (folder);
6674 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
6676 mono_icall_get_logical_drives (void)
6679 gunichar2 buf [256], *ptr, *dname;
6681 guint initial_size = 127, size = 128;
6684 MonoString *drivestr;
6685 MonoDomain *domain = mono_domain_get ();
6691 while (size > initial_size) {
6692 size = (guint) GetLogicalDriveStrings (initial_size, ptr);
6693 if (size > initial_size) {
6696 ptr = (gunichar2 *)g_malloc0 ((size + 1) * sizeof (gunichar2));
6697 initial_size = size;
6711 result = mono_array_new_checked (domain, mono_defaults.string_class, ndrives, &error);
6712 if (mono_error_set_pending_exception (&error))
6719 while (*u16) { u16++; len ++; }
6720 drivestr = mono_string_new_utf16_checked (domain, dname, len, &error);
6721 if (mono_error_set_pending_exception (&error))
6724 mono_array_setref (result, ndrives++, drivestr);
6734 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
6736 ICALL_EXPORT MonoArray *
6737 ves_icall_System_Environment_GetLogicalDrives (void)
6739 return mono_icall_get_logical_drives ();
6742 ICALL_EXPORT MonoString *
6743 ves_icall_System_IO_DriveInfo_GetDriveFormat (MonoString *path)
6746 gunichar2 volume_name [MAX_PATH + 1];
6748 if (GetVolumeInformation (mono_string_chars (path), NULL, 0, NULL, NULL, NULL, volume_name, MAX_PATH + 1) == FALSE)
6750 MonoString *result = mono_string_from_utf16_checked (volume_name, &error);
6751 mono_error_set_pending_exception (&error);
6755 ICALL_EXPORT MonoStringHandle
6756 ves_icall_System_Environment_InternalGetHome (MonoError *error)
6758 return mono_string_new_handle (mono_domain_get (), g_get_home_dir (), error);
6761 static const char *encodings [] = {
6763 "ascii", "us_ascii", "us", "ansi_x3.4_1968",
6764 "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
6765 "iso_ir_6", "iso646_us", "iso_646.irv:1991",
6767 "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
6768 "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
6769 "x_unicode_2_0_utf_7",
6771 "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
6772 "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
6774 "utf_16", "UTF_16LE", "ucs_2", "unicode",
6777 "unicodefffe", "utf_16be",
6784 * Returns the internal codepage, if the value of "int_code_page" is
6785 * 1 at entry, and we can not compute a suitable code page number,
6786 * returns the code page as a string
6788 ICALL_EXPORT MonoString*
6789 ves_icall_System_Text_EncodingHelper_InternalCodePage (gint32 *int_code_page)
6794 char *codepage = NULL;
6796 int want_name = *int_code_page;
6799 *int_code_page = -1;
6801 g_get_charset (&cset);
6802 c = codepage = g_strdup (cset);
6803 for (c = codepage; *c; c++){
6804 if (isascii (*c) && isalpha (*c))
6809 /* g_print ("charset: %s\n", cset); */
6811 /* handle some common aliases */
6814 for (i = 0; p != 0; ){
6817 p = encodings [++i];
6820 if (strcmp (p, codepage) == 0){
6821 *int_code_page = code;
6824 p = encodings [++i];
6827 if (strstr (codepage, "utf_8") != NULL)
6828 *int_code_page |= 0x10000000;
6831 if (want_name && *int_code_page == -1)
6832 return mono_string_new (mono_domain_get (), cset);
6837 ICALL_EXPORT MonoBoolean
6838 ves_icall_System_Environment_get_HasShutdownStarted (void)
6840 if (mono_runtime_is_shutting_down ())
6843 if (mono_domain_is_unloading (mono_domain_get ()))
6851 mono_icall_broadcast_setting_change (void)
6855 #endif /* !HOST_WIN32 */
6858 ves_icall_System_Environment_BroadcastSettingChange (void)
6860 mono_icall_broadcast_setting_change ();
6865 ves_icall_System_Environment_get_TickCount (void)
6867 /* this will overflow after ~24 days */
6868 return (gint32) (mono_msec_boottime () & 0xffffffff);
6872 ves_icall_System_Runtime_Versioning_VersioningHelper_GetRuntimeId (void)
6877 #ifndef DISABLE_REMOTING
6878 ICALL_EXPORT MonoBoolean
6879 ves_icall_IsTransparentProxy (MonoObject *proxy)
6884 if (proxy->vtable->klass == mono_defaults.transparent_proxy_class)
6890 ICALL_EXPORT MonoReflectionMethod *
6891 ves_icall_Remoting_RemotingServices_GetVirtualMethod (
6892 MonoReflectionType *rtype, MonoReflectionMethod *rmethod)
6894 MonoReflectionMethod *ret = NULL;
6899 MonoMethod **vtable;
6900 MonoMethod *res = NULL;
6902 MONO_CHECK_ARG_NULL (rtype, NULL);
6903 MONO_CHECK_ARG_NULL (rmethod, NULL);
6905 method = rmethod->method;
6906 klass = mono_class_from_mono_type (rtype->type);
6907 mono_class_init_checked (klass, &error);
6908 if (mono_error_set_pending_exception (&error))
6911 if (MONO_CLASS_IS_INTERFACE (klass))
6914 if (method->flags & METHOD_ATTRIBUTE_STATIC)
6917 if ((method->flags & METHOD_ATTRIBUTE_FINAL) || !(method->flags & METHOD_ATTRIBUTE_VIRTUAL)) {
6918 if (klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE))
6924 mono_class_setup_vtable (klass);
6925 vtable = klass->vtable;
6927 if (mono_class_is_interface (method->klass)) {
6928 gboolean variance_used = FALSE;
6929 /*MS fails with variant interfaces but it's the right thing to do anyway.*/
6930 int offs = mono_class_interface_offset_with_variance (klass, method->klass, &variance_used);
6932 res = vtable [offs + method->slot];
6934 if (!(klass == method->klass || mono_class_is_subclass_of (klass, method->klass, FALSE)))
6937 if (method->slot != -1)
6938 res = vtable [method->slot];
6944 ret = mono_method_get_object_checked (mono_domain_get (), res, NULL, &error);
6945 mono_error_set_pending_exception (&error);
6950 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6956 klass = mono_class_from_mono_type (type->type);
6957 vtable = mono_class_vtable_full (mono_domain_get (), klass, &error);
6958 if (!is_ok (&error)) {
6959 mono_error_set_pending_exception (&error);
6963 mono_vtable_set_is_remote (vtable, enable);
6966 #else /* DISABLE_REMOTING */
6969 ves_icall_System_Runtime_Activation_ActivationServices_EnableProxyActivation (MonoReflectionType *type, MonoBoolean enable)
6971 g_assert_not_reached ();
6976 ICALL_EXPORT MonoObject *
6977 ves_icall_System_Runtime_Activation_ActivationServices_AllocateUninitializedClassInstance (MonoReflectionType *type)
6984 domain = mono_object_domain (type);
6985 klass = mono_class_from_mono_type (type->type);
6986 mono_class_init_checked (klass, &error);
6987 if (mono_error_set_pending_exception (&error))
6990 if (MONO_CLASS_IS_INTERFACE (klass) || mono_class_is_abstract (klass)) {
6991 mono_set_pending_exception (mono_get_exception_argument ("type", "Type cannot be instantiated"));
6995 if (klass->rank >= 1) {
6996 g_assert (klass->rank == 1);
6997 ret = (MonoObject *) mono_array_new_checked (domain, klass->element_class, 0, &error);
6998 mono_error_set_pending_exception (&error);
7001 MonoVTable *vtable = mono_class_vtable_full (domain, klass, &error);
7002 if (!is_ok (&error)) {
7003 mono_error_set_pending_exception (&error);
7006 /* Bypass remoting object creation check */
7007 ret = mono_object_new_alloc_specific_checked (vtable, &error);
7008 mono_error_set_pending_exception (&error);
7014 ICALL_EXPORT MonoStringHandle
7015 ves_icall_System_IO_get_temp_path (MonoError *error)
7017 return mono_string_new_handle (mono_domain_get (), g_get_tmp_dir (), error);
7020 #ifndef PLATFORM_NO_DRIVEINFO
7021 ICALL_EXPORT MonoBoolean
7022 ves_icall_System_IO_DriveInfo_GetDiskFreeSpace (MonoString *path_name, guint64 *free_bytes_avail,
7023 guint64 *total_number_of_bytes, guint64 *total_number_of_free_bytes,
7027 ULARGE_INTEGER wapi_free_bytes_avail;
7028 ULARGE_INTEGER wapi_total_number_of_bytes;
7029 ULARGE_INTEGER wapi_total_number_of_free_bytes;
7031 *error = ERROR_SUCCESS;
7032 result = GetDiskFreeSpaceEx (mono_string_chars (path_name), &wapi_free_bytes_avail, &wapi_total_number_of_bytes,
7033 &wapi_total_number_of_free_bytes);
7036 *free_bytes_avail = wapi_free_bytes_avail.QuadPart;
7037 *total_number_of_bytes = wapi_total_number_of_bytes.QuadPart;
7038 *total_number_of_free_bytes = wapi_total_number_of_free_bytes.QuadPart;
7040 *free_bytes_avail = 0;
7041 *total_number_of_bytes = 0;
7042 *total_number_of_free_bytes = 0;
7043 *error = GetLastError ();
7049 #if G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT)
7050 static inline guint32
7051 mono_icall_drive_info_get_drive_type (MonoString *root_path_name)
7053 return GetDriveType (mono_string_chars (root_path_name));
7055 #endif /* G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT) */
7057 ICALL_EXPORT guint32
7058 ves_icall_System_IO_DriveInfo_GetDriveType (MonoString *root_path_name)
7060 return mono_icall_drive_info_get_drive_type (root_path_name);
7063 #endif /* PLATFORM_NO_DRIVEINFO */
7065 ICALL_EXPORT gpointer
7066 ves_icall_RuntimeMethodHandle_GetFunctionPointer (MonoMethod *method)
7069 gpointer result = mono_compile_method_checked (method, &error);
7070 mono_error_set_pending_exception (&error);
7074 ICALL_EXPORT MonoString *
7075 ves_icall_System_Configuration_DefaultConfig_get_machine_config_path (void)
7080 path = g_build_path (G_DIR_SEPARATOR_S, mono_get_config_dir (), "mono", mono_get_runtime_info ()->framework_version, "machine.config", NULL);
7082 mono_icall_make_platform_path (path);
7084 mcpath = mono_string_new (mono_domain_get (), path);
7090 /* this is an icall */
7092 get_bundled_app_config (void)
7095 const gchar *app_config;
7098 gchar *config_file_name, *config_file_path;
7099 gsize len, config_file_path_length, config_ext_length;
7102 domain = mono_domain_get ();
7103 file = domain->setup->configuration_file;
7104 if (!file || file->length == 0)
7107 // Retrieve config file and remove the extension
7108 config_file_name = mono_string_to_utf8_checked (file, &error);
7109 if (mono_error_set_pending_exception (&error))
7111 config_file_path = mono_portability_find_file (config_file_name, TRUE);
7112 if (!config_file_path)
7113 config_file_path = config_file_name;
7115 config_file_path_length = strlen (config_file_path);
7116 config_ext_length = strlen (".config");
7117 if (config_file_path_length <= config_ext_length)
7120 len = config_file_path_length - config_ext_length;
7121 module = (gchar *)g_malloc0 (len + 1);
7122 memcpy (module, config_file_path, len);
7123 // Get the config file from the module name
7124 app_config = mono_config_string_for_assembly_file (module);
7127 if (config_file_name != config_file_path)
7128 g_free (config_file_name);
7129 g_free (config_file_path);
7134 return mono_string_new (mono_domain_get (), app_config);
7137 static MonoStringHandle
7138 get_bundled_machine_config (MonoError *error)
7140 const gchar *machine_config;
7142 machine_config = mono_get_machine_config ();
7144 if (!machine_config)
7145 return NULL_HANDLE_STRING;
7147 return mono_string_new_handle (mono_domain_get (), machine_config, error);
7150 ICALL_EXPORT MonoStringHandle
7151 ves_icall_System_Environment_get_bundled_machine_config (MonoError *error)
7153 return get_bundled_machine_config (error);
7157 ICALL_EXPORT MonoStringHandle
7158 ves_icall_System_Configuration_DefaultConfig_get_bundled_machine_config (MonoError *error)
7160 return get_bundled_machine_config (error);
7163 ICALL_EXPORT MonoStringHandle
7164 ves_icall_System_Configuration_InternalConfigurationHost_get_bundled_machine_config (MonoError *error)
7166 return get_bundled_machine_config (error);
7170 ICALL_EXPORT MonoString *
7171 ves_icall_System_Web_Util_ICalls_get_machine_install_dir (void)
7176 path = g_path_get_dirname (mono_get_config_dir ());
7178 mono_icall_make_platform_path (path);
7180 ipath = mono_string_new (mono_domain_get (), path);
7186 ICALL_EXPORT gboolean
7187 ves_icall_get_resources_ptr (MonoReflectionAssemblyHandle assembly, gpointer *result, gint32 *size, MonoError *error)
7189 mono_error_init (error);
7190 MonoPEResourceDataEntry *entry;
7193 if (!assembly || !result || !size)
7198 MonoAssembly *assm = MONO_HANDLE_GETVAL (assembly, assembly);
7199 image = assm->image;
7200 entry = (MonoPEResourceDataEntry *)mono_image_lookup_resource (image, MONO_PE_RESOURCE_ID_ASPNET_STRING, 0, NULL);
7204 *result = mono_image_rva_map (image, entry->rde_data_offset);
7209 *size = entry->rde_size;
7214 ICALL_EXPORT MonoBoolean
7215 ves_icall_System_Diagnostics_Debugger_IsAttached_internal (void)
7217 return mono_is_debugger_attached ();
7220 ICALL_EXPORT MonoBoolean
7221 ves_icall_System_Diagnostics_Debugger_IsLogging (void)
7223 if (mono_get_runtime_callbacks ()->debug_log_is_enabled)
7224 return mono_get_runtime_callbacks ()->debug_log_is_enabled ();
7230 ves_icall_System_Diagnostics_Debugger_Log (int level, MonoString *category, MonoString *message)
7232 if (mono_get_runtime_callbacks ()->debug_log)
7233 mono_get_runtime_callbacks ()->debug_log (level, category, message);
7238 mono_icall_write_windows_debug_string (MonoString *message)
7240 g_warning ("WriteWindowsDebugString called and HOST_WIN32 not defined!\n");
7242 #endif /* !HOST_WIN32 */
7245 ves_icall_System_Diagnostics_DefaultTraceListener_WriteWindowsDebugString (MonoString *message)
7247 mono_icall_write_windows_debug_string (message);
7250 /* Only used for value types */
7251 ICALL_EXPORT MonoObject *
7252 ves_icall_System_Activator_CreateInstanceInternal (MonoReflectionType *type)
7259 domain = mono_object_domain (type);
7260 klass = mono_class_from_mono_type (type->type);
7261 mono_class_init_checked (klass, &error);
7262 if (mono_error_set_pending_exception (&error))
7265 if (mono_class_is_nullable (klass))
7266 /* No arguments -> null */
7269 result = mono_object_new_checked (domain, klass, &error);
7270 mono_error_set_pending_exception (&error);
7274 ICALL_EXPORT MonoReflectionMethod *
7275 ves_icall_MonoMethod_get_base_method (MonoReflectionMethod *m, gboolean definition)
7277 MonoReflectionMethod *ret = NULL;
7280 MonoClass *klass, *parent;
7281 MonoGenericContext *generic_inst = NULL;
7282 MonoMethod *method = m->method;
7283 MonoMethod *result = NULL;
7286 if (method->klass == NULL)
7289 if (!(method->flags & METHOD_ATTRIBUTE_VIRTUAL) ||
7290 MONO_CLASS_IS_INTERFACE (method->klass) ||
7291 method->flags & METHOD_ATTRIBUTE_NEW_SLOT)
7294 slot = mono_method_get_vtable_slot (method);
7298 klass = method->klass;
7299 if (mono_class_is_ginst (klass)) {
7300 generic_inst = mono_class_get_context (klass);
7301 klass = mono_class_get_generic_class (klass)->container_class;
7306 /* At the end of the loop, klass points to the eldest class that has this virtual function slot. */
7307 for (parent = klass->parent; parent != NULL; parent = parent->parent) {
7308 /* on entry, klass is either a plain old non-generic class and generic_inst == NULL
7309 or klass is the generic container class and generic_inst is the instantiation.
7311 when we go to the parent, if the parent is an open constructed type, we need to
7312 replace the type parameters by the definitions from the generic_inst, and then take it
7313 apart again into the klass and the generic_inst.
7315 For cases like this:
7316 class C<T> : B<T, int> {
7317 public override void Foo () { ... }
7319 class B<U,V> : A<HashMap<U,V>> {
7320 public override void Foo () { ... }
7323 public virtual void Foo () { ... }
7326 if at each iteration the parent isn't open, we can skip inflating it. if at some
7327 iteration the parent isn't generic (after possible inflation), we set generic_inst to
7330 MonoGenericContext *parent_inst = NULL;
7331 if (mono_class_is_open_constructed_type (mono_class_get_type (parent))) {
7332 parent = mono_class_inflate_generic_class_checked (parent, generic_inst, &error);
7333 if (!mono_error_ok (&error)) {
7334 mono_error_set_pending_exception (&error);
7338 if (mono_class_is_ginst (parent)) {
7339 parent_inst = mono_class_get_context (parent);
7340 parent = mono_class_get_generic_class (parent)->container_class;
7343 mono_class_setup_vtable (parent);
7344 if (parent->vtable_size <= slot)
7347 generic_inst = parent_inst;
7350 klass = klass->parent;
7353 if (mono_class_is_open_constructed_type (mono_class_get_type (klass))) {
7354 klass = mono_class_inflate_generic_class_checked (klass, generic_inst, &error);
7355 if (!mono_error_ok (&error)) {
7356 mono_error_set_pending_exception (&error);
7360 generic_inst = NULL;
7362 if (mono_class_is_ginst (klass)) {
7363 generic_inst = mono_class_get_context (klass);
7364 klass = mono_class_get_generic_class (klass)->container_class;
7370 klass = mono_class_inflate_generic_class_checked (klass, generic_inst, &error);
7371 if (!mono_error_ok (&error)) {
7372 mono_error_set_pending_exception (&error);
7377 if (klass == method->klass)
7380 /*This is possible if definition == FALSE.
7381 * Do it here to be really sure we don't read invalid memory.
7383 if (slot >= klass->vtable_size)
7386 mono_class_setup_vtable (klass);
7388 result = klass->vtable [slot];
7389 if (result == NULL) {
7390 /* It is an abstract method */
7391 gboolean found = FALSE;
7392 gpointer iter = NULL;
7393 while ((result = mono_class_get_methods (klass, &iter))) {
7394 if (result->slot == slot) {
7399 /* found might be FALSE if we looked in an abstract class
7400 * that doesn't override an abstract method of its
7402 * abstract class Base {
7403 * public abstract void Foo ();
7405 * abstract class Derived : Base { }
7406 * class Child : Derived {
7407 * public override void Foo () { }
7410 * if m was Child.Foo and we ask for the base method,
7411 * then we get here with klass == Derived and found == FALSE
7413 /* but it shouldn't be the case that if we're looking
7414 * for the definition and didn't find a result; the
7415 * loop above should've taken us as far as we could
7417 g_assert (!(definition && !found));
7422 g_assert (result != NULL);
7424 ret = mono_method_get_object_checked (mono_domain_get (), result, NULL, &error);
7425 mono_error_set_pending_exception (&error);
7429 ICALL_EXPORT MonoString*
7430 ves_icall_MonoMethod_get_name (MonoReflectionMethod *m)
7432 MonoMethod *method = m->method;
7434 MONO_OBJECT_SETREF (m, name, mono_string_new (mono_object_domain (m), method->name));
7439 mono_ArgIterator_Setup (MonoArgIterator *iter, char* argsp, char* start)
7441 iter->sig = *(MonoMethodSignature**)argsp;
7443 g_assert (iter->sig->sentinelpos <= iter->sig->param_count);
7444 g_assert (iter->sig->call_convention == MONO_CALL_VARARG);
7447 /* FIXME: it's not documented what start is exactly... */
7451 iter->args = argsp + sizeof (gpointer);
7453 iter->num_args = iter->sig->param_count - iter->sig->sentinelpos;
7455 /* g_print ("sig %p, param_count: %d, sent: %d\n", iter->sig, iter->sig->param_count, iter->sig->sentinelpos); */
7458 ICALL_EXPORT MonoTypedRef
7459 mono_ArgIterator_IntGetNextArg (MonoArgIterator *iter)
7461 guint32 i, arg_size;
7465 i = iter->sig->sentinelpos + iter->next_arg;
7467 g_assert (i < iter->sig->param_count);
7469 res.type = iter->sig->params [i];
7470 res.klass = mono_class_from_mono_type (res.type);
7471 arg_size = mono_type_stack_size (res.type, &align);
7472 #if defined(__arm__) || defined(__mips__)
7473 iter->args = (guint8*)(((gsize)iter->args + (align) - 1) & ~(align - 1));
7475 res.value = iter->args;
7476 #if defined(__native_client__) && SIZEOF_REGISTER == 8
7477 /* Values are stored as 8 byte register sized objects, but 'value'
7478 * is dereferenced as a pointer in other routines.
7480 res.value = (char*)res.value + 4;
7482 #if G_BYTE_ORDER != G_LITTLE_ENDIAN
7483 if (arg_size <= sizeof (gpointer)) {
7485 int padding = arg_size - mono_type_size (res.type, &dummy);
7486 res.value = (guint8*)res.value + padding;
7489 iter->args = (char*)iter->args + arg_size;
7492 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7497 ICALL_EXPORT MonoTypedRef
7498 mono_ArgIterator_IntGetNextArgT (MonoArgIterator *iter, MonoType *type)
7500 guint32 i, arg_size;
7504 i = iter->sig->sentinelpos + iter->next_arg;
7506 g_assert (i < iter->sig->param_count);
7508 while (i < iter->sig->param_count) {
7509 if (!mono_metadata_type_equal (type, iter->sig->params [i]))
7511 res.type = iter->sig->params [i];
7512 res.klass = mono_class_from_mono_type (res.type);
7513 /* FIXME: endianess issue... */
7514 arg_size = mono_type_stack_size (res.type, &align);
7515 #if defined(__arm__) || defined(__mips__)
7516 iter->args = (guint8*)(((gsize)iter->args + (align) - 1) & ~(align - 1));
7518 res.value = iter->args;
7519 iter->args = (char*)iter->args + arg_size;
7521 /* g_print ("returning arg %d, type 0x%02x of size %d at %p\n", i, res.type->type, arg_size, res.value); */
7524 /* g_print ("arg type 0x%02x not found\n", res.type->type); */
7532 ICALL_EXPORT MonoType*
7533 mono_ArgIterator_IntGetNextArgType (MonoArgIterator *iter)
7537 i = iter->sig->sentinelpos + iter->next_arg;
7539 g_assert (i < iter->sig->param_count);
7541 return iter->sig->params [i];
7544 ICALL_EXPORT MonoObject*
7545 mono_TypedReference_ToObject (MonoTypedRef* tref)
7548 MonoObject *result = NULL;
7549 if (MONO_TYPE_IS_REFERENCE (tref->type)) {
7550 MonoObject** objp = (MonoObject **)tref->value;
7554 result = mono_value_box_checked (mono_domain_get (), tref->klass, tref->value, &error);
7555 mono_error_set_pending_exception (&error);
7559 ICALL_EXPORT MonoTypedRef
7560 mono_TypedReference_MakeTypedReferenceInternal (MonoObject *target, MonoArray *fields)
7563 MonoReflectionField *f;
7565 MonoType *ftype = NULL;
7569 memset (&res, 0, sizeof (res));
7572 g_assert (mono_array_length (fields) > 0);
7574 klass = target->vtable->klass;
7576 for (i = 0; i < mono_array_length (fields); ++i) {
7577 f = mono_array_get (fields, MonoReflectionField*, i);
7579 mono_set_pending_exception (mono_get_exception_argument_null ("field"));
7582 if (f->field->parent != klass) {
7583 mono_set_pending_exception (mono_get_exception_argument ("field", ""));
7587 p = (guint8*)target + f->field->offset;
7589 p += f->field->offset - sizeof (MonoObject);
7590 klass = mono_class_from_mono_type (f->field->type);
7591 ftype = f->field->type;
7595 res.klass = mono_class_from_mono_type (ftype);
7602 prelink_method (MonoMethod *method, MonoError *error)
7604 const char *exc_class, *exc_arg;
7606 mono_error_init (error);
7607 if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
7609 mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
7611 mono_error_set_exception_instance (error,
7612 mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg));
7615 /* create the wrapper, too? */
7619 ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
7623 prelink_method (method->method, &error);
7624 mono_error_set_pending_exception (&error);
7628 ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
7631 MonoClass *klass = mono_class_from_mono_type (type->type);
7633 gpointer iter = NULL;
7635 mono_class_init_checked (klass, &error);
7636 if (mono_error_set_pending_exception (&error))
7639 while ((m = mono_class_get_methods (klass, &iter))) {
7640 prelink_method (m, &error);
7641 if (mono_error_set_pending_exception (&error))
7646 /* These parameters are "readonly" in corlib/System/NumberFormatter.cs */
7648 ves_icall_System_NumberFormatter_GetFormatterTables (guint64 const **mantissas,
7649 gint32 const **exponents,
7650 gunichar2 const **digitLowerTable,
7651 gunichar2 const **digitUpperTable,
7652 gint64 const **tenPowersList,
7653 gint32 const **decHexDigits)
7655 *mantissas = Formatter_MantissaBitsTable;
7656 *exponents = Formatter_TensExponentTable;
7657 *digitLowerTable = Formatter_DigitLowerTable;
7658 *digitUpperTable = Formatter_DigitUpperTable;
7659 *tenPowersList = Formatter_TenPowersList;
7660 *decHexDigits = Formatter_DecHexDigits;
7664 add_modifier_to_array (MonoDomain *domain, MonoImage *image, MonoCustomMod *modifier, MonoArrayHandle dest, int dest_idx, MonoError *error)
7666 HANDLE_FUNCTION_ENTER ();
7667 mono_error_init (error);
7668 MonoClass *klass = mono_class_get_checked (image, modifier->token, error);
7672 MonoReflectionTypeHandle rt = mono_type_get_object_handle (domain, &klass->byval_arg, error);
7676 MONO_HANDLE_ARRAY_SETREF (dest, dest_idx, rt);
7678 HANDLE_FUNCTION_RETURN_VAL (is_ok (error));
7682 * We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
7683 * and avoid useless allocations.
7685 static MonoArrayHandle
7686 type_array_from_modifiers (MonoImage *image, MonoType *type, int optional, MonoError *error)
7689 MonoDomain *domain = mono_domain_get ();
7691 mono_error_init (error);
7692 for (i = 0; i < type->num_mods; ++i) {
7693 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
7697 return MONO_HANDLE_NEW (MonoArray, NULL);
7699 MonoArrayHandle res = mono_array_new_handle (domain, mono_defaults.systemtype_class, count, error);
7703 for (i = 0; i < type->num_mods; ++i) {
7704 if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
7705 if (!add_modifier_to_array (domain, image, &type->modifiers[i], res, count , error))
7712 return MONO_HANDLE_NEW (MonoArray, NULL);
7715 ICALL_EXPORT MonoArrayHandle
7716 ves_icall_ParameterInfo_GetTypeModifiers (MonoReflectionParameterHandle param, MonoBoolean optional, MonoError *error)
7718 mono_error_init (error);
7719 MonoReflectionTypeHandle rt = MONO_HANDLE_NEW (MonoReflectionType, NULL);
7720 MONO_HANDLE_GET (rt, param, ClassImpl);
7721 MonoType *type = MONO_HANDLE_GETVAL (rt, type);
7722 MonoObjectHandle member = MONO_HANDLE_NEW (MonoObject, NULL);
7723 MONO_HANDLE_GET (member, param, MemberImpl);
7724 MonoClass *member_class = mono_handle_class (member);
7725 MonoMethod *method = NULL;
7728 MonoMethodSignature *sig;
7730 if (mono_class_is_reflection_method_or_constructor (member_class)) {
7731 method = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionMethod, member), method);
7732 } else if (member_class->image == mono_defaults.corlib && !strcmp ("MonoProperty", member_class->name)) {
7733 MonoProperty *prop = MONO_HANDLE_GETVAL (MONO_HANDLE_CAST (MonoReflectionProperty, member), property);
7734 if (!(method = prop->get))
7738 char *type_name = mono_type_get_full_name (member_class);
7739 mono_error_set_not_supported (error, "Custom modifiers on a ParamInfo with member %s are not supported", type_name);
7741 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
7744 image = method->klass->image;
7745 pos = MONO_HANDLE_GETVAL (param, PositionImpl);
7746 sig = mono_method_signature (method);
7750 type = sig->params [pos];
7752 return type_array_from_modifiers (image, type, optional, error);
7756 get_property_type (MonoProperty *prop)
7758 MonoMethodSignature *sig;
7760 sig = mono_method_signature (prop->get);
7762 } else if (prop->set) {
7763 sig = mono_method_signature (prop->set);
7764 return sig->params [sig->param_count - 1];
7769 ICALL_EXPORT MonoArrayHandle
7770 ves_icall_MonoPropertyInfo_GetTypeModifiers (MonoReflectionPropertyHandle property, MonoBoolean optional, MonoError *error)
7772 mono_error_init (error);
7773 MonoProperty *prop = MONO_HANDLE_GETVAL (property, property);
7774 MonoClass *klass = MONO_HANDLE_GETVAL (property, klass);
7775 MonoType *type = get_property_type (prop);
7776 MonoImage *image = klass->image;
7779 return MONO_HANDLE_CAST (MonoArray, NULL_HANDLE);
7780 return type_array_from_modifiers (image, type, optional, error);
7784 *Construct a MonoType suited to be used to decode a constant blob object.
7786 * @type is the target type which will be constructed
7787 * @blob_type is the blob type, for example, that comes from the constant table
7788 * @real_type is the expected constructed type.
7791 mono_type_from_blob_type (MonoType *type, MonoTypeEnum blob_type, MonoType *real_type)
7793 type->type = blob_type;
7794 type->data.klass = NULL;
7795 if (blob_type == MONO_TYPE_CLASS)
7796 type->data.klass = mono_defaults.object_class;
7797 else if (real_type->type == MONO_TYPE_VALUETYPE && real_type->data.klass->enumtype) {
7798 /* For enums, we need to use the base type */
7799 type->type = MONO_TYPE_VALUETYPE;
7800 type->data.klass = mono_class_from_mono_type (real_type);
7802 type->data.klass = mono_class_from_mono_type (real_type);
7805 ICALL_EXPORT MonoObject*
7806 property_info_get_default_value (MonoReflectionProperty *property)
7810 MonoProperty *prop = property->property;
7811 MonoType *type = get_property_type (prop);
7812 MonoDomain *domain = mono_object_domain (property);
7813 MonoTypeEnum def_type;
7814 const char *def_value;
7817 mono_class_init (prop->parent);
7819 if (!(prop->attrs & PROPERTY_ATTRIBUTE_HAS_DEFAULT)) {
7820 mono_set_pending_exception (mono_get_exception_invalid_operation (NULL));
7824 def_value = mono_class_get_property_default_value (prop, &def_type);
7826 mono_type_from_blob_type (&blob_type, def_type, type);
7827 o = mono_get_object_from_blob (domain, &blob_type, def_value, &error);
7829 mono_error_set_pending_exception (&error);
7833 ICALL_EXPORT MonoBoolean
7834 custom_attrs_defined_internal (MonoObject *obj, MonoReflectionType *attr_type)
7837 MonoClass *attr_class = mono_class_from_mono_type (attr_type->type);
7838 MonoCustomAttrInfo *cinfo;
7841 mono_class_init_checked (attr_class, &error);
7842 if (mono_error_set_pending_exception (&error))
7845 cinfo = mono_reflection_get_custom_attrs_info_checked (obj, &error);
7846 if (!is_ok (&error)) {
7847 mono_error_set_pending_exception (&error);
7852 found = mono_custom_attrs_has_attr (cinfo, attr_class);
7854 mono_custom_attrs_free (cinfo);
7858 ICALL_EXPORT MonoArray*
7859 custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
7861 MonoClass *attr_class = attr_type ? mono_class_from_mono_type (attr_type->type) : NULL;
7866 mono_class_init_checked (attr_class, &error);
7867 if (mono_error_set_pending_exception (&error))
7871 res = mono_reflection_get_custom_attrs_by_type (obj, attr_class, &error);
7872 if (!mono_error_ok (&error)) {
7873 mono_error_set_pending_exception (&error);
7880 ICALL_EXPORT MonoArray*
7881 ves_icall_MonoCustomAttrs_GetCustomAttributesDataInternal (MonoObject *obj)
7885 result = mono_reflection_get_custom_attrs_data_checked (obj, &error);
7886 mono_error_set_pending_exception (&error);
7891 ICALL_EXPORT MonoStringHandle
7892 ves_icall_Mono_Runtime_GetDisplayName (MonoError *error)
7895 MonoStringHandle display_name;
7897 mono_error_init (error);
7898 info = mono_get_runtime_callbacks ()->get_runtime_build_info ();
7899 display_name = mono_string_new_handle (mono_domain_get (), info, error);
7901 return display_name;
7905 static inline gint32
7906 mono_icall_wait_for_input_idle (gpointer handle, gint32 milliseconds)
7908 return WAIT_TIMEOUT;
7910 #endif /* !HOST_WIN32 */
7913 ves_icall_Microsoft_Win32_NativeMethods_WaitForInputIdle (gpointer handle, gint32 milliseconds)
7915 return mono_icall_wait_for_input_idle (handle, milliseconds);
7919 ves_icall_Microsoft_Win32_NativeMethods_GetCurrentProcessId (void)
7921 return mono_process_current_pid ();
7924 ICALL_EXPORT MonoBoolean
7925 ves_icall_Mono_TlsProviderFactory_IsBtlsSupported (void)
7937 ves_icall_System_Runtime_InteropServices_Marshal_GetHRForException_WinRT(MonoException* ex)
7939 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetHRForException_WinRT internal call is not implemented."));
7943 ICALL_EXPORT MonoObject*
7944 ves_icall_System_Runtime_InteropServices_Marshal_GetNativeActivationFactory(MonoObject* type)
7946 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetNativeActivationFactory internal call is not implemented."));
7951 ves_icall_System_Runtime_InteropServices_Marshal_GetRawIUnknownForComObjectNoAddRef(MonoObject* obj)
7953 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.Marshal.GetRawIUnknownForComObjectNoAddRef internal call is not implemented."));
7957 ICALL_EXPORT MonoObject*
7958 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_GetRestrictedErrorInfo()
7960 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.GetRestrictedErrorInfo internal call is not implemented."));
7964 ICALL_EXPORT MonoBoolean
7965 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_RoOriginateLanguageException(int error, MonoString* message, void* languageException)
7967 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.RoOriginateLanguageException internal call is not implemented."));
7972 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_RoReportUnhandledError(MonoObject* error)
7974 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.RoReportUnhandledError internal call is not implemented."));
7978 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsCreateString(MonoString* sourceString, int length, void** hstring)
7980 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsCreateString internal call is not implemented."));
7985 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsDeleteString(void* hstring)
7987 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsDeleteString internal call is not implemented."));
7991 ICALL_EXPORT mono_unichar2*
7992 ves_icall_System_Runtime_InteropServices_WindowsRuntime_UnsafeNativeMethods_WindowsGetStringRawBuffer(void* hstring, unsigned* length)
7994 mono_set_pending_exception(mono_get_exception_not_implemented("System.Runtime.InteropServices.WindowsRuntime.UnsafeNativeMethods.WindowsGetStringRawBuffer internal call is not implemented."));
8001 #ifndef DISABLE_ICALL_TABLES
8003 #define ICALL_TYPE(id,name,first)
8004 #define ICALL(id,name,func) Icall_ ## id,
8005 #define HANDLES(inner) inner
8008 #include "metadata/icall-def.h"
8014 #define ICALL_TYPE(id,name,first) Icall_type_ ## id,
8015 #define ICALL(id,name,func)
8017 #define HANDLES(inner) inner
8019 #include "metadata/icall-def.h"
8025 #define ICALL_TYPE(id,name,firstic) {(Icall_ ## firstic)},
8026 #define ICALL(id,name,func)
8028 #define HANDLES(inner) inner
8030 guint16 first_icall;
8033 static const IcallTypeDesc
8034 icall_type_descs [] = {
8035 #include "metadata/icall-def.h"
8039 #define icall_desc_num_icalls(desc) ((desc) [1].first_icall - (desc) [0].first_icall)
8042 #define HANDLES(inner) inner
8044 #define ICALL_TYPE(id,name,first)
8047 #ifdef HAVE_ARRAY_ELEM_INIT
8048 #define MSGSTRFIELD(line) MSGSTRFIELD1(line)
8049 #define MSGSTRFIELD1(line) str##line
8051 static const struct msgstrtn_t {
8052 #define ICALL(id,name,func)
8054 #define ICALL_TYPE(id,name,first) char MSGSTRFIELD(__LINE__) [sizeof (name)];
8055 #include "metadata/icall-def.h"
8057 } icall_type_names_str = {
8058 #define ICALL_TYPE(id,name,first) (name),
8059 #include "metadata/icall-def.h"
8062 static const guint16 icall_type_names_idx [] = {
8063 #define ICALL_TYPE(id,name,first) [Icall_type_ ## id] = offsetof (struct msgstrtn_t, MSGSTRFIELD(__LINE__)),
8064 #include "metadata/icall-def.h"
8067 #define icall_type_name_get(id) ((const char*)&icall_type_names_str + icall_type_names_idx [(id)])
8069 static const struct msgstr_t {
8071 #define ICALL_TYPE(id,name,first)
8072 #define ICALL(id,name,func) char MSGSTRFIELD(__LINE__) [sizeof (name)];
8073 #include "metadata/icall-def.h"
8075 } icall_names_str = {
8076 #define ICALL(id,name,func) (name),
8077 #include "metadata/icall-def.h"
8080 static const guint16 icall_names_idx [] = {
8081 #define ICALL(id,name,func) [Icall_ ## id] = offsetof (struct msgstr_t, MSGSTRFIELD(__LINE__)),
8082 #include "metadata/icall-def.h"
8085 #define icall_name_get(id) ((const char*)&icall_names_str + icall_names_idx [(id)])
8091 #define ICALL_TYPE(id,name,first) name,
8092 #define ICALL(id,name,func)
8093 static const char* const
8094 icall_type_names [] = {
8095 #include "metadata/icall-def.h"
8099 #define icall_type_name_get(id) (icall_type_names [(id)])
8103 #define ICALL_TYPE(id,name,first)
8104 #define ICALL(id,name,func) name,
8105 static const char* const
8107 #include "metadata/icall-def.h"
8110 #define icall_name_get(id) icall_names [(id)]
8112 #endif /* !HAVE_ARRAY_ELEM_INIT */
8115 #define HANDLES(inner) inner
8118 #define ICALL_TYPE(id,name,first)
8119 #define ICALL(id,name,func) func,
8120 static const gconstpointer
8121 icall_functions [] = {
8122 #include "metadata/icall-def.h"
8126 #ifdef ENABLE_ICALL_SYMBOL_MAP
8128 #define HANDLES(inner) inner
8131 #define ICALL_TYPE(id,name,first)
8132 #define ICALL(id,name,func) #func,
8133 static const gconstpointer
8134 icall_symbols [] = {
8135 #include "metadata/icall-def.h"
8142 #define ICALL_TYPE(id,name,first)
8143 #define ICALL(id,name,func) 0,
8145 #define HANDLES(inner) 1,
8147 icall_uses_handles [] = {
8148 #include "metadata/icall-def.h"
8153 #endif /* DISABLE_ICALL_TABLES */
8155 static mono_mutex_t icall_mutex;
8156 static GHashTable *icall_hash = NULL;
8157 static GHashTable *jit_icall_hash_name = NULL;
8158 static GHashTable *jit_icall_hash_addr = NULL;
8161 mono_icall_init (void)
8163 #ifndef DISABLE_ICALL_TABLES
8166 /* check that tables are sorted: disable in release */
8169 const char *prev_class = NULL;
8170 const char *prev_method;
8172 for (i = 0; i < Icall_type_num; ++i) {
8173 const IcallTypeDesc *desc;
8176 if (prev_class && strcmp (prev_class, icall_type_name_get (i)) >= 0)
8177 g_print ("class %s should come before class %s\n", icall_type_name_get (i), prev_class);
8178 prev_class = icall_type_name_get (i);
8179 desc = &icall_type_descs [i];
8180 num_icalls = icall_desc_num_icalls (desc);
8181 /*g_print ("class %s has %d icalls starting at %d\n", prev_class, num_icalls, desc->first_icall);*/
8182 for (j = 0; j < num_icalls; ++j) {
8183 const char *methodn = icall_name_get (desc->first_icall + j);
8184 if (prev_method && strcmp (prev_method, methodn) >= 0)
8185 g_print ("method %s should come before method %s\n", methodn, prev_method);
8186 prev_method = methodn;
8192 icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
8193 mono_os_mutex_init (&icall_mutex);
8197 mono_icall_lock (void)
8199 mono_locks_os_acquire (&icall_mutex, IcallLock);
8203 mono_icall_unlock (void)
8205 mono_locks_os_release (&icall_mutex, IcallLock);
8209 mono_icall_cleanup (void)
8211 g_hash_table_destroy (icall_hash);
8212 g_hash_table_destroy (jit_icall_hash_name);
8213 g_hash_table_destroy (jit_icall_hash_addr);
8214 mono_os_mutex_destroy (&icall_mutex);
8218 * mono_add_internal_call:
8219 * @name: method specification to surface to the managed world
8220 * @method: pointer to a C method to invoke when the method is called
8222 * This method surfaces the C function pointed by @method as a method
8223 * that has been surfaced in managed code with the method specified in
8224 * @name as an internal call.
8226 * Internal calls are surfaced to all app domains loaded and they are
8227 * accessibly by a type with the specified name.
8229 * You must provide a fully qualified type name, that is namespaces
8230 * and type name, followed by a colon and the method name, with an
8231 * optional signature to bind.
8233 * For example, the following are all valid declarations:
8235 * "MyApp.Services.ScriptService:Accelerate"
8236 * "MyApp.Services.ScriptService:Slowdown(int,bool)"
8238 * You use method parameters in cases where there might be more than
8239 * one surface method to managed code. That way you can register different
8240 * internal calls for different method overloads.
8242 * The internal calls are invoked with no marshalling. This means that .NET
8243 * types like System.String are exposed as `MonoString *` parameters. This is
8244 * different than the way that strings are surfaced in P/Invoke.
8246 * For more information on how the parameters are marshalled, see the
8247 * <a href="http://www.mono-project.com/docs/advanced/embedding/">Mono Embedding</a>
8250 * See the <a href="mono-api-methods.html#method-desc">Method Description</a>
8251 * reference for more information on the format of method descriptions.
8254 mono_add_internal_call (const char *name, gconstpointer method)
8258 g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
8260 mono_icall_unlock ();
8263 #ifndef DISABLE_ICALL_TABLES
8265 #ifdef HAVE_ARRAY_ELEM_INIT
8267 compare_method_imap (const void *key, const void *elem)
8269 const char* method_name = (const char*)&icall_names_str + (*(guint16*)elem);
8270 return strcmp (key, method_name);
8274 find_slot_icall (const IcallTypeDesc *imap, const char *name)
8276 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);
8279 return (nameslot - &icall_names_idx [0]);
8283 find_uses_handles_icall (const IcallTypeDesc *imap, const char *name)
8285 gsize slotnum = find_slot_icall (imap, name);
8288 return (gboolean)icall_uses_handles [slotnum];
8292 find_method_icall (const IcallTypeDesc *imap, const char *name)
8294 gsize slotnum = find_slot_icall (imap, name);
8297 return (gpointer)icall_functions [slotnum];
8301 compare_class_imap (const void *key, const void *elem)
8303 const char* class_name = (const char*)&icall_type_names_str + (*(guint16*)elem);
8304 return strcmp (key, class_name);
8307 static const IcallTypeDesc*
8308 find_class_icalls (const char *name)
8310 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);
8313 return &icall_type_descs [nameslot - &icall_type_names_idx [0]];
8316 #else /* HAVE_ARRAY_ELEM_INIT */
8319 compare_method_imap (const void *key, const void *elem)
8321 const char** method_name = (const char**)elem;
8322 return strcmp (key, *method_name);
8326 find_slot_icall (const IcallTypeDesc *imap, const char *name)
8328 const char **nameslot = mono_binary_search (name, icall_names + imap->first_icall, icall_desc_num_icalls (imap), sizeof (icall_names [0]), compare_method_imap);
8331 return nameslot - icall_names;
8335 find_method_icall (const IcallTypeDesc *imap, const char *name)
8337 gsize slotnum = find_slot_icall (imap, name);
8340 return (gpointer)icall_functions [slotnum];
8344 find_uses_handles_icall (const IcallTypeDesc *imap, const char *name)
8346 gsize slotnum = find_slot_icall (imap, name);
8349 return (gboolean)icall_uses_handles [slotnum];
8353 compare_class_imap (const void *key, const void *elem)
8355 const char** class_name = (const char**)elem;
8356 return strcmp (key, *class_name);
8359 static const IcallTypeDesc*
8360 find_class_icalls (const char *name)
8362 const char **nameslot = mono_binary_search (name, icall_type_names, Icall_type_num, sizeof (icall_type_names [0]), compare_class_imap);
8365 return &icall_type_descs [nameslot - icall_type_names];
8368 #endif /* HAVE_ARRAY_ELEM_INIT */
8370 #endif /* DISABLE_ICALL_TABLES */
8373 * we should probably export this as an helper (handle nested types).
8374 * Returns the number of chars written in buf.
8377 concat_class_name (char *buf, int bufsize, MonoClass *klass)
8379 int nspacelen, cnamelen;
8380 nspacelen = strlen (klass->name_space);
8381 cnamelen = strlen (klass->name);
8382 if (nspacelen + cnamelen + 2 > bufsize)
8385 memcpy (buf, klass->name_space, nspacelen);
8386 buf [nspacelen ++] = '.';
8388 memcpy (buf + nspacelen, klass->name, cnamelen);
8389 buf [nspacelen + cnamelen] = 0;
8390 return nspacelen + cnamelen;
8393 #ifdef DISABLE_ICALL_TABLES
8395 no_icall_table (void)
8397 g_assert_not_reached ();
8402 * mono_lookup_internal_call_full:
8403 * @method: the method to look up
8404 * @uses_handles: out argument if method needs handles around managed objects.
8406 * Returns a pointer to the icall code for the given method. If
8407 * uses_handles is not NULL, it will be set to TRUE if the method
8408 * needs managed objects wrapped using the infrastructure in handle.h
8410 * If the method is not found, warns and returns NULL.
8413 mono_lookup_internal_call_full (MonoMethod *method, mono_bool *uses_handles)
8418 int typelen = 0, mlen, siglen;
8420 #ifndef DISABLE_ICALL_TABLES
8421 const IcallTypeDesc *imap = NULL;
8424 g_assert (method != NULL);
8426 if (method->is_inflated)
8427 method = ((MonoMethodInflated *) method)->declaring;
8429 if (method->klass->nested_in) {
8430 int pos = concat_class_name (mname, sizeof (mname)-2, method->klass->nested_in);
8434 mname [pos++] = '/';
8437 typelen = concat_class_name (mname+pos, sizeof (mname)-pos-1, method->klass);
8443 typelen = concat_class_name (mname, sizeof (mname), method->klass);
8448 #ifndef DISABLE_ICALL_TABLES
8449 imap = find_class_icalls (mname);
8452 mname [typelen] = ':';
8453 mname [typelen + 1] = ':';
8455 mlen = strlen (method->name);
8456 memcpy (mname + typelen + 2, method->name, mlen);
8457 sigstart = mname + typelen + 2 + mlen;
8460 tmpsig = mono_signature_get_desc (mono_method_signature (method), TRUE);
8461 siglen = strlen (tmpsig);
8462 if (typelen + mlen + siglen + 6 > sizeof (mname))
8465 memcpy (sigstart + 1, tmpsig, siglen);
8466 sigstart [siglen + 1] = ')';
8467 sigstart [siglen + 2] = 0;
8472 res = g_hash_table_lookup (icall_hash, mname);
8475 *uses_handles = FALSE;
8476 mono_icall_unlock ();;
8479 /* try without signature */
8481 res = g_hash_table_lookup (icall_hash, mname);
8484 *uses_handles = FALSE;
8485 mono_icall_unlock ();
8489 #ifdef DISABLE_ICALL_TABLES
8490 mono_icall_unlock ();
8491 /* Fail only when the result is actually used */
8492 /* mono_marshal_get_native_wrapper () depends on this */
8493 if (method->klass == mono_defaults.string_class && !strcmp (method->name, ".ctor"))
8494 return ves_icall_System_String_ctor_RedirectToCreateString;
8496 return no_icall_table;
8498 /* it wasn't found in the static call tables */
8501 *uses_handles = FALSE;
8502 mono_icall_unlock ();
8505 res = find_method_icall (imap, sigstart - mlen);
8508 *uses_handles = find_uses_handles_icall (imap, sigstart - mlen);
8509 mono_icall_unlock ();
8512 /* try _with_ signature */
8514 res = find_method_icall (imap, sigstart - mlen);
8517 *uses_handles = find_uses_handles_icall (imap, sigstart - mlen);
8518 mono_icall_unlock ();
8522 g_warning ("cant resolve internal call to \"%s\" (tested without signature also)", mname);
8523 g_print ("\nYour mono runtime and class libraries are out of sync.\n");
8524 g_print ("The out of sync library is: %s\n", method->klass->image->name);
8525 g_print ("\nWhen you update one from git you need to update, compile and install\nthe other too.\n");
8526 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");
8527 g_print ("If you see other errors or faults after this message they are probably related\n");
8528 g_print ("and you need to fix your mono install first.\n");
8530 mono_icall_unlock ();
8537 mono_lookup_internal_call (MonoMethod *method)
8539 return mono_lookup_internal_call_full (method, NULL);
8542 #ifdef ENABLE_ICALL_SYMBOL_MAP
8544 func_cmp (gconstpointer key, gconstpointer p)
8546 return (gsize)key - (gsize)*(gsize*)p;
8551 * mono_lookup_icall_symbol:
8553 * Given the icall METHOD, returns its C symbol.
8556 mono_lookup_icall_symbol (MonoMethod *m)
8558 #ifdef DISABLE_ICALL_TABLES
8559 g_assert_not_reached ();
8562 #ifdef ENABLE_ICALL_SYMBOL_MAP
8566 static gconstpointer *functions_sorted;
8567 static const char**symbols_sorted;
8568 static gboolean inited;
8573 functions_sorted = g_malloc (G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8574 memcpy (functions_sorted, icall_functions, G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8575 symbols_sorted = g_malloc (G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8576 memcpy (symbols_sorted, icall_symbols, G_N_ELEMENTS (icall_functions) * sizeof (gpointer));
8577 /* Bubble sort the two arrays */
8581 for (i = 0; i < G_N_ELEMENTS (icall_functions) - 1; ++i) {
8582 if (functions_sorted [i] > functions_sorted [i + 1]) {
8585 tmp = functions_sorted [i];
8586 functions_sorted [i] = functions_sorted [i + 1];
8587 functions_sorted [i + 1] = tmp;
8588 tmp = symbols_sorted [i];
8589 symbols_sorted [i] = symbols_sorted [i + 1];
8590 symbols_sorted [i + 1] = tmp;
8597 func = mono_lookup_internal_call (m);
8600 slot = mono_binary_search (func, functions_sorted, G_N_ELEMENTS (icall_functions), sizeof (gpointer), func_cmp);
8604 return symbols_sorted [(gpointer*)slot - (gpointer*)functions_sorted];
8606 fprintf (stderr, "icall symbol maps not enabled, pass --enable-icall-symbol-map to configure.\n");
8607 g_assert_not_reached ();
8614 type_from_typename (char *type_name)
8616 MonoClass *klass = NULL; /* assignment to shut GCC warning up */
8618 if (!strcmp (type_name, "int"))
8619 klass = mono_defaults.int_class;
8620 else if (!strcmp (type_name, "ptr"))
8621 klass = mono_defaults.int_class;
8622 else if (!strcmp (type_name, "void"))
8623 klass = mono_defaults.void_class;
8624 else if (!strcmp (type_name, "int32"))
8625 klass = mono_defaults.int32_class;
8626 else if (!strcmp (type_name, "uint32"))
8627 klass = mono_defaults.uint32_class;
8628 else if (!strcmp (type_name, "int8"))
8629 klass = mono_defaults.sbyte_class;
8630 else if (!strcmp (type_name, "uint8"))
8631 klass = mono_defaults.byte_class;
8632 else if (!strcmp (type_name, "int16"))
8633 klass = mono_defaults.int16_class;
8634 else if (!strcmp (type_name, "uint16"))
8635 klass = mono_defaults.uint16_class;
8636 else if (!strcmp (type_name, "long"))
8637 klass = mono_defaults.int64_class;
8638 else if (!strcmp (type_name, "ulong"))
8639 klass = mono_defaults.uint64_class;
8640 else if (!strcmp (type_name, "float"))
8641 klass = mono_defaults.single_class;
8642 else if (!strcmp (type_name, "double"))
8643 klass = mono_defaults.double_class;
8644 else if (!strcmp (type_name, "object"))
8645 klass = mono_defaults.object_class;
8646 else if (!strcmp (type_name, "obj"))
8647 klass = mono_defaults.object_class;
8648 else if (!strcmp (type_name, "string"))
8649 klass = mono_defaults.string_class;
8650 else if (!strcmp (type_name, "bool"))
8651 klass = mono_defaults.boolean_class;
8652 else if (!strcmp (type_name, "boolean"))
8653 klass = mono_defaults.boolean_class;
8655 g_error ("%s", type_name);
8656 g_assert_not_reached ();
8658 return &klass->byval_arg;
8662 * LOCKING: Take the corlib image lock.
8664 MonoMethodSignature*
8665 mono_create_icall_signature (const char *sigstr)
8670 MonoMethodSignature *res, *res2;
8671 MonoImage *corlib = mono_defaults.corlib;
8673 mono_image_lock (corlib);
8674 res = (MonoMethodSignature *)g_hash_table_lookup (corlib->helper_signatures, sigstr);
8675 mono_image_unlock (corlib);
8680 parts = g_strsplit (sigstr, " ", 256);
8689 res = mono_metadata_signature_alloc (corlib, len - 1);
8694 * Under windows, the default pinvoke calling convention is STDCALL but
8697 res->call_convention = MONO_CALL_C;
8700 res->ret = type_from_typename (parts [0]);
8701 for (i = 1; i < len; ++i) {
8702 res->params [i - 1] = type_from_typename (parts [i]);
8707 mono_image_lock (corlib);
8708 res2 = (MonoMethodSignature *)g_hash_table_lookup (corlib->helper_signatures, sigstr);
8710 res = res2; /*Value is allocated in the image pool*/
8712 g_hash_table_insert (corlib->helper_signatures, (gpointer)sigstr, res);
8713 mono_image_unlock (corlib);
8719 mono_find_jit_icall_by_name (const char *name)
8721 MonoJitICallInfo *info;
8722 g_assert (jit_icall_hash_name);
8725 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_name, name);
8726 mono_icall_unlock ();
8731 mono_find_jit_icall_by_addr (gconstpointer addr)
8733 MonoJitICallInfo *info;
8734 g_assert (jit_icall_hash_addr);
8737 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
8738 mono_icall_unlock ();
8744 * mono_get_jit_icall_info:
8746 * Return the hashtable mapping JIT icall names to MonoJitICallInfo structures. The
8747 * caller should access it while holding the icall lock.
8750 mono_get_jit_icall_info (void)
8752 return jit_icall_hash_name;
8756 * mono_lookup_jit_icall_symbol:
8758 * Given the jit icall NAME, returns its C symbol if possible, or NULL.
8761 mono_lookup_jit_icall_symbol (const char *name)
8763 MonoJitICallInfo *info;
8764 const char *res = NULL;
8767 info = (MonoJitICallInfo *)g_hash_table_lookup (jit_icall_hash_name, name);
8769 res = info->c_symbol;
8770 mono_icall_unlock ();
8775 mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
8778 g_hash_table_insert (jit_icall_hash_addr, (gpointer)wrapper, info);
8779 mono_icall_unlock ();
8783 * 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
8784 * icalls without wrappers in some cases.
8787 mono_register_jit_icall_full (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save, gboolean no_raise, const char *c_symbol)
8789 MonoJitICallInfo *info;
8796 if (!jit_icall_hash_name) {
8797 jit_icall_hash_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
8798 jit_icall_hash_addr = g_hash_table_new (NULL, NULL);
8801 if (g_hash_table_lookup (jit_icall_hash_name, name)) {
8802 g_warning ("jit icall already defined \"%s\"\n", name);
8803 g_assert_not_reached ();
8806 info = g_new0 (MonoJitICallInfo, 1);
8811 info->c_symbol = c_symbol;
8812 info->no_raise = no_raise;
8815 info->wrapper = func;
8817 info->wrapper = NULL;
8820 g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
8821 g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
8823 mono_icall_unlock ();
8828 mono_register_jit_icall (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save)
8830 return mono_register_jit_icall_full (func, name, sig, is_save, FALSE, NULL);